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

# Autenticazione

> API key di organizzazione, scope e l'header Bearer richiesto da ogni richiesta alla Samsa API.

Ogni richiesta alla Samsa API è autenticata con una **API key di organizzazione**.
Le chiavi hanno degli scope, vengono mostrate una sola volta e agiscono per
l'organizzazione che le possiede — i credits vengono prelevati dal pool di
quell'organizzazione e gli asset generati appaiono nell'app sotto l'account dell'admin
che ha creato la chiave.

<Note>
  Stai connettendo Samsa a un client MCP (Claude, ChatGPT, Claude Code, Cursor…)? L'
  [MCP server](/it/mcp-server) usa queste stesse API key per i client headless e
  l'accesso OAuth 2.1 per quelli interattivi — gli scope qui sotto si applicano agli
  strumenti MCP in modo identico.
</Note>

## Come funzionano le chiavi

* **Di proprietà dell'organizzazione.** Una chiave appartiene a un'organizzazione, non
  a una persona. Chiunque possieda la chiave agisce per quell'organizzazione.
* **Create da un admin.** Solo un **admin** dell'organizzazione (`OWNER` o `ADMIN`)
  può creare o revocare chiavi, nella scheda **Settings → API Keys** dell'app.
* **Con scope.** Ogni chiave porta un insieme di [scope](#scope) che determinano quali
  endpoint può chiamare. Le chiavi vengono create con tutti gli scope per impostazione
  predefinita; restringili per corrispondere a ciò di cui l'integrazione ha bisogno.
* **Mostrate una sola volta.** Il segreto completo viene visualizzato esattamente una
  volta, alla creazione.

<Warning>
  Samsa memorizza solo un **hash SHA-256** di ogni chiave, mai il testo in chiaro.
  Ecco perché una chiave non può mai essere mostrata di nuovo o recuperata — non c'è
  nulla da cui recuperare. Se perdi una chiave, [revocala e creane una nuova](#ruotare-una-chiave).
</Warning>

## L'header `Authorization`

Invia la tua chiave come **Bearer token** in ogni richiesta:

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

Usa [`GET /me`](/it/quickstart) per confermare che una chiave funzioni — restituisce
l'organizzazione della chiave, i suoi metadati sicuri (prefisso, scope, scadenza) e il
saldo credits disponibile dell'organizzazione, ma mai il segreto.

## Scope

Gli scope seguono la forma `<resource>.<verb>`. Una richiesta a un endpoint il cui
scope manca alla chiave fallisce con [`403 missing_scope`](/it/guides/errors#missing_scope).

| Scope             | Endpoint sbloccati                                                                                                |
| ----------------- | ----------------------------------------------------------------------------------------------------------------- |
| `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` necessita di **qualsiasi** chiave valida — non richiede alcuno scope
  specifico. Le nuove funzionalità aggiungono nuove stringhe di scope; le chiavi
  esistenti non le ereditano mai automaticamente, quindi un admin modifica gli scope
  della chiave o emette una nuova chiave per concedere l'accesso.
</Note>

## Quando l'autenticazione fallisce

I fallimenti di autenticazione e autorizzazione restituiscono l'
[envelope di errore](/it/guides/errors) standard. Una chiave mancante, malformata,
sconosciuta, scaduta o revocata — oppure una chiave il cui creatore non è più membro
dell'organizzazione — restituisce **`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"
  }
}
```

Una chiave valida a cui manca lo scope dell'endpoint restituisce **`403
missing_scope`**, nominando lo scope richiesto:

```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>
  Le chiavi scadute e quelle sconosciute restituiscono entrambe `401 invalid_api_key`
  — deliberatamente indistinguibili, così un estraneo non può sondare quali chiavi
  siano esistite.
</Note>

## Best practice di sicurezza

<AccordionGroup>
  <Accordion title="Conserva le chiavi in variabili d'ambiente" icon="lock">
    Tieni le chiavi fuori dal controllo di versione. Caricale da una variabile
    d'ambiente o da un secrets manager — non scriverle mai hard-coded.

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

  <Accordion title="Non esporre mai le chiavi lato client" icon="browser">
    La Samsa API è **server-side first** — il CORS è deliberatamente restrittivo e le
    chiamate dal browser da origini arbitrarie non sono supportate. Una chiave nel
    codice front-end o in un'app mobile è una chiave trapelata. Chiama sempre l'API dal
    tuo backend.
  </Accordion>

  <Accordion title="Ruota tramite revoca + creazione" icon="rotate">
    Non esiste una rotazione in-place. Per ruotare, [crea una nuova chiave](#ruotare-una-chiave),
    distribuiscila, poi revoca quella vecchia. La revoca è definitiva e ha effetto alla
    richiesta immediatamente successiva.
  </Accordion>

  <Accordion title="Imposta una scadenza per le integrazioni di breve durata" icon="clock">
    Le chiavi possono essere create con una **scadenza** facoltativa. Una chiave
    scaduta fallisce esattamente come una sconosciuta (`401 invalid_api_key`). Usa la
    scadenza per integrazioni temporanee, trial e collaboratori esterni.
  </Accordion>
</AccordionGroup>

### Ruotare una chiave

1. Crea una nuova chiave in **Settings → API Keys** e copiala.
2. Distribuisci la nuova chiave alla tua integrazione.
3. Revoca la vecchia chiave. La revoca è immediata e non può essere annullata.

## Formato della chiave

Una chiave ha questo aspetto:

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

Il corpo di `samsa_sk_` è composto da 43 caratteri base62 che codificano 256 bit di
casualità. Nell'app, le chiavi vengono visualizzate come `samsa_sk_gK3n…3rAb` (un
`prefix` stabile più gli ultimi quattro caratteri) così puoi identificare una chiave
senza esporla.

<Tip>
  Il prefisso costante `samsa_sk_` permette agli scanner di segreti (GitHub secret
  scanning, hook pre-commit, controlli CI) di rilevare una chiave Samsa committata per
  errore. Abilita il secret scanning sui tuoi repository così una chiave trapelata
  viene intercettata prima che venga distribuita.
</Tip>
