Une organisation sous contrat peut avoir plusieurs lots de licences : un forfait et un nombre de licences par lot. Des règles placent chaque membre dans un lot selon ses rôles, ses groupes ou ses étiquettes ; un lot de repli reçoit ceux dont le lot est plein. Une organisation sans lots a un seul lot implicite, workspace, qui couvre tout le monde.
Toutes les routes sont sous https://. Portées : licenses:read pour lire, licenses:write pour écrire. Le contenu des forfaits est sur la page Tarifs.
Lire les licencesLien vers la section Lire les licences
GET / · licenses:read
{
"licensed": true,
"pools": [
{ "id": "8f2c1a3e-5b7d-4c9f-a1e3-5b7d9f1a3c5e", "plan_id": "<id du forfait>", "plan_name": "Lune", "plan_slug": "lune", "seats": 3600, "used": 3412, "source": "contract", "contract_id": "<id du contrat>", "contract_line_id": "<id de la ligne>", "name": null, "period_start": 1756684800, "period_end": 1788220800, "is_fallback": true, "virtual": false },
{ "id": "41bd6e8f-0a2c-4e4a-8c6e-0a2c4e6a8c0e", "plan_id": "<id du forfait>", "plan_name": "Galaxie", "plan_slug": "galaxie", "seats": 400, "used": 398, "source": "contract", "contract_id": "<id du contrat>", "contract_line_id": "<id de la ligne>", "name": null, "period_start": 1756684800, "period_end": 1788220800, "is_fallback": false, "virtual": false }
],
"rules": [
{ "id": "<id de règle>", "pool_id": "41bd6e8f-0a2c-4e4a-8c6e-0a2c4e6a8c0e", "subject_type": "group", "subject_id": "<id de groupe>", "subject_name": "Professeurs", "priority": 0 },
{ "id": "<id de règle>", "pool_id": "8f2c1a3e-5b7d-4c9f-a1e3-5b7d9f1a3c5e", "subject_type": "default", "subject_id": null, "subject_name": null, "priority": 1000 }
],
"fallback_pool_id": "8f2c1a3e-5b7d-4c9f-a1e3-5b7d9f1a3c5e",
"members": 3810,
"unlicensed": 0,
"pending": 0,
"reconciling": false,
"license_version": 57,
"can_manage": true,
"manage_permission": "licenses.manage"
}| Champ | Description |
|---|---|
licensed | false : pas de lots ; pools contient le seul lot implicite workspace (virtual: ). |
seats, used | Licences du lot (null : sans limite) et membres actifs qui en ont une. |
rules | Règles d’attribution, dans l’ordre où elles s’appliquent. |
unlicensed | Membres actifs restés sans licence. |
pending | Membres actifs pas encore placés. |
reconciling | Les règles ont changé et le placement est en cours. |
GET / (licenses:read) rend la licence de la personne qui a créé la clé : licensed, managed, org_name, pool_id, source, has_license, plan_id, plan_name, plan_slug. source dit d’où vient la licence : manual, import, scim, invite, rule, default, fallback ou unplaced. La licence d’un autre membre se lit dans la liste des membres.
Règles d’attributionLien vers la section Règles d’attribution
PUT / · licenses:write
Remplace toute la liste des règles, puis recalcule le lot des membres dont la licence vient des règles.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
rules | liste | oui | 200 règles au plus ; une liste vide retire toutes les règles. |
rules[].pool_id | chaîne | oui | Le lot visé. |
rules[].subject_type | chaîne | oui | role, group, label ou default. |
rules[].subject_id | chaîne | sauf default | owner, admin, member, manager, billing ou custom:<id> pour un rôle ; l’id d’un groupe ou d’une étiquette. |
La première règle qui correspond à un membre décide ; la règle default (une seule) s’applique toujours en dernier. Une règle de groupe ne vaut que pour les membres du groupe, pas pour ses gestionnaires. Les licences choisies à la main, par import, par l’annuaire ou par une invitation ne bougent pas.
curl -X PUT https://chat.realmoon.ai/api/v1/orgs/$ORG_ID/licenses/rules \
-H "Authorization: Bearer $MOONAI_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"rules": [
{"pool_id": "<lot Galaxie>", "subject_type": "group", "subject_id": "<id du groupe Professeurs>"},
{"pool_id": "<lot Lune>", "subject_type": "default"}
]}'import os
import requests
r = requests.put(
f"https://chat.realmoon.ai/api/v1/orgs/{os.environ['ORG_ID']}/licenses/rules",
headers={"Authorization": f"Bearer {os.environ['MOONAI_ADMIN_KEY']}"},
json={"rules": [
{"pool_id": os.environ["POOL_TEACHERS"], "subject_type": "group", "subject_id": os.environ["GROUP_TEACHERS"]},
{"pool_id": os.environ["POOL_DEFAULT"], "subject_type": "default"},
]},
timeout=60,
)
r.raise_for_status()
print(r.json()["changed"], "membres ont changé de licence")const r = await fetch(`https://chat.realmoon.ai/api/v1/orgs/${process.env.ORG_ID}/licenses/rules`, {
method: 'PUT',
headers: { Authorization: `Bearer ${process.env.MOONAI_ADMIN_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
rules: [
{ pool_id: process.env.POOL_TEACHERS, subject_type: 'group', subject_id: process.env.GROUP_TEACHERS },
{ pool_id: process.env.POOL_DEFAULT, subject_type: 'default' },
],
}),
});
if (!r.ok) throw new Error(await r.text());
console.log((await r.json()).changed);La réponse a la forme de la lecture, avec changed : le nombre de membres dont la licence a changé.
| Statut | code | Cause |
|---|---|---|
| 400 | invalid_request | Règle sans subject_id, deux règles default, deux règles sur la même chose, lot, groupe, étiquette ou rôle inconnu. field désigne le champ en cause. |
| 409 | no_license_pools | L’organisation n’a qu’un lot : tous les membres ont la même licence. |
Lot de repliLien vers la section Lot de repli
PUT / · licenses:write
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
pool_id | chaîne | non | Le lot qui reçoit les membres dont le lot est plein ; null : ils restent sans licence. |
Envoyez au moins {}. La réponse a la forme de la lecture, avec changed.
Attribuer à la mainLien vers la section Attribuer à la main
POST / · licenses:write
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
user_ids | liste | user_ids ou filter | 1 à 5 000 membres. |
filter | objet | user_ids ou filter | Membres actifs à la fois dans group_id, avec label_id, avec le rôle role, et avec la licence license (id d’un lot ou none). {} : tous les membres actifs. |
pool_id | chaîne | non | Un lot (gardé par tous les recalculs), none (aucune licence), ou null (retour aux règles). |
{ "filter": { "group_id": "<id de groupe>", "license": "none" }, "pool_id": "41bd6e8f-0a2c-4e4a-8c6e-0a2c4e6a8c0e" }Réponse : {"changed": . skipped liste les ids qui ne sont pas des membres actifs ; fallback et unplaced comptent les membres envoyés au repli ou laissés sans licence par un retour aux règles.
| Statut | code | Cause |
|---|---|---|
| 400 | invalid_request | user_ids et filter ensemble, ni l’un ni l’autre, plus de 5 000 membres trouvés, lot inconnu. |
| 409 | no_license_pools | L’organisation n’a qu’un lot. |
| 409 | pool_full | Le lot n’a pas assez de licences libres ; free et requested donnent les nombres. Rien n’est attribué. |
Le forfait d’un membre (fonctions, limites, modèles) suit sa licence dans les secondes qui suivent. Quand un lot devient plein, l’événement webhook license.pool_full part, au plus une fois par jour et par lot.
Contrat et facturesLien vers la section Contrat et factures
GET / · licenses:read
Rend le contrat de l’organisation et ses factures. La clé doit aussi avoir le droit de lire la facturation (ou son créateur être le contact de facturation de l’organisation) ; sinon la route répond 404.
contract vaut null sans contrat actif ou terminé. Ses champs :
| Champ | Description |
|---|---|
status | active ou ended. |
channel | invoice, external ou offered. |
plan, seats, lines | Le forfait principal, le nombre de licences, et une ligne par forfait (plan, seats, price_per_seat_cents, monthly_amount_ht). |
period_start, period_end, days_left | Période du contrat et jours restants. |
billing_interval | year, semester, quarter, month ou once. |
price_per_seat_cents, monthly_amount_ht, annual_amount_ht, currency | Montants en centimes, hors taxes : prix d’une licence par mois, total par mois, total sur douze mois, et la devise. |
buyer | Acheteur : name, siret, vat_number, address, po_number, engagement_number, service_code, public_buyer. |
billing_emails | Adresses qui reçoivent les factures. |
renewal | Le renouvellement signé, ou null. |
invoices liste les 100 dernières factures, les plus récentes d’abord :
| Champ | Description |
|---|---|
number, kind | Numéro et type : period (période) ou amendment (avenant). |
status, overdue | open, uncollectible, paid ou void ; overdue : ouverte et échue. |
amount_ht, tax_amount, amount_ttc, currency | Montants en centimes. |
issued_at, due_at, paid_at, period_start, period_end | Dates en secondes Unix. |
hosted_url, pdf_url | Liens de la facture, seulement quand elle est ouverte ou payée. |
chorus_pro | Dépôt sur Chorus Pro (deposited_at, reference, status), ou null. |
Voir aussiLien vers la section Voir aussi
- Licences, dans l’administration
- Membres
- Organisation et réglages