API and tokens
The dashboard and the CLI both talk to the same HTTP API at https://vinssi.ai. You can call it directly with a personal API token. The API is stable enough to script against but is not versioned yet; breaking changes will be announced in the changelog before they ship.
Tokens
Tokens are tied to your user account and act with your permissions in your workspace.
Create one from the CLI:
vinssi tokens create "deploy script" --expires-in 30
Or from the dashboard under Settings. The full token is shown exactly once. It looks like vinssi_<prefix>_<secret>; only the prefix is stored in readable form, so it cannot be recovered later.
- Expiry is optional and at most 365 days. Tokens created by
vinssi logindo not expire. - List and revoke with
vinssi tokens listandvinssi tokens revoke <tokenId>. - Token creation is limited to 10 per hour.
Send the token as a bearer token:
Authorization: Bearer vinssi_...
Calling procedures
The API is organised as routers of procedures. Queries use GET with the input as a JSON string in the input query parameter; mutations use POST with a JSON body.
# Query
curl -s "https://vinssi.ai/trpc/project.list" \
-H "Authorization: Bearer $VINSSI_TOKEN"
# Query with input
curl -s "https://vinssi.ai/trpc/deployment.byId?input=$(printf '{"deploymentId":"%s"}' "$ID" | jq -sRr @uri)" \
-H "Authorization: Bearer $VINSSI_TOKEN"
# Mutation
curl -s -X POST "https://vinssi.ai/trpc/project.deploy" \
-H "Authorization: Bearer $VINSSI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"projectId":"'"$PROJECT_ID"'"}'
Successful responses wrap the result:
{ "result": { "data": { "...": "..." } } }
Errors carry a code such as UNAUTHORIZED, FORBIDDEN, NOT_FOUND, BAD_REQUEST or TOO_MANY_REQUESTS, and a message:
{ "error": { "message": "...", "data": { "code": "NOT_FOUND" } } }
Procedures you are likely to use
| Procedure | Kind | Purpose |
|---|---|---|
workspace.current | query | The signed-in workspace and credit balance |
project.list | query | Projects with their current deployment status |
project.byId | query | One project, including build settings and repository |
project.deploy | mutation | Start a deployment; optional gitRef |
project.listDeployments | query | Deployment history for a project |
deployment.byId | query | A deployment with its steps |
deployment.buildLogs | query | Build log lines |
deployment.rollback | mutation | Rebuild a previous healthy deployment |
envVar.list, envVar.set, envVar.setAll, envVar.delete | mixed | Environment variables by name; values are never returned |
project.domains, project.addDomain, project.verifyDomain, project.removeDomain | mixed | Custom domains |
pages.list, pages.createVersion, pages.versions, pages.rollback, pages.delete, pages.usage | mixed | Vinssi Pages |
apiToken.create, apiToken.list, apiToken.revoke | mixed | Tokens |
billing.listPlans | query | Available plans; no authentication needed |
Input and output shapes match what the CLI prints with --json or its JSON-printing commands. The CLI source is the reference client.
Uploading Pages content
Publishing to Pages is two calls: pages.createVersion returns an upload path, then the gzipped tarball is sent with PUT https://vinssi.ai/upload/pages/<versionId> using the same bearer token and Content-Type: application/gzip. The CLI does this for you; use it unless you have a reason not to.
Rate limits
Limits are per workspace and shared across the dashboard, CLI and direct API use. Exceeding one returns TOO_MANY_REQUESTS with a message stating the window.
| Action | Limit |
|---|---|
| Deploy and rollback | 20 per 5 minutes |
| Pages publish and upload | 60 per 5 minutes |
| Token creation | 10 per hour |
| Checkout | 20 per hour |
Health
GET https://vinssi.ai/health returns {"status":"ok"} without authentication and is safe to poll.