CanopyAPI docs

invalid_request

The request body or query parameters failed validation before Canopy attempted the operation.

HTTP 400

When this happens

Canopy validates every /api/v1/* request with a strict schema before touching any state, and returns invalid_request when that validation fails. Two examples: a POST /api/v1/intents body missing a required field or carrying a field of the wrong type, and a GET /api/v1/intents request whose cursor query parameter is not a non-negative integer.

Two other errors are also 400s, with a different code in the envelope below. invalid_json means the body is not parseable JSON at all. unsupported_version means the Canopy-Version header names a version Canopy does not serve.

The error envelope

Every /api/v1/* error shares one shape, and the keys always serialize in this order. param and detail are omitted entirely, never sent as null, when the error does not carry them.

json
{
  "error": {
    "code": "invalid_request",
    "message": "The request body failed validation.",
    "param": "priceUnits",
    "request_id": "req_1a2b3c4d5e6f7a8b9c0d1e2f",
    "docs": "https://canopypay.io/errors/invalid_request"
  }
}

param, when present, names the first field that failed validation, in dot-path notation (metadata.reference for a nested field). Validation stops at the first issue, so treat it as a hint for logging and debugging rather than a list of every violation.

What to do about it

Re-check the request against the operation's documented request schema, paying particular attention to the field named in param when one is present. This is always a client-side fix: retrying the identical request will fail identically. invalid_request is never retried automatically by Canopy's own SDK, because retrying a request that was rejected before any state changed would not change the outcome.

If the request looks correct and you still receive invalid_request, include the request_id from the error body when contacting support. It identifies this exact request in Canopy's logs.