API REST
L'adresse, comment un script se connecte, comment l'organisation est choisie, à quoi ressemblent les erreurs, et des exemples complets avec curl.
Tout ce que font la console et la CLI, elles le font à travers une seule API
HTTP. La CLI est construite dessus et n'a pas de porte dérobée : tout ce que
isogrid peut faire, un script muni du même identifiant peut le faire avec
curl.
Cette page est un guide d'utilisation de cette API : l'adresse, la façon dont un script se connecte, et les appels dont la plupart des équipes ont besoin. Elle ne liste pas tous les points d'accès. S'il vous en faut un qui n'apparaît pas ici, la CLI couvre le même périmètre, et l'équipe vous donne l'appel exact sur demande.
L'adresse
Chaque appel part vers https://api.isogrid.skyvault.pro/api/v1.
Les exemples ci-dessous décrivent ce que l'API accepte aujourd'hui. Revérifiez-les après une mise à jour de la plateforme plutôt que de supposer qu'un champ est toujours là.
Se connecter depuis un script
Chaque appel porte un jeton :
Authorization: Bearer <token>
Pour un script, ce jeton est un identifiant CLI : un jeton de longue durée
qui commence par skv_, créé par vous, en votre nom, pour une seule
organisation. Vous le créez avec la CLI et vous l'approuvez dans le navigateur.
Aucun formulaire de la console ne délivre de jeton sans cette approbation.
export ISOGRID_CONFIG_HOME="$(mktemp -d)"
isogrid --api https://api.isogrid.skyvault.pro login --name my-script
jq -r '.contexts[].token' "$ISOGRID_CONFIG_HOME/config.json"
rm -rf "$ISOGRID_CONFIG_HOME"
Le ISOGRID_CONFIG_HOME temporaire laisse intacte la connexion de votre propre
machine. Installer la CLI explique comment obtenir isogrid.
Ce qu'il faut savoir sur l'identifiant :
- Il est rattaché à l'organisation affichée sur la page d'approbation. Vérifiez-la avant d'approuver.
- Il ne dépasse jamais ce que vous détenez. Ses permissions sont croisées avec votre propre rôle et vos groupes à chaque requête : réduire vos droits réduit aussi ceux du script.
- Restreignez-le. Ajoutez
--scopeavec seulement ce dont le script a besoin, par exemple--scope application:create,application:write-any. Sans--scope, la page d'approbation propose ce qui convient à votre rôle et vous décochez le reste. Voir Déployer depuis la CI/CD pour les portées nécessaires à un déploiement. - Il dure 90 jours, sauf si vous avez choisi une durée plus courte sur la page d'approbation.
- Certaines choses lui sont interdites, quoi qu'il demande : la facturation, la nomination d'administrateurs, et la création ou la révocation d'identifiants. Elles exigent que vous soyez connecté à la console.
- Révoquez-le depuis la page CLI de la console quand le script est retiré ou que le jeton a pu fuiter.
Les exemples ci-dessous supposent :
export ISOGRID_API=https://api.isogrid.skyvault.pro/api/v1
export ISOGRID_TOKEN=skv_...
Gardez le jeton hors de l'historique de votre shell et hors de votre dépôt, comme vous le feriez pour un mot de passe.
Choisir l'organisation
Une personne peut appartenir à plusieurs organisations : tout ce qui appartient à l'une d'elles doit donc savoir laquelle. Vous l'indiquez par un en-tête, avec le slug de l'organisation ou son id :
X-Organization: acme
La même valeur est acceptée en paramètre de requête, ?organization=acme, pour
les cas où un en-tête est peu pratique.
Avec un identifiant CLI, vous pouvez l'omettre : l'identifiant appartient déjà à
une organisation et chaque appel agit dans celle-ci. En nommer une autre est
refusé avec 403, et l'erreur indique à quelle organisation l'identifiant est
rattaché.
À quoi ressemble une erreur
Chaque refus a la même forme, quelle que soit la cause :
{
"error": {
"code": "permission_denied",
"message": "Your role in Acme (developer) does not allow this",
"details": {
"required_permission": "application:create",
"role": "developer",
"organization": "acme"
}
}
}
message est rédigé pour être montré à une personne. code est ce sur quoi un
script doit se baser. details varie selon l'erreur et peut être vide.
| Statut | code |
Signification |
|---|---|---|
401 |
unauthenticated |
Pas de jeton, ou un jeton inconnu, expiré ou révoqué. |
402 |
insufficient_credits |
L'organisation ne peut pas payer ce qui est demandé. details indique combien il fallait. |
403 |
permission_denied |
Vous, ou cet identifiant, n'avez pas le droit de faire cela. |
404 |
not_found |
La ressource n'existe pas, ou vous n'avez pas le droit de la voir. |
409 |
conflict |
La demande heurte l'existant : un nom déjà pris, ou un produit qui n'a pas encore de prix dans cette région. |
422 |
validation_error |
La requête est mal formée. details.fields nomme chaque champ et ce qui ne va pas. |
503 |
no_capacity |
La plateforme ne peut pas héberger cela pour le moment. La requête n'était pas fausse ; réessayez plus tard. |
Avec curl, utilisez -f (ou --fail-with-body, pour garder le message) afin
qu'un refus fasse échouer votre script au lieu d'être transmis à la commande
suivante.
Listes et pages
Les listes principales (applications, bases de données, instances de bases de données, réseaux, régions, images) renvoient une page à la fois :
{ "items": [ ... ], "total": 37, "limit": 50, "offset": 0 }
limit vaut 50 par défaut et 200 au maximum. offset est le point de départ de
la page. Pour tout lire, ajoutez limit à offset jusqu'à atteindre total.
Toutes les listes ne sont pas paginées ainsi. Quelques listes courtes (les constructions d'une application, les types d'instance d'une région) renvoient un simple tableau. Les exemples ci-dessous montrent la forme de chacune.
Ce qui prend du temps
Créer quelque chose rend la main avant que cela ne fonctionne. La réponse vous
dit que la ressource existe et vous donne son id ; vous lisez ensuite son état
jusqu'à ce qu'il se stabilise.
| Vous avez demandé | L'appel répond | Lisez ensuite | Jusqu'à ce que |
|---|---|---|---|
| Une application | 201, avec l'application |
GET /applications/{id}/status |
deployment_status vaille running, ou failed |
| Une construction | 202, avec un build_id |
GET /applications/{id}/builds/{build_id} |
status vaille succeeded, ou l'un de failed, no_dockerfile, restricted, cancelled |
| Un redéploiement | 202 |
GET /applications/{id}/status |
comme pour une application |
| Une base de données | 202, avec la base |
GET /databases/{id} |
status vaille ready, ou failed |
Le deployment_status d'une application vaut none, queued, deploying,
starting, running, degraded, stopped ou failed. degraded signifie
qu'elle fonctionne, mais pas entièrement : moins de copies en marche que
demandé, ou des copies qui redémarrent sans cesse. Le message qui l'accompagne
dit pourquoi, en toutes lettres.
Interrogez toutes les quelques secondes, pas en boucle serrée. La sortie d'une
construction se lit de la même façon :
GET /applications/{id}/builds/{build_id}/logs?after=0 renvoie les lignes
écrites jusque-là et un last_id ; passez-le dans after pour n'obtenir que ce
qui est nouveau.
Exemples complets
Qui suis-je, et où puis-je déployer
curl -fsS "$ISOGRID_API/me" -H "Authorization: Bearer $ISOGRID_TOKEN"
renvoie votre compte et les organisations auxquelles vous appartenez. Les régions qui vous sont ouvertes, et les types d'instance qu'une région propose avec leurs prix :
curl -fsS "$ISOGRID_API/clusters" -H "Authorization: Bearer $ISOGRID_TOKEN" \
| jq '.items[] | {id, slug, name}'
curl -fsS "$ISOGRID_API/pricing/applications/$CLUSTER_ID" \
-H "Authorization: Bearer $ISOGRID_TOKEN" \
| jq '.[] | {id, name, vcpu, memory_mb, prices}'
Dans l'API, une région est un cluster et un type d'instance est un
resource_tier.
Lister vos applications
curl -fsS "$ISOGRID_API/applications?limit=20" \
-H "Authorization: Bearer $ISOGRID_TOKEN" \
| jq '.items[] | {id, slug, deployment_status, public_url}'
Créer une application à partir d'une image
curl -fsS -X POST "$ISOGRID_API/applications" \
-H "Authorization: Bearer $ISOGRID_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "hello",
"source": "registry",
"external_image": "nginx:1.27",
"port": 80,
"is_public": true
}'
La réponse est l'application, avec son id, son slug, et l'adresse à laquelle
elle répondra dans public_url. Son premier déploiement est déjà en file
d'attente.
Ce que signifient les champs, et ce qui se passe quand vous en omettez un :
| Champ | Signification | S'il est omis |
|---|---|---|
name |
Obligatoire. | |
source |
registry pour une image ; github ou gitlab pour construire depuis un dépôt. |
github |
external_image |
Une image de n'importe quel registre, en entier : nginx:1.27, ghcr.io/acme/web:main. |
|
external_registry_id |
Le registre enregistré dont les identifiants servent à la tirer. | L'image doit être publique. |
cluster_id |
La région. | La région du réseau que vous avez nommé, sinon la région par défaut de la plateforme. |
resource_tier_id |
Le type d'instance. | Le plus petit que la région propose. |
network_id |
Le réseau privé sur lequel elle tourne. | Le réseau de votre organisation dans cette région. |
port |
Le port sur lequel le conteneur écoute. | 8080 pour une image. |
replicas |
Nombre de copies, de 1 à 10. | 1 |
environment |
Paramètres non secrets, sous forme d'objet de chaînes. | Aucun. |
is_public |
Si elle est joignable depuis Internet. | false |
Une image du registre de votre organisation se désigne plutôt par image_id
(GET /images les liste). Pour construire depuis un dépôt, envoyez
repository_full_name (acme/api) et, si ce n'est pas main,
default_branch ; le dépôt doit déjà être connecté à votre organisation, comme
décrit dans Dépôts Git.
Les secrets ne vont pas dans environment. Envoyez-les dans secrets ; ils
sont conservés à part et ne sont jamais renvoyés par aucun appel.
Lire son état
curl -fsS "$ISOGRID_API/applications/$APP_ID/status" \
-H "Authorization: Bearer $ISOGRID_TOKEN"
{
"application_id": "5b0c...",
"deployment_status": "running",
"desired": 1,
"running": 1,
"message": null,
"checked_at": "2026-10-07T09:12:44Z",
"listens": true,
"tasks": [ ... ]
}
desired est le nombre de copies demandées et running le nombre de copies en
marche maintenant. Pour attendre dans un script :
while :; do
STATUS=$(curl -fsS "$ISOGRID_API/applications/$APP_ID/status" \
-H "Authorization: Bearer $ISOGRID_TOKEN" | jq -r '.deployment_status')
echo "$STATUS"
case "$STATUS" in running|degraded|stopped|failed) break ;; esac
sleep 5
done
Déployer de nouveau
Pour une application qui exécute une image, redéployez-la :
curl -fsS -X POST "$ISOGRID_API/applications/$APP_ID/deploy" \
-H "Authorization: Bearer $ISOGRID_TOKEN"
Pour une application construite depuis un dépôt, lancez la construction d'une branche, d'un tag ou d'un commit ; elle est déployée quand la construction réussit :
curl -fsS -X POST "$ISOGRID_API/applications/$APP_ID/builds" \
-H "Authorization: Bearer $ISOGRID_TOKEN" \
-H "Content-Type: application/json" \
-d '{"git_ref": "main"}'
Lister vos bases de données
curl -fsS "$ISOGRID_API/databases" -H "Authorization: Bearer $ISOGRID_TOKEN" \
| jq '.items[] | {id, name, engine, status}'
Ce sont les bases de données créées sur un serveur partagé. Vos propres serveurs
de bases de données forment une liste distincte, GET /database-instances. Le
status d'une base vaut pending, creating, importing, ready, failed
ou deleting.
Les informations de connexion, mot de passe compris, font l'objet d'un appel
distinct (GET /databases/{id}/connection) avec une permission distincte :
pouvoir constater qu'une base existe n'est pas la même chose que recevoir ses
identifiants.
Cas particuliers à connaître avant d'y être confronté
Un 401 sur un jeton qui fonctionnait hier. Il a expiré ou a été révoqué.
Créez-en un nouveau ; rien d'autre ne change. La réponse est volontairement la
même pour un jeton inconnu, expiré ou révoqué.
Un 403 qui nomme une autre organisation. Vous avez envoyé X-Organization
pour une organisation à laquelle l'identifiant n'est pas rattaché. Retirez
l'en-tête, ou créez un identifiant pendant que la console affiche l'organisation
voulue.
Un 409 à la création qui parle d'un prix. Ce produit n'a pas encore de
prix dans cette région : il n'y est donc pas en vente. Choisissez une autre
région ou posez la question. Voir Prix et facturation.
Un 402 sur is_public. Votre organisation doit une somme pour une
utilisation antérieure, et la publication est suspendue tant qu'elle n'est pas
réglée. Créez l'application en privé, ou rechargez votre crédit.
L'appel de création a réussi et l'application a échoué. L'appel promettait
seulement que l'application existe. Lisez /status, puis le journal de
construction ou de déploiement. Quand ça ne va pas
passe en revue les causes habituelles.
Les montants sont en nanos. Les montants terminés par _nanos sont des
milliardièmes de l'unité monétaire : 1500000000 vaut 1,5. L'objet prices
placé à côté porte le même chiffre, déjà mis en forme pour l'affichage.
Pour continuer
- Référence des commandes pour les mêmes opérations depuis la CLI.
- Déployer depuis la CI/CD pour un pipeline qui ne demande aucun code d'API.
- Rôles, groupes de permissions et accès pour ce qu'un identifiant peut se voir accorder.
- Prix et facturation.