Skip to content

Membres et invitations ​

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/members ​

Lister les membres

Tous les membres de l’instance, avec statut, rôle et compteurs.

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

Réponses

200 — Les membres.

ChampTypeRequis
membersobject[]oui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "members": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "email": { "type": "string" },
          "name": { "type": "string" },
          "role": { "type": "string", "enum": [ "member", "admin" ] },
          "status": { "type": "string", "enum": [ "active", "suspended" ] },
          "mailboxCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
          "publishedWorkflowCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
          "createdAt": {
            "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": [
          "id",
          "email",
          "name",
          "role",
          "status",
          "mailboxCount",
          "publishedWorkflowCount",
          "createdAt"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [ "members" ],
  "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.

PATCH /api/v1/admin/members/{id} ​

Changer le rôle d’un membre

L’instance garde au moins un administrateur actif : rétrograder le dernier est refusé. Journalisé dans l’audit.

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

Paramètres

NomOùTypeRequis
idcheminstringoui

Corps de la requête (application/json)

ChampTypeRequis
role"member" | "admin"oui
Schéma JSON
json
{
  "type": "object",
  "properties": { "role": { "type": "string", "enum": [ "member", "admin" ] } },
  "required": [ "role" ]
}

Réponses

200 — Le membre.

ChampTypeRequis
memberobjectoui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "member": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "format": "uuid",
          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
        },
        "email": { "type": "string" },
        "name": { "type": "string" },
        "role": { "type": "string", "enum": [ "member", "admin" ] },
        "status": { "type": "string", "enum": [ "active", "suspended" ] },
        "mailboxCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
        "publishedWorkflowCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
        "createdAt": {
          "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": [
        "id",
        "email",
        "name",
        "role",
        "status",
        "mailboxCount",
        "publishedWorkflowCount",
        "createdAt"
      ],
      "additionalProperties": false
    }
  },
  "required": [ "member" ],
  "additionalProperties": false
}

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.not_found, governance.last_admin. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.

POST /api/v1/admin/members/{id}/deactivate ​

Désactiver un membre

Révoque les sessions, déconnecte les boîtes et dépublie les workflows ; la réponse dit ce qui a réellement été coupé. Un administrateur ne se désactive pas lui-même ni le dernier administrateur actif.

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

Paramètres

NomOùTypeRequis
idcheminstringoui

Réponses

200 — Le membre et les effets.

ChampTypeRequis
memberobjectoui
effectsobjectoui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "member": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "format": "uuid",
          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
        },
        "email": { "type": "string" },
        "name": { "type": "string" },
        "role": { "type": "string", "enum": [ "member", "admin" ] },
        "status": { "type": "string", "enum": [ "active", "suspended" ] },
        "mailboxCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
        "publishedWorkflowCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
        "createdAt": {
          "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": [
        "id",
        "email",
        "name",
        "role",
        "status",
        "mailboxCount",
        "publishedWorkflowCount",
        "createdAt"
      ],
      "additionalProperties": false
    },
    "effects": {
      "type": "object",
      "properties": {
        "sessionsRevoked": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
        "mailboxesPaused": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
        "workflowsUnpublished": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
      },
      "required": [ "sessionsRevoked", "mailboxesPaused", "workflowsUnpublished" ],
      "additionalProperties": false
    }
  },
  "required": [ "member", "effects" ],
  "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.

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

POST /api/v1/admin/members/{id}/reactivate ​

Réactiver un membre

Le compte redevient utilisable, et rien d’autre : les boîtes restent déconnectées et les workflows dépubliés.

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

Paramètres

NomOùTypeRequis
idcheminstringoui

Réponses

200 — Le membre.

ChampTypeRequis
memberobjectoui

Même schéma que PATCH /api/v1/admin/members/{id}.

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 — governance.not_found. 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/members/invitations ​

Lister les invitations en attente

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

Réponses

200 — Les invitations.

ChampTypeRequis
invitationsobject[]oui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "invitations": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "email": { "type": "string" },
          "role": { "type": "string", "enum": [ "member", "admin" ] },
          "expiresAt": {
            "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))$"
          },
          "createdAt": {
            "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))$"
          },
          "invitedBy": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              { "type": "null" }
            ]
          },
          "expired": { "type": "boolean" }
        },
        "required": [
          "id",
          "email",
          "role",
          "expiresAt",
          "createdAt",
          "invitedBy",
          "expired"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [ "invitations" ],
  "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.

POST /api/v1/admin/members/invitations ​

Inviter un membre

Crée l’invitation et rend le lien d’acceptation : le seul endroit où un jeton en clair sort de l’instance. L’invitation n’est pas envoyée par email ; l’administrateur transmet le lien. Refusée si un membre ou une invitation en attente existe déjà pour l’adresse.

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

Corps de la requête (application/json)

ChampTypeRequis
emailstringoui
role"member" | "admin"non
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "email": { "type": "string" },
    "role": { "default": "member", "type": "string", "enum": [ "member", "admin" ] }
  },
  "required": [ "email" ]
}

Réponses

201 — L’invitation et son lien.

ChampTypeRequis
invitationobjectoui
acceptUrlstring (uri)oui
tokenstringoui
Schéma JSON
json
{
  "type": "object",
  "properties": {
    "invitation": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "format": "uuid",
          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
        },
        "email": { "type": "string" },
        "role": { "type": "string", "enum": [ "member", "admin" ] },
        "expiresAt": {
          "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))$"
        },
        "createdAt": {
          "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))$"
        },
        "invitedBy": {
          "anyOf": [
            {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            },
            { "type": "null" }
          ]
        },
        "expired": { "type": "boolean" }
      },
      "required": [
        "id",
        "email",
        "role",
        "expiresAt",
        "createdAt",
        "invitedBy",
        "expired"
      ],
      "additionalProperties": false
    },
    "acceptUrl": { "type": "string", "format": "uri" },
    "token": { "type": "string", "minLength": 1 }
  },
  "required": [ "invitation", "acceptUrl", "token" ],
  "additionalProperties": false
}

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.

Cette opération accepte un en-tête Idempotency-Key : rejouer la même requête avec la même clé rend la réponse d’origine au lieu d’agir deux fois. Voir Idempotence.

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

Exemple de requête

json
{ "email": "bob@example.test", "role": "member" }

Exemple de réponse (201)

json
{
  "invitation": {
    "id": "0192f1c2-3b4d-7e8f-9a0b-1c2d3e4f5a6b",
    "email": "bob@example.test",
    "role": "member",
    "invitedBy": "0192f1c2-0000-7000-8000-000000000001",
    "createdAt": "2026-10-04T09:00:00.000Z",
    "expiresAt": "2026-10-11T09:00:00.000Z",
    "status": "pending"
  },
  "acceptUrl": "https://mail.example.test/invite/Qm9uam91cl9jZXN0X3VuX2V4ZW1wbGU",
  "token": "Qm9uam91cl9jZXN0X3VuX2V4ZW1wbGU"
}

DELETE /api/v1/admin/members/invitations/{id} ​

Révoquer une invitation

Une invitation déjà consommée ou inconnue est un 404 et ne laisse aucune trace ; une révocation est journalisée dans l’audit.

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

Paramètres

NomOùTypeRequis
idcheminstringoui

Réponses

204 — Révoquée.

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 — governance.not_found. Les codes communs (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) s’appliquent à toutes les routes ; voir Erreurs.