Gary Club
Resource

SMS Broadcasts

Headless equivalent of the agency Broadcasts dashboard. Create a broadcast against a CRM list (or a smart list), approve it, and send it now or on schedule.

Tenancy + agent
Broadcasts pin org_id, client_id, AND agent_id. The agent must be an SMS agent owned by that client; cross-client agent ids return 422 unprocessable. Client-scoped keys auto- narrow client_id to their bound client.

List broadcasts#

Paginated list

GET/v1/sms-broadcasts

Query parameters

agent_iduuid
Narrow to one SMS agent.
statusstring
Filter — draft, scheduled, pending_approval, approved, sending, completed, cancelled.
limitintegerdefault: 50
page_tokenstring

Create a broadcast#

Create a draft, scheduled, or recurring broadcast

POST/v1/sms-broadcasts
Creates the broadcast row and resolves the recipient list. Sends and approvals are separate endpoints. schedule_mode picks the lifecycle:
• one_shot — created as draft; you call send-now when ready.
• scheduled — fires once at scheduled_at.
• recurring — fires on therecurrence_rule (RRULE syntax) inrecurrence_timezone.

Body parameters

agent_iduuid
Required. SMS agent that owns the conversation.
client_iduuid
Required when using an agency key without X-Gary-Client-Id.
list_iduuid
CRM list to send to. One of list_id or smart_list_slug is required.
smart_list_slugstring
Smart list (e.g. inbound_no_book_30d). Resolved at send time.
namestring
Internal label, ≤200 chars.
bodystring
Message body, ≤1600 chars. Use {{first_name}} / {{last_name}} placeholders.
media_urlsstring[]
Up to 10 MMS attachment URLs.
schedule_modestring
one_shot (default) | scheduled | recurring.
scheduled_atiso datetime
Required when schedule_mode=scheduled.
recurrence_rulestring
iCalendar RRULE; required when schedule_mode=recurring.
recurrence_timezonestring
IANA tz, default UTC.
Request
curl -X POST \
  https://agency.gary.club/api/public/v1/sms-broadcasts \
  -H "Authorization: Bearer cl_live_EXAMPLE_AbCdEfGhIj0123456789" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "agent_3kf9ab",
    "list_id": "list_EXAMPLE_aaaa",
    "name": "Spring promo — leads who never booked",
    "body": "Hey {{first_name}}, the spring tune-up special ends Friday. Reply Y to grab a slot.",
    "schedule_mode": "scheduled",
    "scheduled_at": "2026-04-29T15:00:00.000Z"
  }'
Response
{
  "broadcast": {
    "id": "bc_EXAMPLE_aaaa",
    "client_id": "ccccccc-cccc-4ccc-cccc-cccccccccccc",
    "agent_id": "agent_3kf9ab",
    "list_id": "list_EXAMPLE_aaaa",
    "name": "Spring promo — leads who never booked",
    "body": "Hey {{first_name}}, the spring tune-up special ends Friday. Reply Y to grab a slot.",
    "status": "scheduled",
    "schedule_mode": "scheduled",
    "scheduled_at": "2026-04-29T15:00:00.000Z",
    "next_run_at": "2026-04-29T15:00:00.000Z",
    "recipient_count": 0,
    "delivered_count": 0,
    "failed_count": 0,
    "optout_count": 0,
    "requires_approval": true,
    "approved_at": null,
    "estimated_credits": null,
    "created_at": "2026-04-28T01:18:53.000Z"
  }
}

Read one#

Single broadcast with stats

GET/v1/sms-broadcasts/{id}

Path parameters

iduuidrequired
Broadcast id.

Update#

Update mutable fields (only while in draft / scheduled)

PATCH/v1/sms-broadcasts/{id}

Path parameters

iduuidrequired

Approve#

Approve a broadcast that needs sign-off

POST/v1/sms-broadcasts/{id}/approve
Some broadcasts (large recipient counts, high-cost projections, agency policy) land with requires_approval=true. This endpoint flips them to approved so they can send.

Path parameters

iduuidrequired

Send now#

Force-send a draft or scheduled broadcast immediately

POST/v1/sms-broadcasts/{id}/send-now
Pushes next_run_at to now and flips to sending state. The send worker picks it up on the next tick (within ~60s).

Path parameters

iduuidrequired

Recipients#

Per-recipient delivery state

GET/v1/sms-broadcasts/{id}/recipients
Paginated. Includes message status (queued / sent / delivered / failed / opted_out), reply count, and last-event timestamp.

Path parameters

iduuidrequired

Query parameters

limitintegerdefault: 50
page_tokenstring
statusstring
Narrow to one delivery state.

Webhooks for broadcasts#

  • broadcast.scheduled — created with a future run time.
  • broadcast.send_started — first message left the queue.
  • broadcast.send_completed — final recipient processed.
  • broadcast.opt_out — a recipient replied STOP / unsubscribed.