Campaigns & sequences
Current release · Updated October 2, 2026
DryKraft campaigns & sequences API: methods, permissions, request fields, response shapes, examples and current limits. Read authentication and error handling first.
/api/outreach/campaignsList campaigns and sequences
Access: Workspace member · Success: 200
Latest 100 with connection_name, enrolled and accepted counts. Accepted includes provider accepted/delivered/read/replied, not proof of delivery.
No request body is required.
Response
Campaign[].
curl --request GET \
--url 'https://app.drykraft.com/api/outreach/campaigns' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'/api/outreach/campaignsCreate campaign or sequence draft
Access: Owner, admin or member · Success: 201
Nonfinancial audience <=500 source records. Connection channel must match; no enrollment/send until reviewed launch.
JSON request
Use CampaignInput.
Response
Use Campaign.
curl --request POST \
--url 'https://app.drykraft.com/api/outreach/campaigns' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"name": "Example email follow-up",
"kind": "campaign",
"channel": "email",
"object_key": "people",
"list_id": null,
"connection_id": "00000000-0000-4000-8000-000000000001",
"steps": [
{
"waitHours": 0,
"subject": "Hello {{record.data.name}}",
"body": "Following up on your request."
}
]
}'/api/outreach/campaigns/{id}Inspect campaign
Access: Workspace member · Success: 200
Includes <=500 enrollments with execution state/error and latest 100 deliveries.
No request body is required.
Response
Use Campaign.
| Field | Type | Required | Details |
|---|---|---|---|
enrollments | object[] | No | |
deliveries | object[] | No |
curl --request GET \
--url 'https://app.drykraft.com/api/outreach/campaigns/00000000-0000-4000-8000-000000000001' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'/api/outreach/campaigns/{id}Save campaign draft
Access: Owner, admin or member · Success: 200
Only unchanged draft. Launched steps/audience are immutable; create a new draft to revise.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
name | string | Yes | Nonblank name Max 100 characters. |
kind | campaign | sequence | Yes | A campaign has exactly one step; a sequence has 1-20. |
channel | email | sms | voice | whatsapp | Yes | One channel per campaign/sequence |
object_key | string | No | Pattern: ^[a-z][a-z0-9_]{1,39}$. |
list_id | string or null | No | |
connection_id | uuid | Yes | |
steps | Step[] | Yes | Min 1 items. Max 20 items. |
version | integer | Yes | Positive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1. |
Response
Use Campaign.
curl --request PUT \
--url 'https://app.drykraft.com/api/outreach/campaigns/00000000-0000-4000-8000-000000000001' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"name": "Example email follow-up",
"kind": "campaign",
"channel": "email",
"object_key": "people",
"list_id": null,
"connection_id": "00000000-0000-4000-8000-000000000001",
"steps": [
{
"waitHours": 0,
"subject": "Hello {{record.data.name}}",
"body": "Following up on your request."
}
],
"version": 1
}'/api/outreach/campaigns/{id}/previewReview eligible audience
Access: Owner, admin or member · Success: 200
Consent=true, valid email/international phone, unique addresses and no channel suppression. Returns latest version, SHA256 audience digest and up to 20 eligible contacts, plus skip reasons.
No request body is required.
Response
| Field | Type | Required | Details |
|---|---|---|---|
version | integer | No | Positive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1. |
audienceToken | string | No | Reviewed audience digest |
total | integer | No | Source contacts |
eligible | integer | No | Eligible count |
skipped | object[] | No | |
contacts | object[] | No | |
firstStep | Step | No |
curl --request POST \
--url 'https://app.drykraft.com/api/outreach/campaigns/00000000-0000-4000-8000-000000000001/preview' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'/api/outreach/campaigns/{id}/launchLaunch reviewed audience
Access: Owner or admin · Success: 202
This performs real outreach asynchronously. Fresh digest/version/confirmation required. Verified enabled connector; validates QCall choices or approved WhatsApp body template parameters. Recheck stale audience on 409. Shared sample blocked.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
version | integer | Yes | Positive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1. |
audienceToken | string | Yes | Pattern: ^[a-f0-9]{64}$. |
confirmed | true | Yes |
Response
| Field | Type | Required | Details |
|---|---|---|---|
enrolled | integer | No | Enrolled |
skipped | integer | No | Skipped |
curl --request POST \
--url 'https://app.drykraft.com/api/outreach/campaigns/00000000-0000-4000-8000-000000000001/launch' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"version": 1,
"audienceToken": "<value>",
"confirmed": true
}'/api/outreach/campaigns/{id}/statusPause, resume or cancel
Access: Owner or admin · Success: 200
Cannot change draft/cancelled. Pause waits before future steps; cancel stops unfinished executions. Already accepted provider side effects cannot be recalled.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
status | active | paused | cancelled | Yes | Campaign state |
Response
| Field | Type | Required | Details |
|---|---|---|---|
status | string | No | New state |
curl --request POST \
--url 'https://app.drykraft.com/api/outreach/campaigns/00000000-0000-4000-8000-000000000001/status' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"status": "active"
}'/api/outreach/campaigns/{id}/contacts/{record}/stopStop one enrolled contact
Access: Owner, admin or member · Success: 200
Stops unfinished follow-ups for this campaign; does not permanently suppress other campaigns. Use Suppressions for that.
No request body is required.
Response
Use OK.
curl --request POST \
--url 'https://app.drykraft.com/api/outreach/campaigns/00000000-0000-4000-8000-000000000001/contacts/00000000-0000-4000-8000-000000000001/stop' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'/api/outreach/activityRead recent outreach activity
Access: Workspace member · Success: 200
Latest 100 deliveries and 50 incoming messages, with connection names. Unknown means acceptance was ambiguous: check provider before a new attempt.
No request body is required.
Response
| Field | Type | Required | Details |
|---|---|---|---|
deliveries | object[] | No | |
messages | object[] | No |
curl --request GET \
--url 'https://app.drykraft.com/api/outreach/activity' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'/api/outreach/suppressionsRead channel suppressions
Access: Workspace member · Success: 200
Latest 100. Permanent per workspace/channel; no removal API in current release.
No request body is required.
Response
object[]. channel, recipient, reason, created_at
curl --request GET \
--url 'https://app.drykraft.com/api/outreach/suppressions' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'/api/outreach/suppressionsSuppress recipient
Access: Owner, admin or member · Success: 200
Normalizes email lowercase or international +phone; stops active sequences on this channel/workspace.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
channel | email | sms | voice | whatsapp | Yes | Channel |
recipient | string | Yes | Email or international phone Max 200 characters. |
Response
Use OK.
curl --request POST \
--url 'https://app.drykraft.com/api/outreach/suppressions' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"channel": "email",
"recipient": "<Email or international phone>"
}'