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

# Rate Limits

> API rate limits to ensure fair usage and system stability.

## Overview

OneShot enforces rate limits to ensure fair usage and protect system stability. Limits are applied per agent (identified by wallet address) or per IP address, depending on the endpoint type.

***

## Rate Limits by Endpoint Type

| Endpoint Type            | Limit        | Window   | Key          |
| ------------------------ | ------------ | -------- | ------------ |
| **Paid endpoints**       | 60 requests  | 1 minute | Agent wallet |
| **Expensive operations** | 10 requests  | 1 minute | Agent wallet |
| **Free read endpoints**  | 120 requests | 1 minute | Agent wallet |

***

## Endpoint Categories

### Paid Endpoints (60/min)

Standard paid API calls:

* `POST /v1/tools/email/quote`
* `POST /v1/tools/email/send`
* `POST /v1/tools/enrich/email`
* `POST /v1/tools/enrich/profile`
* `POST /v1/tools/verify/email`
* `POST /v1/tools/commerce/search`
* `POST /v1/tools/commerce/buy`
* `POST /v1/tools/sms/send`

### Expensive Operations (10/min)

Resource-intensive operations with stricter limits:

* `POST /v1/tools/voice/call` — Voice calls
* `POST /v1/tools/research` — Deep web research
* `POST /v1/tools/research/people` — People discovery

### Free Read Endpoints (120/min)

Read-only endpoints that don't require payment:

* `GET /v1/tools/inbox/list` — Email inbox list
* `GET /v1/tools/inbox/:id` — Email details
* `GET /v1/tools/sms/inbox` — SMS inbox list
* `GET /v1/tools/sms/inbox/:id` — SMS details
* `GET /v1/status/:id` — Job status polling

***

## Rate Limit Response

When you exceed a rate limit, you'll receive a `429 Too Many Requests` response:

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "Too many requests, please try again later.",
  "retry_after": 60
}
```

### Response Headers

Rate limit information is included in response headers:

| Header                | Description                          |
| --------------------- | ------------------------------------ |
| `RateLimit-Limit`     | Maximum requests allowed in window   |
| `RateLimit-Remaining` | Requests remaining in current window |
| `RateLimit-Reset`     | Seconds until the window resets      |

***

## Best Practices

<AccordionGroup>
  <Accordion title="Implement exponential backoff">
    When you receive a 429 response, wait for the `retry_after` period before retrying. For repeated rate limits, increase the wait time exponentially.

    ```typescript theme={null}
    async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
      for (let attempt = 0; attempt < maxRetries; attempt++) {
        try {
          return await fn();
        } catch (error: any) {
          if (error.status === 429 && attempt < maxRetries - 1) {
            const delay = Math.pow(2, attempt) * 1000;
            await new Promise(resolve => setTimeout(resolve, delay));
            continue;
          }
          throw error;
        }
      }
      throw new Error('Max retries exceeded');
    }
    ```
  </Accordion>

  <Accordion title="Batch operations when possible">
    For bulk operations, use batch endpoints where available:

    * SMS: Send to multiple recipients in one request (up to 10)
    * Email: Include multiple recipients in one send
  </Accordion>

  <Accordion title="Cache inbox results">
    Free read endpoints like inbox list and status polling have generous limits, but caching results client-side reduces unnecessary API calls.
  </Accordion>

  <Accordion title="Use webhooks for job completion">
    Instead of polling `/status/:id` repeatedly, configure webhooks to receive notifications when jobs complete.
  </Accordion>
</AccordionGroup>

***

## SDK Handling

The OneShot SDK automatically handles rate limit responses with built-in retry logic:

```typescript theme={null}
import { OneShot } from "@oneshot-agent/sdk";

const agent = new OneShot({
  privateKey: process.env.AGENT_PRIVATE_KEY
});

// SDK automatically retries on 429 with exponential backoff
const result = await agent.research({
  query: "Latest AI developments"
});
```

***

## Need Higher Limits?

If your use case requires higher rate limits, contact us at [nicolas@freebutter.com](mailto:nicolas@freebutter.com) to discuss enterprise options.
