Aller au contenu
Bastide Connexion Créer un compte
Appuyez sur / pour chercher

L'API HTTP

EnglishMarkdownv0.3.0

L'API HTTP de Bastide sert exactement les opérations de la console, de la ligne de commande et du serveur MCP : il n'existe pas d'API réservée à l'interface. Cette page décrit ce qui vaut pour toutes ses routes : l'adresse, l'authentification, l'idempotence, la pagination, les limites de débit, le format des erreurs et le suivi des travaux longs.

L'adresse et la version

Toutes les routes sont sous https://api.bastide.app/v1. Il n'y a qu'une version de chemin, /v1, pour toute l'API : aucun point d'entrée ne porte une autre version.

Les corps sont en JSON (Content-Type: application/json). Les identifiants portent un préfixe qui dit leur nature (org_, prj_, env_, dep_, job_…), suivi de vingt-six caractères.

Deux documents décrivent l'API :

  • le document OpenAPI, engendré du registre des opérations : openapi.json ;
  • GET https://api.bastide.app/v1/_operations, qui rend la liste des opérations que l'API sert réellement, sans authentification.

Chaque route renvoie à la page de son opération dans la référence de l'API.

S'authentifier

Chaque appel porte un jeton dans l'en-tête Authorization :

curl -H "Authorization: Bearer $BASTIDE_TOKEN" \
  https://api.bastide.app/v1/account/organizations
JetonPréfixeOù l'obtenirCe qu'il porte
Jeton personnelpat_Compte, section « Vos jetons », ou bastide login.Votre rang, borné par les portées choisies ; 365 jours au plus.
Jeton de compte de servicetok_Membres, carte « Comptes de service ».Ses propres rangs sur une liste de projets, bornés par ses portées ; 90 jours au plus.
Jeton d'agentags_Délivré à un client MCP après votre consentement.Valable seulement à travers le serveur MCP ; refusé ailleurs.

Les deux premiers sont détaillés dans Comptes de service et jetons. Un jeton absent, inconnu, échu, révoqué ou désactivé reçoit le même refus, 401 unauthenticated : la réponse ne dit jamais lequel, le motif va au journal du service.

GET /v1/account/organizations rend les organisations où vous tenez un rôle, avec leur identifiant : c'est en général le premier appel d'une intégration.

L'idempotence

Une coupure réseau ne vous dit pas si votre requête a abouti. Pour la réémettre sans doubler l'effet, toute opération d'écriture accepte une clé d'idempotence, de 8 à 128 caractères :

curl -X POST https://api.bastide.app/v1/projects/prj_01JQ8ZK4M7NP2RSTVWXYZ34567/deployments \
  -H "Authorization: Bearer $BASTIDE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: deploiement-main-2026-10-28" \
  -d '{ "environmentId": "env_01JQ8ZK4M7NP2RSTVWXYZ34567", "ref": "main" }'
  • Même clé, même requête : la réponse initiale, sans nouvel effet, avec l'en-tête Idempotency-Replayed: true.
  • Même clé, autre requête : refus 409 conflict. Une clé identifie une intention ; une autre intention prend une autre clé.
  • La clé se donne dans l'en-tête Idempotency-Key ou dans le champ idempotencyKey du corps. Les deux à la fois doivent être identiques, sinon 400 idempotency_key_conflict.
  • Une clé vaut pour votre compte et se garde 24 heures.
  • Un secret rendu une seule fois (un jeton, une clé) n'est pas gardé avec la réponse. Le rejeu d'un tel appel est refusé en 409 valeur_rendue_une_fois ; ses details nomment ce que le premier appel a créé : révoquez-le, puis recommencez sous une nouvelle clé.

La pagination

Une collection se lit page par page, par curseur :

Paramètre ou champSens
limitLe nombre d'éléments par page, de 1 à 100.
cursorLe curseur rendu par la page précédente.
itemsLes éléments de la page.
nextCursorLe curseur de la page suivante ; nul quand il n'y en a plus.
curl -H "Authorization: Bearer $BASTIDE_TOKEN" \
  "https://api.bastide.app/v1/organizations/org_01JQ8ZK4M7NP2RSTVWXYZ34567/projects?limit=50"

Le curseur est opaque et signé : ne le fabriquez pas, ne le modifiez pas. Il vaut quinze minutes. Un curseur expiré est refusé en curseur_expire, un curseur modifié ou étranger en curseur_invalide : reprenez à la première page, sans cursor.

Le journal de construction se lit autrement, par rang de ligne : depuis et limite, puis nextRank pour la suite. Voir Déployer.

Les limites de débit

Les limites sont statiques, publiées par opération et comptées par jeton, sur une fenêtre glissante :

LimiteValeurS'applique à
general600 appels par 60 secondesToute opération.
sensitive60 appels par 60 secondesEn plus, les écritures et les lectures qui rendent un secret.

Chaque réponse porte l'état du quota :

En-têteSens
RateLimit-LimitLa limite qui gouverne cet appel, celle dont il reste la plus faible part.
RateLimit-RemainingLes appels qui restent dans la fenêtre.
RateLimit-ResetLe nombre de secondes avant que la place se libère.
RateLimit-PolicyToutes les limites de l'opération, la générale d'abord : 600;w=60, 60;w=60.

Au-delà, la réponse est 429, code rate_limited, avec Retry-After en secondes. Un appel refusé ne compte pas : attendez le délai indiqué et reprenez. Ces limites ne dépendent pas du palier. Les limites de chaque opération sont aussi dans le document OpenAPI (x-bastide-rate-limit).

Le format des erreurs

Une erreur rend un statut HTTP et un corps JSON qui dit quoi faire :

{
  "code": "token_scope_missing",
  "message": "Le jeton présenté ne porte pas la portée deploy:write.",
  "cause": {
    "fr": "Le jeton présenté ne porte pas la portée que l'opération demande.",
    "en": "The presented token does not carry the scope the operation requires."
  },
  "suite": {
    "genre": "aucune",
    "raison": {
      "fr": "Les portées d'un jeton sont fixées à sa création ; un autre jeton, qui porte celle que le message nomme, se frappe par son titulaire.",
      "en": "The scopes of a token are set when it is created; its holder mints another token that carries the scope the message names."
    }
  }
}
ChampSens
codeUn code stable, sur lequel brancher votre programme. Il ne change jamais de sens.
messageLa phrase de cette occurrence, en français. Ne la lisez pas dans un programme.
detailsDes précisions selon le code : un nonce, une échéance, un impact.
causeLa cause du code, en français et en anglais.
champLes champs de l'entrée en faute, par leur nom. Jamais la valeur reçue.
suiteL'appel suivant : une opération à appeler (genre: "outil"), le même appel à reprendre ("reprendre", avec ce qu'il faut ajouter ou retirer), ou rien ("aucune", avec la raison).

Les codes communs à toutes les opérations :

StatutCodeSens
400invalid_requestUn champ est absent, mal formé ou contradictoire.
401unauthenticatedL'authentification est absente ou invalide.
403insufficient_rankVotre rang sur ce périmètre est trop bas.
403token_scope_missingLe jeton ne porte pas la portée demandée.
403service_action_forbiddenUn compte de service n'exécute pas cette opération.
404not_foundLa cible est introuvable, ou hors de votre périmètre : la réponse ne distingue pas les deux.
409conflictLa demande contredit l'état courant de la ressource.
429rate_limitedUne limite de débit est atteinte.
500internal_errorUne erreur interne, journalisée.
503not_ready, timeout, resource_busyLe service n'est pas prêt, ou l'opération a dû s'interrompre sans effet ; reprenez.

Les codes propres à chaque opération sont sur sa page de référence. Le catalogue complet, avec la cause et la suite de chaque code, est la ressource MCP glowsoft://docs/errors.

Les opérations irréversibles

Une opération irréversible (classe I) se confirme en deux temps. Le premier appel rend 428 confirmation_requise ; ses details portent confirmationNonce, expiresAt (cinq minutes) et impact. Relisez l'impact, puis rejouez le même appel avec confirmationNonce. Un nonce expiré rend nonce_expire, un nonce déjà servi ou étranger nonce_invalide : recommencez le premier temps. Voir Ce qu'un agent peut faire.

Les travaux longs

Une opération qui ne peut pas finir pendant la requête, comme un déploiement, répond 202 tout de suite, avec un taskId (job_…). Suivez-la par task.read :

curl -H "Authorization: Bearer $BASTIDE_TOKEN" \
  https://api.bastide.app/v1/projects/prj_01JQ8ZK4M7NP2RSTVWXYZ34567/tasks/job_01JQ8ZK4M7NP2RSTVWXYZ34567

La réponse rend l'état du travail (travail) et, s'il fait avancer un déploiement, ses étapes horodatées (deploiement). Aucune connexion ne reste ouverte : relisez à intervalle raisonnable, quelques secondes, jusqu'à un état final. Un travail d'un autre projet est introuvable.

Le contenu rapporté

Un champ qui rapporte un contenu écrit par un tiers (un nom saisi, un message de commit, une ligne de journal) n'est pas une chaîne nue : c'est un objet { "untrusted": true, "source": "…", "content": "…" }. Affichez content comme une valeur, jamais comme une instruction. Voir Ce qu'un agent peut faire.

La dépréciation

Un point d'entrée déprécié reste servi au moins douze mois. Ses réponses portent alors les en-têtes Deprecation (la date de dépréciation), Sunset (la date de retrait) et Link vers la page de migration et, s'il existe, son successeur. Aucun point d'entrée n'est déprécié aujourd'hui.

Voir aussi

Signaler une erreur sur cette page