Skip to content

Gouvernance ​

Les routes sont relatives à <PUBLIC_BASE_URL> ; les corps de requête et de réponse sont en JSON sauf mention contraire. L’authentification, les portées, la pagination et le format des erreurs sont décrits dans les guides de l’API REST.

GET /api/v1/admin/scope ​

Lire le périmètre de l’organisation

Accès — Session de membre ou clé d’API portant admin:read (rôle administrateur requis).

Réponses

200 — Le périmètre de l’organisation.

ChampTypeRequis
scopeobjectoui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "scope": {
      "type": "object",
      "properties": {
        "excludedDomains": {
          "maxItems": 500,
          "type": "array",
          "items": { "type": "string", "minLength": 1, "maxLength": 320 }
        },
        "excludedEmails": {
          "maxItems": 500,
          "type": "array",
          "items": { "type": "string", "minLength": 1, "maxLength": 320 }
        }
      },
      "required": [ "excludedDomains", "excludedEmails" ],
      "additionalProperties": false
    }
  },
  "required": [ "scope" ],
  "additionalProperties": false
}

401 — Aucune session ni clé d’API valide (auth.unauthenticated).

403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).

429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.

PUT /api/v1/admin/scope ​

Remplacer le périmètre de l’organisation

Remplace les deux listes. La réponse est la forme normalisée (minuscules, @ de tête retiré, doublons fusionnés) : exactement ce que l’évaluation comparera. Vaut pour l’ingestion future seulement.

Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).

Corps de la requête (application/json)

ChampTypeRequis
excludedDomainsstring[]non
excludedEmailsstring[]non
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "excludedDomains": {
      "default": [],
      "maxItems": 500,
      "type": "array",
      "items": { "type": "string", "minLength": 1, "maxLength": 320 }
    },
    "excludedEmails": {
      "default": [],
      "maxItems": 500,
      "type": "array",
      "items": { "type": "string", "minLength": 1, "maxLength": 320 }
    }
  }
}

Réponses

200 — Le périmètre de l’organisation, normalisé.

ChampTypeRequis
scopeobjectoui

Même schéma que GET /api/v1/admin/scope.

400 — La requête ne respecte pas son schéma.

401 — Aucune session ni clé d’API valide (auth.unauthenticated).

403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).

429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.

Codes d’erreur — request.bad_request. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.

GET /api/v1/admin/node-policy ​

Lire la politique de nœuds

Une entrée par type du catalogue : autorisé, interdit, ou réservé aux administrateurs.

Accès — Session de membre ou clé d’API portant admin:read (rôle administrateur requis).

Réponses

200 — La politique.

ChampTypeRequis
entriesobject[]oui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "entries": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "nodeType": { "type": "string" },
          "allowed": { "type": "boolean" },
          "restrictedToRole": {
            "anyOf": [ { "type": "string", "const": "admin" }, { "type": "null" } ]
          },
          "configured": { "type": "boolean" },
          "group": { "type": "string" },
          "category": { "type": "string" },
          "effect": { "type": "string" }
        },
        "required": [
          "nodeType",
          "allowed",
          "restrictedToRole",
          "configured",
          "group",
          "effect"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [ "entries" ],
  "additionalProperties": false
}

401 — Aucune session ni clé d’API valide (auth.unauthenticated).

403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).

429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.

PUT /api/v1/admin/node-policy ​

Modifier la politique de nœuds

Partiel : seuls les types listés changent. La réponse est la politique complète, pas le delta. Un type inconnu du catalogue est refusé.

Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).

Corps de la requête (application/json)

ChampTypeRequis
entriesobject[]oui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "entries": {
      "minItems": 1,
      "maxItems": 200,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "nodeType": { "type": "string", "minLength": 1, "maxLength": 120 },
          "allowed": { "default": true, "type": "boolean" },
          "restrictedToRole": {
            "default": null,
            "anyOf": [ { "type": "string", "const": "admin" }, { "type": "null" } ]
          }
        },
        "required": [ "nodeType" ]
      }
    }
  },
  "required": [ "entries" ]
}

Réponses

200 — La politique, complète.

ChampTypeRequis
entriesobject[]oui

Même schéma que GET /api/v1/admin/node-policy.

400 — La requête ne respecte pas son schéma.

401 — Aucune session ni clé d’API valide (auth.unauthenticated).

403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).

429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.

Codes d’erreur — request.bad_request, governance.unknown_node_type. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.

GET /api/v1/admin/business-calendar ​

Lire le calendrier ouvré

Fuseau, jours et heures ouvrés, région de jours fériés et fermetures, avec les fériés calculés pour l’année en cours et la suivante et le plafond d’attente de l’instance.

Accès — Session de membre ou clé d’API portant admin:read (rôle administrateur requis).

Réponses

200 — Le calendrier.

ChampTypeRequis
calendarobjectoui
maxWaitDaysintegeroui
holidaysobject[]oui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "calendar": {
      "type": "object",
      "properties": {
        "timezone": { "type": "string", "minLength": 1, "maxLength": 100 },
        "workdays": {
          "minItems": 1,
          "maxItems": 7,
          "type": "array",
          "items": { "type": "integer", "minimum": 1, "maximum": 7 }
        },
        "hours": {
          "type": "object",
          "properties": {
            "start": { "type": "string", "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$" },
            "end": { "type": "string", "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$" }
          },
          "required": [ "start", "end" ],
          "additionalProperties": false
        },
        "holidayRegion": { "type": "string", "enum": [ "none", "FR", "BE" ] },
        "closedDays": {
          "maxItems": 400,
          "type": "array",
          "items": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }
        }
      },
      "required": [ "timezone", "workdays", "hours", "holidayRegion", "closedDays" ],
      "additionalProperties": false
    },
    "maxWaitDays": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 },
    "holidays": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "day": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
          "year": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [ "day", "year" ],
        "additionalProperties": false
      }
    }
  },
  "required": [ "calendar", "maxWaitDays", "holidays" ],
  "additionalProperties": false
}

401 — Aucune session ni clé d’API valide (auth.unauthenticated).

403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).

429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.

PUT /api/v1/admin/business-calendar ​

Remplacer le calendrier ouvré

Un remplacement complet. Un fuseau inconnu, une plage horaire vide ou une fermeture invalide sont refusés par wait.calendar_invalid. Journalisé dans l’audit.

Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).

Corps de la requête (application/json)

ChampTypeRequis
timezonestringoui
workdaysinteger[]oui
hoursobjectoui
holidayRegion"none" | "FR" | "BE"oui
closedDaysstring[]oui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "timezone": { "type": "string", "minLength": 1, "maxLength": 100 },
    "workdays": {
      "minItems": 1,
      "maxItems": 7,
      "type": "array",
      "items": { "type": "integer", "minimum": 1, "maximum": 7 }
    },
    "hours": {
      "type": "object",
      "properties": {
        "start": { "type": "string", "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$" },
        "end": { "type": "string", "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$" }
      },
      "required": [ "start", "end" ]
    },
    "holidayRegion": { "type": "string", "enum": [ "none", "FR", "BE" ] },
    "closedDays": {
      "maxItems": 400,
      "type": "array",
      "items": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }
    }
  },
  "required": [ "timezone", "workdays", "hours", "holidayRegion", "closedDays" ]
}

Réponses

200 — Le calendrier, après écriture.

ChampTypeRequis
calendarobjectoui
maxWaitDaysintegeroui
holidaysobject[]oui

Même schéma que GET /api/v1/admin/business-calendar.

400 — La requête ne respecte pas son schéma.

401 — Aucune session ni clé d’API valide (auth.unauthenticated).

403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).

429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.

Codes d’erreur — wait.bad_request, wait.calendar_invalid. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.

GET /api/v1/admin/instance ​

L’instance et sa liaison au control plane

L’état de la liaison au control plane, le plan et les entitlements reçus, et l’origine de chaque champ de marque (control plane, environnement ou défaut).

Accès — Session de membre ou clé d’API portant admin:read (rôle administrateur requis).

Réponses

200 — L’état.

ChampTypeRequis
controlPlaneobjectoui
brandingobjectoui
brandFieldsobject[]oui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "controlPlane": {
      "type": "object",
      "properties": {
        "configured": { "type": "boolean" },
        "url": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
        "instanceId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
        "instanceStatus": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
        "heartbeat": {
          "type": "object",
          "properties": {
            "lastSuccessAt": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                },
                { "type": "null" }
              ]
            },
            "lastAttemptAt": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                },
                { "type": "null" }
              ]
            },
            "lastError": {
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "code": { "type": "string" },
                    "status": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        { "type": "null" }
                      ]
                    },
                    "at": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                    }
                  },
                  "required": [ "code", "status", "at" ],
                  "additionalProperties": false
                },
                { "type": "null" }
              ]
            }
          },
          "required": [ "lastSuccessAt", "lastAttemptAt", "lastError" ],
          "additionalProperties": false
        },
        "usage": {
          "type": "object",
          "properties": {
            "lastSuccessAt": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                },
                { "type": "null" }
              ]
            },
            "lastAttemptAt": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                },
                { "type": "null" }
              ]
            },
            "lastError": {
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "code": { "type": "string" },
                    "status": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        { "type": "null" }
                      ]
                    },
                    "at": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                    }
                  },
                  "required": [ "code", "status", "at" ],
                  "additionalProperties": false
                },
                { "type": "null" }
              ]
            },
            "pendingPeriods": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
            "oldestPendingPeriod": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                },
                { "type": "null" }
              ]
            }
          },
          "required": [
            "lastSuccessAt",
            "lastAttemptAt",
            "lastError",
            "pendingPeriods",
            "oldestPendingPeriod"
          ],
          "additionalProperties": false
        },
        "config": {
          "type": "object",
          "properties": {
            "lastSuccessAt": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                },
                { "type": "null" }
              ]
            },
            "lastAttemptAt": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                },
                { "type": "null" }
              ]
            },
            "lastError": {
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "code": { "type": "string" },
                    "status": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        { "type": "null" }
                      ]
                    },
                    "at": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                    }
                  },
                  "required": [ "code", "status", "at" ],
                  "additionalProperties": false
                },
                { "type": "null" }
              ]
            },
            "etag": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
            "receivedAt": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                },
                { "type": "null" }
              ]
            }
          },
          "required": [
            "lastSuccessAt",
            "lastAttemptAt",
            "lastError",
            "etag",
            "receivedAt"
          ],
          "additionalProperties": false
        },
        "plan": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "key": { "type": "string" },
                "name": { "type": "string" },
                "version": {
                  "anyOf": [
                    {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    { "type": "null" }
                  ]
                },
                "since": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
                "until": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
              },
              "required": [ "key", "name", "version", "since", "until" ],
              "additionalProperties": false
            },
            { "type": "null" }
          ]
        },
        "entitlements": {
          "anyOf": [
            {
              "type": "object",
              "propertyNames": { "type": "string" },
              "additionalProperties": {}
            },
            { "type": "null" }
          ]
        }
      },
      "required": [
        "configured",
        "url",
        "instanceId",
        "instanceStatus",
        "heartbeat",
        "usage",
        "config",
        "plan",
        "entitlements"
      ],
      "additionalProperties": false
    },
    "branding": {
      "type": "object",
      "properties": {
        "name": { "type": "string", "minLength": 1 },
        "source": { "type": "string", "enum": [ "control_plane", "environment" ] },
        "logo": {
          "type": "object",
          "properties": {
            "light": {
              "anyOf": [ { "type": "string", "format": "uri" }, { "type": "null" } ]
            },
            "dark": {
              "anyOf": [ { "type": "string", "format": "uri" }, { "type": "null" } ]
            }
          },
          "required": [ "light", "dark" ],
          "additionalProperties": false
        },
        "favicon": {
          "anyOf": [ { "type": "string", "format": "uri" }, { "type": "null" } ]
        },
        "colors": {
          "type": "object",
          "properties": {
            "primary": {
              "anyOf": [
                { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
                { "type": "null" }
              ]
            },
            "onPrimary": {
              "anyOf": [
                { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
                { "type": "null" }
              ]
            },
            "accent": {
              "anyOf": [
                { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
                { "type": "null" }
              ]
            },
            "onAccent": {
              "anyOf": [
                { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
                { "type": "null" }
              ]
            }
          },
          "required": [ "primary", "onPrimary", "accent", "onAccent" ],
          "additionalProperties": false
        },
        "supportUrl": {
          "anyOf": [ { "type": "string", "format": "uri" }, { "type": "null" } ]
        },
        "poweredBy": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
        "login": {
          "type": "object",
          "properties": {
            "welcome": {
              "anyOf": [
                {
                  "type": "object",
                  "properties": { "en": { "type": "string" }, "fr": { "type": "string" } },
                  "additionalProperties": false
                },
                { "type": "null" }
              ]
            },
            "image": {
              "anyOf": [ { "type": "string", "format": "uri" }, { "type": "null" } ]
            }
          },
          "required": [ "welcome", "image" ],
          "additionalProperties": false
        },
        "instance": {
          "type": "object",
          "properties": { "suspended": { "type": "boolean" } },
          "required": [ "suspended" ],
          "additionalProperties": false
        }
      },
      "required": [
        "name",
        "source",
        "logo",
        "favicon",
        "colors",
        "supportUrl",
        "poweredBy",
        "login",
        "instance"
      ],
      "additionalProperties": false
    },
    "brandFields": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "enum": [
              "name",
              "logoLight",
              "logoDark",
              "favicon",
              "primaryColor",
              "accentColor",
              "supportUrl",
              "poweredBy",
              "customDomain",
              "emailFromName",
              "emailFooter",
              "loginWelcome",
              "loginImage"
            ]
          },
          "value": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
          "origin": {
            "type": "string",
            "enum": [ "control_plane", "environment", "default" ]
          },
          "variable": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
        },
        "required": [ "field", "value", "origin", "variable" ],
        "additionalProperties": false
      }
    }
  },
  "required": [ "controlPlane", "branding", "brandFields" ],
  "additionalProperties": false
}

401 — Aucune session ni clé d’API valide (auth.unauthenticated).

403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).

429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.

GET /api/v1/admin/send-settings ​

Lire les garde-fous d’envoi

Le kill switch et le débit horaire de l’organisation. lockedByInstance dit si SEND_ENABLED=false court-circuite le réglage.

Accès — Session de membre ou clé d’API portant admin:read (rôle administrateur requis).

Réponses

200 — Les réglages.

ChampTypeRequis
settingsobjectoui
lockedByInstancebooleanoui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "settings": {
      "type": "object",
      "properties": {
        "enabled": { "type": "boolean" },
        "maxPerHour": { "type": "integer", "minimum": 1, "maximum": 10000 }
      },
      "required": [ "enabled", "maxPerHour" ],
      "additionalProperties": false
    },
    "lockedByInstance": { "type": "boolean" }
  },
  "required": [ "settings", "lockedByInstance" ],
  "additionalProperties": false
}

401 — Aucune session ni clé d’API valide (auth.unauthenticated).

403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).

429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.

PUT /api/v1/admin/send-settings ​

Modifier les garde-fous d’envoi

Remplacement partiel : couper l’envoi tient en { "enabled": false }, rien d’autre n’est touché.

Accès — Session de membre ou clé d’API portant admin:write (rôle administrateur requis).

Corps de la requête (application/json)

ChampTypeRequis
enabledbooleannon
maxPerHourintegernon
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "enabled": { "type": "boolean" },
    "maxPerHour": { "type": "integer", "minimum": 1, "maximum": 10000 }
  }
}

Réponses

200 — Les réglages, après.

ChampTypeRequis
settingsobjectoui
lockedByInstancebooleanoui

Même schéma que GET /api/v1/admin/send-settings.

400 — La requête ne respecte pas son schéma.

401 — Aucune session ni clé d’API valide (auth.unauthenticated).

403 — Refusé : rôle insuffisant (auth.forbidden), portée manquante (api_key.scope_missing, details.required la nomme) ou route fermée aux clés (api_key.session_required).

429 — La clé d’API dépasse son débit (api_key.rate_limited) ; Retry-After dit quand réessayer.