> ## 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.

# Authentification

> API keys d'organisation, scopes et le header Bearer dont chaque requête à l'API Samsa a besoin.

Chaque requête à l'API Samsa est authentifiée avec une **API key
d'organisation**. Les clés sont scopées, affichées une seule fois, et agissent
pour l'organisation qui les possède — les credits sont prélevés sur le pool de
cette organisation et les assets générés apparaissent dans l'app sous le compte de
l'admin qui a créé la clé.

<Note>
  Tu connectes Samsa à un client MCP (Claude, ChatGPT, Claude Code, Cursor…) ? Le
  [MCP server](/fr/mcp-server) utilise ces mêmes API keys pour les clients headless
  et la connexion OAuth 2.1 pour les clients interactifs — les scopes ci-dessous
  s'appliquent identiquement aux outils MCP.
</Note>

## Comment fonctionnent les clés

* **Propriété de l'organisation.** Une clé appartient à une organisation, pas à une
  personne. Quiconque détient la clé agit pour cette organisation.
* **Créée par un admin.** Seul un **admin** de l'organisation (`OWNER` ou `ADMIN`)
  peut créer ou révoquer des clés, dans l'onglet **Settings → API Keys** de l'app.
* **Scopée.** Chaque clé porte un ensemble de [scopes](#scopes) qui déterminent
  quels endpoints elle peut appeler. Les clés sont créées avec tous les scopes par
  défaut ; restreins-les pour correspondre à ce dont l'intégration a besoin.
* **Affichée une seule fois.** Le secret complet est affiché exactement une fois, à
  la création.

<Warning>
  Samsa ne stocke qu'un **hash SHA-256** de chaque clé, jamais le texte en clair.
  C'est pourquoi une clé ne peut jamais être réaffichée ou récupérée — il n'y a
  rien à récupérer. Si tu perds une clé,
  [révoque-la et crées-en une nouvelle](#faire-tourner-une-clé).
</Warning>

## Le header `Authorization`

Envoie ta clé comme **Bearer token** sur chaque requête :

```
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>

Utilise [`GET /me`](/fr/quickstart) pour confirmer qu'une clé fonctionne — il
renvoie l'organisation de la clé, ses métadonnées sûres (préfixe, scopes,
expiration) et le solde de credits disponible de l'organisation, mais jamais le
secret.

## Scopes

Les scopes suivent une forme `<resource>.<verb>`. Une requête vers un endpoint dont
la clé n'a pas le scope échoue avec [`403 missing_scope`](/fr/guides/errors#missing_scope).

| Scope             | Endpoints débloqués                                                                                               |
| ----------------- | ----------------------------------------------------------------------------------------------------------------- |
| `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` a besoin de **n'importe quelle** clé valide — il ne requiert aucun
  scope spécifique. Les nouvelles capacités ajoutent de nouvelles chaînes de
  scope ; les clés existantes ne les héritent jamais automatiquement, donc un admin
  modifie les scopes de la clé ou émet une nouvelle clé pour accorder l'accès.
</Note>

## Quand l'authentification échoue

Les échecs d'authentification et d'autorisation renvoient l'\[enveloppe d'erreur]
(/fr/guides/errors) standard. Une clé manquante, malformée, inconnue, expirée ou
révoquée — ou une clé dont le créateur n'est plus membre de l'organisation —
renvoie **`401 invalid_api_key`** :

```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"
  }
}
```

Une clé valide qui n'a pas le scope du endpoint renvoie **`403 missing_scope`**, en
nommant le scope requis :

```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>
  Les clés expirées et les clés inconnues renvoient toutes deux `401
      invalid_api_key` — délibérément indistinguables, pour qu'un tiers ne puisse pas
  sonder quelles clés ont existé.
</Note>

## Bonnes pratiques de sécurité

<AccordionGroup>
  <Accordion title="Stocke les clés dans des variables d'environnement" icon="lock">
    Garde les clés hors de ton gestionnaire de versions. Charge-les depuis une
    variable d'environnement ou un gestionnaire de secrets — ne les code jamais en
    dur.

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

  <Accordion title="N'expose jamais les clés côté client" icon="browser">
    L'API Samsa est **conçue pour le serveur d'abord** — le CORS est délibérément
    restrictif et les appels navigateur depuis des origines arbitraires ne sont pas
    pris en charge. Une clé dans du code front-end ou dans une app mobile est une
    clé divulguée. Appelle toujours l'API depuis ton backend.
  </Accordion>

  <Accordion title="Fais tourner par révocation + création" icon="rotate">
    Il n'y a pas de rotation sur place. Pour faire tourner une clé,
    [crées-en une nouvelle](#faire-tourner-une-clé), déploie-la, puis révoque
    l'ancienne. La révocation est définitive et prend effet dès la requête suivante.
  </Accordion>

  <Accordion title="Définis une expiration pour les intégrations éphémères" icon="clock">
    Les clés peuvent être créées avec une **expiration** optionnelle. Une clé
    expirée échoue exactement comme une clé inconnue (`401 invalid_api_key`).
    Utilise l'expiration pour les intégrations temporaires, les essais et les
    prestataires.
  </Accordion>
</AccordionGroup>

### Faire tourner une clé

1. Crée une nouvelle clé dans **Settings → API Keys** et copie-la.
2. Déploie la nouvelle clé dans ton intégration.
3. Révoque l'ancienne clé. La révocation est immédiate et ne peut pas être annulée.

## Format de clé

Une clé ressemble à :

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

Le corps `samsa_sk_` fait 43 caractères base62 encodant 256 bits d'aléa. Dans
l'app, les clés sont affichées sous la forme `samsa_sk_gK3n…3rAb` (un `prefix`
stable plus les quatre derniers caractères) afin que tu puisses identifier une clé
sans l'exposer.

<Tip>
  Le préfixe constant `samsa_sk_` permet aux scanners de secrets (GitHub secret
  scanning, hooks pre-commit, vérifications CI) de détecter une clé Samsa commitée
  par accident. Active le secret scanning sur tes dépôts pour qu'une clé divulguée
  soit repérée avant d'être expédiée.
</Tip>
