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

# Authentifizierung

> Organisations-API keys, Scopes und der Bearer-Header, den jede Anfrage an die Samsa API braucht.

Jede Anfrage an die Samsa API wird mit einem **Organisations-API key**
authentifiziert. Keys sind gescopt, werden nur einmal angezeigt und handeln für
die Organisation, die sie besitzt — Credits werden aus dem Pool dieser
Organisation gezogen und generierte Assets erscheinen in der App unter dem Konto
des Admins, der den Key erstellt hat.

<Note>
  Verbindest du Samsa mit einem MCP client (Claude, ChatGPT, Claude Code,
  Cursor…)? Der [MCP server](/de/mcp-server) verwendet für headless Clients
  dieselben API keys und für interaktive Clients OAuth-2.1-Login — die Scopes
  unten gelten für MCP-Tools identisch.
</Note>

## Wie Keys funktionieren

* **Organisationsgebunden.** Ein Key gehört einer Organisation, nicht einer
  Person. Jeder, der den Key besitzt, handelt für diese Organisation.
* **Admin-erstellt.** Nur ein Organisations-**Admin** (`OWNER` oder `ADMIN`) kann
  Keys erstellen oder widerrufen, im Tab **Settings → API Keys** der App.
* **Gescopt.** Jeder Key trägt eine Reihe von [Scopes](#scopes), die bestimmen,
  welche Endpoints er aufrufen kann. Keys werden standardmäßig mit allen Scopes
  erstellt; schränke sie so ein, dass sie zu dem passen, was die Integration
  braucht.
* **Nur einmal angezeigt.** Das vollständige Secret wird genau einmal angezeigt,
  bei der Erstellung.

<Warning>
  Samsa speichert nur einen **SHA-256-Hash** jedes Keys, nie den Klartext. Deshalb
  kann ein Key nie wieder angezeigt oder wiederhergestellt werden — es gibt nichts
  wiederherzustellen. Wenn du einen Key verlierst,
  [widerrufe ihn und erstelle einen neuen](#einen-key-rotieren).
</Warning>

## Der `Authorization`-Header

Sende deinen Key als **Bearer-Token** bei jeder Anfrage:

```
Authorization: Bearer samsa_sk_your_key_here
```

<CodeGroup>
  ```bash curl theme={null}
  curl https://api.samsa.ai/public/v1/me \
    -H "Authorization: Bearer $SAMSA_API_KEY"
  ```

  ```python Python theme={null}
  import os
  import requests

  BASE_URL = "https://api.samsa.ai/public/v1"
  headers = {"Authorization": f"Bearer {os.environ['SAMSA_API_KEY']}"}

  resp = requests.get(f"{BASE_URL}/me", headers=headers)
  resp.raise_for_status()
  print(resp.json())
  ```

  ```typescript TypeScript theme={null}
  const BASE_URL = "https://api.samsa.ai/public/v1";
  const headers = { Authorization: `Bearer ${process.env.SAMSA_API_KEY}` };

  const resp = await fetch(`${BASE_URL}/me`, { headers });
  if (!resp.ok) throw new Error(`GET /me failed: ${resp.status}`);
  console.log(await resp.json());
  ```
</CodeGroup>

Verwende [`GET /me`](/de/quickstart), um zu bestätigen, dass ein Key funktioniert —
der Endpoint gibt die Organisation des Keys, seine sicheren Metadaten (prefix,
scopes, Ablaufdatum) und das verfügbare Credit-Guthaben der Organisation zurück,
aber nie das Secret.

## Scopes

Scopes folgen der Form `<resource>.<verb>`. Eine Anfrage an einen Endpoint, dessen
Scope dem Key fehlt, schlägt mit
[`403 missing_scope`](/de/guides/errors#missing_scope) fehl.

| Scope             | Freigeschaltete Endpoints                                                                                         |
| ----------------- | ----------------------------------------------------------------------------------------------------------------- |
| `images.generate` | `POST /images/generations`, `GET /images/generations/{id}`                                                        |
| `images.edit`     | `POST /images/edits`, `GET /images/edits/{id}`                                                                    |
| `videos.generate` | `POST /videos/generations`, `GET /videos/generations/{id}`, `GET /videos/models`                                  |
| `models.read`     | `GET /models`, `GET /models/{id}`, `GET /models/{id}/status`                                                      |
| `models.write`    | `POST /models`, `POST /models/prepare`, `POST /models/{id}/complete`, `PATCH /models/{id}`, `DELETE /models/{id}` |
| `usage.read`      | `GET /credits`, `GET /usage`                                                                                      |

<Note>
  `GET /me` braucht **irgendeinen** gültigen Key — es erfordert keinen bestimmten
  Scope. Neue Funktionen fügen neue Scope-Strings hinzu; bestehende Keys erben sie
  nie automatisch, daher bearbeitet ein Admin die Scopes des Keys oder erstellt
  einen neuen Key, um Zugriff zu gewähren.
</Note>

## Wenn die Authentifizierung fehlschlägt

Authentifizierungs- und Autorisierungsfehler geben das standardmäßige
[Error-Envelope](/de/guides/errors) zurück. Ein fehlender, fehlerhafter,
unbekannter, abgelaufener oder widerrufener Key — oder ein Key, dessen Ersteller
kein Mitglied der Organisation mehr ist — gibt **`401 invalid_api_key`** zurück:

```json 401 Unauthorized theme={null}
{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "The provided API key is invalid, expired, or revoked.",
    "request_id": "req_8f14e45fceea167a"
  }
}
```

Ein gültiger Key, dem der Scope des Endpoints fehlt, gibt
**`403 missing_scope`** zurück und nennt den erforderlichen Scope:

```json 403 Forbidden theme={null}
{
  "error": {
    "type": "permission_error",
    "code": "missing_scope",
    "message": "The API key is missing the required scope: images.generate.",
    "request_id": "req_1c9a3b7d2e5f4a80",
    "param": "scope"
  }
}
```

<Note>
  Abgelaufene und unbekannte Keys geben beide `401 invalid_api_key` zurück —
  absichtlich nicht unterscheidbar, damit ein Außenstehender nicht ermitteln kann,
  welche Keys einmal existierten.
</Note>

## Security Best Practices

<AccordionGroup>
  <Accordion title="Speichere Keys in Umgebungsvariablen" icon="lock">
    Halte Keys aus der Versionsverwaltung heraus. Lade sie aus einer
    Umgebungsvariablen oder einem Secrets-Manager — hardcode sie nie.

    ```bash theme={null}
    export SAMSA_API_KEY="samsa_sk_..."
    ```
  </Accordion>

  <Accordion title="Gib Keys nie clientseitig preis" icon="browser">
    Die Samsa API ist **server-side first** — CORS ist bewusst restriktiv und
    Browser-Aufrufe von beliebigen Origins werden nicht unterstützt. Ein Key in
    Frontend-Code oder einer Mobile-App ist ein geleakter Key. Rufe die API immer
    von deinem Backend aus auf.
  </Accordion>

  <Accordion title="Rotiere per widerrufen + erstellen" icon="rotate">
    Es gibt keine In-Place-Rotation. Zum Rotieren
    [erstelle einen neuen Key](#einen-key-rotieren), deploye ihn und widerrufe dann
    den alten. Der Widerruf ist terminal und wird bei der allernächsten Anfrage
    wirksam.
  </Accordion>

  <Accordion title="Setze ein Ablaufdatum für kurzlebige Integrationen" icon="clock">
    Keys können mit einem optionalen **Ablaufdatum** erstellt werden. Ein
    abgelaufener Key schlägt genau wie ein unbekannter fehl (`401
            invalid_api_key`). Verwende das Ablaufdatum für temporäre Integrationen, Trials
    und externe Dienstleister.
  </Accordion>
</AccordionGroup>

### Einen Key rotieren

1. Erstelle einen neuen Key in **Settings → API Keys** und kopiere ihn.
2. Deploye den neuen Key in deine Integration.
3. Widerrufe den alten Key. Der Widerruf ist sofortig und kann nicht rückgängig
   gemacht werden.

## Key-Format

Ein Key sieht so aus:

```
samsa_sk_gK3n8vQ1xY7bT2mW9cR4jL6hF0dS5pZaU8eN1oI3rAb
└───┬───┘└──────────────────┬─────────────────────┘
 prefix           43 random base62 characters
```

Der `samsa_sk_`-Body besteht aus 43 base62-Zeichen, die 256 Bit Zufälligkeit
kodieren. In der App werden Keys als `samsa_sk_gK3n…3rAb` angezeigt (ein stabiler
`prefix` plus die letzten vier Zeichen), sodass du einen Key identifizieren
kannst, ohne ihn preiszugeben.

<Tip>
  Der konstante `samsa_sk_`-Prefix erlaubt es Secret-Scannern (GitHub Secret
  Scanning, Pre-Commit-Hooks, CI-Checks), einen versehentlich committeten
  Samsa-Key zu erkennen. Aktiviere Secret Scanning für deine Repositories, damit
  ein geleakter Key erwischt wird, bevor er ausgeliefert wird.
</Tip>
