
# Creare un permesso

`POST /v1/permissions` · permesso `apis:write`

Aggiunge un permesso (scope OAuth) a un'API, facoltativamente con i testi mostrati nella schermata di consenso. Supporta `Idempotency-Key`.

## Richiesta

| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| `api_id` | stringa | sì | L'API (`api_…`). |
| `value` | stringa | sì | Valore dello scope, `resource:action` (`^[a-z0-9_.-]{1,64}:[a-z0-9_.*-]{1,64}$`). Unico all'interno dell'API e non modificabile. Il prefisso `idp_` è riservato. |
| `display_name` | stringa \| null | no | Nome breve mostrato nella schermata di consenso al posto del valore dello scope. Al massimo 128 caratteri. |
| `description` | stringa \| null | no | Riga di dettaglio mostrata sotto il nome nella schermata di consenso. Al massimo 1024 caratteri. |
| `consent_text_i18n` | oggetto \| null | no | Tag di lingua → testo della schermata di consenso, per esempio `{"en": "Read your orders"}`. Al massimo 30 lingue, ogni testo di 1–1024 caratteri, 16 KiB in totale. |
| `sensitivity` | stringa | no | `normal` (predefinito) o `sensitive`. |

### Testi della schermata di consenso

La schermata di consenso ospitata mostra ogni scope richiesto così: la voce di `consent_text_i18n` per la lingua della pagina (tag esatto, altrimenti il suo sottotag principale), altrimenti `display_name`, altrimenti il `value` dello scope; `description` viene mostrata come riga di dettaglio. Tutti e tre sono testo semplice. I caratteri di controllo (inclusi interruzioni di riga e tabulazioni), i separatori di riga e di paragrafo e i caratteri di incorporamento, sovrascrittura e isolamento bidirezionali (U+202A-U+202E, U+2066-U+2069) vengono rifiutati con `422`. Gli spazi iniziali e finali vengono eliminati, e un testo vuoto dopo l'eliminazione degli spazi viene salvato come `null`. L'HTML non viene interpretato: la schermata di consenso lo esegue l'escape.

## Risposta

`201 Created`

```json
{
  "id": "perm_01h455vb4pex5vsknk084sn02s",
  "api_id": "api_01h455vb4pex5vsknk084sn02q",
  "value": "read:orders",
  "display_name": "Read orders",
  "description": "See your past orders and their status",
  "consent_text_i18n": {
    "en": "Read your orders",
    "tr": "Siparişlerinizi okuyun"
  },
  "sensitivity": "normal"
}
```

## Errori

| HTTP | code | Quando |
|---|---|---|
| 400 | `unknown_field` | Il body contiene un campo sconosciuto. |
| 403 | `insufficient_permissions` | La credenziale non ha `apis:write`. |
| 403 | `quota_exceeded` | L'API ha già 1.000 permessi. |
| 404 | `not_found` | Non esiste tale API in questo ambiente. |
| 409 | `conflict` | Il valore esiste già su questa API, oppure l'API è l'API di sistema. |
| 422 | `validation_failed` | Un campo manca o non è valido, oppure un testo non è testo semplice (`errors[].pointer` indica il campo, per esempio `/consent_text_i18n`). |

## Esempio

```bash
curl -X POST https://api.eu.keenauth.com/v1/permissions \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1d2c1e-perm-create" \
  -d '{"api_id":"api_01h455vb4pex5vsknk084sn02q","value":"read:orders","display_name":"Read orders","consent_text_i18n":{"en":"Read your orders"}}'
```

Con la CLI, passa la mappa delle lingue con `--data`:

```bash
echo '{"consent_text_i18n":{"en":"Read your orders"}}' | keenauth permissions create \
  --api-id api_01h455vb4pex5vsknk084sn02q --value read:orders --display-name "Read orders" --data -
```
