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

# SDK reliability

> Control retries, retry budgets, and circuit breakers in the SEC API JavaScript and Python SDKs

Use the SDK retry policy to absorb a short-lived read failure, not to hide a request, account, or data problem. Let one layer own retries: when your job runner, gateway, or application already retries, disable SDK retries there to avoid multiplying attempts during an outage.

The JavaScript and Python SDKs retry eligible transient read failures. `POST`, `PUT`, `PATCH`, and `DELETE` are not retried for transient failures by default. A `429` is retried for any method when retries are enabled unless the API marks the response non-retryable; that does not make replaying a write safe.

## Default retry boundary

| Behavior                      | Default                                                                                                                                     |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Automatically retried methods | `GET`, `HEAD`, `OPTIONS`                                                                                                                    |
| Retryable failures            | Network failures and HTTP `408`, `502`, `503`, `504` when the response is retryable; HTTP `429` unless the response is marked non-retryable |
| Not retried                   | HTTP `400`, `401`, `403`, `404`, `422`, and responses marked non-retryable                                                                  |
| Retry count                   | Up to 3 retries                                                                                                                             |
| Backoff                       | Jittered exponential delay, starting at `200ms` and capped at `5s`                                                                          |
| Retry budget                  | `30s`                                                                                                                                       |
| Circuit breaker               | Opens after 5 terminal retryable failures and cools down for `60s`                                                                          |

When the service provides `Retry-After`, the SDK uses it. When an intermediary removes that header, the SDK can also read structured retry timing in the API error payload.

## Keep write retries explicit

Do not opt a write into retries unless your application can safely repeat the logical operation. Use an idempotency key where the endpoint supports one, keep it stable for that operation, and ensure no outer retry layer will create a second replay.

```ts theme={null}
const client = new SecApiClient({
  apiKey: process.env.SECAPI_API_KEY,
  retry: false,
})

await client.callMcpTool(
  "entities.resolve",
  { ticker: "AAPL" },
  { retry: { enabled: true } },
)
```

MCP tool calls use `POST`. Opt in only for a read-only tool or an operation your application has made idempotent. For a `429`, inspect the response's retry guidance before deciding whether to replay a call.

## Set retry ownership and deadlines

Disable SDK retries when another layer already owns backoff. Keep an application deadline around the whole user or worker operation; a retry budget controls the SDK attempt sequence, not the rest of your work.

<CodeGroup>
  ```ts TypeScript theme={null}
  const client = new SecApiClient({
    apiKey: process.env.SECAPI_API_KEY,
    retry: false,
  })
  ```

  ```python Python theme={null}
  import os

  from secapi_client import SecApiClient

  client = SecApiClient(
      api_key=os.environ["SECAPI_API_KEY"],
      retry=False,
      timeout=10,
  )
  ```
</CodeGroup>

The Python SDK uses a `30s` per-request socket timeout by default. Choose a shorter timeout for latency-sensitive work, or ensure an outer transport layer provides the deadline you need. The JavaScript SDK applies its retry budget to the request attempt sequence.

## Diagnose an SDK failure

API failures expose HTTP status, API error code, request ID, and response payload. Log the request ID with the operation that failed, then classify the response before retrying:

* Correct `400` responses from the route or tool schema.
* Repair the key or account context for `401`, `402`, and `403` responses.
* On a retryable `429` or temporary service failure, follow the returned retry timing and keep concurrency bounded.
* When the client circuit is open, wait for its cooldown instead of creating parallel client instances to bypass it.

The JavaScript SDK emits `client_retry_attempt` only when a telemetry capture token is configured. The Python SDK emits retry telemetry by default; set `telemetry=False` or `telemetry={"enabled": False}` to disable it.

Read [Troubleshooting](/troubleshooting) for HTTP recovery decisions and [MCP workflows](/mcp-workflows) before enabling retries for an MCP call.
