API keys
An API key lets scripts, backends, and agents call the Corte API and MCP server as your account.
Create a key
- Open Settings → API in the app.
- Click Create key and give it a name that says where it will live —
ci-render-bot,zapier,claude-code. - Copy the secret now. It starts with
corte_sk_and is shown exactly once; Corte stores only a hash, so there is no way to see it again later.
Prefer to do it programmatically? With a signed-in session:
POST /v1/api-keys { "name": "ci-render-bot", "scopes": ["media:rw"] } # scopes required
GET /v1/api-keys # list (names + scopes, no secrets)
DELETE /v1/api-keys/:id # revoke immediately
Full request and response shapes: Account & keys.
Scopes
Choose what a key can reach when you create it. Scopes are coarse — one entry per product area, each read-only or read-write — because the question you are answering is "what is this integration for", not "which endpoints does it call".
| Area | Covers |
|---|---|
content | Content types, documents, revisions, delivery tokens and webhooks. |
media | Uploads, stored files, the library and transcriptions. |
integrations | Connected sources like Shopify and Dropbox, and importing from them. |
generation | Models, generation jobs, applications and the AI agent proxy. Spends credits. |
workflows | Workflow definitions and runs. Running one spends credits. |
cuts | Video edits — timelines, tracks and their saved content. |
projects | Projects, members and invites. |
plugins | Published plugins, versions and installs. |
community | Shared community templates. |
build | App builder connections, including GitHub. A key with no build scope cannot reach the Build plane at all. |
agents | Agents — creating, editing and running standing automations. Their runs spend credits. |
account | Profile, plan, usage, billing and API keys. Grant sparingly. |
Each area takes :read (GET requests) or :rw (everything). :rw includes
:read, so content:rw is the whole area — you never need both.
# A key for a website that only reads published content
{ "name": "marketing-site", "scopes": ["content:read"] }
# A key for a bot that drafts and publishes, and uploads the images it needs
{ "name": "content-bot", "scopes": ["content:rw", "media:rw"] }
A request outside the key's scopes fails with 403 forbidden and a message
naming the scope it needed, so a misconfigured integration tells you what to
fix. The same scopes apply to the MCP server: a scoped key
is offered only the tools it can call.
Areas don't imply each other, which occasionally bites on project-scoped
routes: several content endpoints are addressed as
/v1/projects/{projectId}/content/…, and listing your projects to find that id
is the projects area. Copy the id from Settings → Project (it sits under the
name) and hard-code it, or add projects:read to the key.
:::note Scopes are set once There is no way to edit a live key's scopes. A key is already pasted into something; widening it would make a grant you thought you had bounded into a moving target, and narrowing it would break that integration with no warning. To change what a key can do, create a new one and revoke the old. :::
Every new key must name at least one area — there is no way to create one with full access. Keys made before scopes existed show as Full access and keep working exactly as they did; replace them when convenient.
:::warning A secret key is never safe to embed
There is no "public" scope. If you need a browser, a static site, or a mobile
app to read published content, that is a
delivery token — a corte_ct_
credential that only ever reads published content for one project. A
corte_sk_ key acts as your account no matter how narrowly it is scoped, so it
belongs on a server.
:::
Use it
Send the secret as a bearer token on every request:
curl https://api.corte.so/v1/account \
-H "Authorization: Bearer corte_sk_…"
:::warning A key is your account Keys act as you: they read your workflows and assets, and every generation, LLM step, and workflow run they start spends your credits (or, for project-billed work, the project owner's pool — see Pooled billing). Treat a key like a password. :::
Key hygiene
- One key per integration. When a key leaks or a tool is retired, you can revoke just that key without breaking everything else.
- Keep secrets out of source control. Load keys from environment variables or your secret manager, never from committed files.
- Rotate on suspicion. Create a new key, switch the integration over, then delete the old one — revocation is immediate.
- Watch the ledger. Key-driven spend shows up in Settings → Usage like any other activity, so an unfamiliar burst of generations is easy to spot.
If a key is compromised
Delete it in Settings → API (or DELETE /v1/api-keys/:id) — requests with
that key fail with unauthenticated from that moment. Then review your
usage ledger and
contact us if you see spend you don't
recognize.