Skip to content

JaxSuite API Reference

44 endpoints

RESTful API for managing contacts, campaigns, and email operations. Authenticate using Bearer tokens generated from the JaxSuite dashboard under Settings → API.

Contacts

get/api/v1/contactsList contacts

Retrieve a paginated list of contacts. When `campaign_id` is provided, only contacts belonging to that campaign are returned and each contact includes campaign-specific fields.

ParameterInRequiredDescription
pagequerynoPage number
limitquerynoItems per page
tagsquerynoComma-separated tag filter
searchquerynoSearch query
campaign_idquerynoWhen provided, the operation is scoped to contacts within the specified campaign. The authenticated user must have ownership of the campaign.
  • 200Paginated list of contacts. When `campaign_id` is provided, each contact includes campaign-specific fields.
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 500Internal server error

post/api/v1/contactsCreate contacts

Import one or more new contacts. When `campaign_id` is provided in the request body, created contacts are automatically linked to the specified campaign.

  • 201Contacts created successfully
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 500Internal server error

get/api/v1/contacts/{id}Get contact

Retrieve a single contact by ID. When `campaign_id` is provided, the response includes campaign-specific fields and the contact must belong to the specified campaign.

ParameterInRequiredDescription
campaign_idquerynoWhen provided, the operation is scoped to contacts within the specified campaign. The authenticated user must have ownership of the campaign.
  • 200Contact details. Includes campaign-specific fields when `campaign_id` is provided.
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 404Resource not found
  • 500Internal server error

put/api/v1/contacts/{id}Update contact

Update an existing contact by ID. When `campaign_id` is provided in the request body, the contact must exist in the campaign and campaign-specific fields (e.g. `custom_variables`) can be updated.

  • 200Contact updated
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 404Resource not found
  • 422Request validation failed
  • 500Internal server error

delete/api/v1/contacts/{id}Delete contact

Delete a contact by ID. When `campaign_id` is provided in the request body, the contact is only removed from the specified campaign (soft-delete) rather than being permanently deleted.

  • 200Contact deleted or removed from campaign
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 404Resource not found
  • 500Internal server error

post/api/v1/contacts/bulkBulk get contacts

Retrieve multiple contacts by their IDs in a single request. Uses POST to avoid URL length limitations. Returns found contacts and a list of IDs that were not found.

  • 200Bulk get results
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 500Internal server error

put/api/v1/contacts/bulkBulk update contacts

Update multiple contacts in a single request. Each contact in the array specifies its own fields to update. Returns lists of successfully updated and not-found IDs.

  • 200Bulk update results
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 500Internal server error

delete/api/v1/contacts/bulkBulk delete contacts

Delete multiple contacts in a single request. When `campaign_id` is provided, contacts are only removed from the campaign (soft-delete). Returns lists of deleted and not-found IDs.

  • 200Bulk delete results
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 500Internal server error

Campaigns

get/api/v1/campaignsList campaigns

Retrieve a paginated list of campaigns for the authenticated token's team. For a workspace-level token (no team_id), returns the workspace-level campaigns owned by the token's user.

ParameterInRequiredDescription
pagequerynoPage number
limitquerynoItems per page
statusquerynoFilter by campaign status. "all" (default) returns every status.
  • 200Paginated list of campaigns.
  • 401Authentication required or token invalid
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

post/api/v1/campaignsCreate campaign

Create a new campaign for the authenticated token's team (or, for a workspace-level token with no team_id, a workspace-level campaign owned by the token's user). The new campaign starts in Draft status. Uses the same validation as the MCP create_campaign tool.

  • 201Campaign created successfully
  • 401Authentication required or token invalid
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

get/api/v1/campaigns/{id}Get campaign

Retrieve a single campaign by ID, scoped to the authenticated token owner. A campaign that does not exist or is outside the token's scope returns 404 (existence is not leaked).

  • 200Campaign details
  • 401Authentication required or token invalid
  • 404Resource not found
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

delete/api/v1/campaigns/{id}Delete campaign

Soft-delete a campaign and queue its permanent removal. Requires ownership of the campaign. Mirrors the MCP delete_campaign tool.

  • 200Campaign deleted
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

patch/api/v1/campaigns/{id}/statusPause or resume campaign

Pause or resume a campaign. Requires ownership. `resume` re-checks the workspace's plan email-sending limit server-side and fails (without changing the campaign) when it is exceeded. Mirrors the MCP pause_campaign / resume_campaign tools.

  • 200Campaign status updated
  • 401Authentication required or token invalid
  • 402The workspace's plan email-sending limit is reached; the campaign was not activated
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

post/api/v1/campaigns/{id}/scheduleSet campaign schedule

Set a campaign's sending window (start/end date, daily from/to time, timezone) and optionally activate it. Requires ownership. At least one field must be provided; an omitted window field is left unchanged, and null clears one. `activate: true` re-checks the workspace's plan email-sending limit and fails (without changing status) when exceeded. Mirrors the MCP schedule_campaign tool.

  • 200Campaign schedule saved
  • 401Authentication required or token invalid
  • 402The workspace's plan email-sending limit is reached; the campaign was not activated
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

put/api/v1/campaigns/{id}/accountsReplace campaign sending accounts

Replace a campaign's sending accounts/tags with the full desired end-state (not an incremental add/remove). An empty array clears all sending accounts. Each item must set exactly one of email_account_id or tag_id, and every referenced account/tag must belong to the token's tenant scope. Requires ownership. Mirrors the MCP update_campaign_accounts tool.

  • 200Sending accounts replaced. Returns the campaign's new sending-account rows.
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

get/api/v1/campaigns/{id}/analyticsGet campaign analytics

Retrieve a campaign analytics aggregate — overall stats, a daily timeline, and a provider bounce warning — optionally scoped to an inclusive [start_date, end_date] window (omit both for all-time). Requires ownership. Mirrors the MCP get_campaign_analytics tool.

ParameterInRequiredDescription
start_datequerynoInclusive window start (YYYY-MM-DD).
end_datequerynoInclusive window end (YYYY-MM-DD).
  • 200Campaign analytics aggregate
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

get/api/v1/campaigns/{id}/sender-healthGet campaign sender health

Retrieve reputation signals for the email accounts configured to send the campaign (direct picks and tag-group members): a warmup-derived health score, real bounce rate over a configurable window, and live Google Postmaster domain reputation when the sending domain is connected. Requires ownership. Mirrors the MCP get_campaign_sender_health tool.

ParameterInRequiredDescription
bounce_window_daysquerynoLook-back window for the bounce-rate calculation, in days.
  • 200Campaign sender health
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

put/api/v1/campaigns/{id}/contentAppend campaign content steps

Append one or more email step(s) to a campaign, each with 1-5 A/B variants, an optional per-step delay, personalization, spintax, and an auto-injected unsubscribe link. `dry_run: true` returns the per-variant content QA report without writing anything. Requires ownership. Mirrors the MCP write_campaign_content tool.

  • 200Content steps appended (or the QA report when dry_run is true).
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

post/api/v1/campaigns/check-deliverabilityCheck content deliverability

Analyze draft content (subject + HTML body) for spam-trigger phrases, unsubscribe merge-tag usage, unrecognized personalization variables, and a spintax preview: the same checks write_campaign_content runs, without writing anything. `unsubscribe_placeholder_present` reports whether the body uses the {{unsubscribeLink}} tag, which is what triggers footer injection on write; it is not a compliance verdict, and a hand-written unsubscribe anchor reports false. Supply text_content for a text-only send: `text_opt_out_present` then reports whether the delivered plain-text body carries an opt-out the recipient can act on, and is null when no text body was supplied. Supply campaign_id to also recognize the custom personalization variables that campaign uses (ownership is then checked); omit it and only the standard fields are recognized. Mirrors the MCP check_content_deliverability tool.

  • 200Content deliverability analysis
  • 401Authentication required or token invalid
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

Email accounts

get/api/v1/email-accountsList sending accounts

List the sending email accounts this token can use, with the email_account_id values the campaign account endpoints and the account settings endpoints accept. Each entry carries provider, status, health score, the daily campaign limit and how much of it is used today, assigned tags, and campaigns_paused_until (set while an account rests from warmup, during which campaigns skip it). Defaults to status 'active'; pass status=all to include disconnected or expired accounts. Mirrors the MCP list_email_accounts tool.

ParameterInRequiredDescription
pagequeryno
limitqueryno
statusquerynoAccount status to filter on, or 'all' to skip the filter.
  • 200Paginated sending accounts in the token scope.
  • 401Authentication required or token invalid
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

get/api/v1/email-account-tagsList account tags

List the email account tags this token can assign, with the tag_id values the account tag endpoint and the campaign account endpoints accept. Assigning a tag to a campaign sends from every account carrying that tag, so the effective sender set can change after assignment as accounts are tagged or untagged. Mirrors the MCP list_email_account_tags tool.

ParameterInRequiredDescription
pagequeryno
limitqueryno
  • 200Paginated account tags in the token scope.
  • 401Authentication required or token invalid
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

get/api/v1/email-accounts/{id}Get one sending account configuration

One account's full configuration in a single call, grouped into sender identity, custom tracking domain, sending capacity and pacing, bounce protection, warmup, read emulation and tags, plus the read-only signals worth acting on: health score, the last mailbox-read error, whether bounce protection has already paused the mailbox, and the warmup rest window. Read this before any of the PATCH endpoints below, since those are partial. Mirrors the MCP get_email_account tool.

  • 200The account configuration.
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

patch/api/v1/email-accounts/{id}/settingsPatch sender identity, tracking, pacing and bounce protection

Patch a sending account's settings; only the fields present in the body change. Covers sender identity, custom tracking domain, sending capacity and pacing, and bounce protection. Note that time_between_emails is in SECONDS. Google and Microsoft accounts are additionally clamped to provider policy at send time, so a daily limit above it is stored but not used. Pass null for first_name or last_name to clear it; a patch that would leave the account with no sender name at all answers 422, because the sending identity would fall back to the raw address. Mirrors the MCP update_email_account_settings tool.

  • 200Settings patched. `inboxlogy_sync` is present when a sender name changed and the mailbox is hosted by the mailbox provider; a failure there is reported rather than rolled back, because the settings row is already written.
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

patch/api/v1/email-accounts/{id}/warmupPatch warmup configuration

Patch a sending account's warmup configuration; only the fields present in the body change. Warmup volume and reply rate drive real mail between real mailboxes, which is what the account's deliverability reputation is built from. Warmup pause state (campaigns_paused_until, paused_at, resume_at, pause_reason) is owned by the warmup engine: readable through GET /email-accounts/{id}, not settable here. Mirrors the MCP update_email_account_warmup tool.

  • 200Warmup settings patched.
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

patch/api/v1/email-accounts/{id}/read-emulationPatch read emulation

Patch read emulation for a sending account; only the fields present in the body change. This is what share of incoming warmup mail gets marked read, marked important, or rescued from spam in the real mailbox. Available on done-for-you and pre-warmed accounts, or on any account with a paid Outreach subscription; anything else answers 403. Mirrors the MCP update_email_account_read_emulation tool.

  • 200Read emulation settings patched.
  • 401Authentication required or token invalid
  • 403Either the account is outside the token scope, or it has no read emulation entitlement.
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

put/api/v1/email-accounts/{id}/tagsReplace an account tag set

Replace a sending account's tags with the full desired END STATE. Any tag the account currently carries and the body omits is removed, and an empty array clears every tag. Every referenced tag must belong to the token's tenant scope. Tags matter beyond labelling: assigning a tag to a campaign sends from every account carrying it, so changing the tags on an account changes which campaigns can send from it. Mirrors the MCP set_email_account_tags tool.

  • 200Tags replaced, with what the replacement actually changed.
  • 401Authentication required or token invalid
  • 403Access to the requested resource is denied
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

Email validation

post/api/v1/email-validation-batchValidate a few addresses and get the verdicts now

Validates up to 5 addresses and answers with the verdicts in the same response. The verdicts themselves are not stored, so there is nothing to download later: use the bulk endpoint for anything you want to come back to. The charge is `0.1` credits per address after duplicates are removed, and the count is taken from what the server parsed rather than from the request. Credits are charged only once the verdicts exist, so a call that fails, times out, or finds no validation capacity costs nothing at all. Every verdict is one of three values: `valid`, `risky` or `invalid`. There is no fourth, inconclusive value. Sometimes no validation capacity is free and an address cannot actually be checked, and because you have already paid for it, it is neither dropped nor handed back as a placeholder. It comes back as `risky` with `retryable` set to true, which is the difference between an address we examined and found questionable and one we could not examine at all. Those addresses are also moved onto the background queue as a job of their own, at no extra charge, and `retry` in the response tells you what happened to them. When `retry.status` is `queued` or `pending`, poll `retry.request_id` on `GET /email-validation-bulk/{job_id}` and read the verdicts from `GET /email-validation-bulk/{job_id}/results`, exactly as you would for a bulk submit. The queue re-checks each one, so its verdict can improve to `valid` or `invalid`. If capacity never frees, the address stays `risky` and carries a reason saying it was never checked. It is never downgraded to `invalid` on the strength of a check that did not run. Each token also has its own daily credit ceiling, separate from your balance. Reaching it answers 429 with the code `TOKEN_DAILY_CREDIT_CEILING` and resets at midnight UTC. The retried addresses do not count against it a second time. Expect this to take seconds rather than milliseconds: an SMTP conversation is a live check against the recipient's mail server, not a lookup.

  • 200The verdicts
  • 402Not enough Jax Credits for this call. `details` carries `required` and `available`, both fractional.
  • 422Request validation failed
  • 429Two different limits answer with this status and they are told apart by `error.code`. `RATE_LIMITED` is about how OFTEN you call and clears in seconds. `TOKEN_DAILY_CREDIT_CEILING` is about how MUCH this token has spent: each token has its own daily Jax Credit ceiling, `details` carries `ceiling`, `spent`, `required` and `resets_at`, and `Retry-After` counts down to midnight UTC. A request that would cross the ceiling is refused whole rather than trimmed to the part that fits, so retrying a smaller list can succeed. The ceiling is per token, so the workspace's other tokens keep working, and topping up credits does not lift it.
  • 500Internal server error
  • 503Either no validation capacity is available (`VALIDATION_UNAVAILABLE`) or the charge could not be processed for a reason that is not your balance (`CREDIT_SERVICE_UNAVAILABLE`). Nothing was charged in either case, and retrying re-runs the check.

post/api/v1/email-validation-bulkSubmit addresses for validation

Parses the payload server-side, removes duplicates, stores the addresses, charges Jax Credits for the addresses it counted, and queues the work. Returns a request id immediately; validation happens in the background. The address count is never taken from the request. Whatever the server parses and dedupes is what is charged, so `accepted_count` and the amount billed always agree. `credits.charged` is what the ledger actually took, not an estimate, and `credits.enforced` says whether crediting applied at all. While it is unenforced the balance is not consulted and the whole list is accepted. If the balance covers only part of the list, the affordable portion is accepted and `rejected_count` reports the remainder. Nothing is charged for a rejected address; resubmit them after topping up. This endpoint is idempotent, and it needs no header from you to be so. A submit is fingerprinted from the owner, the `name`, the `description` and the deduplicated address list, and the addresses are stored before anything is charged, so resending a request you did not get an answer to returns the ORIGINAL request id and charges once. The practical consequence: revalidating the same list later means sending a different `name`, otherwise the earlier job is handed back instead of a new one starting. Separately from your balance, each token has its own daily Jax Credit ceiling. It bounds credits rather than requests, so one large submit can reach it as quickly as many small ones, and a submit that would cross it is refused whole rather than partially accepted. Reaching it answers 429 with the code `TOKEN_DAILY_CREDIT_CEILING` and resets at midnight UTC. Because the ceiling is per token, a token that exhausts itself does not stop your other tokens.

  • 202Accepted and queued
  • 402Not enough Jax Credits to validate any of the addresses. `details` carries `required` and `available`, both fractional. This is the only credit error a top-up fixes.
  • 422Request validation failed
  • 429Two different limits answer with this status and they are told apart by `error.code`. `RATE_LIMITED` is about how OFTEN you call and clears in seconds. `TOKEN_DAILY_CREDIT_CEILING` is about how MUCH this token has spent: each token has its own daily Jax Credit ceiling, `details` carries `ceiling`, `spent`, `required` and `resets_at`, and `Retry-After` counts down to midnight UTC. A request that would cross the ceiling is refused whole rather than trimmed to the part that fits, so retrying a smaller list can succeed. The ceiling is per token, so the workspace's other tokens keep working, and topping up credits does not lift it.
  • 500The submit could not be completed. `INTERNAL_ERROR` means nothing was stored and nothing was charged, so retry the identical request. `SUBMIT_NOT_QUEUED` means the addresses were stored and charged but the queue could not be reached: `details.request_id` is your handle on that job, it will be picked up automatically, and resending the identical request returns the same id rather than charging again.
  • 503The charge could not be processed for a reason that is not your balance, so topping up will not help. Nothing was charged and nothing was queued; retry the identical request later. The error code is `CREDIT_SERVICE_UNAVAILABLE`.

get/api/v1/email-validation-bulk/{job_id}Check a validation job

Progress for one submitted job. `processed_count` is the authority on how far the job has got. The per-outcome counts below it do not necessarily sum to it: some results carry an outcome the batch keeps no column for, and `other_count` is that difference rather than a hidden gap.

ParameterInRequiredDescription
job_idpathyesThe request id returned by the submit call
  • 200Job progress
  • 404Resource not found
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

get/api/v1/email-validation-bulk/{job_id}/resultsRead validation results

The verdicts for one job, a page at a time. Rows appear as they are validated, so this can be read before the job completes. Branch on `checked`, not on `status` alone. `risky` covers two different situations: an address that was examined and came back genuinely uncertain, such as a catch-all domain or a provider that accepts every mailbox, and an address that was never examined at all because no validation capacity was free for it. The first will not change, so re-submitting it spends a credit for the same answer. The second has no verdict yet and may resolve to `valid` or `invalid` on a later submit. `checked` is false only for the second kind, and `attempts` says how many times we deferred it before giving up. `failed` rows are also unchecked, for the same reason: nothing was learned about the address.

ParameterInRequiredDescription
job_idpathyes
pagequeryno
limitquerynoHow many results to return per page. This is the same name the response echoes back in `meta.limit`, so the value read from one page can be sent straight back for the next.
statusquerynoReturn only results with this outcome
  • 200A page of results
  • 422Request validation failed
  • 429Too many requests — retry after the given number of seconds
  • 500Internal server error

MCP

post/api/v1/mcpMCP (Model Context Protocol) endpoint

JSON-RPC 2.0 over Streamable HTTP, per the MCP spec. Requires Bearer token auth — the same api_tokens system used by the REST endpoints above. This is a generic JSON-RPC transport: request/response shapes vary by `method` (e.g. "tools/list", "tools/call") and are not individually documented here. Available tools: - `write_campaign_content` — append email step(s) with A/B variants, personalization, spintax, and unsubscribe link to a campaign. Mirrors the campaign editor UI.

  • 200JSON-RPC response. Tool-level failures (validation errors, rate limiting, access denial) are returned as a 200 with an error content block, not as an HTTP error status — only transport-level failures (e.g. bad auth) use non-2xx codes.
  • 401Authentication required or token invalid
  • 500Internal server error