# Your first call with curl

After this guide, you have called two routes with your key, your own account and your playlists, and seen the headers of a response. Five minutes, no installation except curl.

> **Type:** guide
> **For:** Developers with a freshly created API key
> **Prerequisite:** a key `ak_…` with the permission `playlist.list` (the class **Read only** is enough) and the base URL of your environment, the origin your portal also talks to
> **Where:** command line

## Steps

1. Store the address and key in environment variables. The key belongs in a header, never in the address. Addresses end up in logs, headers do not.

   ```bash
   export SZENERA_API="https://<basis-adresse-ihrer-umgebung>"
   export SZENERA_API_KEY="ak_…"
   ```

2. Fetch your own account. `GET /v1/me` reads the user profile the key belongs to, and the response is shortened here to the fields that matter:

   ```bash
   curl -sS "$SZENERA_API/v1/me" \
     -H "Authorization: Bearer $SZENERA_API_KEY"
   ```

   ```json
   {
     "id": "usr_01KERQ74K0TEAM000000000001",
     "email": "owner@demo.local",
     "tenantId": "tnt_01KERPXZM0DEM0000000000001",
     "status": "active",
     "profile": { "displayName": "Julia Petersen", "locale": "de-DE", "timezone": "Europe/Berlin" },
     "roleAssignments": [
       { "roleId": "rol_01KERPYWXGRECHT00000000001", "assignedAt": "2026-01-12T09:05:00.000Z", "assignedById": "usr_01KERQ74K0TEAM000000000001", "expiresAt": null }
     ]
   }
   ```

   `tenantId` is the ID of your organization. If a different one appears than the one you expected, the key points somewhere other than you intended.

3. Fetch the list of your playlists. `GET /v1/playlists` needs the permission `playlist.list`, which the classes **Read only**, **Playout control**, and **Full access** include. A key of the class **Media automation** or **Content authoring** gets a `403` here. This response is also shortened to the most important fields:

   ```bash
   curl -sS "$SZENERA_API/v1/playlists?limit=5" \
     -H "Authorization: Bearer $SZENERA_API_KEY"
   ```

   ```json
   {
     "items": [
       {
         "id": "pll_01KWV91ZS0PRGRAMM000000001",
         "name": "Tagesprogramm",
         "version": 6,
         "createdAt": "2026-07-06T08:35:00.000Z",
         "updatedAt": "2026-07-13T07:52:00.000Z",
         "items": [
           { "id": "pli_01KWV92A70PKT0000000000001", "kind": "scene", "sceneId": "scn_01KJPX8NH0SZENE00000000001", "sceneVersionId": null, "durationMs": 10000, "transition": null, "order": 0 }
         ]
       }
     ],
     "nextCursor": "cGxsOjIwMjYtMDMtMTE",
     "total": 2
   }
   ```

   This list accepts `limit` between 1 and 200 (default 50) and pages through results with `cursor`. `nextCursor` is absent on the last page. You reach the displays (`GET /v1/players`) the same way with a key, because `fleet.player.list` is key-capable. You cannot reach the devices behind them (`GET /v1/devices`) that way, because `identity.device.list` is meant for user accounts only. A display is the surface that shows something. A device is the machine with certificate and pairing, and access to it stays reserved for people.

4. Look at the headers. With `-i`, curl shows the status and the headers before the body:

   ```bash
   curl -sSi "$SZENERA_API/v1/me" \
     -H "Authorization: Bearer $SZENERA_API_KEY" | head -n 12
   ```

   Two lines matter: `Content-Type: application/json` and `X-Trace-Id: trc_…`. The trace ID is the trace of this one call. Write it down when something is wrong.

## The same call with the command line

The `szenera` command line takes address and key from environment variables and talks to the same routes. If standard output is not a terminal, it prints JSON. It reads the key from the same `SZENERA_API_KEY` as in step 1, and the address from `SZENERA_BASE_URL`:

```bash
SZENERA_BASE_URL="$SZENERA_API" szenera whoami
SZENERA_BASE_URL="$SZENERA_API" szenera playlist list --limit=5
```

How to get the command line is described under [Get the CLI](/cli/get-cli).

## Check the result

- Both calls answer with `200` and a JSON body. Errors would come as a body with `code`, `message`, and `traceId`.
- The list of playlists carries `items` and, as long as more pages follow, `nextCursor`.
- In the portal, the key now appears under **Settings › Organization › API keys** with a timestamp in **Last used**.

## If something goes wrong

| Symptom | Meaning | Solution |
|---|---|---|
| `401` with `Auth.Required` | The header is missing, `Bearer` is missing, or the value has no known prefix (a typo in the prefix). | Check the header and the variable. See [When the first call fails](/getting-started/troubleshooting). |
| `401` with `Auth.TokenMalformed` | The prefix `ak_` is right, but the key is truncated or contains invalid characters. | Copy the full value from the secret store: `ak_` plus 26 characters. |
| `401` with `Auth.ApiKeyUnknown`, `Auth.ApiKeyRevoked`, or `Auth.ApiKeyExpired` | The key does not exist, was revoked, or has expired. | Create a new key. |
| `403` with `Permission.Denied` | The key does not carry the permission of the operation, or the route requires a permission that keys never carry (devices, pairing and deleting displays, key management). | Adjust the class or permissions when creating the key. For these routes, use a session token. |
| `404` with `Resource.NotFound` | The path matches no route, usually because `/v1` is missing or the base URL is wrong. | Check address and path. |
| `422` with `Validation.Failed` | A parameter is invalid, such as `limit=500`. | Read `details.issues` and correct the value. |

## Related

- [What a response contains](/getting-started/response-contents)
- [When the first call fails](/getting-started/troubleshooting)
- [Paging](/api/pagination)
