Guide cas concret · API Datacopro v2 · Assemblées générales
Préparer l'ordre du jour d'une AG
Créer une assemblée générale, composer son ordre du jour (résolutions, sous-résolutions, majorités, clés de répartition), le réordonner, figer les textes de convocation et y joindre les pièces, jusqu'à l'envoi de la convocation.
Périmètre : une copropriétéAvant la séanceSuite : guide « Tenir une AG »
À propos de ce guide
Ce guide décrit uniquement le contrat de l'API Datacopro : les appels, leur ordre, les paramètres utiles et les comportements à connaître. Vous n'avez besoin de connaître aucun logiciel de gestion en particulier. Les parcours s'inspirent d'une intégration réelle en production, citée ponctuellement à titre d'illustration.
La tenue de la séance (émargement, votes, calcul des résultats, clôture) fait l'objet d'un guide séparé : Tenir une AG.
01
Modèle & périmètre
Une assemblée générale appartient à une copropriété. Son ordre du jour n'est pas un objet à part : c'est la liste des résolutions rattachées à l'assemblée, chacune portant son numéro d'ordre. Toutes les routes sont préfixées par https://syndic.datacopro.org/v2 et scopées par /copro/{idCopro}. Les dates s'échangent au format AAAA-MM-JJ HH:MM:SS.
Exemple : ordre du jour tel que l'API le structure
1Élection du président de séancesimple · art. 24
2Approbation des comptes de l'exercice 2025simple · art. 24
3Désignation du syndicabsolue · art. 25 · revotable
4Ravalement de la façade sur rueabsolue · art. 25 · revotable
4.1Choix de l'entreprise Asous-résolution
4.2Choix de l'entreprise Bsous-résolution
5Questions diversessans vote
Assemblée /copro/{id}/assemblee/{idAg}
id, type : ordinaire, extraordinaire ou constitutive
estAvecVotes : l'assemblée enregistre-t-elle des votes nominatifs
acces[] : modalités de participation (type, libelle, description, procedure)
exercices[], documents[], resolutions[]
statut : ouverte, confirmée ou annulée
Résolution resolutions[]
id, numero, numeroReference (numéro du parent pour une sous-résolution)
majorite : la référence textuelle (simple, absolue…), pas un identifiant
estRevotable : éligible au second vote (passerelle art. 25-1 / 26-1)
cle : clé de répartition qui porte les tantièmes du vote
contact, historique (qui a suggéré la résolution)
Trois jeux de textes : voir ci-dessous
sousResolutions[], resolutionRevote, documents[]
Trois versions du texte d'une résolution
Champs
Rôle
Quand l'écrire
libelle, contenu
Texte de travail, éventuellement avec vos propres variables de modèle.
Pendant la préparation.
libelleConvocation, contenuConvocation
Texte définitif tel qu'il figure dans la convocation.
Avant de générer la convocation.
libellePv, contenuPv
Texte final, éventuellement amendé, tel qu'il figurera au procès-verbal.
Pendant la séance (guide « Tenir une AG »).
En lecture, contenuVariabilise renvoie contenuConvocation, ou contenu si le premier est vide. contenuFinal renvoie contenuPv. L'API ne remplace aucune variable : les substitutions (nom du syndic, date de l'assemblée…) sont à votre charge.
Où en est l'assemblée ? Lire les dates, pas le statut
Le champ statut est un statut administratif (ouverte à la création, puis éventuellement confirmée ou annulée). Il ne reflète pas l'avancement. Pour savoir à quelle étape se trouve l'assemblée, lisez ses dates, de la plus avancée à la moins avancée :
Condition
Étape
Ordre du jour modifiable ?
dateEnvoiPv renseignée
PV envoyé, assemblée terminée
Non (convention recommandée)
dateFermeture renseignée
Séance close, PV à envoyer
Ajout et suppression refusés par l'API
Statut annulée
Assemblée annulée
Non (convention recommandée). L'API, elle, ne bloque rien
dateReelle sans dateFermeture
Séance en cours
Voir « Tenir une AG »
dateEnvoiConvocation renseignée
Convocation envoyée, assemblée à tenir
Non (convention recommandée)
datePrevisionnelle et au moins un accès
Prête à convoquer
Oui
Aucune de ces dates
Brouillon
Oui
Illustration
Cette lecture par étapes est une convention, pas une donnée de l'API. C'est ainsi qu'un logiciel de gestion existant affiche l'étape d'une assemblée à ses utilisateurs, et c'est lui qui interdit l'édition de l'ordre du jour une fois la convocation envoyée. L'API, elle, ne l'interdit pas (voir Limites).
Périmètre
La clé de répartition d'une résolution doit appartenir à la même copropriété.
Le contact éventuel doit appartenir à la même copropriété.
Le parent d'une sous-résolution doit être une résolution de la même assemblée. Un seul niveau de sous-résolution est utilisé en pratique.
Les majorités disponibles dépendent du cadre juridique de la copropriété (France ou Belgique).
Les modèles de résolutions ou d'ordres du jour (bibliothèques) n'existent pas dans l'API. Si vous en proposez, ils vivent dans votre logiciel et vous les matérialisez en résolutions au moment de l'import.
02
Contrôle d'accès
Chaque appel est authentifié par un jeton OAuth. Le client doit être autorisé sur la copropriété visée, sinon l'API répond 403 avec {"message":["User not allowed"],"code":403}. L'API vérifie aussi que l'assemblée appartient bien à la copropriété de l'URL, et la résolution à l'assemblée. Aucun accès « copropriétaire » n'est prévu : ces routes sont réservées à l'usage du gestionnaire.
03
Parcours fonctionnels
A
Créer l'assemblée
Cas d'usage : le gestionnaire ouvre une nouvelle AG ordinaire pour approuver les comptes de l'exercice écoulé.
POST/copro/{idCopro}/assemblee.json
{
"type": "ordinaire",
"libelle": "AG ordinaire 2026",
"datePrevisionnelle": "2026-06-18 18:30:00",
"avecVotes": 1,
"exercices": [812],
"langues": [],
"acces": [
{ "type": "physique", "libelle": "Salle paroissiale",
"description": "12 rue des Lilas, Lyon" },
{ "type": "correspondance", "libelle": "Vote par correspondance",
"procedure": "Formulaire à retourner au syndic au moins 3 jours francs avant la séance" }
]
}
exercices : identifiants des exercices comptables de la copropriété soumis à l'assemblée (pour une AG ordinaire d'approbation des comptes).
acces : un seul accès par type (physique, visio, audio, correspondance, autre). type et libelle sont obligatoires pour chaque accès.
avecVotes : à 1 par défaut. À 0, la séance n'enregistrera que les résultats, sans vote nominatif.
libelle : 256 caractères au maximum.
Réponse 201 : l'assemblée complète, au statut ouverte. Conservez son id.
Limite
À la création, seuls type, libelle, note, datePrevisionnelle, avecVotes, acces, exercices et langues sont pris en compte. Les autres champs acceptés par la route (dateEnvoiConvocation, distributionPouvoir, tags…) sont ignorés sans erreur. Renseignez-les ensuite par un PUT.
PUT/copro/{idCopro}/assemblee/{idAg}.json
Modification partielle : seuls les champs envoyés sont modifiés. Le statut ne se change pas ici (voir Tenir une AG).
Limite
La liste acces est traitée par type. Retirer un accès en l'omettant n'est pas garanti : relisez l'assemblée après modification pour vérifier que l'accès retiré a bien disparu. Lorsque vous modifiez acces ou exercices, renvoyez toujours la liste complète.
B
Charger les référentiels : majorités et clés
Cas d'usage : proposer au gestionnaire, dans un formulaire de résolution, uniquement les majorités et les clés valables pour cette copropriété.
GET/copro/{idCopro}/type/majorite.json
Renvoie les majorités du cadre juridique de la copropriété, plus sans vote. Chaque entrée porte sa reference (la valeur à envoyer dans majorite), ses seuils (tauxTantiemesMin, tauxParticipationMin) et ses traductions.
Référence
Article (France)
Revotable ?
simple
art. 24
Non
absolue
art. 25
Oui : passerelle art. 25-1 vers un second vote à l'art. 24
double
art. 26
Oui : passerelle art. 26-1 vers un second vote à l'art. 25
unanimité
unanimité
Non
sans vote
point d'information
Non
Les copropriétés belges reçoivent leurs propres références (absolue (belgique), deux-tiers (belgique), etc.). Certaines copropriétés disposent de majorités spécifiques supplémentaires : ne codez donc pas la liste en dur.
Pourquoi
À la création d'une résolution, l'API vérifie que la référence existe, pas qu'elle correspond au cadre de la copropriété. C'est à vous de ne proposer que les majorités renvoyées par cette route.
Liste les clés de répartition. L'exclusion !tantiemesParLot.* évite de rapatrier les tantièmes lot par lot, inutiles pour un simple choix de clé. Proposez par défaut la clé générale de la copropriété (celle qui répartit les charges communes sur l'ensemble des lots) : c'est la clé habituelle des résolutions sans objet de dépense spécifique.
C
Ajouter une résolution, puis ses sous-résolutions
Cas d'usage : inscrire le ravalement de façade (art. 25, revotable), puis deux variantes à départager, une par entreprise.
{
"numero": 4,
"libelle": "Ravalement de la façade sur rue",
"contenu": "L'assemblée générale, après en avoir délibéré, décide…",
"majorite": "absolue",
"revotable": 1,
"cle": 3021,
"historique": "Résolution inscrite à la demande du conseil syndical"
}
Obligatoires : numero (entier non nul), libelle, majorite (référence), cle (identifiant d'une clé de la copropriété).
contenu est facultatif : un point « Questions diverses » peut n'avoir aucun texte.
revotable n'est accepté qu'avec absolue ou double. C'est ce drapeau qui déclenchera automatiquement le second vote pendant la séance si les conditions légales sont réunies.
Vous pouvez aussi envoyer d'emblée libelleConvocation et contenuConvocation (voir parcours E).
Réponse 201 : la résolution créée, avec son id.
Limite
numero n'est pas contrôlé en unicité : deux résolutions peuvent porter le même numéro. Calculez vous-même le prochain numéro libre (le plus grand numéro existant + 1). Évitez aussi revotable avec une majorité absente ou invalide : l'API répond alors une erreur 500 au lieu d'un 400 explicite.
resolutionParente rattache la résolution à son parent (90412, la résolution 4 créée juste avant). Le numero d'une sous-résolution est son rang parmi ses sœurs (1, 2…). L'affichage « 4.1 » se déduit de numeroReference (numéro du parent) et numero. En pratique, reprenez la clé et la majorité du parent comme valeurs par défaut.
Effet de bord
Ajouter une résolution en dernière position étend automatiquement jusqu'à elle les présences déjà enregistrées qui couraient jusqu'à la fin de l'ordre du jour. Sans conséquence en préparation, ce comportement est utile en séance (guide « Tenir une AG »).
D
Réordonner, modifier, supprimer
Cas d'usage : le gestionnaire déplace « Désignation du syndic » en tête, corrige une clé, puis retire un point devenu inutile.
Il n'existe pas de route de réordonnancement : l'ordre du jour est trié par numero. Pour déplacer une résolution, attribuez-lui son nouveau numéro, puis renumérotez ses sœurs (même niveau, même parent) en n'envoyant un PUT qu'aux résolutions dont le numéro change réellement.
Le même PUT modifie n'importe quel champ : libelle, contenu, majorite, revotable, cle, contact, historique… Seuls les champs présents sont modifiés. Réponse 202 avec la résolution.
Limite : aucun contrôle de périmètre en modification
Contrairement à la création, cette route ne refuse pas une clé, un contact ou un parent hors périmètre : une clé ou un contact d'une autre copropriété, ou un parent pris dans une autre assemblée, est accepté et enregistré, avec une réponse 202. Relire la réponse ne suffit donc pas à détecter l'erreur. Validez l'identifiant avant l'envoi : la clé doit figurer dans GET /copro/{idCopro}/cles.json, le contact dans les contacts de la copropriété, le parent parmi les résolutions de premier niveau de cette assemblée. Seuls un identifiant qui n'existe pas du tout et une référence de majorité inconnue sont ignorés : pour ces deux cas, comparez la résolution renvoyée à ce que vous avez envoyé.
Limite
La règle « revotable seulement avec absolue ou double » n'est vérifiée qu'à la création. Si vous passez une résolution de absolue à simple, envoyez aussi "revotable": 0 dans le même appel. Une sous-résolution ne peut pas être détachée de son parent : supprimez-la et recréez-la au premier niveau. Enfin, en modification, rien n'empêche de rattacher une résolution sous une sous-résolution (deux niveaux) : n'acceptez comme parent qu'une résolution de premier niveau.
Réponse 204. La suppression emporte les sous-résolutions et les votes. Les pièces jointes sont détachées de la résolution mais restent dans les documents de la copropriété.
Limite
Les résolutions restantes ne sont pas renumérotées. Supprimer la 3 sur 6 laisse la suite 1, 2, 4, 5, 6. Renumérotez les sœurs de 1 à n juste après (un PUT {"numero": i} par résolution décalée). Pour vider entièrement l'ordre du jour, supprimez les résolutions une à une, en commençant par les sous-résolutions.
E
Figer les textes de convocation
Cas d'usage : vos modèles contiennent des variables (nom du syndic, date de l'assemblée, majorité, clé). Avant de produire la convocation, il faut en stocker la version définitive.
{
"libelleConvocation": "Ravalement de la façade sur rue",
"contenuConvocation": "L'assemblée générale du 18 juin 2026, statuant à la majorité de l'article 25…"
}
Recalculez ces deux champs après chaque modification de l'ordre du jour ou de l'assemblée (la date, par exemple), pour chaque résolution et sous-résolution, et n'envoyez le PUT que si la valeur change.
Pourquoi
Garder contenu comme texte de travail et contenuConvocation comme texte envoyé vous permet de régénérer la convocation sans perdre le modèle. Le jour de la séance, le texte au procès-verbal part de la version convoquée.
Illustration
Un logiciel de gestion existant refait ce calcul après chaque ajout, modification ou suppression de résolution, puis supprime les convocations déjà générées pour éviter d'en envoyer une version périmée.
F
Ordre du jour bilingue (copropriétés belges)
Cas d'usage : une assemblée convoquée en français et en néerlandais.
Créez l'assemblée avec "langues": ["FR","NL"]. Créez chaque résolution dans la langue principale, puis envoyez les textes de chaque langue par un PUT portant le paramètre locale : d'abord la langue secondaire, puis la langue principale.
PUT /copro/{idCopro}/assemblee/{idAg}/resolution/{idRes}.json
{ "locale": "NL", "libelle": "Gevelrenovatie", "contenu": "…" }
PUT /copro/{idCopro}/assemblee/{idAg}/resolution/{idRes}.json
{ "locale": "FR", "libelle": "Rénovation de la façade", "contenu": "…" }
En lecture, ajoutez ?locale=NL (ou FR) pour obtenir les textes dans la langue voulue.
Illustration
Cet ordre (secondaire, puis principale) est celui qu'utilise une intégration en production pour que les deux traductions soient bien enregistrées. Relisez la résolution dans chaque locale pour vérifier le résultat.
G
Joindre les pièces et marquer la convocation envoyée
Cas d'usage : annexer un devis à une résolution, déposer la convocation générée, puis enregistrer la date d'envoi.
fichier.mode vaut url (l'API télécharge le fichier) ou base64 (contenu dans valeur). {type} est libre pour une pièce de résolution ; autre convient.
Limite
Retirer une pièce d'une résolution (DELETE …/resolution/{idRes}/document/{idDoc}.json) supprime le document lui-même, pas seulement le lien. Si le fichier sert ailleurs, gardez-en une copie.
Même corps de requête. Les types d'usage courant sont convocation, odj, coproprietaire (convocation nominative), note-informations-convocation et comptabilite. Utilisez ces valeurs : l'API ne les valide pas, mais les consommateurs de l'assemblée s'appuient dessus pour retrouver les pièces.
Si vous régénérez une convocation, retirez d'abord l'ancienne version avec DELETE /copro/{idCopro}/assemblee/{idAg}/document/{idDoc}.json. Cet appel supprime aussi le fichier lui-même lorsqu'il n'est pas utilisé ailleurs (par exemple dans un envoi déjà journalisé).
PUT/copro/{idCopro}/assemblee/{idAg}.json
{ "dateEnvoiConvocation": "2026-05-20 09:12:00" }
À n'envoyer qu'une fois la convocation réellement expédiée. Cette date fait passer l'assemblée à l'étape « à tenir » pour tous les logiciels qui la lisent.
Limite
L'API ne verrouille pas l'ordre du jour après l'envoi de la convocation : ajouts, modifications et suppressions restent techniquement possibles jusqu'à la clôture de la séance. Or une résolution non inscrite à la convocation ne peut pas être valablement votée. Bloquez vous-même l'édition dès que dateEnvoiConvocation est renseignée.
H
Relire l'ordre du jour
Cas d'usage : afficher l'ordre du jour d'une assemblée, ou lister les assemblées d'une copropriété.
Sans displays, l'API renvoie l'assemblée complète, y compris la feuille de présence et tous les votes. Les deux exclusions ci-dessus allègent fortement la réponse pour un simple affichage de l'ordre du jour.
resolutions[] ne contient que les résolutions de premier niveau, sans tri garanti. Les sous-résolutions sont imbriquées dans sousResolutions[] et un éventuel second vote dans resolutionRevote. Triez vous-même chaque niveau par numero.
GET/copro/{idCopro}/assemblees.json
Liste les assemblées de la copropriété (notez le pluriel : /assemblee.json est la route de création). Cette liste n'est pas paginée et renvoie des assemblées complètes : utilisez les mêmes exclusions, ou une inclusion explicite des seuls champs utiles (displays[]=id&displays[]=libelle&displays[]=datePrevisionnelle…).
Pour une vue multi-copropriétés, GET /domaines/{idDomaine}/assemblees.json renvoie les assemblées d'un domaine, avec leur copropriété et leurs exercices, mais sans résolutions ni documents.
04
Référence des endpoints
Méthode
Route
Rôle
GET
/copro/{id}/assemblees.json
Lister les assemblées d'une copropriété.
GET
/copro/{id}/assemblee/{idAg}.json
Lire une assemblée et son ordre du jour.
POST
/copro/{id}/assemblee.json
Créer une assemblée.
PUT
/copro/{id}/assemblee/{idAg}.json
Modifier une assemblée (partiel), dont dateEnvoiConvocation.
Historique des modifications de l'assemblée et de ses résolutions.
GET
/domaines/{idDomaine}/assemblees.json
Assemblées de toutes les copropriétés d'un domaine (vue résumée).
Une route de duplication de résolution existe (PUT …/resolution/{idRes}/dupliquer.json), mais elle place la copie en fin de liste et ne renvoie pas l'identifiant créé. Pour dupliquer, relisez la résolution source et recréez-la par un POST.
Sans paramètre ou avec des exclusions seulement : tout sauf les champs exclus. Avec au moins une inclusion : seuls les champs listés, et sur une assemblée la feuille de présence et les votes ne sont alors chargés que si vous incluez resolutions.* ou presences.*. C'est le levier principal pour alléger la réponse.
filters
filters[champ]=valeur, filters[champ__op]=valeur, groupes filters[0][…] combinés en OU
Sur les listes seulement. Opérateurs : eq, diff, gt, gte, lt, lte, contains, ncontains, empty, nempty. Texte : contains par défaut. Nombres et dates : opérateur obligatoire, par exemple filters[datePrevisionnelle__gte]=2026-01-01 00:00:00.
locale
FR, NL
Langue des textes lus ou écrits (assemblées multilingues).
Pièges de syntaxe
Pour un objet ou une liste, l'inclusion doit se terminer par .*. displays[]=resolutions seul renvoie des objets vides. De même, l'exclusion d'une liste s'écrit !presences.*.
Pour « inférieur ou égal », utilisez le suffixe __lte. Les préfixes <= dans la valeur sont refusés. Pour « différent de », utilisez __diff.
Les routes d'assemblée ne gèrent ni tri ni pagination : triez côté client.
06
Limites & pièges connus
Pas de verrou après convocation. Seule la clôture de la séance (dateFermeture) empêche d'ajouter ou de supprimer une résolution. Les modifications restent possibles même après, et deux mécanismes ajoutent encore des résolutions après la clôture : la duplication et la création automatique d'un second vote. Le respect de l'ordre du jour convoqué est à votre charge.
Pas de renumérotation automatique après suppression, et pas d'unicité des numéros. Renumérotez les sœurs vous-même.
Pas de contrôle de périmètre en modification. Un PUT de résolution accepte une clé ou un contact d'une autre copropriété et un parent d'une autre assemblée, avec un 202. Validez les identifiants avant l'envoi.
revotable contrôlé à la création seulement. Remettez-le à 0 si la majorité change pour une majorité non revotable.
Champs ignorés à la création d'assemblée : dateEnvoiConvocation, distributionPouvoir, tags… passent par un PUT ultérieur.
Ordre des résolutions non garanti en lecture : triez par numero à chaque niveau.
Retirer une pièce de résolution supprime le document, alors que supprimer la résolution se contente de détacher ses pièces.
Erreurs 500 génériques sur certaines entrées invalides (revotable sans majorité valide). Validez vos données avant l'envoi.
Webhooks. Toute modification d'une résolution, d'un accès, d'un document, d'une présence ou d'un vote remonte comme une mise à jour de l'assemblée pour les abonnés aux webhooks assemblee.
07
Questions de validation
Je supprime la résolution n° 3 d'un ordre du jour qui en compte 6. Les suivantes sont-elles renumérotées ?
Non. L'ordre du jour devient 1, 2, 4, 5, 6. Envoyez ensuite un PUT {"numero": i} à chaque résolution décalée du même niveau. Voir parcours D.
Mon PUT qui change la clé de répartition d'une résolution a répondu 202. Suis-je sûr que la bonne clé est enregistrée ?
Non. En modification, l'API ne vérifie pas que la clé appartient à la copropriété : une clé d'une autre copropriété est enregistrée sans erreur, et la réponse renvoie bien l'identifiant envoyé. Vérifiez donc, avant l'envoi, que la clé figure dans GET /copro/{idCopro}/cles.json. Seul un identifiant inexistant est ignoré, ce que la comparaison de la réponse permet de repérer. Voir parcours D.
Une fois la convocation envoyée, l'API m'empêche-t-elle de modifier l'ordre du jour ?
Non. Renseigner dateEnvoiConvocation ne verrouille rien. Seule la clôture de la séance (dateFermeture) bloque l'ajout et la suppression de résolutions ; même alors, les modifications restent possibles. Le statut annulée ne bloque rien non plus. Bloquez l'édition dans votre logiciel. Voir parcours G et Limites.