Documentation
Obtenir une clé
- Un administrateur de votre organisation demande une clé ci-dessus, avec son nom et l’usage prévu.
- Atlas examine chaque demande, puis l’approuve ou la refuse en motivant sa décision. La décision s’affiche ici.
- Une fois la clé approuvée, la personne qui l’a demandée la révèle UNE seule fois et la range dans un coffre à secrets.
- La clé est liée à votre organisation ET au compte qui l’a demandée : si ce compte quitte l’organisation ou est bloqué, la clé cesse de fonctionner.
Authentification
Chaque requête porte la clé dans l’en-tête Authorization : « Authorization: Bearer <votre clé> ». Jamais dans l’adresse (URL) : une adresse se retrouve dans les journaux, les historiques et les proxys.
L’API est faite pour des appels de SERVEUR À SERVEUR. Une requête qui porte un en-tête Origin (donc partie d’un navigateur) est refusée (403 browser_origin_refused) : une clé ne doit jamais se trouver dans du code exécuté chez vos visiteurs.
Une clé compromise se révoque immédiatement ci-dessus ; « Faire tourner » en délivre une nouvelle et coupe l’ancienne sur-le-champ.
Authorization: Bearer <key> Adresse de base
https://api.astro.atlascontrole.be/api/client/v1 Toutes les routes sont relatives à cette adresse, en HTTPS uniquement. Les réponses sont en JSON (UTF-8), les dates au format ISO 8601.
Routes
| Route | Ce qu’elle rend | Paramètres |
|---|---|---|
GET /me | La clé utilisée, votre organisation, vos limites et la consommation du jour. | — |
GET /inspections | Vos inspections, triées par date de mise à jour croissante (idéal pour synchroniser). | status, from, to, updated_since, limit, cursor |
GET /inspections/{ref} | Une inspection, par sa référence. | — |
GET /orders | Vos commandes et devis. | status, limit, cursor |
GET /invoices | Vos factures, par pages de 20. Réservé aux clés d’un administrateur de l’organisation. | status, year, cursor |
GET /sites | Vos biens (adresses) et les installations qui s’y trouvent, par pages de 20. | cursor |
GET /catalog | Ce que vous pouvez commander, comme l’espace client vous le montre : services, options, vos prix. Sert à composer les lignes (lines) de POST /orders. | — |
GET /openapi.json | La description OpenAPI de l’API. Sans clé. | — |
Droits d’une clé
Une clé lit toujours. Elle n’écrit que pour les droits demandés à la création de la clé (ou plus tard, avec « Changer les droits ») ET accordés par Atlas, un par un. Une clé d’avant octobre 2026 reste en lecture jusqu’à un nouvel accord. GET /me rend les droits de la clé (scopes) et ceux qui attendent Atlas (pendingScopes).
read- Lire : inspections, commandes, factures, biens. Toujours inclus.
documents:write- Déposer des documents (schémas et plans) sur une commande ou une inspection.
messages:write- Écrire sur le fil d’une commande ou d’une inspection.
orders:write- Chiffrer, commander, demander un devis, se rétracter d’une commande, demander un rappel.
quotes:sign- Signer et confirmer un devis. Un droit à part, accordé séparément par Atlas : il n’est pas compris dans orders:write.
appointments:write- Demander à déplacer ou annuler une visite planifiée.
complaints:write- Ouvrir une plainte et répondre dans son dossier.
payments- Obtenir le lien de paiement en ligne d’une facture — le seul geste de paiement de l’API : ni paiement par carte, ni paiement d’une commande.
sites:write- Ajouter ou archiver un bien.
organization:write- Inviter, changer le rôle ou retirer un membre ; statuer sur une demande d’adhésion ; adresse de facturation.
directory:write- Gérer vos fiches clients et entrepreneurs.
sharing:write- Donner ou retirer l’accès d’un entrepreneur à vos commandes.
Écrire : les règles
Chaque écriture est un geste de l’espace client, jugé PAR l’espace client avec les droits de la personne qui a demandé la clé : mêmes contrôles, mêmes prix, mêmes règles de créneau, mêmes e-mails. Ce que l’espace client refuse à cette personne, l’API le refuse aussi, avec le même motif (error.code).
Les fichiers sont envoyés en JSON : { "name", "mimeType", "dataBase64" }, 5 au plus par requête, PDF jusqu’à 15 Mo, image jusqu’à 5 Mo, 30 Mo au total. Le type est vérifié sur le contenu du fichier : un fichier qui n’est pas ce qu’il annonce est refusé (attachment_type).
Une réussite rend { "data": { … } } (201 pour une création) ; data reprend ce que l’espace client répond pour ce geste.
Les écritures ont leur propre quota du jour : 600 écritures par clé et par jour (rendu par GET /me), en plus des limites générales.
Ne passent pas par l’API pour l’instant : le partage du lien d’un rapport, l’envoi de photos de remise en conformité, la signature groupée de devis et l’export de vos données personnelles (RGPD). Faites-les dans l’espace client.
La rétractation d’une commande suit exactement la règle de l’espace client : l’API la permet quand l’espace client la permet.
| Route | Ce qu’elle fait | Droit |
|---|---|---|
POST /orders/{id}/documents | Déposer des schémas et plans sur une commande (annexDocType : unifilaire, position ou other ; taskRefs pour viser des visites). | documents:write |
POST /inspections/{ref}/documents | Déposer des schémas et plans sur une inspection. | documents:write |
POST /orders/{id}/messages | Écrire sur le fil d’une commande (photos et PDF permis). | messages:write |
POST /inspections/{ref}/messages | Écrire sur le fil d’une inspection. | messages:write |
POST /orders/{id}/complaints | Ouvrir une plainte sur une commande (dossier PL-…, accusé de réception par e-mail). | complaints:write |
POST /inspections/{ref}/complaints | Ouvrir une plainte sur une inspection. | complaints:write |
POST /complaints/{reference}/messages | Répondre dans un dossier de plainte. | complaints:write |
POST /orders/pricing | Chiffrer un panier, comme l’espace client (n’écrit rien). | orders:write |
POST /orders/slots | Proposer des créneaux de visite (n’écrit rien) : un slotToken à passer à POST /orders. | orders:write |
POST /orders | Commander : mêmes prix, mêmes créneaux, même confirmation par e-mail que l’espace client. | orders:write |
POST /quotes | Demander un devis (Atlas le chiffre ; rien n’est commandé). | orders:write |
POST /quotes/{reference}/cancel | Annuler une demande de devis. | orders:write |
POST /orders/{id}/sign | Signer et confirmer un devis. | quotes:sign |
POST /orders/{id}/withdrawal | Se rétracter d’une commande, quand l’espace client le permet. | orders:write |
POST /requests | Demander à être recontacté pour un service. | orders:write |
POST /inspections/{ref}/visit-change | Demander à déplacer (reschedule) ou annuler (cancel) une visite. | appointments:write |
POST /invoices/{id}/payment-link | Le lien de paiement en ligne d’une facture (administrateurs). | payments |
POST /sites | Ajouter un bien (adresse vérifiée au registre bpost). | sites:write |
POST /sites/archive | Archiver un bien sans historique. | sites:write |
POST /organization/invitations | Inviter une personne (elle reçoit l’e-mail d’invitation). | organization:write |
POST /organization/invitations/revoke | Retirer une invitation en attente. | organization:write |
POST /organization/members/role | Changer le rôle d’un membre. | organization:write |
POST /organization/members/remove | Retirer un membre. | organization:write |
POST /organization/join-requests/decide | Accepter ou refuser une demande d’adhésion. | organization:write |
POST /organization/billing | Adresse e-mail de facturation. | organization:write |
POST /clients, /clients/update, /clients/archive | Vos fiches clients. | directory:write |
POST /contractors, /contractors/update, /contractors/archive, /contractors/merge | Vos fiches entrepreneurs. | directory:write |
POST /contractor-links, /contractor-links/{id}/revoke, /contractor-links/{id}/grants/{grantId}/revoke | Donner ou retirer l’accès d’un entrepreneur à vos commandes. | sharing:write |
Idempotency-Key : jamais deux fois le même geste
Chaque écriture porte un en-tête Idempotency-Key unique (8 à 255 caractères, par exemple un UUID). Sans lui : 400 idempotency_key_required.
Si la réponse se perd (coupure, délai dépassé), renvoyez la MÊME requête avec la MÊME clé : l’API rejoue la première réponse (en-tête Idempotent-Replayed: true) au lieu de refaire le geste — une commande n’est jamais passée deux fois. La clé est gardée 24 heures.
La même clé pour une requête différente est refusée (422 idempotency_key_reused). Après un 429 ou une erreur 5xx, rien n’est gardé : réessayez avec la même clé.
POST /orders/pricing et POST /orders/slots n’écrivent rien et n’en demandent pas.
Une inspection, champ par champ
ref, state, completion (status : done / cancelled / not-done ; doneIn), scheduledStart, scheduledEnd, type et subtype (fr / nl), title, address (fr / nl), inspectorName, order (id, reference, clientReference, paymentStatus), report (status, conclusion, issuedConclusion, held, pdf fr / nl, portalUrl), nextDueDate, updatedAt. report.status vaut platform, held, awaiting-payment, pending, unavailable, unverified ou null ; les liens report.pdf sont signés et s’ouvrent sans clé.
Un bien : key, address et installations (id, reference, type fr / nl, lastInspectionRef, lastInspectionAt, nextDueDate, conclusion).
Exemples
Vérifier la clé et lire vos limites :
curl -sS --compressed \
-H "Authorization: Bearer $ATLAS_API_KEY" \
https://api.astro.atlascontrole.be/api/client/v1/me Lire les inspections terminées depuis le 1er octobre, par pages de 100 :
curl -sS --compressed \
-H "Authorization: Bearer $ATLAS_API_KEY" \
"https://api.astro.atlascontrole.be/api/client/v1/inspections?status=done&from=2026-10-01&limit=100" Page suivante : reprendre la même requête avec le curseur rendu par la précédente.
curl -sS --compressed \
-H "Authorization: Bearer $ATLAS_API_KEY" \
"https://api.astro.atlascontrole.be/api/client/v1/inspections?status=done&from=2026-10-01&limit=100&cursor=<nextCursor>" Commander (un créneau proposé par POST /orders/slots) :
curl -sS --compressed -X POST \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"lines":[{"service":"<service>","qty":1}],"address":{"street":"Rue de la Loi 16","zip":"1000","city":"Bruxelles"},"phone":"+32 2 000 00 00","slotToken":"<slotToken>"}' \
https://api.astro.atlascontrole.be/api/client/v1/orders Déposer un schéma unifilaire sur une inspection :
{
"annexDocType": "unifilaire",
"attachments": [
{ "name": "unifilaire.pdf", "mimeType": "application/pdf", "dataBase64": "JVBERi0xLjcK…" }
]
} curl -sS --compressed -X POST \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d @document.json \
https://api.astro.atlascontrole.be/api/client/v1/inspections/DOM-2026-ABC123/documents Pagination par curseur
Les listes rendent { "data": [...], "nextCursor": "…" }. Tant que nextCursor n’est pas null, passez-le tel quel dans le paramètre cursor pour obtenir la page suivante.
Le curseur est opaque : ne le décodez pas, ne le construisez pas. limit va de 1 à 100 (50 par défaut) et ne vaut que pour /inspections et /orders : /invoices et /sites rendent des pages fixes de 20.
Pour une synchronisation incrémentale, conservez la date updatedAt la plus récente reçue et repartez de updated_since=<cette date> au passage suivant. Le filtre porte sur la date de mise à jour de l’enregistrement ; certains changements faits en arrière-plan ne la font pas avancer : prévoyez aussi une resynchronisation complète périodique (par exemple chaque semaine).
{
"data": [ { "ref": "…", "state": "done", "updatedAt": "2026-10-02T09:14:00.000Z", … } ],
"nextCursor": "eyJ1IjoiMjAyNi0xMC0wMlQwOToxNDowMC4wMDBaIn0"
} Filtres
- Inspections — status : todo, in_progress, ready, done, cancelled ; from et to : date planifiée, au format AAAA-MM-JJ ; updated_since : date ISO 8601.
- Commandes — status : quotation, order, cancelled.
- Factures — status : paid, unpaid ; year : AAAA.
- Un paramètre inconnu ou mal formé rend 400 invalid_parameter, avec le nom du paramètre dans le message.
Cache : ETag et If-None-Match
Chaque réponse porte un en-tête ETag. Renvoyez-le dans If-None-Match à l’appel suivant : si rien n’a changé, l’API répond 304 Not Modified, sans corps.
Les réponses de /orders, /invoices et /sites sont mises en cache jusqu’à 60 secondes par clé : un changement peut mettre une minute à apparaître.
Demandez la compression (Accept-Encoding: gzip, br) : les réponses sont compressées en transit.
curl -sS -i --compressed \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H 'If-None-Match: "<ETag>"' \
https://api.astro.atlascontrole.be/api/client/v1/sites Limites de débit et quota
Chaque clé a une limite par minute et un quota par jour (par défaut 60 requêtes par minute et 10 000 par jour ; vos valeurs exactes sont affichées plus haut et rendues par GET /me).
Au-delà, l’API répond 429 (rate_limited par minute, quota_exceeded par jour) avec un en-tête Retry-After, en secondes : attendez ce délai avant de réessayer.
Écritures : un quota du jour à part (par défaut 600 par clé), en plus de ces limites ; au-delà, 429 write_quota_exceeded.
X-RateLimit-Limit- Requêtes permises par minute.
X-RateLimit-Remaining- Requêtes restantes dans la minute en cours.
X-RateLimit-Reset- Secondes avant la fin de la fenêtre d’une minute.
X-RateLimit-Limit-Day- Requêtes permises par jour.
X-RateLimit-Remaining-Day- Requêtes restantes aujourd’hui.
X-RateLimit-Remaining-Write-Day- Écritures restantes aujourd’hui.
Erreurs
Une erreur rend toujours la même forme : { "error": { "code": "…", "message": "…" } }. Le code est stable ; le message est destiné à un humain et peut changer.
{ "error": { "code": "rate_limited", "message": "…" } } | Statut | Code | Signification |
|---|---|---|
| 400 | invalid_parameter | Paramètre inconnu ou mal formé. |
| 401 | unauthorized | Clé absente ou inconnue. |
| 401 | key_revoked | Clé révoquée. |
| 401 | key_expired | Clé expirée. |
| 401 | key_not_active | Clé pas encore active (en attente, ou pas encore révélée). |
| 403 | forbidden | Accès refusé à cette ressource. |
| 403 | browser_origin_refused | Appel parti d’un navigateur (en-tête Origin). |
| 403 | invoices_forbidden | Le titulaire de la clé n’est plus administrateur de l’organisation. |
| 404 | not_found | Ressource inexistante, ou hors de votre organisation. |
| 429 | rate_limited | Limite par minute atteinte (voir Retry-After). |
| 429 | quota_exceeded | Quota du jour atteint (voir Retry-After). |
| 400 | invalid_body | Corps de requête manquant ou mal formé. |
| 400 | idempotency_key_required | Écriture sans en-tête Idempotency-Key. |
| 400 | invalid_idempotency_key | Idempotency-Key mal formée (8 à 255 caractères). |
| 403 | insufficient_scope | La clé n’a pas reçu le droit nécessaire (voir error.details.required). |
| 409 | idempotency_in_progress | Une requête avec cette Idempotency-Key est encore en cours : réessayez dans quelques secondes. |
| 413 | payload_too_large | Requête trop volumineuse. |
| 422 | idempotency_key_reused | Cette Idempotency-Key a déjà servi pour une autre requête. |
| 429 | write_quota_exceeded | Quota d’écritures du jour atteint (voir Retry-After). |
| 500 | internal_error | Erreur inattendue de notre côté : réessayez plus tard. |
| 502 | upstream_unavailable | Source de données momentanément injoignable : réessayez plus tard. |
| 503 | disabled | API momentanément désactivée. |
Description OpenAPI
La description complète (schémas, paramètres, réponses) est publiée au format OpenAPI 3, lisible par la plupart des outils (Postman, Insomnia, générateurs de clients) :
Journal des versions
- v1 — 2026-10
- Première version, lecture seule.
- v1.1 — 2026-10
- Écritures : gestes de l’espace client par droit accordé, Idempotency-Key, quota d’écritures.