Skip to content

Commerce MCP

Limits and errors

How much you can call, what the errors mean, and how fresh the data is.

Rate limits#

Sliding one-minute windows. These are the defaults; Aiptimise can set other values for your consumer.
CallerLimitCounted per
API keys600 requests / minuteConsumer, across all its keys
Sandbox consumers60 requests / minuteConsumer, across all its keys
Directory endpoints (anonymous)60 requests / minuteClient IP address, per platform
Directory endpoints (anonymous)3000 requests / minuteAll anonymous callers of one platform together
OAuth sign-in120 requests / minuteSigned-in user
Console playground30 requests / minuteConsumer

A consumer can also have a daily cap covering its keyed and anonymous calls. Your console Overview shows the limits that apply to you. Over any limit, the response is HTTP 429 with Retry-After in seconds.

HTTP errors#

Answered before any tool runs, with a JSON body { "error": "…" }.
StatuserrorWhenHeaders
401authentication_requiredNo credential was sent to an endpoint that needs one: /api/mcp without a key, or a directory endpoint that is not open to anonymous calls.WWW-Authenticate: Bearer resource_metadata="…"
401invalid_tokenThe API key is malformed, unknown, revoked or expired, or the OAuth access token is invalid or no longer honored (client, membership or consumer changed).WWW-Authenticate: Bearer resource_metadata="…", error="invalid_token"
403consumer_suspendedThe key is valid but its consumer is not active (pending, suspended or revoked).
403consumer_mismatchThe key belongs to another consumer than the /api/mcp/p/{slug} path it was sent to. Send keys to /api/mcp.
403insufficient_scopeAn OAuth call used a tool whose scope your consumer has but the token lacks. The body's error_description is "Allow this app to access this data on Aiptimise to use this tool"; re-authorize with the scopes named in the challenge.WWW-Authenticate: Bearer resource_metadata="…", error="insufficient_scope", scope="…"
404unknown_endpointThere is no directory endpoint /api/mcp/p/{slug} with that slug.
429rate_limit_exceededA rate limit was reached. Wait the number of seconds in Retry-After, then retry.Retry-After: <seconds>
503mcp_unavailableThe service is switched off by Aiptimise, or rate limiting is unavailable (the service fails closed rather than serve unmetered). Retry later.
Example: an invalid key on /api/mcp
HTTP 401
content-type: application/json
www-authenticate: Bearer resource_metadata="https://app.aiptimise.com/.well-known/oauth-protected-resource/api/mcp", error="invalid_token"
x-request-id: <uuid>

{
  "error": "invalid_token"
}

resource_metadata in WWW-Authenticate points OAuth clients to the sign-in metadata (see Authentication and access). ChatGPT only offers sign-in when the challenge arrives in a tool result, so a call carrying ChatGPT's openai/* request _meta gets the same challenge that way instead (HTTP 200):

JSON
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "isError": true,
    "content": [
      {
        "type": "text",
        "text": "Allow this app to access this data on Aiptimise to use this tool."
      }
    ],
    "_meta": {
      "mcp/www_authenticate": [
        "Bearer resource_metadata=\"https://app.aiptimise.com/.well-known/oauth-protected-resource/api/mcp/p/openai\", error=\"insufficient_scope\", error_description=\"Allow this app to access this data on Aiptimise to use this tool\", scope=\"catalog:read offers:read\""
      ]
    }
  }
}

No tool requires sign-in today, so the sign-in form of this challenge (“Sign in to Aiptimise to use this tool”) is not sent; only OAuth callers can get the step-up form above.

Protocol errors#

Standard JSON-RPC errors from the MCP transport.
CaseHTTPJSON-RPC code
Body is not valid JSON400-32700 Parse error: Invalid JSON
accept header lacks application/json or text/event-stream406-32000 Not Acceptable: Client must accept both application/json and text/event-stream
Unknown method (for example resources/list)200-32601 Method not found

Tool errors#

HTTP 200 with result.isError: true and the message in content[0].text. Show the shopper a plain explanation; do not retry unchanged.
CaseMessage
The store or product does not exist, is not served to you, belongs to another store, or is in a restricted category. The answer is the same in every case, so IDs cannot be probed.The requested store or product is not available.
A tool refused its input; the message says what to change.This product has 4 variants; pass variant_id. Valid IDs: demo-summit-rain-jacket:demo-variant-1-1, demo-summit-rain-jacket:demo-variant-1-2, demo-summit-rain-jacket:demo-variant-1-3, demo-summit-rain-jacket:demo-variant-1-4
Arguments do not match the input schema.MCP error -32602: Input validation error: Invalid arguments for tool get_store_info: Invalid UUID at store_id
The tool does not exist, or your scopes do not include it.MCP error -32602: Tool place_order not found

An unexpected failure answers “The request could not be completed. Please try again later.” Retry later, and quote the response's X-Request-Id if it persists.

Freshness: as_of, source and valid_until#

  • Search results and variants report price and availability from the last catalog sync; each search result has its as_of time.
  • get_live_price_and_inventory returns source: live when it read the merchant's platform just now, or snapshot when it used the last catalog sync. Live reads are supported for Shopify stores; if one takes longer than 700 ms, the snapshot is returned instead.
  • A live offer has as_of and valid_until, 30 seconds later. The same offer is served from cache until then. Do not show it after valid_until; call again.
  • Show prices with their as_of time. The data-use terms set how long you may cache catalog content.