Skip to main content

What can the Vertra Cloud API do?

The Vertra Cloud public REST API manages applications, databases, workspaces and every other resource of the platform programmatically — every operation available in the dashboard is available over HTTP. Vertra Cloud is a Brazilian application hosting platform (PaaS); this API is how you automate deploys, restarts, environment variables, snapshots and monitoring from your own tooling. Base URL: https://api.vertracloud.app

How do you authenticate?

Every request carries an API key as a Bearer token in the Authorization header; there is no other authentication method for the public API.

API key format

A key created today looks like vc_live_ followed by 48 hex characters. The full secret is shown once, at creation or rotation time — only a hash is stored, so it cannot be recovered later. Keys created before this format (64 hex characters, no prefix) keep working with every scope.

Creating and managing keys

Manage keys from https://vertracloud.app/dashboard/settings. Key management itself (list, create, update, rotate, delete) is dashboard-session only — calling any of those routes with an API key answers 403 API_KEY_SCOPE_DENIED, so a leaked key can’t mint or edit keys for itself. See API Keys for the full request/response shape. You can hold up to 10 keys per account. Each key has:
  • A name — 1 to 40 characters.
  • Scopes — which routes the key can call (see below). At least one is required.
  • Allowed IPs (optional) — up to 20 IPs or CIDRs. Empty means any IP can use the key.
There’s also a legacy route, POST /v1/users/me/generate-api-key, kept for backward compatibility (mainly the CLI): it creates or rotates the account’s single key named “CLI” (full scope), without touching your other keys. Calling it again just gives that same “CLI” key a new secret — it never creates a second one.

Scopes

Every route the API exposes to a key belongs to exactly one scope, grouped by resource. A key must carry the scope a route requires, or the request answers 403 API_KEY_SCOPE_DENIED with details.required naming the missing scope. A route that isn’t in the catalog at all — key management itself or the database Data tab (/v1/databases/{id}/data/*) — always answers 403, regardless of scopes: the Data tab can only be driven by a dashboard session. Three presets speed up creation: read marks every *:read scope, write adds every *:write scope on top of read, full marks the entire catalog, including scopes with no read/write suffix (delete, envs, files, credentials). 20 scopes across 6 groups:
To drive the platform from your own agent, use the MCP server with the apps:read, apps:write and apps:files scopes above.
There is no databases:data scope either. The database Data tab (/v1/databases/{id}/data/* — schemas, tables, rows, SQL console, collections, documents, keys) is dashboard-session only: an API key gets 403 on every one of those routes, regardless of scope.
account:write does not cover every account action. It covers profile updates and personal folders/favorites. Revoking sessions (DELETE /v1/users/me/sessions) and downgrading the plan (POST /v1/users/me/downgrade) are dashboard-session only — an API key gets 403 API_KEY_SCOPE_DENIED on both, regardless of scope.
workspaces:delete and workspaces:invites have no read/write suffix, so the read and write presets never include them — only full or a custom selection does. workspaces:read also lists action requests. Some workspace actions stay dashboard-session only and no scope covers them: creating an invite (a leaked key could leave behind access that outlives revoking it), transferring ownership (it could be used to take over the workspace), and approving or rejecting an action request (a human decision, including when an agent asked for it). With an API key those routes answer 403 API_KEY_SCOPE_DENIED.
The activity log is dashboard-session only. Listing activities and exporting a workspace’s activity log both get 403 API_KEY_SCOPE_DENIED for an API key, regardless of scope — the log stays available in the dashboard.
Orders are the one billing action an API key can drive: billing:read covers listing orders and checking an order’s status, billing:write covers creating a plan order and generating its PIX payment, and redeem:write covers redeeming a promo code. Downgrading the plan stays dashboard-only, as noted above.

Allowed IPs

An empty allowed_ips list means the key works from any IP. Once you add at least one IP or CIDR, every request from outside that list answers 403 API_KEY_IP_DENIED, even with a correct key and scope. The IP checked is the one Vertra’s edge sees the connection come from — client-sent headers like X-Forwarded-For or CF-Connecting-IP are ignored, so they can’t be spoofed to bypass the allowlist.

Errors specific to API keys

Connecting through OAuth

Besides pasting a key from the dashboard, a client can obtain one through a standard OAuth flow — this is how third-party agent clients connect to your Vertra account without you ever handling a raw key.
  • Discovery: GET /.well-known/oauth-authorization-server returns the standard metadata document (authorization_endpoint, token_endpoint, registration_endpoint, supported grant and PKCE methods).
  • Dynamic client registration: POST to registration_endpoint registers the connecting client and returns a client_id; no manual app registration in the dashboard is needed.
  • Authorization: the client sends the user to authorization_endpoint with PKCE — S256 is the only supported code_challenge_method. You approve on a Vertra consent screen that lists the scopes being requested and shows the name of the connecting client, then choose to allow it.
  • Token exchange: POST to token_endpoint accepts only grant_type=authorization_code with the matching PKCE code_verifier. There’s no refresh token grant, because the token it returns doesn’t expire.
  • What you get back: the “access token” is an ordinary Vertra API key — same format, same scopes, same rate limits as one created in the dashboard — created with the name of the connecting client. It shows up in Settings → API keys, prefixed oauth:, and you revoke it the same way you’d revoke any other key.

What does a response look like?

Every response uses the same envelope: a success carries the payload under response, an error carries a stable code, an optional message and, on some codes, a details object with the numbers you need to act (the missing scope, the retry delay, the limit). The HTTP status tells you which one it is. Success:
A route with nothing to return (a delete, a file save, a cache purge) answers { "response": null }. Error:

What error codes can the API return?

Error codes are stable strings, safe to branch on — the message is not. These are the ones you will meet most often; the endpoint pages document the codes specific to each route.

OPERATION_IN_PROGRESS

Lifecycle operations on the same application or database are serialised: only one runs at a time. If you ask for a second one while the first is still going, the API answers 409 OPERATION_IN_PROGRESS and leaves the resource unchanged. This is contention, not a failure. Wait a few seconds and retry. It can be returned by start, restart, stop, delete, dependency installs, deploys and snapshot operations.
Error Response (409)

STORAGE_ABOVE_NEW_LIMIT

Every application has a fixed disk ceiling (see Limitations). If the volume already holds more than that ceiling, a change through Update Configuration is refused with 409 instead of being applied. The response carries the numbers you need to act on, in MB:
Error Response (409)
free_mb is how much you have to delete before the change can be applied.

How is the API rate limited?

The API has three layers of limits, and a single call can be rejected by any of them. 1. Per-route, fixed, the same on every plan. Application lifecycle routes — start, restart, stop and publish — share a single budget of 10 requests per minute per application, so restarting an app ten times in a row leaves no allowance for stopping it in that same minute. Database reset is capped at 1 per hour; subdomain changes at 5 per minute with a 5-minute cooldown; the SQL console at 30 per minute; every other Data tab route at 120 per minute; workspace exports at 5 per minute. Every other route, databases included, keeps its own budget. Over the limit: 429 RATE_LIMIT_EXCEEDED. 2. Per minute, per account, scaled by plan. This layer only counts requests authenticated with an API key — dashboard sessions don’t count against it. Every API-key response carries x-ratelimit-limit, x-ratelimit-remaining and x-ratelimit-reset (seconds) headers. Over the limit: 429 RATE_LIMIT_EXCEEDED with details: { scope: "minute", limit, used, retry_after }. 3. Per day, per account, scaled by plan. Also API-key only, and resets at midnight in the America/Fortaleza (Brasília) timezone. Every API-key response carries x-quota-limit, x-quota-remaining and x-quota-reset (seconds) headers. Over the limit: 429 DAILY_QUOTA_EXCEEDED with details: { scope: "day", limit, used, retry_after }. We recommend implementing retry logic with exponential backoff for any 429 response. Deploys have their own hourly budget, separate from the request budgets above. Creating an application, uploading a ZIP, deploying from GitHub, a restart with reinstall_dependencies or force_build, and changing the build command all draw from one counter per account, sized by plan (5/hour on Free up to 60/hour on Intermediary and every Enterprise tier — see Plans and limits). Starting, stopping and a plain restart do not draw from it. Over the limit, the API answers 429 DEPLOY_RATE_LIMITED with details.limit, details.window_seconds (3600) and details.retry_after. Manual snapshot creation has its own budget too, on top of the per-route limit: at most 1 every 5 minutes per project and 10 per hour per account. Over the limit, the API answers 429 SNAPSHOT_RATE_LIMITED with details: { scope: "resource" | "account", retry_after }. Restoring or downloading a snapshot isn’t affected, and snapshots the platform takes automatically before a destructive operation don’t count against this budget.

Which resources does the API cover?

Seven groups: users, applications, databases, workspaces, billing, redeem codes and platform status. Each has its own reference page with the request body, the response and the error codes.

Users

Query information about the authenticated user.

Applications

Manage complete application lifecycle: creation, deployment, start/stop, files, environment variables, snapshots and domains.

Databases

Manage databases: creation, start/stop, reset, metrics and credentials.

Workspaces

Manage workspaces: creation, members, permissions and resource association.

Billing

List orders, create a plan order and generate its PIX payment.