API & intégration
API publique
Mis à jour le 4 septembre 2026Plateforme v1 Markdown brut
Base et authentification
L’API publique est servie sur le domaine principal de l’application :
https://capibara.fr/api/public/v1/…
Un seul mécanisme d’authentification, trois porteurs possibles dans l’en-tête
Authorization :
Authorization: Bearer <clé API ck_live_… OU jeton d'accès OAuth>
- Clé API (
ck_live_…) — générée depuis/dev/keys, section « Clés
API ». C’est le chemin le plus simple pour une app hybride : la clé ne
change pas tant que vous ne la révoquez pas. - Jeton d’accès OAuth — obtenu via l’un des deux grants décrits dans
Sign in with Capibara (OAuth). Valable 1 heure ; à
renouveler en refaisant le flux (il n’y a pas derefresh_tokenà ce
stade). - Clé de projet (
cpk_…) — générée sur la page d’une app (section
Code, carte « Clé de projet & CLI »), bornée à CE projet : elle n’ouvre
que l’API de projet ci-dessous (celle de la
CLI), jamais/meni les façades.
Aucune requête n’aboutit sans l’un des trois : une absence ou une valeur
invalide renvoie 401 avec un en-tête WWW-Authenticate: Bearer.
GET /api/public/v1/me
L’endpoint de test d’authentification et d’identité (clé API ou jeton
OAuth) :
GET https://capibara.fr/api/public/v1/me
Authorization: Bearer ck_live_VOTRE_CLE
Réponse (200) :
{
"developer": {
"slug": "studio-forge",
"displayName": "Studio Forge",
"partner": false
},
"scopes": ["crm:read", "shop:read"],
"auth": "api_key"
}
auth vaut "api_key" ou "oauth" selon le porteur utilisé — utile pour
distinguer vos deux modes d’intégration dans vos propres journaux. scopes
reflète exactement ceux de la clé (ou du jeton) utilisé, pas l’ensemble des
scopes possibles.
Cet endpoint ne coûte pas de quota différent des autres : il compte comme
n’importe quel appel dans la limite ci-dessous. Utilisez-le pour vérifier
qu’une intégration est bien configurée avant de construire dessus, pas en
polling répété.
Scopes disponibles
Les scopes d’une clé API (ou d’un client OAuth) sont des familles de
module : ils disent ce que la CLÉ du développeur peut toucher. Pour agir sur
une organisation, il faut en plus qu’une installation de votre app y ait
accordé le scope feuille correspondant.
| Scope de clé | Couvre |
|---|---|
crm:read / crm:write |
Façades du CRM (contacts, sociétés, opportunités, activités). |
billing:read / billing:write |
Façades de la facturation (devis, factures, avoirs). |
shop:read / shop:write |
Façades de la boutique (produits, commandes). |
projects:read / projects:write |
Façades des projets (projets, tâches, temps). |
planning:read / planning:write |
Façades du planning (ressources, réservations). |
site:read |
Membres du site. |
formation:read |
Catalogue et sessions de formation. |
media:read |
Réservé (médiathèque, à venir). |
GET /api/public/v1/embed-context (mode hybride)
Une page montée par embedUrl (entrée de menu ou widget embed) reçoit
?capibara_token=<jwt> dans son URL. Votre backend l’échange ici — avec
SA clé API ou son jeton OAuth — contre le contexte de la visite :
GET https://capibara.fr/api/public/v1/embed-context?token=<jwt>
Authorization: Bearer ck_live_VOTRE_CLE
{
"addonKey": "sync-compta-externe",
"tenant": { "id": "cm9x…", "slug": "mon-organisation" },
"userAccountId": "acc_…",
"grantedPermissions": ["billing-fr.documents:read"],
"installId": "inst_…",
"expiresAt": "2026-09-04T10:05:00.000Z"
}
Le jeton vaut 5 minutes, n’est résolu que par le développeur de l’app
visée (403 forbidden sinon), et ne contient jamais l’e-mail de la
personne. installId est la valeur à passer ensuite dans
X-Capibara-Install. Erreurs propres : missing_token et
invalid_token (400).
Façades par installation
POST /api/public/v1/<module>/<entité>/<op> avec X-Capibara-Install: <installId> exécute une façade au nom du compte de
service de votre app dans cette organisation — lectures en GET possibles,
écritures idempotentes par Idempotency-Key, 120 appels / minute par
installation (en plus du quota de la clé). GET /api/public/v1/facades
renvoie le catalogue complet (schémas d’entrée et de sortie) ; les codes
d’erreur sont sur la page des façades. Le SDK expose la
même chose via client.install(installId).
L’API de projet (clé de projet)
/api/public/v1/project/… est l’API que la CLI utilise —
et que vous pouvez appeler directement. Elle s’authentifie par une clé de
projet cpk_… (Authorization: Bearer cpk_…) et n’agit que sur le
projet qui l’a émise. Les installations de test qu’elle pose ne visent qu’une
organisation dont le créateur de la clé est propriétaire. Chaque réponse est
enveloppée : { "ok": true, "result": … } ou { "ok": false, "error": "<code>", "message": "…", …détails }.
| Méthode et chemin | Rôle |
|---|---|
GET /project |
État du projet : versions (canal, bundle), fiche, installations de test, organisations cibles, runtime. |
GET /project/scopes |
Scopes de la dernière version avec leur phrase de consentement + ce que chaque organisation de test a accordé. |
GET /project/logs?org=&installId=&after=&limit= |
Journal des exécutions sur les installations de test (curseur after = dernier id reçu). |
GET /project/runtime?route=<clé>[@<versionId>]&hash=<sha256> |
L’isolate de cette route est-il monté, et avec quel bundle ? Renvoie state (nommé) + message + expectedHash/mountedHash — ce sur quoi capibara dev attend et que capibara status affiche. |
POST /project/dev { manifest, files, org? } |
Valide le manifeste, scanne et bundle les sources, enregistre le brouillon et pose/actualise l’installation de test (deploy-on-save). |
POST /project/deploy { manifest, files } |
Même construction, puis la version part en review (build automatisé). |
POST /project/publish { semver? } |
Publie une version APPROVED (la dernière approuvée sans semver). |
POST /project/install { org?, semver? } · POST /project/uninstall { org? } |
Pose ou retire une installation de test (retirer purge ses données). |
POST /project/kit-check { doc, surface? } |
Valide un document (ou un nœud) du Kit avec le validateur réel. |
manifest est le texte brut de add-on.json ; files un objet
{ "src/index.ts": "…" } (80 fichiers, 1,5 Mo au total, 512 Ko par
fichier, corps ≤ 3 Mo). Codes d’erreur propres à cette API :
version_locked (409 : la version du manifeste est en review, approuvée
ou publiée — incrémentez version), invalid_manifest (400, avec
issues[]), key_mismatch / author_mismatch / main_missing (400),
invalid_sources et forbidden_pattern (400, avec findings[] du
scan), bundle_failed (400), no_test_org (412, avec targets[]),
org_required / org_not_found, no_version / not_approved (412),
version_not_found (404), invalid_route (400), invalid_json (400),
payload_too_large (413), unauthorized (401), rate_limited (429).
Quota dédié : 240 appels par minute et 60 déploiements par minute
par clé de projet.
Quotas
120 requêtes par minute, par identifiant authentifié — pas par adresse
IP. L’identifiant est votre clé API (ou votre compte développeur, si vous
appelez via OAuth) : plusieurs backends utilisant la même clé partagent le
même quota, et à l’inverse, une même IP appelant pour plusieurs devs ne les
fait pas se gêner entre eux.
Au-delà du quota :
HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json
{ "error": "rate_limited" }
Attendez le délai indiqué par Retry-After (en secondes) avant de
réessayer — un retry immédiat en boucle prolonge votre propre exclusion sans
bénéfice.
Conventions d’erreur
Deux formes, selon la famille d’endpoints — le champ error est la valeur
stable dans les deux cas, le message peut évoluer :
/meet/embed-context:{ "error": "<code>" }.- Les façades et l’API de projet : une enveloppe
{ "ok": false, "error": "<code>", "message": "…" }(+issues,
findings,targets… selon le cas), et{ "ok": true, "result": … }
en succès.
Codes communs :
| HTTP | error |
Sens |
|---|---|---|
| 401 | unauthorized |
en-tête Authorization absent, mal formé, ou clé/jeton invalide (WWW-Authenticate: Bearer). |
| 403 | forbidden / key_scope_missing |
authentification valide mais scope insuffisant, ou ressource d’un autre développeur. |
| 404 | not_found / unknown_facade / install_not_found |
ressource absente ou hors de portée du compte authentifié. |
| 429 | rate_limited |
quota dépassé (voir ci-dessus), Retry-After fourni. |
Les codes propres aux façades (scope_not_granted, consent_outdated,
killed…) sont listés sur Les façades ; ceux de l’API
de projet ci-dessus.
Et pour le reste de la plateforme ?
Si votre app a besoin d’une ressource qui n’est pas encore exposée
publiquement, décrivez le besoin depuis /dev/support — la priorité des
prochains endpoints suit les demandes réelles des développeurs du portail,
et sera documentée ici au fur et à mesure de sa sortie.