
# Créer une autorisation

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

Ajoute une autorisation (scope OAuth) à une API, éventuellement avec les textes affichés sur l'écran de consentement. Prend en charge `Idempotency-Key`.

## Demande

| Champ | Type | Obligatoire | Description |
|---|---|---|---|
| `api_id` | chaîne | oui | L'API (`api_…`). |
| `value` | chaîne | oui | Valeur du scope, `resource:action` (`^[a-z0-9_.-]{1,64}:[a-z0-9_.*-]{1,64}$`). Unique au sein de l'API et non modifiable. Le préfixe `idp_` est réservé. |
| `display_name` | chaîne \| null | non | Nom court affiché sur l'écran de consentement à la place de la valeur du scope. 128 caractères au maximum. |
| `description` | chaîne \| null | non | Ligne de détail affichée sous le nom sur l'écran de consentement. 1024 caractères au maximum. |
| `consent_text_i18n` | objet \| null | non | Balise de langue → texte de l'écran de consentement, par exemple `{"en": "Read your orders"}`. 30 langues au maximum, chaque texte de 1 à 1024 caractères, 16 Kio au total. |
| `sensitivity` | chaîne | non | `normal` (par défaut) ou `sensitive`. |

### Textes de l'écran de consentement

L'écran de consentement hébergé affiche chaque scope demandé comme suit : l'entrée `consent_text_i18n` pour la langue de la page (balise exacte, sinon sa sous-balise principale), sinon `display_name`, sinon la `value` du scope ; `description` est affichée comme ligne de détail. Les trois sont du texte brut. Les caractères de contrôle (y compris les sauts de ligne et les tabulations), les séparateurs de ligne et de paragraphe, et les caractères de sens bidirectionnel d'imbrication, de substitution et d'isolation (U+202A-U+202E, U+2066-U+2069) sont rejetés avec `422`. Les espaces en début et en fin sont supprimés, et un texte vide après suppression est enregistré comme `null`. Le HTML n'est pas interprété : l'écran de consentement l'échappe.

## Réponse

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

## Erreurs

| HTTP | code | Quand |
|---|---|---|
| 400 | `unknown_field` | Le corps contient un champ inconnu. |
| 403 | `insufficient_permissions` | L'identifiant ne dispose pas de `apis:write`. |
| 403 | `quota_exceeded` | L'API possède déjà 1 000 autorisations. |
| 404 | `not_found` | Cette API n'existe pas dans cet environnement. |
| 409 | `conflict` | La valeur existe déjà sur cette API, ou l'API est l'API système. |
| 422 | `validation_failed` | Un champ est absent ou invalide, ou un texte n'est pas du texte brut (`errors[].pointer` indique le champ, par exemple `/consent_text_i18n`). |

## Exemple

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

Avec la CLI, transmettez la table des langues avec `--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 -
```
