DocumentationOuvrir Moon AI
Parcourir la documentation

SCIM 2.0

Le service SCIM 2.0 d’une organisation gérée : jeton de l’annuaire, ressources Users et Groups, filtres, opérations PATCH, limites et erreurs au format SCIM.

Sur cette page

Le service SCIM 2.0 d’une organisation suit les RFC 7643 et 7644. Votre annuaire (Microsoft Entra ID, Okta, Google Workspace…) l’appelle pour créer, suspendre et retirer les membres, et pour tenir les groupes à jour. La mise en place pas à pas est dans Annuaire SCIM.

Adresse et authentificationLien vers la section Adresse et authentification

ÉlémentValeur
Adresse de basehttps://chat.realmoon.ai/api/v1/orgs/scim/v2
AuthentificationAuthorization: Bearer moai_scim_…
Réponsesapplication/scim+json ; le type de contenu de la requête n’est pas lu

Le jeton désigne l’organisation : l’adresse ne contient jamais son identifiant. Un jeton absent, faux, révoqué ou d’un workspace personnel reçoit 401 avec WWW-Authenticate: Bearer et le message « Jeton invalide. ». Toutes les routes demandent le jeton, y compris /ServiceProviderConfig, /ResourceTypes et /Schemas.

Le jeton de l’annuaireLien vers la section Le jeton de l’annuaire

Une organisation a un seul jeton actif. Il se crée dans l’administration › « Connexion » › « Annuaire », par le propriétaire ou un administrateur de l’organisation. Il est montré une seule fois ; en créer un nouveau révoque le précédent tout de suite.

Les routes du jeton sont sous https://chat.realmoon.ai/api/v1/orgs/{org_id} :

Méthode et cheminQuiRôle
GET /scim-tokenClé avec security:readÉtat du jeton, jamais sa valeur.
POST /scim-tokenPropriétaire ou administrateur, avec sa sessionCréer un jeton et révoquer le précédent.
DELETE /scim-tokenPropriétaire ou administrateur, avec sa sessionRévoquer le jeton actif (404 s’il n’y en a pas).

Une clé d’administration reçoit 403 owner_only sur POST et DELETE.

JSON
{
  "can_configure": false,
  "active": true,
  "prefix": "moai_scim_X7k2Qp",
  "created_at": 1762339200,
  "last_used_at": 1762339800,
  "created_by_name": "Camille Martin",
  "base_url": "https://chat.realmoon.ai/api/v1/orgs/scim/v2"
}

last_used_at est mis à jour au plus une fois par minute. La réponse de création ajoute token (sa valeur) et revoked_previous. Chaque écriture de l’annuaire est au journal de l’organisation avec l’auteur scim:<début du jeton>.

Ce que le service annonceLien vers la section Ce que le service annonce

GET /ServiceProviderConfig :

FonctionPrise en charge
patchoui
filteroui, 200 résultats au plus
bulknon
changePasswordnon
sortnon
etagnon
Authentificationjeton porteur (oauthbearertoken)

GET /ResourceTypes et GET /Schemas décrivent les ressources User et Group.

UsersLien vers la section Users

Un User est un membre de l’organisation, actif ou suspendu.

Méthode et cheminRôle
GET /UsersListe, avec startIndex (à partir de 1), count (100 par défaut, 200 au plus) et filter ; triée par date d’arrivée.
GET /Users/{id}Un membre.
POST /UsersAjouter un membre ; répond 201.
PUT /Users/{id}Appliquer les attributs envoyés.
PATCH /Users/{id}Modifier des attributs.
DELETE /Users/{id}Retirer le membre de l’organisation ; répond 204 sans corps.

FiltresLien vers la section Filtres

Une seule condition attribut eq "valeur", sur userName, externalId, id, emails, emails.value ou emails[type eq "work"].value. Seul l’opérateur eq est pris en charge ; la valeur fait 512 caractères au plus, le filtre 1 024. userName et les adresses sont comparés sans tenir compte de la casse. Exemple : GET /Users?filter=userName eq "camille.martin@ecole.fr".

Une ressource UserLien vers la section Une ressource User

JSON
{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
  "id": "<id du compte>",
  "externalId": "<id dans votre annuaire>",
  "userName": "camille.martin@ecole.fr",
  "name": { "formatted": "Camille Martin", "givenName": "Camille", "familyName": "Martin" },
  "displayName": "Camille Martin",
  "emails": [{ "value": "camille.martin@ecole.fr", "type": "work", "primary": true }],
  "active": true,
  "groups": [{ "value": "<id du groupe>", "display": "Site de Lyon", "$ref": "https://chat.realmoon.ai/api/v1/orgs/scim/v2/Groups/<id du groupe>" }],
  "meta": { "resourceType": "User", "created": "2026-11-05T09:00:00+00:00", "lastModified": "2026-11-05T09:00:00+00:00", "location": "https://chat.realmoon.ai/api/v1/orgs/scim/v2/Users/<id du compte>" }
}

groups ne liste que les groupes créés par l’annuaire. givenName et familyName sont tirés du nom affiché, coupé au premier espace.

Créer un membreLien vers la section Créer un membre

  • L’adresse est lue dans userName, sinon dans l’adresse primary, sinon la première de emails.
  • Elle doit être dans un domaine vérifié par l’organisation, sinon 409 (scimType invalidValue), que le compte existe ou non.
  • Un compte inconnu est créé ; un compte existant est rattaché. Le nom vient de name.formatted, sinon de givenName et familyName, sinon de displayName.
  • active absent vaut true ; active: false crée le membre suspendu.
  • 409 aussi quand la personne a déjà une place dans l’organisation (uniqueness), quand tous les sièges sont pris ou pour le compte d’un administrateur de la plateforme. Même réponse sur un workspace payé par carte : chaque siège ajouté serait facturé, invitez la personne depuis l’administration.

Modifier et retirerLien vers la section Modifier et retirer

  • PUT n’applique que les attributs présents : un attribut absent ne change rien.
  • active: false suspend le membre et ferme toutes les sessions de son compte. active: true lève une suspension faite par l’annuaire ; une suspension décidée dans l’administration répond 403. Sur un workspace payé par carte, la réactivation se fait depuis l’administration (409).
  • DELETE retire le membre et ferme ses sessions. Son compte reste, sauf s’il a été créé par cet annuaire, n’a eu aucune activité et n’appartient à aucun autre workspace d’équipe : il est alors supprimé.
  • Le propriétaire, les administrateurs de l’organisation et les administrateurs de la plateforme ne sont jamais suspendus ni retirés par l’annuaire (403).
  • L’adresse ne change pas : une autre adresse répond 400 (scimType mutability), la même est acceptée. Le nom ne change que pour un compte créé par l’organisation ou dont l’adresse est d’un domaine vérifié ; sinon il est ignoré sans erreur.
  • Les attributs inconnus sont ignorés.

PATCHLien vers la section PATCH

Opérations add, replace et remove, de 1 à 100 par requête, dans Operations. Chemins pris en charge : active, displayName, name, name.formatted, name.givenName, name.familyName, externalId, userName, emails, emails.value, emails[type eq "work"].value. Une opération sans path accepte un objet dont les clés sont ces chemins.

remove vide name.givenName et name.familyName, répond 400 (mutability) sur active, et n’a pas d’effet sur les autres chemins. active accepte un booléen ou la chaîne "true" ou "false".

cURL
curl -X PATCH https://chat.realmoon.ai/api/v1/orgs/scim/v2/Users/$USER_ID \
  -H "Authorization: Bearer $MOONAI_SCIM_TOKEN" \
  -H "Content-Type: application/scim+json" \
  -d '{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [{ "op": "replace", "path": "active", "value": false }]
  }'
Python
import os
import requests

r = requests.patch(
    f"https://chat.realmoon.ai/api/v1/orgs/scim/v2/Users/{os.environ['USER_ID']}",
    headers={
        "Authorization": f"Bearer {os.environ['MOONAI_SCIM_TOKEN']}",
        "Content-Type": "application/scim+json",
    },
    json={
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [{"op": "replace", "path": "active", "value": False}],
    },
    timeout=30,
)
r.raise_for_status()
print(r.json()["active"])
JavaScript
const r = await fetch(`https://chat.realmoon.ai/api/v1/orgs/scim/v2/Users/${process.env.USER_ID}`, {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.MOONAI_SCIM_TOKEN}`,
    'Content-Type': 'application/scim+json',
  },
  body: JSON.stringify({
    schemas: ['urn:ietf:params:scim:api:messages:2.0:PatchOp'],
    Operations: [{ op: 'replace', path: 'active', value: false }],
  }),
});
if (!r.ok) throw new Error(await r.text());
console.log((await r.json()).active);

GroupsLien vers la section Groups

Un Group est un groupe de l’organisation créé par l’annuaire. Ces groupes sont en lecture seule dans l’administration.

Méthode et cheminRôle
GET /GroupsListe, avec filter : displayName eq "…", id eq "…", ou id eq "…" and members[value eq "…"] ; excludedAttributes=members allège la réponse.
GET /Groups/{id}Un groupe, avec tous ses membres.
POST /GroupsCréer un groupe (displayName obligatoire, members) ; répond 201.
PUT /Groups/{id}Remplacer le nom et les membres. Sans members, le groupe est vidé.
PATCH /Groups/{id}Chemins displayName, members et members[value eq "<id>"] (pour retirer un membre).
DELETE /Groups/{id}Supprimer le groupe ; ses membres restent dans l’organisation. Répond 204.
  • remove sur members sans valeur vide le groupe. Un autre chemin répond 400 (invalidPath), sauf externalId qui est ignoré.
  • Un identifiant de members qui n’est pas un membre de l’organisation est ignoré.
  • 5 000 membres au plus par liste members d’une requête ou d’une opération (400, tooMany).
  • 1 000 groupes au plus par organisation, groupes de l’administration compris (400, tooMany).
  • Deux groupes ne peuvent pas porter le même nom, sans tenir compte de la casse, même avec un groupe de l’administration (409, uniqueness).
  • L’annuaire ne remplit jamais un groupe qui donne le rôle d’administrateur (409, mutability), ni un groupe dont les rôles dépassent ce que la personne qui a créé le jeton peut donner (403).

Effets sur l’organisationLien vers la section Effets sur l’organisation

Les créations et rattachements envoient l’événement webhook member.joined, les retraits member.removed, les suspensions member.suspended et les réactivations member.reactivated.

LimitesLien vers la section Limites

LimiteValeur
Requêtes par jeton600 par minute (429, scimType tooMany, Retry-After: 60)
Échecs d’authentification par adresse IP60 en 10 minutes, puis 429
Taille du corps1 Mio (413)
Opérations par PATCH100

ErreursLien vers la section Erreurs

Les erreurs suivent le format SCIM :

JSON
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
  "status": "409",
  "scimType": "uniqueness",
  "detail": "Un groupe porte déjà ce nom."
}
StatutCause
400Requête invalide : JSON illisible, filtre non pris en charge, opération ou valeur invalide.
401Jeton absent ou invalide.
403Personne ou groupe protégé, suspension décidée dans l’administration.
404Membre ou groupe introuvable.
409Domaine non vérifié, déjà membre, sièges pleins, nom de groupe pris, groupe administrateur.
413Corps trop grand.
429Trop de requêtes ou d’échecs d’authentification.
503Service momentanément indisponible ; réessayez.

scimType est présent quand il précise la cause : uniqueness, mutability, invalidFilter, invalidSyntax, invalidPath, invalidValue, tooMany.

Voir aussiLien vers la section Voir aussi

Moon AI

Moon AI en action

0:00

À découvrir

Captures de chat.realmoon.ai du 29 octobre 2026, avec des données fictives.

Moon AI

Vos préférences

Aucun suivi publicitaire.

Ce site ne dépose aucun cookie publicitaire ni cookie de mesure d’audience : notre serveur compte les visites sans cookie. Votre thème et la fermeture de l’information sur les cookies sont mémorisés sur cet appareil.

L’application Moon AI possède ses propres réglages de confidentialité.