# Authentication

API keys for your own code and scripts, sign-in with Citypicked for AI assistants. Both act as a person on your team, never more.

Source: https://citypicked.com/en/developers/authentication

## API keys

Owners and managers make keys in the app under **Settings > Sending > API** ([go there](https://app.citypicked.com/settings/api)). Send the key on every call.

```
Authorization: Bearer cp_live_xxxxxxxx
```

- Every key starts with `cp_live_` and is shown once, when it is made
- An account can have up to 20 active keys
- A key acts as the person who made it, with their role and locations at the moment of the call
- Anything outside that reach answers 404, exactly like an id that does not exist
- A key stops working when its person leaves the team, changes role or locations, or logs out everywhere
- Revoke a key in the same place in the app. Everything that uses it stops at once

## Scopes

| Scope | In the app | What it allows |
| --- | --- | --- |
| `read` | Read | Every `GET`, so the account, locations, review links, requests, feedback, numbers and webhooks |
| `send` | Read and send requests | Also `POST /v1/requests`, canceling a planned request, and adding or removing webhooks |

Every key has `read`. Sending through the API is part of the Pro and Business plans; reading works on every plan. `GET /v1/me` answers `can_send` so you can check before you send.

## OAuth for MCP

AI assistants connect to the MCP server at `https://mcp.citypicked.com/mcp` without a key. The person signs in to Citypicked, sees what the assistant asks for and picks **Allow**. Details for each assistant are on the [MCP page](https://citypicked.com/en/developers/mcp).

- Only owners and managers can allow a connection, and it acts as the person who allowed it
- The consent screen shows the assistant, the account, the locations and the two scopes
- A connection allowed to read only gets 403 `insufficient_scope` when it tries to send, so the assistant can ask again
- Every connected assistant is listed under **Settings > Sending > API** and can be disconnected there at any time

### For client developers

Standard OAuth 2.1 with PKCE (S256). The MCP server publishes its protected resource metadata at `/.well-known/oauth-protected-resource/mcp` and names `https://app.citypicked.com` as the authorization server, whose metadata is at `https://app.citypicked.com/.well-known/oauth-authorization-server`.

- Client ID metadata documents are supported, and dynamic client registration for clients without one
- Scopes are `read` and `send`; the resource is the MCP address above
- Access tokens last an hour, refresh tokens rotate on every use

## Keep keys safe

- Keep keys on your server, never in a browser, an app bundle or a public repository
- Give each tool its own key, so you can revoke one without touching the rest
- Give a key `send` only when it needs to send
