startwave

Developer guide

Connect your tools

Manage campaigns, audiences and conversations through the same workspace rules used by the app. The current deployment uses test-mode billing.

Get a workspace key

Sign in as a workspace owner, then open Settings → API keys. Choose only the scopes your integration needs and an expiry. Copy the secret once into your server's secret store. Keys cannot create other keys or access Operations. Never put a secret in a browser bundle, URL or support message.

Keys are bound to their workspace and issuing owner's authority. Expiry, revocation or membership changes can end access. Recheck the current state before resuming automation.

Your first request

Base URL: https://app.startwave.io. Supply Authorization: Bearer YOUR_KEY. This read needs campaigns:read:

curl --fail-with-body https://app.startwave.io/campaigns?limit=25 \
  -H "Authorization: Bearer $STARTWAVE_API_KEY"

Keep the variable in your environment; do not paste the real value into shared commands. Follow each endpoint's cursor parameter and returned next_cursor; stop at null. Do not load an entire workspace into memory to display one page.

Download the customer OpenAPI reference for exact request fields and parameter limits. It contains only API-key-accessible routes. Some response objects are not fully typed in the current backend schema; do not treat an unspecified response as empty or successful.

Launch safely

  1. Create a draft and append contacts; retain returned revisions. Imported contacts do not start sending.
  2. Read verification configuration, submit a verification batch under explicit spending authority, and wait for its original receipt. Invalid and catch-all contacts remain blocked.
  3. Request a capacity quote and campaign Start review. Present the actual cost, term, schedule and blockers before consent.
  4. Start using the reviewed receipt and original operation ID. Read the Start operation until it reaches an authoritative outcome; an HTTP success is not proof of a sent message.
  5. Refill through the refill endpoint rather than silently changing a published audience. Refill is spending consent for added eligible sends at the authorized price.

Paid routes require both their ordinary scope and spending:write. A scope alone does not bypass funds, review, verification, suppression, schedule or transport gates. Creating a key never authorizes an autonomous campaign.

Errors, retries and limits

Use JSON request bodies. A 401 requires credential repair; a 403 means the current authority cannot perform the action. A 409 requires reading the current revision or operation before deciding what to do. A 422 means request validation failed. On 429, honor Retry-After with bounded backoff. Tenant limits survive key rotation.

Retain IDs and receipts for mutations. After a timeout or lost response, retrieve the original operation; never invent a new ID to retry a potentially paid or sent action. Where the endpoint documents replay, use the same ID and identical body. Accepted or unknown mail must never be resent automatically. Do not assume a generic Idempotency-Key header substitutes for the documented body fields.

Replies, STOP suppression and conversation history stay within the original workspace and sender history. Relabeling a reply does not remove suppression or restart outreach. Queueing a reply does not prove delivery.

Available routes and scopes

Generated from the executable key grants. Paths use the base URL above. Key creation and administrative routes are deliberately excluded.

Method and pathRequired scopes
GET /analytics/verificationusage:read
GET /campaignscampaigns:read
POST /campaignscampaigns:write
GET /campaigns/{cid}campaigns:read
PATCH /campaigns/{cid}campaigns:write
GET /campaigns/{cid}/audiencecampaigns:read
POST /campaigns/{cid}/contactsaudiences:write
GET /campaigns/{cid}/materializationcampaigns:read
GET /campaigns/{cid}/refillscampaigns:read
POST /campaigns/{cid}/refillsaudiences:write
GET /campaigns/{cid}/refills/{identity}campaigns:read
GET /campaigns/{cid}/startcampaigns:read
POST /campaigns/{cid}/startcampaigns:write, spending:write
POST /campaigns/{cid}/start-reviewcampaigns:write
GET /campaigns/{cid}/start-reviewscampaigns:read
POST /campaigns/{cid}/statecampaigns:write
GET /campaigns/{cid}/verificationcampaigns:read
GET /campaigns/{cid}/verification/batchescampaigns:read
POST /campaigns/{cid}/verification/batchesaudiences:write, spending:write
GET /campaigns/{cid}/windowscampaigns:read
GET /capacity/currentusage:read
GET /capacity/expansions/{identity}usage:read
POST /capacity/expansions/{identity}/cancelcampaigns:write
POST /capacity/expansions/{identity}/confirmcampaigns:write, spending:write
GET /capacity/operationsusage:read
GET /capacity/operations/{activation}/expansionsusage:read
POST /capacity/operations/{activation}/expansionscampaigns:write
GET /capacity/operations/{operation}usage:read
POST /capacity/quotescampaigns:write
GET /compliancecampaigns:read
GET /conversationsinbox:read
GET /conversations/{identity}inbox:read
PATCH /conversations/{identity}/archiveinbox:write
GET /conversations/{identity}/archive-historyinbox:read
PATCH /conversations/{identity}/assignmentinbox:write
GET /conversations/{identity}/assignmentsinbox:read
GET /conversations/{identity}/changesinbox:read
GET /conversations/{identity}/notesinbox:read
POST /conversations/{identity}/notesinbox:write
POST /conversations/{identity}/readinbox:write
PATCH /conversations/{identity}/statusinbox:write
GET /inboxinbox:read
PATCH /inbox/{event_id}/intentinbox:write
GET /jobs/{jid}/retriesinbox:read
GET /ledgerusage:read
GET /membersinbox:read
POST /repliesinbox:write, spending:write
GET /starts/{identity}campaigns:read
POST /starts/{identity}/cancelcampaigns:write
POST /starts/{identity}/release-capacitycampaigns:write
POST /starts/{identity}/reusecampaigns:write, spending:write
GET /suppressionssuppressions:read
POST /suppressionssuppressions:write
POST /suppressions/batchsuppressions:write
GET /suppressions/exportsuppressions:read
GET /suppressions/operationssuppressions:read
GET /suppressions/operations/{identity}suppressions:read
GET /usageusage:read
GET /verification/batches/{identity}campaigns:read
POST /verification/batches/{identity}/cancelaudiences:write
GET /verification/configcampaigns:read