Référence de l’API
Toute l’API REST de Spunto — chaque endpoint, ses corps de requête et ses schémas de réponse.
L’API Spunto est une API REST. Tous les endpoints demandent un token Bearer (sauf les routes publiques d’authentification).
La référence interactive complète de l’API se trouve à :
https://spunto.net/api/docsElle est générée automatiquement à partir du spec OpenAPI 3.1 — toujours à jour.
Toutes les requêtes à l’API (sauf /api/auth/*) demandent :
Authorization: Bearer <token>Deux sortes de tokens sont acceptées :
- Token de session — émis quand vous vous connectez avec Google. Le parcours d’authentification pose le même token dans un cookie httpOnly
session— les requêtes du navigateur l’envoient automatiquement. Accès complet (pas de scopes). - Clé d’API (
spk_...) — un token à scopes, révocable, généré depuis le dashboard pour un accès sans navigateur (scripts, CI, agents IA). Voir la page Clés d’API pour en créer et en utiliser une.
https://spunto.netTous les endpoints commencent par /api/.
PATCH est partiel : le corps d’une requête ne touche que les champs qu’il nomme, et tout ce qu’il
omet reste tel quel. Renommer un projet, c’est {"name": "..."} — ses dépôts, ses features et ses
extensions restent où ils étaient.
Vider quelque chose doit donc se dire explicitement :
- une liste se vide en l’envoyant explicitement vide —
{"forwardPorts": []} - un champ de texte libre se vide en envoyant
""—{"description": ""}enregistrenull(des espaces comptent comme vide). Omettre la clé garde l’ancienne valeur ; cela ne veut jamais dire « effacer ».
Les secrets partagés d’un projet passent dans le même corps, et sont partiels de la même façon — une liste de changements, pas l’état final voulu :
PATCH /api/orgs/:orgId/projects/:projectId
{
"secrets": [
{ "name": "API_TOKEN", "value": "sk-..." }, // write (creates or replaces, by name)
{ "name": "OLD_TOKEN", "value": null } // remove
]
}Un nom que vous ne mentionnez pas garde ce qu’il avait. Les valeurs sont en écriture seule : aucun endpoint ne les
renvoie jamais. Les écrire est réservé aux owners/admins, et une clé d’API a besoin du scope secrets:write en plus
de projects:write — les mêmes garde-fous que les routes dédiées
/secrets, qui restent disponibles pour un changement ponctuel.
GET /api/orgs List organizations
POST /api/orgs Create organization
GET /api/orgs/:orgId Get organization details
GET /api/orgs/:orgId/members List membersGET /api/orgs/:orgId/projects List projects
POST /api/orgs/:orgId/projects Create project
GET /api/orgs/:orgId/projects/:projectId Get project
PATCH /api/orgs/:orgId/projects/:projectId Update project
DELETE /api/orgs/:orgId/projects/:projectId Delete projectGET /api/orgs/:orgId/sandboxes List sandboxes (?projectId=)
POST /api/orgs/:orgId/sandboxes Create a sandbox { projectId, appId: "spunto-cloud", branch?, size?, fromSnapshot? }
GET /api/orgs/:orgId/sandboxes/:sandboxId Get a sandbox
POST /api/orgs/:orgId/sandboxes/:sandboxId/start Start a stopped or paused sandbox
POST /api/orgs/:orgId/sandboxes/:sandboxId/stop Stop it (/workspace kept)
POST /api/orgs/:orgId/sandboxes/:sandboxId/pause Pause it (memory kept, not billed)
POST /api/orgs/:orgId/sandboxes/:sandboxId/rebuild Rebuild at the project's current version
POST /api/orgs/:orgId/sandboxes/:sandboxId/exec Run a command
GET /api/orgs/:orgId/sandboxes/:sandboxId/ports The IDE's URL and listening ports
POST /api/orgs/:orgId/sandboxes/:sandboxId/snapshots Snapshot it
DELETE /api/orgs/:orgId/sandboxes/:sandboxId Destroy it and its storagePOST /api/orgs/:orgId/projects/:projectId/tasks Delegate a task { prompt, ... }
GET /api/orgs/:orgId/tasks Every task of the organization
GET /api/orgs/:orgId/projects/:projectId/tasks/:taskId Get a taskToutes les routes des tâches : Tâches avancées.
GET /api/orgs/:orgId/api-keys List keys
POST /api/orgs/:orgId/api-keys Create a key (token shown once)
DELETE /api/orgs/:orgId/api-keys/:keyId Revoke a keySession uniquement — une clé d’API ne peut pas servir à gérer d’autres clés d’API. Voir Clés d’API.
GET /api/users/me Get current user (dotfilesRepo)
PATCH /api/users/me Update user settings
GET /api/users/me/secrets List secret names
POST /api/users/me/secrets Create / replace secret
DELETE /api/users/me/secrets/:secretId Delete secretTout ce qui est en direct passe par un upgrade WebSocket plutôt que par un appel REST. Ces endpoints figurent dans le spec OpenAPI comme le reste de l’API — repérez (WebSocket) dans leur résumé ; chacun documente ses paramètres de requête et la forme exacte des frames qu’il échange.
| Endpoint | Description |
|---|---|
GET /api/sandboxes/:id/terminal?mode=terminal | S’attacher à une session de terminal persistante dans une sandbox |
GET /api/sandboxes/:id/terminal?mode=logs | Suivre les logs de la sandbox |
GET /api/sandbox-builds/:id/logs | Le log du build d’un projet, avec ses étapes |
GET /api/sandboxes/:id/prepare/logs | Le log de setup d’une sandbox |
Le handshake s’authentifie exactement comme un appel REST — Authorization: Bearer <token>, avec un token de
session, ou une clé d’API qui a le scope workers:exec pour le terminal d’une sandbox. Un navigateur ne peut pas
poser d’en-têtes sur un WebSocket : depuis le navigateur, c’est le cookie session qui sert.
Le terminal d’une sandbox est persistant : le programme continue de tourner quand vous vous déconnectez, et vous retrouvez en vous rattachant son historique de défilement — c’est ce qui le rend utilisable depuis un téléphone.
GET /api/orgs/:orgId/sandboxes/:sandboxId/terminals List sessions
POST /api/orgs/:orgId/sandboxes/:sandboxId/terminals Create a session
DELETE /api/orgs/:orgId/sandboxes/:sandboxId/terminals/:name Kill a sessionListez les sessions, puis attachez-vous à l’une d’elles par son nom. Fermer le socket détache la session ; cela ne la tue pas.
const ws = new WebSocket(`wss://spunto.net/api/sandboxes/${sandboxId}/terminal?session=main`)
ws.onmessage = (e) => {
const frame = JSON.parse(e.data)
// "ready" once attached, then "output" frames — base64-encoded raw bytes.
if (frame.type === "output") term.write(atob(frame.data))
}
ws.send(JSON.stringify({ type: "input", data: btoa("ls -la\n") }))
ws.send(JSON.stringify({ type: "resize", cols: 80, rows: 24 }))Ils ne font pas partie de la surface de l’API — ils s’authentifient avec des tokens d’infrastructure, pas avec les vôtres.
| Endpoint | Description |
|---|---|
GET /api/sandbox-agent/connect | L’agent dans une sandbox (token de la sandbox) |
GET /api/tunnel/relay | Relais proxy ↔ agent |