Campaigns
One-off email campaigns, templates, audience resolution, test sends and sending.
15 endpoints· 5 called live· 10 not exercised here· verified against http://127.0.0.1:8741
15 endpoints
GET/api/v1/salesshift/campaignsCalled liveThe organization's campaigns with their tracking rollups.
Request
curl 'https://api.vxcloud.io/api/v1/salesshift/campaigns' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "bool",
"data": [
{
"id": "str",
"name": "str",
"status": "str",
"subject": "str",
"body_html": "str",
"template_key": "str",
"from_label": "str",
"sender_account_id": "null",
"sender_integration_id": "null",
"from_name": "str",
"from_email": "str",
"reply_to": "str",
"list_ids": [
"<empty list>"
],
"contact_ids": [
"...",
"...x2"
],
"send_at": "null",
"sent_at": "str",
"total_recipients": "int",
"sent_count": "int",
"failed_count": "int",
"suppressed_count": "int",
"error": "null",
"created_at": "str",
"opened": "int",
"replied": "int",
"clicked": "int"
},
"...x2"
],
"cap": "int"
}POST/api/v1/salesshift/campaignsNot exercised hereCreate a campaign after validating the sender and resolving the audience.
Request body (required) — CampaignIn
| Field | Type | Required | Notes |
|---|---|---|---|
| name | string | required | ≤ 255 chars. |
| subject | string | optional | Default "". |
| body_html | string | optional | Default "". |
| template_key | string? | optional | |
| list_ids | string(uuid)[] | optional | Default []. |
| contact_ids | string(uuid)[] | optional | Default []. |
| sender_account_id | string(uuid)? | optional | |
| sender_integration_id | string(uuid)? | optional | |
| from_name | string | optional | Default "". |
| from_email | string | optional | Default "". |
| reply_to | string | optional | Default "". |
Values in the request below are typed placeholders, not sample data.
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/campaigns' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "name": "<string>", "subject": "", "body_html": "", "template_key": "<string>", "list_ids": [], "contact_ids": [], "sender_account_id": "<string(uuid)>", "sender_integration_id": "<string(uuid)>", "from_name": "", "from_email": "", "reply_to": "" }'Response · 201
{
"data": "…",
"success": "…"
}GET/api/v1/salesshift/campaigns/{campaign_id}Called liveOne campaign with its stats and per-recipient tracking rows.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| campaign_id | string(uuid) | required |
Request
curl 'https://api.vxcloud.io/api/v1/salesshift/campaigns/{campaign_id}' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "bool",
"data": {
"id": "str",
"name": "str",
"status": "str",
"subject": "str",
"body_html": "str",
"template_key": "str",
"from_label": "str",
"sender_account_id": "null",
"sender_integration_id": "null",
"from_name": "str",
"from_email": "str",
"reply_to": "str",
"list_ids": [
"<empty list>"
],
"contact_ids": [
"str",
"...x2"
],
"send_at": "null",
"sent_at": "str",
"total_recipients": "int",
"sent_count": "int",
"failed_count": "int",
"suppressed_count": "int",
"error": "null",
"created_at": "str",
"opened": "int",
"replied": "int",
"clicked": "int"
},
"recipients": [
{
"to_email": "str",
"status": "str",
"opened": "bool",
"replied": "bool",
"error": "null",
"sent_at": "str"
},
"...x2"
]
}PATCH/api/v1/salesshift/campaigns/{campaign_id}Not exercised hereEdit a campaign; only drafts and scheduled campaigns can be edited.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| campaign_id | string(uuid) | required |
Request body (required) — CampaignIn
| Field | Type | Required | Notes |
|---|---|---|---|
| name | string | required | ≤ 255 chars. |
| subject | string | optional | Default "". |
| body_html | string | optional | Default "". |
| template_key | string? | optional | |
| list_ids | string(uuid)[] | optional | Default []. |
| contact_ids | string(uuid)[] | optional | Default []. |
| sender_account_id | string(uuid)? | optional | |
| sender_integration_id | string(uuid)? | optional | |
| from_name | string | optional | Default "". |
| from_email | string | optional | Default "". |
| reply_to | string | optional | Default "". |
Values in the request below are typed placeholders, not sample data.
Request
curl -X PATCH 'https://api.vxcloud.io/api/v1/salesshift/campaigns/{campaign_id}' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "name": "<string>", "subject": "", "body_html": "", "template_key": "<string>", "list_ids": [], "contact_ids": [], "sender_account_id": "<string(uuid)>", "sender_integration_id": "<string(uuid)>", "from_name": "", "from_email": "", "reply_to": "" }'Response · 200
{
"data": "…",
"success": "…"
}Errors
| Status | detail |
|---|---|
| 400 | Only drafts can be edited |
DELETE/api/v1/salesshift/campaigns/{campaign_id}Not exercised hereDelete a campaign.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| campaign_id | string(uuid) | required |
Request
curl -X DELETE 'https://api.vxcloud.io/api/v1/salesshift/campaigns/{campaign_id}' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "…"
}POST/api/v1/salesshift/campaigns/{campaign_id}/sendNot exercised hereSend or schedule a campaign to its resolved audience.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| campaign_id | string(uuid) | required |
Request body (required) — app__services__salesshift__campaigns_router__SendIn
| Field | Type | Required | Notes |
|---|---|---|---|
| send_at | string(date-time)? | optional |
Values in the request below are typed placeholders, not sample data.
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/campaigns/{campaign_id}/send' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "send_at": "<string(date-time)>" }'Response · 200
{
"failed": "…",
"send_at": "…",
"sent": "…",
"status": "…",
"success": "…",
"suppressed": "…"
}Errors
| Status | detail |
|---|---|
| 400 | Campaign already {...} |
| 400 | Campaign needs a subject and a body |
POST/api/v1/salesshift/campaigns/{campaign_id}/test-sendNot exercised hereSend one preview copy to a chosen address using a transient probe contact.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| campaign_id | string(uuid) | required |
Request body (required) — TestSendIn
| Field | Type | Required | Notes |
|---|---|---|---|
| to_email | string | required |
Values in the request below are typed placeholders, not sample data.
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/campaigns/{campaign_id}/test-send' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "to_email": "<string>" }'Response · 200
{
"error": "…",
"provider": "…",
"status": "…",
"success": "…"
}Errors
| Status | detail |
|---|---|
| 400 | computed at runtime: str(exc) |
POST/api/v1/salesshift/campaigns/{campaign_id}/unscheduleNot exercised herePut a scheduled campaign back into draft.
Put a scheduled campaign back into draft. Scheduling was a one-way door: `process_due_campaigns` would fire it and the UI offered no way to stop it. Clearing `send_at` with the status is what keeps the dispatch loop from picking it up again.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| campaign_id | string(uuid) | required |
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/campaigns/{campaign_id}/unschedule' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"data": "…",
"success": "…"
}Errors
| Status | detail |
|---|---|
| 400 | Campaign is {...}, not scheduled |
POST/api/v1/salesshift/campaigns/audience-previewCalled liveResolve lists and contact ids to a sendable audience, reporting what was dropped and the cap.
Request body (required) — AudiencePreviewIn
| Field | Type | Required | Notes |
|---|---|---|---|
| list_ids | string(uuid)[] | optional | Default []. |
| contact_ids | string(uuid)[] | optional | Default []. |
The body in the request below is the exact one sent during verification.
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/campaigns/audience-preview' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "list_ids": [], "contact_ids": [] }'Response · 200
{
"success": "bool",
"count": "int",
"dropped": "int",
"cap": "int",
"over_cap": "int",
"sample": [
"<empty list>"
]
}GET/api/v1/salesshift/campaigns/sendersCalled liveAvailable sending servers: every active BYOK email integration (multi-SMTP: one entry per configured server, default first) + every active connected mailbox (each one a full SMTP identity).
Available sending servers: every active BYOK email integration (multi-SMTP: one entry per configured server, default first) + every active connected mailbox (each one a full SMTP identity).
Request
curl 'https://api.vxcloud.io/api/v1/salesshift/campaigns/senders' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "bool",
"data": [
{
"id": "str",
"kind": "str",
"label": "str",
"from_email": "str",
"from_name": "str",
"reply_to": "str",
"is_default": "bool",
"provider": "str"
},
"...x7"
]
}GET/api/v1/salesshift/campaigns/templatesCalled liveBuilt-in email templates plus the organization's saved ones.
Request
curl 'https://api.vxcloud.io/api/v1/salesshift/campaigns/templates' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "bool",
"builtin": [
{
"key": "str",
"name": "str",
"category": "str",
"description": "str",
"subject": "str",
"body_html": "str"
},
"...x6"
],
"custom": [
{
"key": "str",
"id": "str",
"name": "str",
"category": "str",
"description": "str",
"subject": "str",
"body_html": "str",
"created_at": "str",
"updated_at": "str"
},
"...x11"
]
}POST/api/v1/salesshift/campaigns/templatesNot exercised hereSave a custom email template.
Request body (required) — TemplateIn
| Field | Type | Required | Notes |
|---|---|---|---|
| name | string | required | |
| category | string | optional | Default "Custom". |
| subject | string | optional | Default "". |
| body_html | string | optional | Default "". |
Values in the request below are typed placeholders, not sample data.
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/campaigns/templates' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "name": "<string>", "category": "Custom", "subject": "", "body_html": "" }'Response · 201
{
"data": "…",
"id": "…",
"success": "…"
}PUT/api/v1/salesshift/campaigns/templates/{template_id}Not exercised hereUpdate a saved email template.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| template_id | string(uuid) | required |
Request body (required) — TemplateUpdateIn
| Field | Type | Required | Notes |
|---|---|---|---|
| name | string? | optional | |
| category | string? | optional | |
| subject | string? | optional | |
| body_html | string? | optional |
Values in the request below are typed placeholders, not sample data.
Request
curl -X PUT 'https://api.vxcloud.io/api/v1/salesshift/campaigns/templates/{template_id}' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "name": "<string>", "category": "<string>", "subject": "<string>", "body_html": "<string>" }'Response · 200
{
"data": "…",
"success": "…"
}DELETE/api/v1/salesshift/campaigns/templates/{template_id}Not exercised hereDelete a saved email template.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| template_id | string(uuid) | required |
Request
curl -X DELETE 'https://api.vxcloud.io/api/v1/salesshift/campaigns/templates/{template_id}' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "…"
}POST/api/v1/salesshift/campaigns/templates/seedNot exercised hereDrop the starter 1:1 sales library into this org.
Drop the starter 1:1 sales library into this org. Idempotent — a template whose name already exists in the org is skipped, never duplicated or overwritten (the rep's edits win).
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/campaigns/templates/seed' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"created": "…",
"data": "…",
"skipped": "…",
"success": "…"
}