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

# Authentication

> How to create and use API keys to authenticate with the Moda REST API.

The Moda REST API uses API keys for authentication. Include your key as a Bearer token in the `Authorization` header of every request.

## Creating an API key

1. Open the Moda app and go to **Settings > Developer**
2. Under **REST API**, click **Create Key**
3. Give the key a name (e.g., "CI Pipeline" or "Internal Dashboard")
4. Select the scopes the key needs (see [Scopes](#scopes) below)
5. Click **Create**
6. Copy the key immediately -- it is only shown once

API keys use the format `moda_live_<hex_chars>`.

## Using your key

Include the key in the `Authorization` header:

```bash theme={null}
curl https://api.moda.app/v1/canvases \
  -H "Authorization: Bearer moda_live_abc123def456..." \
  -H "Moda-Version: 2026-05-01"
```

Every request without a valid key returns `401 Unauthorized` with `WWW-Authenticate: Bearer`. Pin `Moda-Version` on every request so your response shapes stay stable across releases — see [Versioning](/api-reference/versioning).

## Scopes

Each API key is granted one or more scopes that control what it can access. Choose the minimum scopes your integration needs.

| Scope                | Grants access to                        |
| -------------------- | --------------------------------------- |
| `canvases:read`      | List and search canvases                |
| `canvases:write`     | Create and modify canvases              |
| `designs:read`       | Fetch design pseudo-HTML, tokens, pages |
| `designs:export`     | Export and download files               |
| `tasks:read`         | Get task status and list tasks          |
| `tasks:write`        | Start design and remix tasks            |
| `tasks:cancel`       | Cancel in-flight tasks                  |
| `brand_kits:read`    | List brand kits                         |
| `brand_kits:write`   | Create and update brand kits            |
| `uploads:write`      | Upload files and import from URLs       |
| `organizations:read` | List organizations and teams            |
| `credits:read`       | Check credit balance                    |
| `webhooks:manage`    | Manage webhook configuration            |

For example, a read-only dashboard integration would need `canvases:read` and `designs:read`. An automation that generates designs would also need `tasks:write` and `canvases:write`.

## Security best practices

* **Do not commit keys to source control.** Use environment variables or a secrets manager.
* **Use the narrowest scopes possible.** A key that only reads canvases should not have write scopes.
* **Rotate keys periodically.** Delete keys you no longer use from **Settings > Developer**.
* **Use separate keys per integration.** This lets you revoke access to one system without affecting others.
* **Keep keys server-side.** Never expose API keys in frontend code, mobile apps, or client-side bundles.

## Resource ID formats

Every resource has a prefixed wire ID like `cvs_01HT9WK8...` (canvas), `task_01HT9WK8...` (task), `bk_01HT9WK8...` (brand kit). The prefix disambiguates the resource type on sight and prevents accidental cross-resource lookups.

Two rules, different strictness:

* **JSON request / response body fields** — strict. Always the prefixed form (`cvs_...`, `task_...`, etc.). Sending a bare UUID in a body field returns `400 invalid_request`.
* **Path parameters** — tolerant. Accept either the prefixed form **or** a bare UUID string (`550e8400-e29b-41d4-a716-446655440000`). Pass a UUID straight from your database or a tool response without re-encoding.

Response `id` fields always come back prefixed, so stored references should prefer the prefixed form. The bare-UUID path-parameter tolerance is a convenience for integrators who already hold UUIDs.

```bash theme={null}
# Both of these work for path parameters:
curl -X POST https://api.moda.app/v1/canvases/cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV/export ...
curl -X POST https://api.moda.app/v1/canvases/550e8400-e29b-41d4-a716-446655440000/export ...

# This does NOT work -- body fields require prefixed:
curl -X POST https://api.moda.app/v1/remix \
  -d '{"canvas_id": "550e8400-e29b-41d4-a716-446655440000"}'
# -> 400 invalid_request
```

## Revoking a key

Go to **Settings > Developer > REST API**, find the key, and click **Delete**. The key stops working immediately. Any requests using the deleted key return `401 Unauthorized`.

## Related

* [Versioning](/api-reference/versioning) — pin a version with the `Moda-Version` header.
