GET https://instantcampaign.ai/api/v1/openapi.json while signed in or with a workspace API key. You can import that document into Postman, Insomnia or an OpenAPI code generator.
Only the endpoints documented here are public. The dashboard calls other
/api/* routes with a browser session. Those routes are internal, they can change without notice, and they do not accept API keys.Base URL
API keys
To create a key, open Settings → API Keys. Creating or deleting keys needs the API keys: manage permission: Owners, Administrators, or a custom role that grants it. The full key is shown once, when it is created. It starts withic_. We keep only a hash of it, so a lost key has to be replaced.
Send the key as a bearer token:
401. You can delete a key at any time on the same page.
Scopes
A key can be limited to scopes. A key with no scopes has full access. A key with scopes can only call endpoints whose scope it holds. Any other call answers:requiredScope, so check code.
The journey trigger endpoint accepts a key with any scopes.
Rate limits
Limits are counted per workspace, per endpoint, per minute, and each endpoint has its own counter. Going over a limit answers429 with { "error": "…" }. No Retry-After header is sent, so wait and retry with backoff.
Request size limits
Bodies are capped before they are read. A larger body answers413 with code: "PAYLOAD_TOO_LARGE", and nothing is processed.
Errors
Errors are JSON with anerror message. Many also include a machine-readable code.
400. Some routes also list the fields that failed:
Pagination
Two styles are used:- Page numbers.
GET /v1/contactstakespage(from 1) andlimit(1–100, default 50). It returnspagination: { page, limit, total, totalPages }. - Cursor.
GET /v1/transactionaltakeslimit(1–100, default 50) and returnsnextBefore. To get the next page, pass that value back asbefore.nextBeforeisnullonce a page comes back less than full.
GET /v1/lists returns every list in one response.
Idempotency
Two write endpoints take anexternalId: a key of your own, unique per workspace. It is best to use the ID of the thing that caused the call, such as an order ID.
POST /v1/events,/v1/events/importand/public/events: a repeat answers200withstatus: "duplicate"and the original event’s ID, and records nothing.POST /v1/transactional/send: a repeat answers200with the original message anddeduplicated: true. Nothing is sent, even when the calls run at the same time.
POST /v1/webhooks/subscribe is naturally idempotent: subscribing the same event and URL again returns the existing subscription. No other endpoint deduplicates.
Request log
API calls are recorded in the request log under Settings → API log. That covers every call to/v1/*, /public/events, /public/journeys/trigger and /mcp. Viewing the log requires the API-keys management permission. Each row shows the time, method, path, status, duration, and the key that was used. It also shows whatever the call produced, such as a transactional message, event, journey run or contact, along with the recipient and externalId.
Request and response bodies are stored for debugging, with a size cap. Fields whose names look like secrets (password, secret, token, authorization, apiKey, credential) are redacted, and attachment contents are left out. Rows are kept for 90 days. Calls that fail authentication are not logged, because there is no workspace to attach them to.