# Authentication

Authenticate API requests with a project access key sent in the x-access-key header.


Every request to `/v1/*` must include an access key. Keys belong to a project: a key can see and publish to every social account connected in that project, and nothing else.

## Create a key

1. Open **Access Keys** at [https://social-publish-kappa.vercel.app/dashboard/api-keys](https://social-publish-kappa.vercel.app/dashboard/api-keys).
2. Click **Create key** and give it a name (up to 60 characters) that tells you where it's used.
3. Copy the key. It looks like `sp_live_...` and is shown **only once**.

Relaycast stores only a SHA-256 hash of the key, so a lost key can't be recovered. Create a new one instead. Only project owners and admins can create or revoke keys (see [Collaborators & Projects](/docs/team)).

## Send the key

Use the `x-access-key` header:

```bash tab="cURL"
curl https://social-publish-api.onrender.com/v1/accounts \
  -H "x-access-key: $RELAYCAST_API_KEY"
```

```ts tab="Node.js"
const res = await fetch("https://social-publish-api.onrender.com/v1/accounts", {
  headers: { "x-access-key": process.env.RELAYCAST_API_KEY! },
});
```

```python tab="Python"
import os
import requests

res = requests.get(
    "https://social-publish-api.onrender.com/v1/accounts",
    headers={"x-access-key": os.environ["RELAYCAST_API_KEY"]},
)
```

A standard bearer token works too, which is handy for tools that only support `Authorization` headers:

```http
GET /v1/accounts HTTP/1.1
Authorization: Bearer sp_live_...
```

If both headers are sent, `x-access-key` wins.

## Authentication errors

A missing, unknown or revoked key returns `401`:

```json
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid API key"
  }
}
```

The message is `Missing API key (x-access-key header)` when no key was sent at all. Unauthenticated requests are not recorded in [Request Logs](/docs/logs), because there's no project to attach them to.

## Revoke and rotate keys

Click **Revoke** next to a key on the Access Keys page. Revocation takes effect immediately: the next request with that key gets `401`.

To rotate without downtime:

1. Create a new key.
2. Deploy it to your servers.
3. Confirm traffic has moved. The Access Keys page shows when each key was last used (updated about once a minute), and [Request Logs](/docs/logs) show which key made each call.
4. Revoke the old key.

## Keep keys safe

- Call the API from your server or a trusted backend job, never from browser or mobile code.
- Keep keys in environment variables or a secrets manager, not in source control.
- Use one key per environment or service, so you can revoke one without affecting the others.

## Rate limits

Each key has its own per-minute request limit, and responses include `X-RateLimit-Limit` and `X-RateLimit-Remaining` headers. See [Rate Limits](/docs/limits).

## Public endpoints

`GET /health` and `GET /ready` don't need a key. See [Health & readiness](/docs/api/health).
