Définir le CSS personnalisé
PUT /v1/branding/css · permission branding:write
Écrit le CSS personnalisé du brouillon de l'environnement (plan Startup ou supérieur, fonctionnalité branding_custom_css). Le CSS passe par un assainisseur à liste blanche : seules les classes ui_catalog (idp-*) et les propriétés et valeurs autorisées sont acceptées ; la couche protégée (texte légal, consentement et éléments d'accessibilité) ne peut être ni masquée ni recouverte. Tout ou rien : à la moindre violation, rien n'est écrit. Le brouillon enregistre la sortie canonique de l'assainisseur, et non le texte envoyé ; css dans la réponse est cette sortie. Une chaîne vide l'efface et n'est pas soumise au plan.
Requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
If-Match |
en-tête | oui | L'ETag du brouillon lu en dernier ("0" s'il n'a jamais été écrit). Absent : 428 ; périmé : 412. |
css |
chaîne | oui | 51200 octets au plus, UTF-8 valide ; "" efface. |
Réponse
200 OK avec le brouillon de l'environnement et son ETag. theme ne contient que les jetons définis ; les autres héritent de la valeur par défaut de la plateforme.
{
"theme": {"mode": "light", "light": {"color": {"primary": "#0a3d91"}}, "logo_height": 40},
"css": ".idp-c .idp-title{color:#0a3d91}\n",
"page_template": null,
"updated_at": "2026-10-05T09:30:00.123456Z"
}
Erreurs
| HTTP | code | Quand |
|---|---|---|
| 400 | unknown_field |
Le corps contient un champ inconnu ou n'est pas un objet JSON. |
| 403 | plan_feature_unavailable |
Le plan n'inclut pas la fonctionnalité (plan_feature_unavailable, extensions feature et required_plan). Les environnements de développement ne sont pas restreints. |
| 412 | precondition_failed |
If-Match ne correspond pas à la version actuelle du brouillon. |
| 422 | validation_failed |
css est absent ou null (required), trop long (too_long) ou n'est pas de l'UTF-8 valide (invalid_utf8). |
| 422 | branding_validation_failed |
Le CSS n'a pas passé l'assainisseur. L'extension violations liste toutes les violations : line, column (à partir de 1), rule (par exemple class_not_in_catalog, protected_property, property_not_allowed, syntax_error) et, le cas échéant, name (nom de la propriété, de la classe ou de la fonction). Les valeurs CSS ne sont jamais renvoyées. Après 100 violations, l'assainisseur s'arrête ; le dernier élément a la règle too_many_issues. Le résultat canonique est plus long que l'entrée (chaque règle reçoit un préfixe de portée) ; s'il dépasse 51200 octets, la seule violation est la règle too_large à la ligne 1, colonne 1. |
| 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 n'a pas la permission requise. |
| 429 | rate_limited |
La limite de débit est dépassée ; réessayez après le délai Retry-After. |
| 503 | service_unavailable |
Une dépendance est temporairement indisponible ; réessayez après le délai Retry-After. |
Exemple de rejet par l'assainisseur :
.idp-button{position:fixed}
.my-banner{color:red}
{
"type": "https://docs.keenauth.com/errors/branding_validation_failed",
"title": "Branding validation failed",
"status": 422,
"code": "branding_validation_failed",
"violations": [
{"line": 1, "column": 13, "rule": "property_not_allowed", "name": "position"},
{"line": 2, "column": 1, "rule": "class_not_in_catalog", "name": "my-banner"}
],
"request_id": "req_01J9Z3N5W8Q2F6V4K7T1M0XB3C"
}
Exemple
curl -X PUT https://api.eu.keenauth.com/v1/branding/css \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-H 'If-Match: "3"' \
-d '{"css":".idp-title { color: #0a3d91 }"}'