# When the first call fails

The symptoms are listed in the order in which they most often occur on the first call. Read the status first, then the field `code` in the error body, and keep the `traceId` in case you have to ask for help.

> **Type:** troubleshooting
> **For:** Developers whose first call does not answer with `200`
> **Prerequisite:** the complete error response (status, headers, body), for example from `curl -sSi`

## Symptoms by frequency

### 401 with `Auth.Required`

**Meaning:** The `Authorization` header is missing, the word `Bearer` before it is missing, or the value has no known prefix (a typo in the prefix). The platform never treats an unusable credential as anonymous. Even a value with an unknown prefix lands here and not on a 404.

**Solution:** Check that the header reads exactly `Authorization: Bearer ak_…` and that the environment variable is set (`echo "$SZENERA_API_KEY" | cut -c1-3` must show `ak_`). Command line: exit code 3. See [Your first call with curl](/getting-started/first-call).

### 401 with `Auth.TokenMalformed`

**Meaning:** The prefix `ak_` is right, but the rest does not match the pattern of a key: exactly 26 characters made of digits and capital letters, without I, L, O, and U. A typical cause is a key truncated while copying, or a value with unexpected characters such as spaces, quotation marks, or lowercase letters.

**Solution:** Copy the full value from your secret store and check the length (`echo -n "$SZENERA_API_KEY" | wc -c` must print `29`). Command line: exit code 3. See [Your first call with curl](/getting-started/first-call).

### 401 with `Auth.ApiKeyUnknown`, `Auth.ApiKeyRevoked`, or `Auth.ApiKeyExpired`

**Meaning:** Prefix and pattern are right, but the key does not exist (a typo in the value that still fits the 26-character pattern), was revoked, or has passed its date under **Valid until**.

**Solution:** Create a new key and replace the value in your secret store. A revoked key does not come back. See [Create an API key](/getting-started/create-api-key).

### 401 with `Auth.TokenExpired`

**Meaning:** You are sending a session token (`eyJ…`) from the sign-in, and it expired after 15 minutes.

**Solution:** For machines, use a key `ak_…`. If you need the sign-in flows, the refresh is described under [Authentication](/api/authentication).

### 403 with `Permission.Denied`

**Meaning:** The credential is valid but does not carry the permission of the operation. Each operation names its permission in the reference (such as `identity.device.list`), and a key has only the permissions chosen when it was created. Some permissions keys never carry, such as `identity.device.list` (devices), `fleet.playback-history.read` (the daily playback history of a display), and `identity.api-key.create`. You reach these routes only with a session token.

**Solution:** In the portal under **Settings › Organization › API keys**, check the columns **Name / permissions** and **Class** of the key. If the permission is missing, create a key with a suitable class or add it with **Adjust individual permissions**. Command line: exit code 4. See [Create an API key](/getting-started/create-api-key).

### 403 with `Permission.OperatorOnly`

**Meaning:** The route under `/v1/platform/…` is open only to platform operations. No key of an organization ever gets in there. A new credential does not help here, but a different route does.

**Solution:** Use the route of your organization (such as `GET /v1/playlists` instead of a route under `/v1/platform`). See [The areas of the reference](/api/reference-areas).

### 402 with `Billing.AddonRequired`

**Meaning:** When creating or rotating a key: the organization’s package does not include API access. Existing keys keep working, and only new ones require the enablement.

**Solution:** Choose a package from Premium (“API and webhooks”) or agree on the enablement of API access by contract. See [Create an API key](/getting-started/create-api-key).

### 404 with `Resource.NotFound`

**Meaning:** The path matches no route. On the first call it is almost always one of three things: `/v1` is missing (`/me` instead of `/v1/me`), there is a typo in the path, or the base URL points to the portal instead of the API.

**Solution:** Check address and path. Every route begins with `/v1`. Command line: exit code 5. See [Base URL, /v1, and stability](/api/base-url-and-stability).

### 404 with `<Resource>.NotFound` (such as `Scene.NotFound`, `Device.NotFound`)

**Meaning:** The route is right, but the ID does not belong to your organization or no longer exists. An ID from another organization cannot be told apart from a made-up one: both give the same 404.

**Solution:** Take the ID from a list of your organization (`GET /v1/scenes`, `GET /v1/playlists`, …) and match the prefix to the resource (`scn_` for scenes, `pll_` for playlists). See [What a response contains](/getting-started/response-contents#identifiers).

### 422 with `Validation.Failed`

**Meaning:** A parameter or a field in the body violates the contract, such as `limit=500` where at most 200 applies, a missing required field, or a wrong type.

**Solution:** Read `details.issues`: each entry names the field path and the violation. Command line: exit code 7. The command line checks a body you wrote yourself before sending and reports the field path with exit code 1. See [The error format](/api/error-format).

### 429 with `RateLimit.Exceeded`

**Meaning:** Too many requests in one window. The routes most prone to abuse are throttled above all: sign-in, registration, and password reset. A few other routes say so in the reference. Your first call with a key does not hit them, but anyone who repeats the sign-in in a loop does.

**Solution:** The header `Retry-After` gives the seconds until the next permitted attempt, and `X-RateLimit-Reset` the start of the next window. Wait, then retry, and for machines use a key instead of the sign-in. Command line: exit code 8. See [Throttling and rate-limit headers](/api/rate-limits).

### No HTTP response: connection refused, timeout, TLS error

**Meaning:** The call did not reach the platform. The base URL is wrong, the port is missing or wrong, the certificate does not match the name, or a proxy blocks it.

**Solution:** First check the address without a credential. `szenera health` queries the public readiness route of your environment and does not fail on the sign-in, so a wrong port does not look like a wrong key. Command line: exit code 10. Then step 1 under [Your first call with curl](/getting-started/first-call).

## Keep the trace ID

Every error response carries `traceId` in the body and `X-Trace-Id` in the header, the same value `trc_…`. It is the trace of exactly this call on the platform. When you ask for help, name it. Without it, a single call cannot be found again.

## Related

- [Create an API key](/getting-started/create-api-key)
- [Your first call with curl](/getting-started/first-call)
- [Error codes: general](/api/error-codes-general)
