API reference
Build hardened server images from a spec you write, check how each image was built, and install it on your own servers.
The API is plain HTTPS with JSON in and JSON out. Every operation in this reference is also an MCP tool with the same name, and the dashboard uses the same operations. The machine-readable description of the whole API is at GET /v1.
Base URL
https://api.tarsana.io
Every path starts with /v1. Send JSON request bodies with Content-Type: application/json.
Authentication
Send exactly one credential with every request that needs one:
| Header | Credential | Where you get it |
|---|---|---|
X-Tarsana-Access-Token | An API access token. Lasts 90 days. Use it in scripts, CI jobs and MCP clients. | issue-access-token |
X-Tarsana-Session | A session. Lasts one hour. Needed to create, list and revoke access tokens. | login |
Requests that read or change something in your tenant also send your tenant ID in the X-Tarsana-Tenant header, and the same ID in the address. Tarsana checks that your credential belongs to that tenant.
curl "https://api.tarsana.io/v1/tenants/acme/audit" \
-H "X-Tarsana-Access-Token: $ACCESS_TOKEN" \
-H "X-Tarsana-Tenant: acme"
A request with no credential, or one Tarsana does not recognise, gets unauthenticated. A credential whose role does not allow the operation gets forbidden, with the roles that do. Each operation's page says which roles can call it:
| Role | What it can do |
|---|---|
viewer | Can read your submissions and download what your builds produced. Cannot submit specs or change servers. Give it to dashboards, status checks and auditors. |
builder | Can do everything a viewer can, and submit and check specs. Cannot change servers. Give it to CI jobs that build images. |
deployer | Can do everything a builder can, and install images on your servers, manage your servers and store your provider credentials. The widest role a tenant can hold. |
Signing up, signing in and reading the API description need no credential.
Errors
A request to the API that Tarsana refuses, including one whose body is not valid JSON, gets an HTTP status of 400 or higher and an error object with a code, a message for people, sometimes a detail object, and a doc_url that links to the code's entry in the error reference:
{
"error": {
"code": "rate_limited",
"message": "One sentence that says what went wrong.",
"detail": {"retry_after_seconds": 30},
"doc_url": "https://docs.tarsana.io/api/errors#rate_limited"
}
}
Act on the code, never on the message. The error reference lists every code with what happened and what to do.
Retries and idempotency
You can repeat these requests safely:
| Operation | What happens when you repeat it |
|---|---|
submit | The same spec returns the same submission; created is false and no second build starts. |
create-server | The same request_id for the same submission returns the server the first request created. A new request_id creates a new server. |
decommission-server | Continues from the step where an earlier request stopped. |
complete-signup | Returns the same login, with secret set to null. |
remove-provider-credential, revoke-access-token | Answer removed: false or revoked: false when there is nothing left to remove. |
Every operation with the Read badge changes nothing and can be repeated at any time.
Rate limits
When you send too many requests in a short time you get rate_limited with HTTP status 429. The Retry-After header and detail.retry_after_seconds say how many seconds to wait.
Request IDs
Answers do not carry a request ID yet. If you contact Tarsana support about a request, include the time you sent it, the operation, your tenant ID and the error code.
Operations
Create your account
Sign up, then sign in.
| Operation | What it does | |
|---|---|---|
POST /v1/signups | Change | Create your Tarsana account |
POST /v1/signups/complete | Change | Finish creating your account |
POST /v1/sessions | Session | Sign in and start a session |
DELETE /v1/sessions/current | Session | End your session |
Set up access
Create API access tokens for your scripts and MCP clients, and store the API token of your cloud provider.
| Operation | What it does | |
|---|---|---|
POST /v1/access-tokens | Change | Create an API access token |
GET /v1/access-tokens | Read | List your API access tokens |
DELETE /v1/access-tokens/{token_id} | Destructive | Revoke an API access token |
POST /v1/tenants/{tenant}/providers/{provider_name}/credential | Change | Store or replace your provider credential |
GET /v1/tenants/{tenant}/providers/{provider_name}/credential | Read | Check whether your provider credential is stored |
DELETE /v1/tenants/{tenant}/providers/{provider_name}/credential | Destructive | Remove your provider credential |
Build an image
Check your spec, submit it, follow the build and verify what it produced.
| Operation | What it does | |
|---|---|---|
POST /v1/tenants/{tenant}/specs/validate | Read | Check a spec without submitting it |
POST /v1/tenants/{tenant}/specs | Change | Submit a spec to build an image |
GET /v1/tenants/{tenant}/submissions/{submission} | Read | See the status of a submission |
GET /v1/tenants/{tenant}/submissions/{submission}/{artifact} | Read | Download a record of a submission |
GET /v1/tenants/{tenant}/submissions/{submission}/attestation | Read | Get what you need to verify an image yourself |
GET /v1/tenants/{tenant}/audit | Read | Read your audit trail |
Run it on your servers
Create a server from your spec or install your image on one, review the servers in your cloud account, and remove the ones you no longer need.
| Operation | What it does | |
|---|---|---|
POST /v1/tenants/{tenant}/submissions/{submission}/create-server | Change | Create a server from your spec |
POST /v1/tenants/{tenant}/servers/{server_name}/install-command | Change | Get the one-line command that installs Tarsana on a server you have |
POST /v1/tenants/{tenant}/submissions/{submission}/provision | Change | Install a built image on one of your servers |
GET /v1/tenants/{tenant}/providers/{provider_name}/servers | Read | List the servers in your cloud account that Tarsana did not create |
POST /v1/tenants/{tenant}/providers/{provider_name}/servers/{server_id}/decommission | Destructive | Decommission a server that Tarsana created |
POST /v1/tenants/{tenant}/providers/{provider_name}/servers/{server_id}/destroy | Destructive | Delete a server that Tarsana did not create |
Reference
The machine-readable description of this API.
| Operation | What it does | |
|---|---|---|
GET /v1 | Read | Get the full API description as JSON |