API Documentation

This is the public API reference: explore every endpoint, field, error, code sample, connector and download here, no sign-in required. API access is included with every paid and lifetime plan at no extra cost. Sign in and open the API Console to create a key, run live tests and see your own IDs.
Interactive testing, your API keys, and your profile/workspace IDs light up in the in-app Console. Sign in to open it.

Let's build your integration

Bring an AI agent, automation platform, or custom application. We'll provide the marketing workflows, permissions, safeguards, and destinations so you can move fast with confidence.

What do you want this integration to do?

Build a custom integration Use several API capabilities inside your own application, product, or internal system. Choose API capabilities
Not sure where to start? Choose the outcome first. We'll guide you through the right tool, credentials, permissions, and testing.

Make your first post in 60 seconds

Here is exactly what a request looks like. In the in-app version you can run it right here (it creates a draft, so nothing is published), and your draft lands in your Publisher, ready to review, edit or schedule.

Safe to try: it only ever creates a draft, never publishes
1
This is what a request looks like. Replace PASTE_YOUR_API_KEY_HERE with your own API key in your tool's Authorization field. Nothing runs on this page, and you should never paste a key into a web page. The in-app Console injects it for you instead. Add a profile in your workspace settings and it will appear in Your IDs.
POST https://sandbox.sociamonials.com/api/v1/posts Authorization: Bearer PASTE_YOUR_API_KEY_HERE Content-Type: application/json { "mode": "draft", "message": "Hello from the API - this is a draft, nothing is published.", "networks": { "fb": { "profile_refs": [ "[your profile ID]" ] } } }
2
Send it. We run the request with your account's key behind the PASTE_YOUR_API_KEY_HERE. You never have to paste or handle it here.
Activate your live API keys in the app to run this.
In the app, Send creates a real draft using your key (never shown in your browser). Nothing publishes.
3
Open your Publisher. Your draft is waiting. When you're ready to automate for real, the same request works from any tool below.

Want to build it in a tool? See Set up an integration for Make, Zapier, n8n, and AI assistants like Claude and ChatGPT. Need the full endpoint list? See API Reference.

API keys

API keys authenticate every request. Each key acts with a chosen user's permissions, profile access and approval routing. Keys are created and managed inside your account. They are never shown on this public page.

Sign in and open the API Console to create, copy and manage your keys.
Who can create a key? API access is included with every paid and lifetime plan at no extra cost. It is not sold separately. Free trials are excluded: the Console opens but Create API Key sends you to choose a plan, and a credential belonging to a trial, lapsed or suspended account returns 402 api_subscription_inactive. The AgencyPro API additionally requires an active AgencyPro subscription on the primary agency workspace; without it that workspace gets the Workspace API instead.
Keep your keys safe. A key is shown only once, when you create or rotate it. We store only a one-way hash and can never show it again. Paste a key only into a tool's dedicated API-key, secret, or Authorization field. Never paste it into a chat message, support ticket, screenshot, or document. If a key is exposed, revoke it and create a new one.

Webhooks

Send real-time events to your applications and automations.

Get started in 4 simple steps

1
Add an endpoint Enter your https URL and pick the events to send.
2
Copy your signing secret Shown once when you save. Use it to verify each delivery.
3
Send a test event Confirm your receiver gets it. The endpoint must be enabled.
4
Enable & monitor New endpoints start enabled: events flow while enabled. Watch results below and re-enable any that turn off.
Webhook notifications are configured here when you sign in.

Delivery contract & verifying signatures

Every delivery is an HTTPS POST with a JSON body in this envelope:

{
  "event_id": "evt_sm_…",        // stable across retries, deduplicate on this
  "type": "campaign.entry_received",
  "version": 1,                    // fields may be added; meanings never change within a version
  "created_utc": "2026-08-02T18:00:00+00:00",   // when it happened, not when delivered
  "workspace_registration_id": 12345,
  "workspace_name": "Client name",  // route per-client automations on these two
  "source": { "type": "api|ui|system", "credential_id": null },
  "data": { … }                  // the event's own fields
}

Headers: X-Webhook-Event (the type), X-Webhook-Event-Id, and X-Webhook-Signature as t=<unix>,v1=<hex> where v1 = HMAC-SHA256("<t>.<raw body>", your signing secret).

// verify (PHP), same idea in any language
[$t, $v1] = sscanf($_SERVER['HTTP_X_WEBHOOK_SIGNATURE'], 't=%d,v1=%s');
$expected = hash_hmac('sha256', $t . '.' . file_get_contents('php://input'), $secret);
$ok = hash_equals($expected, $v1) && abs(time() - $t) < 300; // reject > 5 min old
  • At-least-once: a delivery can arrive twice (retries after a lost response). Deduplicate on X-Webhook-Event-Id.
  • Ordering is not guaranteed: a retried event can arrive after a newer one; each event stands alone and carries created_utc.
  • Retries: a failed delivery is attempted up to 6 times in total (5 retries) over about 8.5 hours, always with the original payload. After 5 consecutive events exhaust every attempt, the endpoint is disabled automatically. This pane shows the reason, and re-enabling clears the failure count.
  • Self-echo: actions your own integration performs via the API come back as events with source.type = "api". Filter on it to avoid loops.
  • Ignore unknown fields: new fields may appear within a version; never reject a payload for carrying one.

Event payloads

Every event uses the envelope above; only data differs. Each event always sends the same keys: one that does not apply on a given path arrives as null rather than going missing, so a single parser per event is enough.

Leads
New lead captured campaign.entry_received
A campaign entry with contact info was received, ready to send to your CRM.
FieldTypeDescription
campaign_id integer
the campaign that was entered
campaign_type string
campaign type code
entry_type string
which kind of entry was submitted
entry_id integer
id of the entry in its per-type table
crm_id integer
CRM contact row created for this entrant
unique_id string
per-entrant unique id, stable across the entry
email string
entrant email address
first_name string
entrant first name
last_name string
entrant last name
fields object | null
every custom form field captured, keyed by field name
field_ids array
field definition ids matching `fields`, for mapping to your own schema
referred_by_id integer | null
the entrant who referred this one, when the entry came through a referral link
content string | null
what the entrant actually submitted: testimonial text, or the video caption. null for photo entries.
{ "event_id": "evt_sm_9f1c4a2b", "type": "campaign.entry_received", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "campaign_id": 8812, "campaign_type": "1", "entry_type": "text", "entry_id": 55021, "crm_id": 90233, "unique_id": "a41f9c22", "email": "dana@example.com", "first_name": "Dana", "last_name": "Reyes", "fields": { "How did you hear about us?": "A friend", "City": "Austin" }, "field_ids": [ 4471, 4472 ], "referred_by_id": 90180, "content": "Genuinely the smoothest onboarding I have had." } }
Approvals
Post awaiting approval post.submitted_for_approval
A post was submitted for approval or put on hold for named approvers.
FieldTypeDescription
post_id integer
the post awaiting approval
hold_type string
why it is held
approvers string | null
comma-separated approver user ids, when hold_type is named_approvers
note string | null
note left for the approver
admin_approve integer | null
legacy admin-approval flag on the post
mode string | null
publish mode requested (API submissions only)
acting_sub_user_id integer | null
sub-user who submitted it, when a sub-user did
{ "event_id": "evt_sm_9f1c4a2b", "type": "post.submitted_for_approval", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "post_id": 771204, "hold_type": "named_approvers", "approvers": "3391,3402", "note": "Please check the pricing line.", "admin_approve": 0, "mode": null, "acting_sub_user_id": 3388 } }
Post approved post.approved
A held post was approved and released.
FieldTypeDescription
post_id integer
the post that was approved
via string
where the approval happened
hold_released boolean
true when this approval released a note/moderation hold rather than a first approval
previous object | null
prior approval state, when the emitting path recorded it
acting_sub_user_id integer | null
sub-user who approved, when a sub-user did
{ "event_id": "evt_sm_9f1c4a2b", "type": "post.approved", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "post_id": 771204, "via": "approve_screen", "hold_released": false, "previous": null, "acting_sub_user_id": 3391 } }
Post rejected post.rejected
A pending post was rejected (deleted from the approval email).
FieldTypeDescription
post_id integer
the post that was rejected
via string
where the rejection happened
deleted boolean
true when the rejection also deleted the post
acting_sub_user_id integer | null
sub-user who rejected, when a sub-user did
{ "event_id": "evt_sm_9f1c4a2b", "type": "post.rejected", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "post_id": 771205, "via": "email_link", "deleted": true, "acting_sub_user_id": null } }
Social profiles
Profile needs reconnecting social.reconnect_required
A social account's access token stopped working, so posting pauses until it is reconnected.
FieldTypeDescription
network string
which network the connection belongs to
account_id string
the network's own id for the connected profile
account_name string
display name of the connected profile
reason string
why the token stopped working, as reported by the network
post_id integer | null
the post whose delivery surfaced the failure, when it was surfaced by a publish attempt
{ "event_id": "evt_sm_9f1c4a2b", "type": "social.reconnect_required", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "network": "facebook", "account_id": "10221144", "account_name": "Northside Dental", "reason": "Error validating access token: session has expired", "post_id": null } }
Token expiring soon social.token_expiring
A connection expires within 14 days, so reconnect before posting stops. Coverage begins as accounts connect or refresh.
FieldTypeDescription
network string
which network the connection belongs to
account_id string
the network's own id for the connected profile
account_name string
display name of the connected profile
kind string
which credential is expiring
expires_at string
when it expires
days_left integer
whole days until expiry at the time of the warning
{ "event_id": "evt_sm_9f1c4a2b", "type": "social.token_expiring", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "network": "linkedin", "account_id": "urn:li:person:AbC", "account_name": "Dana Reyes", "kind": "access_token", "expires_at": "2026-08-16T00:00:00+00:00", "days_left": 13 } }
Client billing
Client subscribed to a plan workspace.plan_subscribed
A client workspace subscribed to (or changed) one of your pricing plans.
FieldTypeDescription
plan_id integer
the pricing plan subscribed to
plan_name string
display name of that plan
amount number
amount charged, in the plan currency
frequency string | null
billing frequency, when the emitting path knows it
change boolean | null
true when this replaced an existing plan rather than being a first subscribe
manual_or_free boolean | null
true when the agency assigned the plan manually or it is a free plan
agency_registration_id integer
the agency that owns the client workspace
stripe_event_id string | null
originating Stripe event, on Stripe-driven subscribes only
stripe_event_type string | null
originating Stripe event type, on Stripe-driven subscribes only
{ "event_id": "evt_sm_9f1c4a2b", "type": "workspace.plan_subscribed", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "plan_id": 244, "plan_name": "Growth Monthly", "amount": 149, "frequency": "monthly", "change": true, "manual_or_free": null, "agency_registration_id": 5501, "stripe_event_id": null, "stripe_event_type": null } }
Client plan cancelled workspace.plan_cancelled
A client's plan ended, cancelled by them, by you, or after repeated payment failures.
FieldTypeDescription
reason string
why the plan ended
plan_id integer | null
the plan that ended, when the emitting path knows it
plan_name string | null
display name of that plan
workspace_deleted boolean | null
true when the workspace itself was deleted
had_stripe_subscription boolean | null
whether a live Stripe subscription was cancelled alongside
agency_registration_id integer
the agency that owns the client workspace
acting_sub_user_id integer | null
sub-user who cancelled, when a sub-user did
stripe_event_id string | null
originating Stripe event, on Stripe-driven cancellations only
stripe_subscription_id string | null
the Stripe subscription that ended, when applicable
{ "event_id": "evt_sm_9f1c4a2b", "type": "workspace.plan_cancelled", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "reason": "payment_failure", "plan_id": 244, "plan_name": "Growth Monthly", "workspace_deleted": null, "had_stripe_subscription": true, "agency_registration_id": 5501, "acting_sub_user_id": null, "stripe_event_id": "evt_1P9x", "stripe_subscription_id": "sub_1P9x" } }
Client payment failed workspace.payment_failed
A client's payment failed and their grace period started.
FieldTypeDescription
plan_id integer
the plan whose payment failed
plan_name string | null
display name of that plan
grace_until string
when the grace period ends and paid features are withdrawn
agency_registration_id integer
the agency that owns the client workspace
stripe_event_id string | null
originating Stripe event, on Stripe-driven failures only
{ "event_id": "evt_sm_9f1c4a2b", "type": "workspace.payment_failed", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "plan_id": 244, "plan_name": "Growth Monthly", "grace_until": "2026-08-09", "agency_registration_id": 5501, "stripe_event_id": "evt_1P9y" } }
Client payment recovered workspace.payment_recovered
A previously failing client payment went through.
FieldTypeDescription
plan_id integer
the plan whose payment recovered
plan_name string | null
display name of that plan
amount number
amount successfully charged
agency_registration_id integer
the agency that owns the client workspace
stripe_event_id string | null
originating Stripe event, on Stripe-driven recoveries only
{ "event_id": "evt_sm_9f1c4a2b", "type": "workspace.payment_recovered", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "plan_id": 244, "plan_name": "Growth Monthly", "amount": 149, "agency_registration_id": 5501, "stripe_event_id": "evt_1P9z" } }
Workspaces
Workspace tags changed workspace.tags_changed
A workspace was added to or removed from a tag segment.
FieldTypeDescription
workspace_registration_id integer
the workspace whose tags changed
tags array
the complete tag list AFTER the change
added array
tags added by this change
removed array
tags removed by this change
{ "event_id": "evt_sm_9f1c4a2b", "type": "workspace.tags_changed", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "workspace_registration_id": 12345, "tags": [ "dental", "texas" ], "added": [ "texas" ], "removed": [] } }
Bulk jobs
Bulk job completed bulk_job.completed
A CSV import or bulk publish finished.
FieldTypeDescription
kind string
which bulk path produced this job: the discriminator for which of the fields below are populated
bulk_job_id integer | null
bulk job id (api_bulk_publish only) - the same integer you poll at GET /api/v1/jobs/{id}
total_rows integer | null
rows in the uploaded file (csv_import only)
rows_consumed integer | null
rows actually consumed (csv_import only)
succeeded integer | null
workspaces published to successfully (api_bulk_publish only)
failed integer | null
workspaces that failed (api_bulk_publish only)
held_for_approval boolean | null
whether imported posts were held for approval (csv_import only)
draft_only boolean | null
whether the import created drafts only (csv_import only)
workspaces integer | null
workspaces targeted (api_bulk_publish only)
tags array | null
tag segment targeted (api_bulk_publish only)
pricing_plans array | null
pricing plan ids targeted (api_bulk_publish only; mutually exclusive with tags)
acting_sub_user_id integer | null
sub-user who ran the job, when a sub-user did (csv_import only)
{ "event_id": "evt_sm_9f1c4a2b", "type": "bulk_job.completed", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "kind": "csv_import", "bulk_job_id": null, "total_rows": 250, "rows_consumed": 250, "succeeded": null, "failed": null, "held_for_approval": false, "draft_only": false, "workspaces": null, "tags": null, "pricing_plans": null, "acting_sub_user_id": 3388 } }
Bulk job partially completed bulk_job.partially_completed
A bulk publish finished with some workspaces failing.
FieldTypeDescription
kind string
which bulk path produced this job: the discriminator for which of the fields below are populated
bulk_job_id integer | null
bulk job id (api_bulk_publish only) - the same integer you poll at GET /api/v1/jobs/{id}
total_rows integer | null
rows in the uploaded file (csv_import only)
rows_consumed integer | null
rows actually consumed (csv_import only)
succeeded integer | null
workspaces published to successfully (api_bulk_publish only)
failed integer | null
workspaces that failed (api_bulk_publish only)
held_for_approval boolean | null
whether imported posts were held for approval (csv_import only)
draft_only boolean | null
whether the import created drafts only (csv_import only)
workspaces integer | null
workspaces targeted (api_bulk_publish only)
tags array | null
tag segment targeted (api_bulk_publish only)
pricing_plans array | null
pricing plan ids targeted (api_bulk_publish only; mutually exclusive with tags)
acting_sub_user_id integer | null
sub-user who ran the job, when a sub-user did (csv_import only)
{ "event_id": "evt_sm_9f1c4a2b", "type": "bulk_job.partially_completed", "version": 1, "created_utc": "2026-08-02T18:00:00+00:00", "workspace_registration_id": 12345, "workspace_name": "Client name", "source": { "type": "system", "credential_id": null }, "data": { "kind": "api_bulk_publish", "bulk_job_id": 77, "total_rows": null, "rows_consumed": null, "succeeded": 18, "failed": 2, "held_for_approval": null, "draft_only": null, "workspaces": 20, "tags": [ "dental" ], "pricing_plans": null, "acting_sub_user_id": null } }

Reference

Technical details for the Sociamonials API, MCP server, account IDs, and usage limits.

Every endpoint, with live examples. Send your key as Authorization: Bearer <key>. The Bearer prefix is optional. Read requests run right here with your key injected securely; nothing is ever shown or published.

Testing here only reads data or creates drafts: it never publishes and never shows your key

Troubleshoot an error

Paste the error from your API, AI agent, or automation tool. We'll identify the cause and show you how to fix it.

Credentials, tokens and personal details are removed before analysis: in your browser first, then again on the server. Nothing is run or published.
Analyze error
The error analyzer runs in the in-app version. Sign in to use it.

No error code? Start here.

Choose the symptom closest to what you're seeing.

GET /workspaces returned [] (no workspaces)
A workspace-type credential only sees the one workspace it is bound to, and only once that registration is provisioned as a workspace; an agency credential sees its estate. Check GET /api/v1/me. It shows your agent type and the workspaces the credential can reach. An empty list there means the credential has no assigned workspace yet, not that the call failed.
A post was accepted (200) but never publishes
Check three things: mode: a draft is saved, never published; approval: a post held for approval waits until someone approves it; and schedule: publish_at is ISO-8601 UTC, so a local time sent without a zone can land hours away. The post id from the create response, on your Publisher, shows its real state.
A webhook never arrives
A new endpoint is delivered to only while it is enabled: enable it (the Webhooks pane shows a prominent button when it is off). Then open GET /api/v1/webhooks/{id}/deliveries (the Recent activity feed on the Webhooks pane): every attempt is logged with its status and response. If you see nothing at all, the event you expect may not be in the endpoint's selected events; if you see failures, read the next two items.
Webhook signature won't verify
X-Webhook-Signature is t=<unix>,v1=<hex> where v1 = HMAC-SHA256("<t>.<raw body>", signing secret). Sign the raw request bytes (not re-encoded JSON), compare with a constant-time check, use the current secret (a rotate takes effect immediately), and reject deliveries whose t is more than 5 minutes old.
An endpoint was disabled after repeated failures
After 5 consecutive events exhaust every retry, the endpoint is turned off automatically. Fix your receiver (reachable over HTTPS, valid certificate, returns 2xx quickly), then re-enable it. Re-enabling clears the failure count. Events that occurred while it was off are not re-sent.

Error reference

Find an HTTP status or error code and see what it means and how to fix it.

Each endpoint lists the errors it returns in the API Reference. Paste a raw error into Troubleshoot above for a guided diagnosis.

HTTPerror.code What it meansWhat to do
400 credentials_in_query_string
The key was sent as a ?token=, ?api_key= or ?access_token= query parameter. That exposes it in logs and browser history, so the request is refused and the exposure is recorded.
Move the key into the Authorization header: Authorization: Bearer <key>. Then rotate that key. Treat it as exposed.
401 missing_credentials
No Authorization header reached the API.
Send Authorization: Bearer <key>. In no-code tools this is the connection or Header Auth credential, not a body field. Some proxies strip the header. Check your tool's header settings.
401 invalid_credentials
The credential is not valid. Unknown, revoked and expired keys are deliberately indistinguishable.
Confirm you pasted the whole key with no leading or trailing space. The Bearer prefix is optional. Both forms authenticate identically. If the key was revoked or rotated, create a new one in the Console.
402 api_subscription_inactive
The credential is valid, but API access is not active for this account: it is on a free trial, or its plan has lapsed or been suspended. API access is not sold separately - it is included with every paid and lifetime plan.
The account owner activates a paid plan; API access follows automatically. AgencyPro API credentials additionally need an active AgencyPro subscription. Without it the message says so, and a Workspace API credential still works.
403 permission_denied
The credential authenticated, but this API Agent has not been granted the permission the operation needs (for example posts.publish_direct, analytics.read or clients.provision).
Call GET /api/v1/me. It returns the full per-workspace permission map. Grant the missing permission to the agent, or use an operation you are allowed to call (for example create for approval instead of publishing directly).
403 workspace_access_denied
The workspace exists but this API Agent is not assigned to it.
Use GET /api/v1/workspaces to list the workspaces the credential can reach, or assign the workspace to the agent.
403 profile_not_assigned
You named a social profile in networks.<code>.profile_refs that this API Agent, or the user the credential is attached to, is not assigned to in that workspace. This is the most common first-integration failure.
List the workspace's profiles with GET /workspaces/{workspaceId}/social-profiles and use only those whose agent_can_publish_to is true. A profile that arrives via a post_preset is dropped with a warning for attached-user agents, but a profile you name explicitly always hard-fails.
403 attached_user_no_reports_permission
This credential is attached to a workspace user, and that user does not hold the "Access Reports" permission that analytics requires.
Grant "Access Reports" to that user in Workspace Users, then retry. Or use a credential that is not restricted to that user.
403 agency_agent_required
Client provisioning and the client lifecycle operations need an Agency API Agent. The credential you used is a Workspace API Agent.
Use an AgencyPro API credential from the primary agency workspace. That workspace needs an active AgencyPro subscription to be an AgencyPro API account at all.
403 agencypro_required
The credential is an AgencyPro API Agent, but client provisioning is an AgencyPro feature and this agency does not have an active AgencyPro subscription.
Reactivate AgencyPro on the agency. Publishing, sweepstakes and analytics for workspaces you already operate are unaffected.
403 client_not_owned
The workspace you targeted is not a client of this agency, or you aimed a client-lifecycle operation at the agency's own account, which is never allowed.
GET /workspaces lists the client workspaces this credential can operate. The agency's own workspace can never be paused, resumed or deleted through client lifecycle.
403 provision_limit_reached
This agency has already provisioned its daily maximum of new client workspaces.
Retry tomorrow, or have an administrator raise the per-agency daily provisioning limit. The message names the current cap.
403 api_write_operations_disabled
The administrator has turned the API write kill-switch on. Reads keep working; anything that would change data is refused.
Nothing to change in your integration. Retry once writes are re-enabled. Read endpoints are unaffected.
404 not_found
The post, job, sweepstakes or provisioning record does not exist, or it is not in a workspace this credential can read.
Re-check the id, and check the workspace: an id from another workspace looks exactly like a missing one.
405 method_not_allowed
The path is right and the method is wrong. The route exists for a different verb.
Check the method against the endpoint list on the left. Reading a post is GET /posts/{id}; cancelling it is DELETE /posts/{id}.
409 existing_account
The email you passed to client provisioning already has an account. Attaching an existing account to an agency is not supported yet.
Provision with an email that has no account. An existing workspace has to be linked to the agency outside the API.
409 idempotency_in_flight
A request carrying this idempotency_key is already being processed. This is the guard that stops a retry creating a second post.
Wait a moment and retry the same key. You will collect the original result rather than create a duplicate.
409 cannot_cancel
The post is no longer in a state that can be cancelled (it has already been sent, or already cancelled).
Read the post first and cancel only while it is still pending.
409 cannot_reissue
The provisioning handoff link cannot be reissued in its current state.
Read the provisioning record for its current state before reissuing.
422 validation_failed
The request reached the platform's validation pipeline and one or more fields were rejected. error.errors maps each field to its own problem.
Fix the named fields. This is the code a dry-run returns too, so you can validate without creating anything.
422 workspace_required
This credential could not be matched to a single workspace, so the API cannot tell which one the call should act on.
Pass workspace_registration_id. GET /workspaces lists the ones this credential can use.
422 unsupported_campaign_type
The campaign you referenced is not a V2 Viral Sweepstakes. The API only supports V2 Viral Sweepstakes, never contests or the legacy campaign builders.
Target a V2 Viral Sweepstakes, or create one with the sweepstakes endpoints.
429 rate_limited
The credential exceeded its per-minute read or write limit.
Wait for Retry-After seconds. X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset are on every response, so you can pace requests instead of retrying blind.
500 internal_error
An unexpected failure on the platform side, not a problem with your request.
Retry. This class of failure is treated as transient. If it persists, contact support and quote the request_id from the response.
503 api_access_disabled
The API is switched off platform-wide by the administrator. This is not about your account or your key.
Retry later; no change to your integration is needed.
4xx / 5xx http_error
The request failed at the HTTP layer before any endpoint logic could classify it: a malformed request, an unsupported media type, a request that never reached a controller. The response status tells you which.
Check the URL, method, headers and body encoding. If the same status keeps coming back, contact support and quote the request_id.

Standard error response format

API failures use this structure. Handle errors using code and include request_id when contacting support.

{ "error": { "code": "validation_failed", "message": "One or more fields are invalid.", "request_id": "9f1c...", "errors": { "message": "is required" } } }

Match on code, never on the message text. errors is present only on validation_failed, where it maps each field to its own problem. Rate-limited responses also carry Retry-After and the X-RateLimit-* headers.