# Projects

A project holds its own contacts, campaigns, sender and settings. Every other route works inside one project.

## List projects

`GET /projects`

Every project you own. Projects are capped by your plan, so they all come back in one page.

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

### Response

```json 200
{
  "projects": [
    {
      "id": "ujzde8gxd6ncf10epf91dhodzdoc9is0",
      "name": "Acme",
      "timezone": "America/New_York",
      "postal_address": "Acme Inc., 548 Market St, San Francisco, CA 94104",
      "inbound_address": "acme-7kq2@in.sendocado.com",
      "created_at": 1787408000000
    }
  ],
  "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 a project

`POST /projects`

A new, empty project. The time zone is the default for its campaigns. Marketing email needs the postal address, because it goes in every footer; you can add it later.

### Body

Send JSON with every field.

| Field | Type | Notes |
| --- | --- | --- |
| `name` | string | Required |
| `timezone` | string | Required |
| `postal_address` | string \| null | Required |

```sh Request
curl -X POST "https://sendocado.com/api/v1/projects" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Acme",
  "timezone": "America/New_York",
  "postal_address": "Acme Inc., 548 Market St, San Francisco, CA 94104"
}'
```

### Response

```json 201
{
  "id": "ujzde8gxd6ncf10epf91dhodzdoc9is0",
  "name": "Acme",
  "timezone": "America/New_York",
  "postal_address": "Acme Inc., 548 Market St, San Francisco, CA 94104",
  "inbound_address": "acme-7kq2@in.sendocado.com",
  "created_at": 1787408000000
}
```

### 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. |
| 402 | `plan_limit_reached` | Your plan allows 5,000 contacts. Upgrade the plan to add more. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |

## Get a project

`GET /projects/{project_id}`

inbound_address is where the project receives mail: replies to its emails come in through it.

### Parameters

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

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

### Response

```json 200
{
  "id": "ujzde8gxd6ncf10epf91dhodzdoc9is0",
  "name": "Acme",
  "timezone": "America/New_York",
  "postal_address": "Acme Inc., 548 Market St, San Francisco, CA 94104",
  "inbound_address": "acme-7kq2@in.sendocado.com",
  "created_at": 1787408000000
}
```

### Errors

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

## Update a project

`PUT /projects/{project_id}`

Send every field; the project becomes exactly what you send.

### Parameters

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

### Body

Send JSON with every field.

| Field | Type | Notes |
| --- | --- | --- |
| `name` | string | Required |
| `timezone` | string | Required |
| `postal_address` | string \| null | Required |

```sh Request
curl -X PUT "https://sendocado.com/api/v1/projects/$PROJECT_ID" \
  -H "Authorization: Bearer $SENDOCADO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Acme",
  "timezone": "America/New_York",
  "postal_address": "Acme Inc., 548 Market St, San Francisco, CA 94104"
}'
```

### Response

```json 200
{
  "id": "ujzde8gxd6ncf10epf91dhodzdoc9is0",
  "name": "Acme",
  "timezone": "America/New_York",
  "postal_address": "Acme Inc., 548 Market St, San Francisco, CA 94104",
  "inbound_address": "acme-7kq2@in.sendocado.com",
  "created_at": 1787408000000
}
```

### 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. |
| 404 | `project_not_found` | Project not found. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |

## Delete a project

`DELETE /projects/{project_id}`

The project is gone at once; its contacts, campaigns and sends are deleted in the background. This cannot be undone.

### Parameters

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

```sh Request
curl -X DELETE "https://sendocado.com/api/v1/projects/$PROJECT_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 | `project_not_found` | Project not found. |
| 429 | `rate_limited` | Too many requests. Try again in 12 seconds. |
