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 login do not expire.
  • List and revoke with vinssi tokens list and vinssi 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

ProcedureKindPurpose
workspace.currentqueryThe signed-in workspace and credit balance
project.listqueryProjects with their current deployment status
project.byIdqueryOne project, including build settings and repository
project.deploymutationStart a deployment; optional gitRef
project.listDeploymentsqueryDeployment history for a project
deployment.byIdqueryA deployment with its steps
deployment.buildLogsqueryBuild log lines
deployment.rollbackmutationRebuild a previous healthy deployment
envVar.list, envVar.set, envVar.setAll, envVar.deletemixedEnvironment variables by name; values are never returned
project.domains, project.addDomain, project.verifyDomain, project.removeDomainmixedCustom domains
pages.list, pages.createVersion, pages.versions, pages.rollback, pages.delete, pages.usagemixedVinssi Pages
apiToken.create, apiToken.list, apiToken.revokemixedTokens
billing.listPlansqueryAvailable 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.

ActionLimit
Deploy and rollback20 per 5 minutes
Pages publish and upload60 per 5 minutes
Token creation10 per hour
Checkout20 per hour

Health

GET https://vinssi.ai/health returns {"status":"ok"} without authentication and is safe to poll.