Remplacer la politique d'âge
PUT /v1/age-policy · autorisation identity-settings:write
Écrit la politique d'âge complète. If-Match est requis (428 si absent, 412 si la valeur ne correspond pas) ; une politique jamais écrite a la version "0". Règles : min_age et les seuils par pays vont de 13 à 21 ; les codes pays sont ISO 3166-1 alpha-2 (majuscules), au maximum 250 entrées ; parental_consent_below vaut null ou 1..min_age ; store_birthdate ne peut valoir true que lorsque mode vaut birthdate. La politique s'applique uniquement aux inscriptions ultérieures ; les utilisateurs existants ne changent pas.
Requête
Corps JSON (les champs inconnus sont rejetés avec 400 unknown_field) :
| Champ | Type | Requis | Description |
|---|---|---|---|
If-Match |
en-tête | oui | En-tête : la valeur ETag provenant de GET /v1/age-policy. |
mode |
chaîne | oui | off, attestation (question neutre sur l'année et le mois de naissance, valeur non stockée) ou birthdate. |
min_age |
entier | oui | 13 à 21. |
country_min_age |
objet | oui | Code pays → seuil (13 à 21) ; les pays absents utilisent min_age. |
country_source |
chaîne | oui | ip ou declared. |
under_age_action |
chaîne | oui | block ou create_minor. |
parental_consent_below |
entier | null | non | null (pas de consentement parental) ou 1..min_age. |
pending_consent_action |
chaîne | oui | block_sign_in ou issue_limited. |
store_birthdate |
booléen | oui | true uniquement avec mode: birthdate. |
applies_to |
chaîne | oui | self_signup ou all. |
Réponse
200 OK avec la politique et l'en-tête ETag.
{
"mode": "attestation",
"min_age": 16,
"country_min_age": {"DE": 16, "FR": 15, "IT": 14},
"country_source": "ip",
"under_age_action": "block",
"parental_consent_below": null,
"pending_consent_action": "block_sign_in",
"store_birthdate": false,
"applies_to": "self_signup",
"updated_at": "2026-10-05T09:30:00.123456Z"
}
Jetons
Tant que mode n'est pas off, les jetons ID, les jetons d'accès et la réponse UserInfo transportent le age_group de l'utilisateur (adult, minor ou unknown) quels que soient les scopes demandés, et parental_consent_status (not_required, pending, granted, denied ou revoked) lorsqu'il a une valeur. Avec mode: off, aucun des deux claims n'est émis. Les deux sont écrits uniquement par KeenAuth (vos hooks et modèles de claims ne peuvent pas les définir) ; modifiez-les avec PATCH /v1/users/{user_id}.
Sous pending_consent_action: block_sign_in, un utilisateur dont parental_consent_status vaut pending, denied ou revoked ne reçoit aucun jeton : la requête d'autorisation se termine avec access_denied et le point de terminaison de jeton répond invalid_grant (Parental consent has not been granted.) pour les types d'octroi code d'autorisation, code d'appareil et jeton de rafraîchissement. Un jeton de rafraîchissement n'est pas révoqué ; il fonctionne à nouveau dès que le consentement vaut granted. Sous issue_limited, les jetons sont émis et votre application restreint l'utilisateur à partir des claims.
Erreurs
| HTTP | code | Quand |
|---|---|---|
| 400 | unknown_field |
Le corps contient un champ inconnu. |
| 412 | precondition_failed |
If-Match ne correspond pas à la version actuelle. |
| 415 | unsupported_media_type |
Le type de contenu n'est pas application/json. |
| 422 | validation_failed |
Un champ est absent (required) ou enfreint une règle ci-dessus ; le pointeur désigne le champ, par exemple /country_min_age/DE. |
| 428 | precondition_required |
L'en-tête If-Match est absent. |
| 401 | unauthenticated |
L'identifiant est absent, invalide ou révoqué. |
| 403 | insufficient_permissions |
L'identifiant ne dispose pas de l'autorisation requise. |
| 429 | rate_limited |
La limite de débit a été dépassée ; réessayez après la période Retry-After. |
| 503 | service_unavailable |
Une dépendance est temporairement indisponible ; réessayez après la période Retry-After. |
Exemple
curl -X PUT https://api.eu.keenauth.com/v1/age-policy \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-H 'If-Match: "0"' \
-d '{"mode":"attestation","min_age":16,"country_min_age":{"DE":16,"FR":15},"country_source":"ip","under_age_action":"block","parental_consent_below":null,"pending_consent_action":"block_sign_in","store_birthdate":false,"applies_to":"self_signup"}'