> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shodai.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors and troubleshooting

> Resolve common API authentication, entitlement, validation, signing, deployment, and input-submission failures.

For the complete documentation index, see [llms.txt](https://docs.shodai.network/llms.txt).

Use this page when an API request fails or when an agreement does not move through the lifecycle as expected.

## HTTP status codes

Error responses use a top-level `error` object. Use `error.requestId` when sharing a failure with support.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "error": {
    "code": "bad_request",
    "message": "limit must be an integer between 1 and 100",
    "details": {
      "field": "limit"
    },
    "requestId": "req_123"
  }
}
```

| Status | Meaning                                                                                       | Common cause                                                                                                                     |
| ------ | --------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | The request is malformed or semantically invalid.                                             | Invalid status filter, deployment payload, agreement JSON, or signed input payload.                                              |
| `401`  | Missing, invalid, or unsupported API credential.                                              | `X-API-Key` is absent, revoked, disabled, or incorrect; `Authorization: Bearer cns_pk_...` is accepted only as an API-key alias. |
| `402`  | The authenticated API principal has `paid_required` entitlement mode for the requested scope. | Per-call x402 settlement is not implemented. Treat this as an entitlement/operator issue.                                        |
| `403`  | Authenticated but not allowed.                                                                | Missing active entitlement, blocked entitlement, or resource access denial.                                                      |
| `404`  | Requested agreement or resource was not found.                                                | Wrong agreement ID, wrong deployed address, or unavailable record.                                                               |
| `429`  | Rate limited.                                                                                 | Too many requests in a short window; back off before retrying.                                                                   |

Use the API Reference group in the sidebar for endpoint-specific response schemas.

## Downstream conflict responses

Some deployment or input operations may surface `409 Conflict` from the downstream agreements service. This note is separate from the main status table; use the API Reference group for generated endpoint-specific response codes.

| Status | Where it may surface            | Common cause                                                                                                             | Next check                                                                                                              |
| ------ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| `409`  | Deployment or input operations. | The record is in the wrong lifecycle status for the operation, or the live state no longer accepts the submitted action. | Reread the agreement record and current state, then confirm the requested operation is valid for that status and state. |

## Validate the right thing

`POST /v0/agreements/validate-template` checks authored agreement JSON only. If it fails or returns warnings, inspect participant variable keys, input IDs, state IDs, and agreement structure before preparing deployment.

`POST /v0/agreements/validate` checks the assembled deployment request. If it fails, compare the authored agreement with `initValues`, participant wallet mappings, observers, and the normalized `variables` response.

<Note>
  Deployment preflight does not deploy the agreement and does not validate permit signatures.
</Note>

## Fix signing failures

Regenerate the signature if any of these values change:

* agreement JSON
* `initValues`
* `docUri`
* chain
* factory or agreement address
* signer nonce
* deadline
* input ID
* input values

<Warning>
  For deployment, sign the effective post-mapping values returned by `POST /v0/agreements/validate`, not raw caller input, when participant mappings change values included in the signature.
</Warning>

The TypeScript client uses a one-hour default permit lifetime through `computeDefaultDeadlineSeconds()`. Use a shorter deadline if your integration requires a tighter replay window, and regenerate the signature whenever the deadline expires.

## Diagnose errors in the TypeScript client

`ApiClient` throws `AgreementsApiError` for unexpected HTTP responses. Inspect `status`, `errorPayload`, `bodyText`, and `parsedBody` before retrying.

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { AgreementsApiError } from '@cns-labs/agreements-api-client';

try {
  await client.validateDeployment(payload);
} catch (error) {
  if (error instanceof AgreementsApiError) {
    console.error({
      status: error.status,
      message: error.errorPayload?.error.message,
      code: error.errorPayload?.error.code,
      requestId: error.errorPayload?.error.requestId,
      body: error.parsedBody,
    });
  }
  throw error;
}
```

Use `client.exchangeJson('GET', '/v0/agreements')` when you need `status`, `ok`, `headers`, `bodyText`, and `parsedBody` without throwing on HTTP errors.

For successful raw HTTP responses, inspect `data` first. List responses also include `pageInfo`; single-resource responses include only `data` and `meta`.

## Input does not move the agreement

Check these conditions in order:

1. The agreement is in the state that accepts the input.
2. The submitted `inputId` exists in the authored agreement.
3. The submitted `values` match the input schema.
4. The signer is allowed by the input `issuer`.
5. The transition condition references that input from the current state.
6. The signature has not expired and was generated for this exact payload.

If an input record is `MINED` but state has not updated yet, reread `GET /v0/agreements/{id}/state` after a short delay and use `GET /v0/agreements/{id}/inputs` as the audit trail.

## Deployment conflicts

For deployment and operation failures, confirm that:

1. the agreement ID or deployed address points to the intended record
2. the API key can access that record
3. the requested operation is valid for the agreement's current lifecycle position
4. the current state still accepts the action you are submitting
5. the signing wallet is authorized for the requested action

## Related pages

* [Authentication](/authentication)
* [Validate Agreement Structure](/workflow/validate-agreement-structure)
* [Deploy an Agreement](/workflow/deploy-an-agreement)
* [Operate a Deployed Agreement](/workflow/operate-a-deployed-agreement)
* [TypeScript client reference](/sdks/typescript-client)
* [EIP-712 Signing Reference](/reference/eip-712-signing)
