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

# Authentication

> How to authenticate to the Signal API with an API key: creating, sending, replacing and revoking keys, and what to do when a request is refused.

Last reviewed 9 November 2026

Every request to the Signal API carries an API key. A key belongs to your organization, not to a person, and it reads only the Signals chosen when it was created.

> [!NOTE]
> **Using the MCP server?**
>
> The MCP server does not use API keys. You sign in with your Odyssey account when you connect it. See [Install the MCP server](https://docs.odysseysignal.com/mcp/install-mcp).

## Send the key with each request

Put the key in the `X-Api-Key` header of every request. All requests go to `https://api.odysseysignal.app` over HTTPS.

**curl**

```bash
curl https://api.odysseysignal.app/v1/signals \
  -H "X-Api-Key: $ODYSSEY_API_KEY"
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://api.odysseysignal.app/v1/signals",
    headers={"X-Api-Key": os.environ["ODYSSEY_API_KEY"]},
    timeout=30,
)
response.raise_for_status()
print(response.json())
```

**JavaScript**

```javascript
const response = await fetch("https://api.odysseysignal.app/v1/signals", {
  headers: {"X-Api-Key": process.env.ODYSSEY_API_KEY},
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
console.log(await response.json());
```

> [!WARNING]
> **Not in the Authorization header**
>
> Send the key in `X-Api-Key` only. A key sent as `Authorization: Bearer <key>` is not recognized, and the request fails with 401.

## Create a key

API keys are created in the portal by an **API admin** in your organization. Organization admins can see the keys but not create or revoke them. If you cannot create a key, ask your organization's administrator, or contact us at support@odysseysignal.com.

1. **Open the API keys**

   In the portal, open **Settings** and choose **API keys**.

2. **Create the key**

   Select **Create key**. Give it a **Label** that says who or what uses it, such as "Power BI" or "Data warehouse sync". The label is shown in the list of keys.

3. **Choose the kind and the Signals**

   Choose **Live** or **Test** (see below), then tick the Signals the key may read. A key reads nothing else.

4. **Copy the key**

   The key is shown once. Select **Copy key** and store it somewhere safe, such as your secret manager. We keep only a fingerprint of it, so neither you nor we can show it again.

If you lose a key, create a new one and revoke the old one.

## Live and test keys

| Kind | Starts with | What it reads |
| --- | --- | --- |
| Live | `osk_live_` | The Signals you chose when you created the key. |
| Test | `osk_test_` | Only demo Signals, with brand names masked. Use it to build and try out an integration before it reads real data. |

A key looks like `osk_live_` followed by 22 random characters, an underscore and a 6-character checksum. The list of keys in the portal shows only the start, such as `osk_live_a1b2`, so you can tell keys apart. A key with a typo or a missing character is refused at once by its checksum.

## What a key can access

- Only your own organization, and only the Signals the key was given. Everything else answers as if it did not exist (404 `not-found`).
- Read access only: a key can list and describe Signals and run queries on them. It cannot change anything.
- A key belongs to the organization, not to the person who created it. Revoke keys you no longer use.
- If access to Odyssey Signal is blocked for your organization, every request is refused with 403 `forbidden` and `reason` `organization_blocked`. See [Errors](https://docs.odysseysignal.com/api/errors).

## Replace or revoke a key

To revoke a key, select **Revoke** on its row in **Settings → API keys**. Requests with the key stop working within a minute. Revoking cannot be undone.

To replace a key without a break, for example on a schedule or when someone who knew it leaves:

1. Create a new key for the same Signals.
2. Put the new key into your integration and check that its requests work.
3. Revoke the old key. Its **Last used** time shows whether anything still uses it.

## See how a key is used

The list of keys in **Settings → API keys** shows for each key when it was **Last used** and its **Calls this month** (by calendar month in UTC). The numbers are updated about once a minute. Refused requests, such as a 429, count as use too. A request whose key was not recognized does not count for any key.

## When authentication fails

A request without a valid key gets 401 with the type `unauthorized`:

```json
{
  "type": "https://api.odysseysignal.app/problems/unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication failed.",
  "instance": "/v1/signals"
}
```

The answer is the same whatever the cause, so that it gives nothing away to someone guessing keys. Check these, in this order:

- The header is named `X-Api-Key` and holds the whole key, with no quotes, spaces or line breaks.
- The key has not been revoked. Look for it in **Settings → API keys**.
- You copied the key itself, not the shortened start shown in the list.

## Protection against guessed keys

When many requests with an invalid key come from the same network address within a minute, further requests from that address are refused for a short time with 429, `reason` `rate_limit` and the header `X-RateLimit-Scope: ip`. The block lifts by itself; `Retry-After` says when.

A key that has worked in the last minute keeps working from that address during the block, so one misconfigured client does not lock out the rest of your network. Do not retry a 401 in a loop: fix the key first.

If the key cannot be checked because of a fault on our side, the request gets 503 with the type `unavailable` and `Retry-After: 5`. Nothing was run, and you can retry after five seconds.

## Keep your keys safe

- Call the API from a server, a scheduled job or a tool you run yourself. Never put a key in a web page or an app that others download: anyone can read it there. The API does not accept requests from web pages on other sites.
- Keep keys in a secret manager or an environment variable, never in source code or in a file you commit.
- Create one key for each integration, with a label that names it. Then you can revoke one without stopping the others, and the usage numbers show which integration made the calls.
- Give a key only the Signals the integration needs.
- If a key may have leaked, revoke it at once and create a new one.

What you may do with the API and the data it returns is set out in [API and MCP Access](https://docs.odysseysignal.com/legal/user-terms#12-api-and-mcp-access) in the Platform and AI Services User Terms.

Too many requests in a short time are refused. See [Rate limiting](https://docs.odysseysignal.com/api/rate-limiting).
