Errors

Markdown

Every refusal carries a stable code: act on it, never on the message text, which is written for people and may change. The HTTP status says the class, the code says what happened. Each operation page lists the codes it can return.

Over REST

A JSON body with error.code and error.message; retryAfterMs on 429, details on not_publishable.

HTTP/1.1 409 Conflict
Content-Type: application/json

{
  "error": {
    "code": "not_publishable",
    "message": "Not ready to publish: 1 spot has no photo (Tunnel View)",
    "details": {
      "blocking": [
        { "code": "missing_photos", "message": "1 spot has no photo (Tunnel View)" }
      ]
    }
  }
}

Over MCP

A tool result with isError: true and the code at the start of the text. A refused call is never a JSON-RPC protocol error.

{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "content": [
      { "type": "text", "text": "Error rate_limited: Too many attempts. Try again later." }
    ],
    "isError": true
  }
}

400

  • invalid_argumentA field has the wrong shapeREST and MCPSCN-400

    A required field is missing, a field is unknown, or a value does not match its type (the Convex validator's path and value are in the message).

    What to do: Fix the field named in the message. The operation's parameters list every accepted field with its type.

  • invalid_requestThe input was refusedREST and MCPSCN-400

    A writer refused a value: a map link on a host that is not allowed, a title that is too long, a date that does not exist, too many items in a list. The message is the writer's own sentence.

    What to do: Change the value the message names and send the request again. Do not retry unchanged.

  • invalid_jsonThe body is not a JSON objectRESTSCN-400

    A POST, PUT or PATCH body is not valid JSON, or is JSON but not an object.

    What to do: Send a JSON object with Content-Type: application/json.

  • unsupported_imageNot a JPEG, PNG or WebPRESTSCN-400

    An upload's bytes are not a JPEG, PNG or WebP file, or their dimensions cannot be read. The bytes are checked, not the Content-Type header.

    What to do: Convert the photo to JPEG or WebP and upload it again.

  • image_too_largeThe photo is too largeRESTSCN-400

    An upload is more than 6,000 px on a side.

    What to do: Resize to 2,048 px on the long side and compress before uploading.

  • unknown_toolNo such toolMCPSCN-400

    tools/call names a tool the server does not have.

    What to do: Call tools/list and use a listed name.

401

  • unauthenticatedNo API keyREST and MCPSCN-401

    The request carries no key. Send it as Authorization: Bearer sk_sceniq_... (or X-Api-Key).

    What to do: Add the header. MCP clients take it in their server config.

  • invalid_api_keyThe key does not workREST and MCPSCN-401

    The key is unknown, revoked or expired.

    What to do: Ask the creator for a new key (studio, Settings, API keys). Keys are shown once, when they are created.

403

  • api_scope_requiredThe key lacks a scopeREST and MCPSCN-403

    A read-only key called a write operation, or a key without the publish option called publish_changes.

    What to do: Ask the creator for a key with the scope the message names. Never work around it.

  • api_key_not_allowedOnly the creator can do thisREST and MCPSCN-403

    The action is interactive only: putting a guide on sale, store visibility, archiving a guide, payouts, the account. A key never reaches it.

    What to do: Hand the step to the creator with its studio link (get_guide_readiness lists them in handoff).

  • forbiddenThe key has no creatorREST and MCPSCN-403

    The key belongs to a creator account that is no longer active.

    What to do: Stop and tell the creator; the account needs attention in the studio.

404

  • not_foundNot foundREST and MCPSCN-404

    The id does not exist or belongs to another creator. The two answers are identical on purpose, so ids never reveal what exists.

    What to do: Read the id again from a list operation (list_guides, list_spots, ...).

  • unknown_routeNo such endpointRESTSCN-400

    No operation answers at this method and path.

    What to do: Check the path against the reference or the OpenAPI document.

405

  • method_not_allowedWrong methodREST and MCPSCN-400

    The path exists for other methods (the Allow header lists them), or a GET or DELETE reached the MCP endpoint.

    What to do: Use a method from the Allow header. The MCP endpoint only takes POST.

409

  • stale_editorIt changed since you read itREST and MCPSCN-409

    The row changed after the expectedUpdatedAt you sent (update_chapter, save_sales_page_draft).

    What to do: Read the row again, apply your change to the new version, and send it with the new updatedAt.

  • guide_soldThe guide has buyersREST and MCPSCN-409

    delete_spot on a guide someone bought. Buyers keep what they paid for.

    What to do: Archive the spot instead: update_spot with archived true.

  • conflictThe row's state refuses itREST and MCPSCN-409

    The request clashes with the row's current state. The message says what to change.

    What to do: Read the row again and follow the message.

  • not_publishableA publish gate is openREST and MCPSCN-409

    publish_changes while a gate is open: the agreement, no live spot, a live spot without a pin or a photo, no price. details.blocking lists each gate as { code, message }.

    What to do: Fix each blocking item (get_publish_status lists them), then publish only if the creator asks.

  • not_liveThe guide is not on saleREST and MCPSCN-409

    publish_changes on a draft or archived guide. A draft's first publish happens in the studio.

    What to do: Hand the creator the reviewUrl; putting a guide on sale is their click.

  • no_changesNothing to publishREST and MCPSCN-409

    publish_changes when buyers already see every change.

    What to do: Nothing to do. get_publish_status shows the live version.

  • agreement_outdatedThe agreement needs acceptingREST and MCPSCN-409

    A price change or a publish before the creator accepted the current creator agreement.

    What to do: Ask the creator to accept it in the studio, then try again.

413

  • payload_too_largeThe request is too largeREST and MCPSCN-400

    A JSON body over 2 MB, an image over 6 MB, a batch upload over 19 MB, or an MCP message over 2 MB.

    What to do: Split the request (upsert_spots takes 25 spots per call) or compress the photo.

429

  • rate_limitedToo many requestsREST and MCPSCN-429

    Over a limit: requests per key per minute, per creator per hour, uploads per key per minute, or check_links per guide per hour.

    What to do: Wait for Retry-After (seconds) or retryAfterMs, then continue. Do not retry in a tight loop.

500

  • internal_errorSomething failed on our sideREST and MCPSCN-400

    An unexpected failure. The message is hidden on purpose.

    What to do: Try once more after a short wait. If it repeats, tell the creator and write to creators@sceniq.earth with the time and the operation.

MCP protocol errors

A malformed message is answered as JSON-RPC: -32700 (not JSON), -32600 (not a JSON-RPC 2.0 message), -32601 (a method the server does not offer: it offers initialize, ping, tools/list and tools/call), -32602 (tools/call without a known tool name). A missing or invalid key answers HTTP 401 with -32000 and the error code in error.data.code.

The SCN- reference beside each code is what the Sceniq apps show people for the same class of error; quote it when writing to creators@sceniq.earth.