# Account and keys

Your account, plan and usage, API keys, and the apps you connected over OAuth.

## Get your account

`GET /account`

Your plan, this month’s usage and your limits. The plan is a paid one only while its subscription is active; the subscription fields show either way, so a failed payment is visible.

```sh Request
curl "https://sendocado.com/api/v1/account" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY"
```

### Response

```json 200
{
  "id": "k1n7c2bq4vxd8a0e3f6g9h2j5m8p1r4s",
  "email": "founder@acme.example",
  "name": "Sam Rivera",
  "plan": {
    "id": "starter",
    "name": "Starter",
    "interval": "month",
    "status": "active",
    "current_period_end": 1791728000000,
    "is_canceled_at_period_end": false
  },
  "usage": {
    "contact_count": 2418,
    "month_send_count": 9310
  },
  "limits": {
    "max_contact_count": 5000,
    "max_monthly_send_count": 50000,
    "max_project_count": 3
  }
}
```

### Errors

| Status | Type | Example message |
| --- | --- | --- |
| 401 | `unauthorized` | Send a valid API key as "Authorization: Bearer sc_…", or sign in. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |

## Delete your account

`DELETE /account`

Cancels your subscription, then deletes every project, key and record of the account in the background. Agents connected over MCP cannot do this; only the app and this route can.

```sh Request
curl -X DELETE "https://sendocado.com/api/v1/account" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY"
```

### Response

`204` with no body.

### Errors

| Status | Type | Example message |
| --- | --- | --- |
| 401 | `unauthorized` | Send a valid API key as "Authorization: Bearer sc_…", or sign in. |
| 404 | `account_not_found` | Account not found. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |

## Start a plan checkout

`POST /billing/checkout-sessions`

A Stripe Checkout page for a paid plan. Send the person to url; the plan applies once Stripe confirms the payment.

### Body

Send JSON with every field.

| Field | Type | Notes |
| --- | --- | --- |
| `plan_id` | "starter" \| "growth" | Required |
| `interval` | "month" \| "year" | Required |

```sh Request
curl -X POST "https://sendocado.com/api/v1/billing/checkout-sessions" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "plan_id": "starter",
  "interval": "year"
}'
```

### Response

```json 201
{
  "url": "https://checkout.stripe.com/c/pay/cs_live_a1B2c3D4"
}
```

### Errors

| Status | Type | Example message |
| --- | --- | --- |
| 400 | `invalid_data` | Send a JSON request body. |
| 401 | `unauthorized` | Send a valid API key as "Authorization: Bearer sc_…", or sign in. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |

## Open the billing portal

`POST /billing/portal-sessions`

A Stripe billing portal page where you change plan, update the card, download invoices or cancel.

```sh Request
curl -X POST "https://sendocado.com/api/v1/billing/portal-sessions" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY"
```

### Response

```json 201
{
  "url": "https://billing.stripe.com/p/session/live_a1B2c3D4"
}
```

### Errors

| Status | Type | Example message |
| --- | --- | --- |
| 401 | `unauthorized` | Send a valid API key as "Authorization: Bearer sc_…", or sign in. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |

## List API keys

`GET /api-keys`

Your keys, without the keys themselves. A key works for every project you own.

```sh Request
curl "https://sendocado.com/api/v1/api-keys" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY"
```

### Response

```json 200
{
  "api_keys": [
    {
      "id": "pt49zhkken659o2v21i9mpflv9fupxqm",
      "name": "Production server",
      "prefix": "sc_Xk29fPq7",
      "created_at": 1788790400000,
      "last_used_at": 1789999880000
    }
  ],
  "next_cursor": null
}
```

### Errors

| Status | Type | Example message |
| --- | --- | --- |
| 401 | `unauthorized` | Send a valid API key as "Authorization: Bearer sc_…", or sign in. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |

## Create an API key

`POST /api-keys`

The only response that contains the key; store it now, it cannot be read again.

### Body

Send JSON with every field.

| Field | Type | Notes |
| --- | --- | --- |
| `name` | string | Required |

```sh Request
curl -X POST "https://sendocado.com/api/v1/api-keys" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Production server"
}'
```

### Response

```json 201
{
  "id": "pt49zhkken659o2v21i9mpflv9fupxqm",
  "name": "Production server",
  "prefix": "sc_Xk29fPq7",
  "created_at": 1790000000000,
  "last_used_at": null,
  "key": "sc_Xk29fPq7mN3vB8cR1tY6uW0zA4sD2fG5hJ9kL7qE1"
}
```

### Errors

| Status | Type | Example message |
| --- | --- | --- |
| 400 | `invalid_data` | Send a JSON request body. |
| 401 | `unauthorized` | Send a valid API key as "Authorization: Bearer sc_…", or sign in. |
| 409 | `conflict` | This campaign has enrollments, so it cannot be deleted. Pause it instead. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |

## Revoke an API key

`DELETE /api-keys/{api_key_id}`

The key stops working at once.

### Parameters

| Name | In | Type | Notes |
| --- | --- | --- | --- |
| `api_key_id` | path | string | Required |

```sh Request
curl -X DELETE "https://sendocado.com/api/v1/api-keys/$API_KEY_ID" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY"
```

### Response

`204` with no body.

### Errors

| Status | Type | Example message |
| --- | --- | --- |
| 401 | `unauthorized` | Send a valid API key as "Authorization: Bearer sc_…", or sign in. |
| 404 | `api_key_not_found` | API key not found. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |

## List connected apps

`GET /connected-apps`

MCP clients you approved with OAuth, such as Claude or Cursor.

```sh Request
curl "https://sendocado.com/api/v1/connected-apps" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY"
```

### Response

```json 200
{
  "connected_apps": [
    {
      "oauth_client_id": "mmex6l2qagwncxvjcnqcnau0xltenc59",
      "name": "Claude",
      "connected_at": 1789740800000
    }
  ],
  "next_cursor": null
}
```

### Errors

| Status | Type | Example message |
| --- | --- | --- |
| 401 | `unauthorized` | Send a valid API key as "Authorization: Bearer sc_…", or sign in. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |

## Disconnect an app

`DELETE /connected-apps/{oauth_client_id}`

Deletes the app’s tokens; its next call fails with 401.

### Parameters

| Name | In | Type | Notes |
| --- | --- | --- | --- |
| `oauth_client_id` | path | string | Required |

```sh Request
curl -X DELETE "https://sendocado.com/api/v1/connected-apps/$OAUTH_CLIENT_ID" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY"
```

### Response

`204` with no body.

### Errors

| Status | Type | Example message |
| --- | --- | --- |
| 401 | `unauthorized` | Send a valid API key as "Authorization: Bearer sc_…", or sign in. |
| 404 | `connected_app_not_found` | Connected app not found. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |
