Skip to content

Varity Public API Reference

Varity TeamCore Contributors

Varity’s public API is a resource API for deployments, self-managed machines, templates, pricing and quotes, balance, API keys, AI Gateway attachments, and webhooks. Use it for direct integrations, custom agents, launchpads, internal tools, and backend services that need to deploy or operate Varity apps without the dashboard.

The machine-readable source is:

  • https://docs.varity.so/openapi.yaml
  • https://varity.app/api/openapi.json

Varity exposes two public base URLs:

Platform APIs cover apps, deployments, templates, pricing, balance, API keys, and webhooks. That is everything on this page:

https://varity.app/api

AI Gateway covers OpenAI-compatible inference: chat completions, embeddings, images, audio, and model listing:

https://ai.varity.app/v1

For the older varity.app/v1 alias, see AI Gateway Endpoints.

These are two different products with two different contracts:

  • /api/* is the platform surface. Resource CRUD for deployments, machines, templates, pricing, balance, keys, and webhooks. Everything on this page. Errors use the Varity error envelope.
  • /v1/* is the OpenAI-compatible inference surface. Chat completions, embeddings, images, audio, and model listing. Point any OpenAI client at it by setting the base URL. It has its own error shape and its own rate limits, documented in the AI Gateway docs. Nothing on this page applies to it.

A single Varity API key does not automatically work on both surfaces: keys are scoped per product, and using one out of scope returns 403 credential_scope_violation. Create AI Gateway keys from the Developer Portal Inference keys tab, which calls POST /v1/keys on https://ai.varity.app with your Portal session; that is the only AI Gateway key issuer (see Billing and Keys).

For non-browser callers, send your Varity API key as a bearer credential:

Authorization: Bearer $VARITY_API_KEY

Create deploy keys in the Developer Portal settings page. Deploy key plaintext is shown once. Listing and revoking keys require an authenticated Developer Portal session; plaintext keys are never returned after creation.

POST /api/deployments creates a deployment from one source: repository, image, or template. It returns 202 Accepted. Creation is asynchronous.

Send an Idempotency-Key on creates so a retry cannot produce a duplicate deployment:

  • Deployment and template creates accept an optional key up to 160 characters.
  • Machine create and delete require [A-Za-z0-9._:-]{8,128}.
  • AI Gateway attachment mutations require [A-Za-z0-9._:-]{1,160}.
  • Retention: 24 hours.
  • Replaying the same key with the same body returns the original result, flagged replayed: true.
  • Reusing the same key with a different body returns 409 idempotency_key_reused.

The header is optional on POST /api/deployments and POST /api/templates/{id}/deploy; it is required on machine create/delete and every /api/ai-gateway/attachments mutation. The operation-specific OpenAPI parameter is authoritative.

Do not fire concurrent create requests with the same idempotency key; atomic concurrent idempotency is a backend hardening follow-up for v1.

Terminal window
curl -X POST https://varity.app/api/deployments \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: deploy-my-app-001" \
-d '{
"name": "my-app",
"repository": {
"url": "https://github.com/me/my-app"
}
}'

The 202 response includes id, app_name, status: "deploying", runtime, run_id, and status_url. public_url is not guaranteed on acceptance. On the durable path the URL is only projected once the canonical route is proven, so read it from the deployment once the run succeeds rather than from the create response.

Poll the run until it reaches succeeded or failed:

Terminal window
curl "https://varity.app/api/deployments/runs/$RUN_ID?app=my-app" \
-H "Authorization: Bearer $VARITY_API_KEY"

List deployments:

Terminal window
curl https://varity.app/api/deployments \
-H "Authorization: Bearer $VARITY_API_KEY"

Read one deployment:

Terminal window
curl https://varity.app/api/deployments/$DEPLOYMENT_ID \
-H "Authorization: Bearer $VARITY_API_KEY"

Read logs and events:

Terminal window
curl https://varity.app/api/deployments/$DEPLOYMENT_ID/logs \
-H "Authorization: Bearer $VARITY_API_KEY"
curl https://varity.app/api/deployments/$DEPLOYMENT_ID/events \
-H "Authorization: Bearer $VARITY_API_KEY"

Both responses include a complete flag and an observed_at timestamp. When complete is false, the returned window may be partial (for example when the live runtime source was momentarily unavailable) and a warning_code is set. The read is safe to retry for a complete window.

A static site has no runtime, so it has no runtime logs. GET /api/deployments/{id}/logs answers it with a non-retryable 409 runtime_not_started (“This is a static site: it is served as files and has no runtime, so there are no runtime logs.”), not with an incomplete window to retry. Its build and publish steps are the deployment run’s events: read run_id from GET /api/deployments/{id}, then GET /api/deployments/runs/{run_id}. A deployment that never started a runtime (a failed create, a machine) gets the same 409 with “No runtime logs: this deployment did not start a runtime.”

Read durable runtime and route health history:

Terminal window
curl "https://varity.app/api/deployments/$DEPLOYMENT_ID/health-history?limit=100" \
-H "Authorization: Bearer $VARITY_API_KEY"

The response contains a summary with the latest runtime and route health state and reasons, consecutive failure counts, a freshness_at timestamp, and bounded per-service facts (replica, endpoint, and port counts), plus an observations array of recent health checks, bounded by limit (default 100, maximum 500). Per-service entries report restart_count_supported: false and a null restart_count; restart counting is not supported by the current runtime substrate.

List environment variable keys. Values are write-only and are not returned:

Terminal window
curl https://varity.app/api/deployments/$DEPLOYMENT_ID/env \
-H "Authorization: Bearer $VARITY_API_KEY"

Update environment variables and redeploy in place:

Terminal window
curl -X PATCH https://varity.app/api/deployments/$DEPLOYMENT_ID/env \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "env": { "FEATURE_FLAG": "on" } }'

Redeploy, restart, or delete:

Terminal window
curl -X POST https://varity.app/api/deployments/$DEPLOYMENT_ID/redeploy \
-H "Authorization: Bearer $VARITY_API_KEY"
curl -X POST https://varity.app/api/deployments/$DEPLOYMENT_ID/restart \
-H "Authorization: Bearer $VARITY_API_KEY"
curl -X DELETE https://varity.app/api/deployments/$DEPLOYMENT_ID \
-H "Authorization: Bearer $VARITY_API_KEY"

Templates are deployable app starters. Pricing is estimated from the live API, not a hardcoded table, and returns fixed monthly hardware-reservation cost for the requested profile.

Terminal window
curl https://varity.app/api/templates \
-H "Authorization: Bearer $VARITY_API_KEY"
curl "https://varity.app/api/pricing/estimate?profile=web-app" \
-H "Authorization: Bearer $VARITY_API_KEY"
curl https://varity.app/api/credits \
-H "Authorization: Bearer $VARITY_API_KEY"

Create a webhook:

Terminal window
curl -X POST https://varity.app/api/webhooks \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/varity/webhook",
"events": ["deployment.accepted", "deployment.live", "deployment.failed"]
}'

The response includes signing_secret once. Store it to verify webhook deliveries. Varity signs each delivery with:

  • X-Varity-Event-Id
  • X-Varity-Timestamp
  • X-Varity-Signature

The signature is v1= plus an HMAC-SHA256 over timestamp.body using the webhook signing secret. Webhook endpoint URLs must be public HTTPS URLs; local and private hosts are rejected.

Subscribable event types:

deployment.accepted, deployment.progress, deployment.live, deployment.failed, deployment.unhealthy, deployment.env_updated, deployment.redeploy_requested, deployment.redeploy_completed, deployment.restart_requested, deployment.deleted, credit.updated.

Webhook handlers should be idempotent. Delivery-time DNS/IP revalidation, durable delivery queue hardening, and additional signing-secret custody hardening remain non-blocking v1 follow-ups.

List webhooks and delivery status:

Terminal window
curl "https://varity.app/api/webhooks?include_deliveries=true" \
-H "Authorization: Bearer $VARITY_API_KEY"

Delete a webhook:

Terminal window
curl -X DELETE https://varity.app/api/webhooks/$WEBHOOK_ID \
-H "Authorization: Bearer $VARITY_API_KEY"

Self-managed machines are a separate resource from deployments: you get a machine you administer, not a managed app. Quote first, then create.

Terminal window
curl -X POST https://varity.app/api/pricing/machine-quote \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ ... }'
curl -X POST https://varity.app/api/machines \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: machine-001" \
-d '{ ... }'

Create and delete return 202. List, read, and run bounded synchronous actions:

Terminal window
curl https://varity.app/api/machines \
-H "Authorization: Bearer $VARITY_API_KEY"
curl https://varity.app/api/machines/$MACHINE_ID \
-H "Authorization: Bearer $VARITY_API_KEY"
curl -X POST https://varity.app/api/machines/$MACHINE_ID/actions \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ ... }'

Request and response schemas are in the OpenAPI document; read it rather than hand-copying field lists.

Before deploying, discover what is actually available instead of assuming a catalog.

GET /api/deployment-capabilities returns the provider-neutral catalog of workloads and execution options.

GET /api/deployment-profiles returns normalized profiles, prices, and aggregate availability for a scope. Both workload and execution_class are required:

Terminal window
curl "https://varity.app/api/deployment-profiles?workload=gpu&execution_class=virtual_machine" \
-H "Authorization: Bearer $VARITY_API_KEY"

workload is one of gpu, virtual_machine, cpu. execution_class is one of container, virtual_machine, bare_metal, cpu_virtual_machine. An invalid combination returns 422 deployment_profile_scope_invalid.

Profiles carry availability, not a price commitment. For an exact hourly figure, take a quote:

Terminal window
curl -X POST https://varity.app/api/pricing/machine-quote \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ ... }'

Attaching the Varity AI Gateway to a Cloud deployment injects a scoped inference credential into that deployment, so your app can call /v1 without you managing a key by hand.

Terminal window
curl -X POST https://varity.app/api/ai-gateway/attachments \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: attach-my-app-001" \
-d '{ ... }'

Idempotency-Key is required on attach, detach, and rotate. All three return 202. Attachment ids match vai_[A-Za-z0-9_-]{20,64}.

Terminal window
curl https://varity.app/api/ai-gateway/attachments \
-H "Authorization: Bearer $VARITY_API_KEY"
curl -X POST https://varity.app/api/ai-gateway/attachments/$ATTACHMENT_ID/rotate \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Idempotency-Key: rotate-my-app-001"

These routes accept either an API key or a Developer Portal session.

Every platform-API error returns the same envelope:

{
"code": "authentication_required",
"message": "A Bearer API key is required.",
"action": "Send Authorization: Bearer <VARITY_API_KEY>.",
"retryable": false,
"docs_url": "https://docs.varity.so/api/errors#authentication_required",
"correlation_id": "3e0dbab4-bb81-4e95-a9b6-baefeff0e52e"
}

Branch on code and retryable, never on message. Send an X-Request-Id header and it comes back as correlation_id; include it in support requests.

There are no per-route request budgets. A full deployment queue answers a create with 429 queue_saturated (retry with the same Idempotency-Key), and the edge’s per-client abuse limit answers a runaway client with a plain-text 429.

See API Errors and Rate Limits for the full reference.

The live OpenAPI document at https://varity.app/api/openapi.json is authoritative.

MethodsPathPurpose
GET, POST/api/deploymentsList or create deployments
GET/api/deployments/runs/{run_id}Get deployment run status
GET, DELETE/api/deployments/{deployment_id}Read or delete a deployment
GET/api/deployments/{deployment_id}/access-credentialRead owner-only private application access with a Portal session
GET/api/deployments/{deployment_id}/logsRead deployment logs
GET/api/deployments/{deployment_id}/eventsRead deployment events
GET/api/deployments/{deployment_id}/health-historyRead durable runtime and route health history
GET, PATCH/api/deployments/{deployment_id}/envList environment variable keys or update values
POST/api/deployments/{deployment_id}/redeployRedeploy in place
POST/api/deployments/{deployment_id}/restartRestart as a verified replacement
GET, PUT, DELETE/api/deployments/{deployment_id}/domainRead, attach, or remove a custom domain
POST/api/deployments/{deployment_id}/domain/verifyObserve DNS and verify HTTPS serving
MethodsPathPurpose
GET, POST/api/machinesList or create self-managed machines
GET, DELETE/api/machines/{machine_id}Read or delete one machine
POST/api/machines/{machine_id}/actionsRun a bounded synchronous action
MethodsPathPurpose
GET/api/deployment-capabilitiesProvider-neutral deployment catalog
GET/api/deployment-profilesNormalized profiles, prices, and availability
GET/api/pricing/estimateEstimate fixed monthly cost
POST/api/pricing/machine-quoteExact machine quote
GET/api/creditsRead your USD balance and deploy eligibility
MethodsPathPurpose
GET/api/templatesList templates
GET/api/templates/{template_id}Read a template
POST/api/templates/{template_id}/deployDeploy a template
MethodsPathPurpose
GET, POST/api/webhooksList or create webhooks
DELETE/api/webhooks/{webhook_id}Delete a webhook
MethodsPathPurpose
GET, POST/api/ai-gateway/attachmentsList or create attachments
GET, DELETE/api/ai-gateway/attachments/{attachment_id}Read or detach one attachment
POST/api/ai-gateway/attachments/{attachment_id}/rotateRotate the deployment credential
MethodsPathPurposeAuth
GET, POST/api/api-keysList or create Cloud API keysPortal session
DELETE/api/api-keys/{key_id}Revoke an API keyPortal session
GET/api/api-keys/auditList key lifecycle eventsPortal session
GET/api/openapi.jsonRead the live OpenAPI contractNone