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.
An AI assistant can use the same workspace through the MCP connector at https://mcp.vinssi.ai/mcp. That connector signs in with OAuth. A personal API token still works as a bearer token for clients that can send one.
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
Token creation and revocation are available through the CLI. 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.