---
title: Authentication
description: Send an API key as a bearer token, learn which organization and which permissions it carries, and see which permission each AdCrunch API needs.
---

Each request sends one header:

```http
Authorization: Bearer <credential>
```

The four APIs accept the same credential. No operation takes a credential in another place.

## Two credentials

- **An API key** starts with `acr_`. Your server code sends it. [API keys](/account/api-keys) tells you how to create one, how long it lives, and how to revoke it.
- **A session** comes from the AdCrunch sign-in flow. The console uses it when it calls the API from the browser. Your code does not need it.

An AI agent does not use either of these. It connects over MCP with OAuth, and its permissions come from the scopes of its token. See [Auth and scopes](/mcp/auth).

## The credential names the organization

No operation has an organization parameter. The credential names the organization. Each request reads and writes that organization only.

## The permissions of a key

A key carries the permissions of the member who created it. [API keys](/account/api-keys) explains which organization a key acts for, and what occurs when its creator changes role or leaves.

Each operation needs one permission:

| Permission | Operations |
| --- | --- |
| `observe:read` | Each Observe operation |
| `mutation:write` | Start a Mutation (`POST /mutations`), and read that Mutation (`GET /mutations/{id}`) |
| `mutation:read` | List the Mutation history (`GET /mutations`) |
| `skill:read`, `skill:write` | Skills |
| `brand:read`, `brand:write` | Brands, Personas, Documents, and the advertisers of a Brand |
| `campaign_plan:read`, `campaign_plan:write` | Campaign Plans and Line Items |
| `asset:read`, `asset:write` | Assets |

A `read` permission reads. A `write` permission creates, changes, and deletes. To poll a Mutation, you need `mutation:write`, because the caller that polls is the caller that started it.

Today, each role that you can give a member holds each of these permissions: member, admin, and owner. See [Team and roles](/account/team).

## When the credential fails

| Status | `error` | Cause |
| --- | --- | --- |
| `401` | `unauthorized` | The request has no credential, or the credential does not resolve. The key is revoked or expired, or its creator deleted their account. |
| `403` | `forbidden` | The credential resolves, but it does not hold the permission that the operation needs. A key also answers this when its creator left the organization. |
| `403` | `missing_write_access` | `POST /mutations` only. The connection of the advertiser has no write access. A person must connect the advertiser again and grant write access. |

[Errors](/api/errors) explains the shape of each failure.

## Call the API from a server

Send a key from your server only. A browser can read each header that a page sends, so a key in a browser is a key that you publish.

The API also refuses a browser request from any origin other than the AdCrunch console. This is a CORS rule, and only a browser applies it. It has no effect on a server that sends a key.
