Error codes

The REST API and the MCP server return these HTTP status codes:

StatusMeaning
400 or 422The request or one of its parameters is invalid.
401The token is missing, invalid, expired, or unknown.
403The client is disabled or the effective scope is insufficient.
404The route or organization-scoped resource was not found.
405The HTTP method is not supported for the public resource.
409The operation conflicts with the current saved state or lifecycle state.
413The request body exceeds the size limit, or a computation payload contains an array longer than 500 items.
429A request budget was exceeded. Respect Retry-After.
500An unexpected server error occurred.
502A required upstream service failed to complete the operation.
503Authentication or a required service is temporarily unavailable. Respect Retry-After when present.

Every error the API returns has the same shape: a requestId and an error object. error.code is for your code and error.message is for people. An oversized body (413) and a malformed Content-Length header (400) are rejected before the request reaches the API, so they return {"error": "<message>"} with no request ID; on /oauth2/* those two use the OAuth shape with error set to invalid_request.

error.codeMeaning
invalid_request400 or 422; error.details names the failing fields when there are any.
unauthorized401.
forbidden403, the client is disabled.
insufficient_scope403, the token lacks a scope the operation requires.
not_found404.
method_not_allowed405.
conflict409.
request_too_large413.
rate_limit_exceeded429.
result_not_representable422; a strict payloadContract admitted the request but cannot express the result. See Pin a strict contract.
internal_errorAny 5xx.
temporarily_unavailable503.
request_failedAny other status.

The token endpoint uses the OAuth 2.0 error shape instead; its codes are under Authentication. MCP tool errors carry the same envelope inside the tool result; see Connect over MCP.

Validation details

error.details is present, one entry per failing field, on:

  • 422: a request parameter failed validation.
  • 400: the default computation boundary refused an inputs cell.
  • 400: a strict payloadContract refused the request.
  • 400: a saved-state scenario named a cell the engagement owns.
{
  "requestId": "2f711c6917484e93b3c45a034a405c91",
  "error": {
    "code": "invalid_request",
    "message": "The computation input does not satisfy the selected strict contract.",
    "details": [
      {
        "location": "body.inputs.partnership.priorInterestAcb",
        "message": "Does not satisfy the 'maximum' constraint of the selected strict input schema.",
        "code": "maximum"
      }
    ]
  }
}

Each entry has three fields:

  • location is the dotted path to the field in your request. An array element appears as its index, so the second element of an array named rows is body.inputs.rows.1.
  • message says what was wrong, in one sentence.
  • code names the check that failed. On a 422 it is the parameter validator's error type, such as missing or less_than_equal. On a 400 it is a JSON Schema keyword, which you can check against the cell's entry in the computation reference.

The default boundary reports these keywords:

codeMeaning
additionalPropertiesThe cell is not published for the requested targets, or, in a scenario, the saved engagement owns it.
typeThe value is not the cell's published JSON type.
requiredA rollover fact the computation needs was omitted or null. The computation reference marks these cells as always required.
notTwo facts in the request contradict each other.

A strict contract can report any keyword in the cell's strict profile, such as required, maximum, or pattern.

Submitted values are never echoed back in an error response.

Every /api/v1 response carries an X-Request-Id header, and MCP carries the same identifier in _meta["ca.filemark/requestId"]. Quote it when you write to support@filemark.ca about a failed request. Never include credentials or access tokens.

Filemark | Error codes