Gary Club
Resource

SDR Campaigns

Outbound voice SDR. Create campaigns from the API, attach prospect lists, set the calling window, and let the dialer cron work the queue.

Agency-only resource
SDR campaigns live at the agency (org) level — there is no per-client scoping. Client-bound keys (cl_live_…) are rejected with 403. Use a gc_live_… agency key. The campaign reuses the org's shared inbound SDR agent + phone, so you must have SDR provisioned in the agency portal first.
Feature gate
SDR outbound is gated on organizations.ai_sdr_outbound_enabled per agency. POST returns 403 feature_disabled until that flag is on. Reach out to your account contact when you're ready to flip it.

List campaigns#

List SDR campaigns

GET/v1/sdr/campaigns

Query parameters

statusstring
Filter — draft, scheduled, active, paused, completed, cancelled, archived.
limitintegerdefault: 50
page_tokenstring

Create a campaign#

Create an outbound voice campaign

POST/v1/sdr/campaigns
Defaults are pulled from the agency's inbound SDR config (voice, business name, from-number) when omitted. Optionally attach prospect_ids to queue dialing.

Body parameters

namestring
Required. ≤200 chars.
descriptionstring
Optional, ≤4000 chars.
opening_messagestring
What the agent says when the prospect picks up.
voicemail_messagestring
Pre-recorded VM drop content if no answer.
system_promptstring
Override the SDR agent prompt for this campaign.
voice_idstring
ElevenLabs voice override.
voice_namestring
Display name for the voice.
from_numberstring
E.164. Defaults to org SDR phone.
prospect_idsuuid[]
Existing prospect rows to enqueue (status flips to queued).
max_concurrent_callsinteger
1–10. How many lines the dialer can run in parallel.
calling_window_startHH:mm
Default 09:00.
calling_window_endHH:mm
Default 20:00.
calling_daysinteger[]
ISO weekdays 1=Mon … 7=Sun. Default [1,2,3,4,5].
respect_timezoneboolean
When true, window is per-prospect TZ (default true).
max_attemptsinteger
1–10. Default 3.
retry_interval_hoursinteger
Hours between attempts (default 24).
ring_timeout_secondsinteger
15–120. Default 60.
max_duration_secondsinteger
30–1800. Default 300.
scheduled_start_atiso datetime
When omitted, campaign is created in draft state. When set, status=scheduled.
voicemail_enabledboolean
Default true.
cal_com_booking_urlstring
For agents that book on cal.com.
post_call_emailstring
Email summary destination after each completed call.
Request
curl -X POST \
  https://agency.gary.club/api/public/v1/sdr/campaigns \
  -H "Authorization: Bearer gc_live_EXAMPLE_AbCdEfGhIj0123456789" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q2 reactivation — lapsed customers",
    "description": "Win-back dial to customers who haven't booked in 90+ days",
    "opening_message": "Hi this is Sarah from {{business_name}} — quick check-in on your service plan, do you have a sec?",
    "voicemail_message": "Hi, this is Sarah from {{business_name}}. Wanted to check in about your service plan. Give us a ring back when you have a moment, thanks!",
    "calling_window_start": "10:00",
    "calling_window_end": "18:00",
    "calling_days": [1, 2, 3, 4, 5],
    "respect_timezone": true,
    "max_attempts": 3,
    "retry_interval_hours": 48,
    "max_concurrent_calls": 2,
    "scheduled_start_at": "2026-04-29T15:00:00.000Z",
    "prospect_ids": ["pro_EXAMPLE_aaaa", "pro_EXAMPLE_bbbb"]
  }'
Response
{
  "campaign": {
    "id": "sdrc_EXAMPLE_aaaa",
    "name": "Q2 reactivation — lapsed customers",
    "status": "scheduled",
    "scheduled_start_at": "2026-04-29T15:00:00.000Z",
    "calling_window_start": "10:00",
    "calling_window_end": "18:00",
    "calling_days": [1, 2, 3, 4, 5],
    "respect_timezone": true,
    "max_attempts": 3,
    "max_concurrent_calls": 2,
    "total_prospects": 2,
    "from_number": "+15124204121",
    "elevenlabs_agent_id": "el_agent_xyz",
    "voicemail_enabled": true,
    "created_at": "2026-04-28T01:18:53.000Z"
  }
}

Read one#

Single campaign with stats

GET/v1/sdr/campaigns/{id}

Path parameters

iduuidrequired

Update / pause / resume#

Update mutable fields or change status

PATCH/v1/sdr/campaigns/{id}
Status transitions: draft → scheduled → active → paused → active → completed. Setting status=paused halts dialing on the next tick; status=active resumes.

Path parameters

iduuidrequired

Body parameters

statusstring
draft | scheduled | active | paused | completed | cancelled | archived.
namestring
descriptionstring
scheduled_start_atiso datetime | null
calling_window_startHH:mm
calling_window_endHH:mm
calling_daysinteger[]
max_concurrent_callsinteger
max_attemptsinteger
retry_interval_hoursinteger
ring_timeout_secondsinteger
max_duration_secondsinteger

Archive#

Soft-archive (status=archived)

DELETE/v1/sdr/campaigns/{id}
Does NOT cancel in-flight dials. Pause first if you want them stopped.

Path parameters

iduuidrequired

Webhooks for SDR campaigns#

  • sdr.campaign.started — first dial fired.
  • sdr.campaign.completed — queue drained.
  • sdr.call.connected — prospect picked up.
  • sdr.call.voicemail — VM drop completed.
  • sdr.call.booked — call ended with a booking outcome.