Skip to main content

Errors

Every non-2xx response on this API — except 429, see the note below — is application/problem+json:

{
"type": "/errors/PRODUCT_NOT_FOUND",
"title": "Not Found",
"status": 404,
"code": "PRODUCT_NOT_FOUND",
"detail": "One or more productIds were not found.",
"instance": "/api/public/v1/runs",
"requestId": "a1b2c3d4-e5f6-4a3b-8c9d-0e1f2a3b4c5d",
"errors": [{ "field": "productIds", "message": "prod_unknown123 does not exist" }]
}
FieldAlways present?Meaning
typeyesA stable URI reference identifying the problem type — /errors/{code}.
titleyesThe HTTP status reason phrase.
statusyesThe HTTP status code, duplicated in the body per RFC 9457.
codeyesThe stable machine-readable error code. Branch on this, not on detail or status alone — several codes share a status.
detailusuallyA human-readable, non-leaky explanation of this specific occurrence. Not a contract — don't parse it.
instanceusuallyThe request path this occurrence happened on.
requestIdyesThe correlation id for this request. Quote it when you ask for help — it's what support uses to find the request in logs.
errorson 422 onlyOne entry per offending field, { field, message }.
currentStatuson 409 CREATIVE_NOT_PENDING and CREATIVE_NOT_DELETABLEThe status the creative is actually in, so you can reconcile without another read.
generatingCount, reasonon 409 CAMPAIGN_NOT_DELETABLEHow many of the campaign's creatives are QUEUED or GENERATING; or reason: "still_being_created" while the campaign is still being created.
limitKey, limit, currenton 403 LIMIT_EXCEEDEDWhich plan limit you hit, what the plan allows, and where you stand.

Quoting requestId​

If a request fails in a way you can't resolve yourself, include requestId when you reach out — without it, finding the specific request in server-side logs is far slower, and sometimes not possible at all.

Common codes by status​

This is not the full list — every operation's specific error codes are documented on that operation's page in the API reference. These are the ones you'll see across most endpoints.

StatusTypical codesWhat they mean
400VALIDATION_ERROR, IDEMPOTENCY_KEY_REQUIRED, INVALID_IDEMPOTENCY_KEYThe request itself is malformed — a bad field shape, a missing required value, a missing or malformed Idempotency-Key. Fix the request; don't retry unchanged.
401(no pinned code)The token is missing, malformed, unknown, revoked, expired, or the account's plan no longer grants this operation. See Authentication.
403API_TOKEN_SCOPE_DENIED, TIER_REQUIRED, LIMIT_EXCEEDEDThe token is valid but lacks the required scope — for example, a read-only key calling approve — or the plan doesn't include the feature (TIER_REQUIRED), or a plan limit is reached (LIMIT_EXCEEDED; a plan limit is a 403, never a 429). See Authentication and Managing campaigns.
404PRODUCT_NOT_FOUND, CREATIVE_NOT_FOUND, ASSET_NOT_FOUND, CAMPAIGN_NOT_FOUNDA referenced resource doesn't exist, doesn't belong to the account/brand this key resolves to, or — on a write — is deleted or has no public representation. All of these get the same answer.
409IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_IN_PROGRESS, PRICE_EXCEEDS_MAX, PRICE_CHANGED, ACCOUNT_SPEND_CAP_EXCEEDED, CREATIVE_NOT_PENDING, CREATIVE_NOT_DELETABLE, CREATIVE_CAMPAIGN_DELETED, CAMPAIGN_NOT_DELETABLE, CAMPAIGN_CASCADE_PENDINGA conflict with the request's current state — a reused idempotency key, a price that no longer matches what you expected, a spend cap, a creative already reviewed the other way, something busy generating, or a change still finishing. See Idempotency, Try it safely, Reviewing creatives and the write-error table below.
412PRECONDITION_FAILEDThe If-Match you sent no longer matches the resource: it changed since you read it. Nothing was changed. Read it again and retry. See Managing creatives.
422VALIDATION_ERRORA field-level validation failure. Read errors[] for exactly which field(s) to fix.
429RATE_LIMITEDToo many requests in the current window. See the note below and Rate limits.
503ACCOUNT_SPEND_UNAVAILABLE, WRITES_PAUSED, SERVICE_UNAVAILABLETemporarily unable to act — carries Retry-After, and is safe to retry with the same Idempotency-Key. ACCOUNT_SPEND_UNAVAILABLE (runs): a dependency needed to answer this request couldn't be reached at that moment — not a statement about your account's balance. WRITES_PAUSED (every write): Mocart has paused API writes for your account or for everyone; nothing changed, and reads are unaffected. See Reviewing creatives. SERVICE_UNAVAILABLE (campaign create or restore): other changes on your account were in flight at once and yours lost the race; nothing was changed.

Write errors​

The write operations add these codes. Branch on code, as always. Each operation's guide lists its own errors in full: Reviewing creatives, Managing creatives, Managing assets and Managing campaigns.

StatuscodeWhat it meansWhat to do
403LIMIT_EXCEEDEDCreating or restoring a campaign would put you over your plan's campaign limit, or a campaign over its products limit. limitKey, limit and current say which.Delete a campaign you no longer need, name fewer products, or upgrade. Don't retry unchanged.
403TIER_REQUIREDYour plan doesn't include campaigns.Upgrade the plan.
409CREATIVE_NOT_DELETABLEThe creative is QUEUED or GENERATING and can't be deleted yet. currentStatus says which.Wait for generation to finish, then retry.
409CREATIVE_CAMPAIGN_DELETEDYou restored a creative that was deleted with its campaign, and that campaign is still deleted.Restore the campaign first.
409CAMPAIGN_NOT_DELETABLEThe campaign holds creatives that are QUEUED or GENERATING (generatingCount), or is still being created (reason).Wait, then retry.
409CAMPAIGN_CASCADE_PENDINGThe campaign's previous delete or restore is still finishing its creatives. Carries Retry-After.Wait Retry-After, then retry the same request. It succeeds shortly.
412PRECONDITION_FAILEDIf-Match no longer matches. Nothing was changed.Read the resource again and retry with the new ETag. For a campaign, the ETag also changes when its status or counts do, so this can happen without anyone editing it.
503WRITES_PAUSEDMocart paused API writes for your account or for everyone. Nothing changed and the key wasn't used.Wait Retry-After, then resend the identical request with the same Idempotency-Key.

429 isn't application/problem+json everywhere yet​

On the Generation plane (GET /presets, every /runs operation), 429 is already application/problem+json with code: "RATE_LIMITED", like every other error on that plane.

On Catalog, Campaigns & Creatives, and Deliveries, 429 is still the one exception: it returns a non-JSON body (today, express-rate-limit's own default message) rather than a problem-details document. This is a known gap on those planes, slated to become application/problem+json after a 90-day deprecation notice (see Versioning) — but until that notice has run its course, don't parse a 429 body from those planes. Rely on the HTTP status code and the Retry-After header, which are both stable today on every plane. See Rate limits.

Every write operation — the creative reviews, and the edits, deletes and restores of creatives, assets and campaigns — is in the same position: its 429 is the same plain-text body, and every other error it returns is application/problem+json. Don't parse their 429 body either.