Skip to content

CaaS

POST /v1/caas/{id}/apps · scope caas:write · reversible · idempotent · deprecated

Creates the app and configures its source, but does not deploy it: it stays idle until you call POST /v1/caas/{id}/apps/{app_id}/deploy. Separating the two is what lets you create the app, load its variables, and only then deploy — the reverse order would start the application without its configuration.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"api"}'

operationId: caas.apps.create

DELETE /v1/caas/{id}/apps/{app_id} · scope caas:write · destructive — cannot be undone · idempotent · deprecated

Destructive. Deletes the app, its variables, and its domains. The service’s database data is untouched: it lives separately.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps/app_9f2c1b7e \
-X DELETE \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.apps.delete

POST /v1/caas/{id}/apps/{app_id}/deploy · scope caas:deploy · reversible · asynchronous · idempotent · deprecated

Returns 202 as soon as the deployment starts. The operation resolves by looking up that deployment in the app’s history, the only place the backend reports its outcome. Wait on it with GET /v1/operations/{id}; failure details are in GET /v1/caas/{id}/apps/{app_id}/logs.

It lives in its own scope (caas:deploy) because deploying executes whatever code is in the configured source — which is different from editing the app’s configuration.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps/app_9f2c1b7e/deploy \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.apps.deploy

GET /v1/caas/{id}/apps/{app_id} · scope caas:read · deprecated

Returns only the declared fields. The backend responds with the deployment engine’s full internal object —including plaintext environment variables—; none of that leaves through here. For variable names, use GET /v1/caas/{id}/apps/{app_id}/env.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps/app_9f2c1b7e \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.apps.get

GET /v1/caas/{id}/apps · scope caas:read · deprecated

source comes back null: the backend does not include it in the listing.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.apps.list

GET /v1/caas/{id}/apps/{app_id}/logs · scope caas:read · deprecated

A snapshot, not a stream. Returns whatever the backend has at call time, and there is no way to ask for “what came after”: the backend accepts a cursor but never emits the next one, so this endpoint publishes none. To follow an application live, call again.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps/app_9f2c1b7e/logs \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.apps.logs

POST /v1/caas/{id}/apps/{app_id}/restart · scope caas:write · reversible · idempotent · deprecated

Restarts the process without rebuilding the image: it picks up the current environment variables but does not pull new code. That is what deploy is for.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps/app_9f2c1b7e/restart \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.apps.restart

POST /v1/caas/{id}/builds/{number}/cancel · scope caas:deploy · reversible · idempotent

A queued build never starts; a running one is stopped. Refused with 400 validation_failed once the build has finished or is already deploying.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/builds/12/cancel \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.builds.cancel

GET /v1/caas/{id}/builds/{number} · scope caas:read

Its status, the commit it built, the resulting image by digest and, with deploy, the stack version it created.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/builds/12 \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.builds.get

GET /v1/caas/{id}/builds · scope caas:read

Newest first. Builds from every origin: the API, reruns, and pushes to connected repositories.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/builds \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.builds.list

GET /v1/caas/{id}/builds/{number}/log · scope caas:read

Read it incrementally: pass the offset of each response to the next call to get only what is new, and stop when done is true.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/builds/12/log \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.builds.log

POST /v1/caas/{id}/builds/{number}/rerun · scope caas:deploy · reversible · idempotent

Queues a new build (a new number) with the same settings. A build of a source runs with what the source says now, and is coalesced like any build of a source.

The build runs inside your own cluster: with the Dockerfile if the repository has one, otherwise with automatic detection (Railpack). It is capped at 30 minutes. One build runs at a time per cluster and up to 5 wait in the queue; a sixth is refused with 400 validation_failed. The image is stored by digest in the cluster registry (image), so rolling a stack back brings back the same bytes.

With deploy, a successful build is deployed as a new version of that stack service; the stack must already be deployed with that service, or the request fails with 400 validation_failed before anything is queued. A build that ends succeeded with an error built the image but could not deploy it.

Returns 202 with the build; poll GET /v1/caas/{id}/builds/{number} (or its /log) until it finishes. It is not an operation.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/builds/12/rerun \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.builds.rerun

POST /v1/caas/{id}/builds · scope caas:deploy · reversible · idempotent

From a public repository (repo), or from a connected one (source) — private repositories go through a source. Starting from a source while a build of it is already waiting returns that build (coalesced: true) instead of queuing another.

The build runs inside your own cluster: with the Dockerfile if the repository has one, otherwise with automatic detection (Railpack). It is capped at 30 minutes. One build runs at a time per cluster and up to 5 wait in the queue; a sixth is refused with 400 validation_failed. The image is stored by digest in the cluster registry (image), so rolling a stack back brings back the same bytes.

With deploy, a successful build is deployed as a new version of that stack service; the stack must already be deployed with that service, or the request fails with 400 validation_failed before anything is queued. A build that ends succeeded with an error built the image but could not deploy it.

Returns 202 with the build; poll GET /v1/caas/{id}/builds/{number} (or its /log) until it finishes. It is not an operation.

Requires caas:deploy: with deploy, the build ends up running.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/builds \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

operationId: caas.builds.start

POST /v1/caas/{id}/domains · scope caas:write · reversible · asynchronous · idempotent

First create a CNAME from your domain to the cluster hostname (cluster.name). The request checks it and fails with 400 validation_failed if the domain does not resolve to the cluster yet — nothing is changed. Then the three nodes start routing it and the certificate is issued; the operation finishes when TLS answers on all three.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/domains \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"host":"app.example.com"}'

operationId: caas.cluster_domains.create

Remove a domain from an Enterprise cluster

Section titled “Remove a domain from an Enterprise cluster”

DELETE /v1/caas/{id}/domains/{host} · scope caas:write · destructive — cannot be undone · asynchronous · idempotent

Refused with 400 validation_failed while a deployed stack routes it (remove it from the stack’s labels and deploy first), and for the cluster hostname.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/domains/app.example.com \
-X DELETE \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.cluster_domains.delete

GET /v1/caas/{id}/domains · scope caas:read

The cluster hostname first, then yours, each with whether its DNS points at the cluster right now and when its certificate expires. A stack serves a domain from this list by naming it in a Host() rule of its Traefik labels.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/domains \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.cluster_domains.list

Recover a single-node service from its VM backup

Section titled “Recover a single-node service from its VM backup”

POST /v1/caas/{id}/recover · scope caas:write · destructive — cannot be undone · asynchronous · idempotent

Brings the node back from the latest daily backup of its VM: the machine, its private address, and the data in your stack volumes. Use it when the node is lost or its disk is damaged. Your apps are down while it runs (a few minutes), and anything written after that backup is lost. The operation result carries backup_at and backup_age_seconds. Stacks that changed after the backup are redeployed as currently declared.

Only for single-node services (capabilities.recover); on three nodes it responds 400 unsupported_for_product. Refused with 412 precondition_failed when there is no backup to restore, and with 409 operation_in_progress while another cluster operation runs.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/recover \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.cluster.recover

POST /v1/caas/{id}/restart · scope caas:write · reversible · asynchronous · idempotent

Restarts the three nodes one at a time. Each one leaves the cluster hostname first, its replicas move to the other two, and it rejoins once it serves TLS again. Services with two or more replicas keep answering; one with a single replica is cut while its node restarts. Takes several minutes.

Refused with 412 precondition_failed if a node is already unhealthy, and with 409 operation_in_progress while another cluster operation runs. Deploys are refused until it finishes.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/restart \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.cluster.restart

DELETE /v1/caas/{id}/configs/{name} · scope caas:write · destructive — cannot be undone · idempotent

Refused with 400 validation_failed while a deployed stack uses it: remove it from the compose and deploy first.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/configs/db-url \
-X DELETE \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.configs.delete

GET /v1/caas/{id}/configs · scope caas:read

Names and when they were last written. Never the value, by any endpoint.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/configs \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.configs.list

PUT /v1/caas/{id}/configs/{name} · scope caas:write · reversible · idempotent

A config is mounted as a file wherever the services that list it under configs: say (target:). Stored encrypted; the value is never returned.

Services that already run keep the value they started with: redeploy_needed lists the stacks to deploy again for them to pick up the new one.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/configs/db-url \
-X PUT \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"value":"<value>"}'

operationId: caas.configs.put

POST /v1/caas/{id}/databases · scope caas:write · reversible · idempotent · deprecated

The platform generates the password and it is not returned here or by any other /v1 endpoint: there is no way to recover it through this API. Connect from an app in the same service, where the connection string is already available.

Deleting a database is not in this version: the backend does not implement it yet, and publishing an endpoint that always fails would be publishing roadmap.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/databases \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"engine":"postgres","name":"main"}'

operationId: caas.databases.create

GET /v1/caas/{id}/databases · scope caas:read · deprecated

They belong to the service, not to an app: several apps in the same service can use the same database. Credentials are not returned by any endpoint of this API.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/databases \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.databases.list

POST /v1/caas/{id}/deploy-key · scope caas:deploy · reversible

Generates the key your CI uses to redeploy a stack after building an image, and returns it once. The previous key stops working immediately.

The key only redeploys stacks that already exist, with their current compose file (optionally swapping images): it cannot create stacks, read anything, or touch secrets. That is why it is separate from your API keys.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/deploy-key \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.deploy_key.rotate

GET /v1/caas/{id}/apps/{app_id}/deployments · scope caas:read · deprecated

Newest first, as the backend returns it.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps/app_9f2c1b7e/deployments \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.deployments.list

POST /v1/caas/{id}/apps/{app_id}/domains · scope caas:write · reversible · idempotent · deprecated

The host’s DNS must point at the service’s IP before you call: certificate issuance is validated over HTTP.

Two more things to know:

  • It is not atomic. Creation registers the domain and then rebuilds the ingress routing; if the second step fails, the call returns an error with the domain already created. Retrying is safe and is the right move — creation is idempotent per host.
  • The certificate is issued afterwards, asynchronously, with no state or id to query. That is why certificate_type comes back null here. The only real check is an HTTPS request to the host.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps/app_9f2c1b7e/domains \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"host":"app.example.com"}'

operationId: caas.domains.create

DELETE /v1/caas/{id}/apps/{app_id}/domains/{host} · scope caas:write · destructive — cannot be undone · idempotent · deprecated

Deleting a host that is not on the app is not an error: the ingress routing is rebuilt either way, which is what makes retrying safe.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps/app_9f2c1b7e/domains/app.example.com \
-X DELETE \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.domains.delete

GET /v1/caas/{id}/apps/{app_id}/domains · scope caas:read · deprecated

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps/app_9f2c1b7e/domains \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.domains.list

GET /v1/caas/{id}/apps/{app_id}/env · scope caas:read · deprecated

Returns names, never values. There is no version of this endpoint that returns them: once written, a value is read only by the application. The backend masks by applying a regex to the key name, which lets anything not named like a secret (DATABASE_URL, SENTRY_DSN) through in plaintext; that is not a classification policy and it is not published.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps/app_9f2c1b7e/env \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.env.list

PUT /v1/caas/{id}/apps/{app_id}/env · scope caas:write · destructive — cannot be undone · idempotent · deprecated

Replaces the entire set: anything missing from vars is deleted. Not a limitation — it is the semantics of the backend, which writes the whole block at once.

Since GET /env returns no values, the set has to come from your side — your secrets manager or your configuration repository. That is the natural shape for declarative infrastructure, and it also removes the panel’s failure mode, where saving without rewriting the secrets erased them.

Changes take effect on the next deploy or restart.

Deprecated on 2026-10-19; it stops working on 2027-10-19. See https://docs.truo.cloud/changelog/caas-discovery-apps.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/apps/app_9f2c1b7e/env \
-X PUT \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"vars":[]}'

operationId: caas.env.replace

DELETE /v1/caas/{id}/github/installations/{installation_id} · scope caas:deploy · reversible · idempotent

Unbinds it from this service; the app stays installed on GitHub. Builds of github sources on that account fail until it is connected again.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/github/installations/51234567 \
-X DELETE \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.github_installations.delete

GET /v1/caas/{id}/github · scope caas:read

Whether the TruoCloud GitHub App is available and which of its installations (GitHub users or organizations) are connected to this service. A github source needs an installation that covers its repository.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/github \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.github.get

POST /v1/caas/{id}/github/install · scope caas:deploy

A link, valid for one hour, to install (or reconfigure) the TruoCloud GitHub App and connect it to this service. Open it signed in to GitHub, choose the repositories, and authorize: only installations your GitHub user can see are connected.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/github/install \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.github.install_link

GET /v1/caas/{id} · scope caas:read

Queries the control plane. If it does not respond, provisioning_state and machine come back null instead of failing: a control plane hiccup should not stop you from reading the rest of the resource or its capabilities.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432 \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.instances.get

GET /v1/caas · scope caas:read

Served from the database, without querying the control plane: provisioning_state and machine come back null. Fetching them would cost two calls per page item.

A page can come back with fewer items than limit even when more exist: every control plane product shares the same provisioning module, so the family filter can only be applied after reading the page. has_more remains the correct signal for whether anything is left to fetch.

Terminal window
curl https://api.truo.cloud/v1/caas \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.instances.list

POST /v1/caas/{id}/previews/{name}/build · scope caas:deploy · reversible · idempotent

The same as a push to its branch: builds the latest commit, deploys it and pushes its expiry back.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/previews/pr-12/build \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.previews.build

POST /v1/caas/{id}/previews · scope caas:deploy · reversible · idempotent

Builds ref from the production source and, when it succeeds, runs it in its own stack pv-<name> with the compose file of the running base_stack: one replica per service, every route to https://<name>.<cluster name>, TRUO_PREVIEW=<name> in every service (so the app can turn off real emails or jobs with side effects) and new, empty volumes. With database, it also gets its own empty PostgreSQL database, mounted under the production secret name; the app runs its migrations on start.

A push to ref rebuilds it and pushes its expiry back; after ttl_hours (24 by default) without one, it closes by itself. Up to 3 may be open per service. Requires previews enabled (POST /v1/caas/{id}/previews/enable).

Returns 202 with the preview in building; poll GET /v1/caas/{id}/previews/{name}.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/previews \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

operationId: caas.previews.create

DELETE /v1/caas/{id}/previews/{name} · scope caas:deploy · reversible · idempotent

Removes what the preview created —its stack, its secret, its database— and nothing else. Answers 202 with the preview in closing.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/previews/pr-12 \
-X DELETE \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.previews.delete

POST /v1/caas/{id}/previews/enable · scope caas:write · reversible · asynchronous · idempotent

Once per service: publishes the wildcard *.<cluster name>, issues its certificate and routes it on every node, then checks TLS through each one. After that, opening a preview touches neither DNS nor certificates. Running it again only checks again.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/previews/enable \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.previews.enable

GET /v1/caas/{id}/previews/{name} · scope caas:read

An open preview, with its status, address, latest build and error.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/previews/pr-12 \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.previews.get

GET /v1/caas/{id}/previews · scope caas:read

The open ones, whether previews are enabled, and how many may be open at once.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/previews \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.previews.list

DELETE /v1/caas/{id}/registries/{server} · scope caas:write · destructive — cannot be undone · idempotent

Services already running are not affected; the next deploy that pulls from that server fails.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/registries/ghcr.io \
-X DELETE \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.registries.delete

GET /v1/caas/{id}/registries · scope caas:read

Server and username. Never the password or token, by any endpoint.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/registries \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.registries.list

PUT /v1/caas/{id}/registries/{server} · scope caas:write · reversible · idempotent

Every deploy pulls with them, for any image on that server (ghcr.io, registry.gitlab.com, docker.io…). Use a read-only token.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/registries/ghcr.io \
-X PUT \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"username":"<username>","password":"<password>"}'

operationId: caas.registries.put

DELETE /v1/caas/{id}/secrets/{name} · scope caas:write · destructive — cannot be undone · idempotent

Refused with 400 validation_failed while a deployed stack uses it: remove it from the compose and deploy first.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/secrets/db-url \
-X DELETE \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.secrets.delete

GET /v1/caas/{id}/secrets · scope caas:read

Names and when they were last written. Never the value, by any endpoint.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/secrets \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.secrets.list

PUT /v1/caas/{id}/secrets/{name} · scope caas:write · reversible · idempotent

A secret is mounted as a file at /run/secrets/<name> in the services that list it under secrets:. Stored encrypted; the value is never returned.

Services that already run keep the value they started with: redeploy_needed lists the stacks to deploy again for them to pick up the new one.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/secrets/db-url \
-X PUT \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"value":"<value>"}'

operationId: caas.secrets.put

POST /v1/caas/{id}/sources/{name}/build · scope caas:deploy · reversible · idempotent

The latest commit of its branch, with its settings. ref builds another branch or tag and deploy sends the image elsewhere (null = build only); a different ref without deploy builds only, so a branch never lands on the source stack unless you name it. If a build of this source for the same branch and target is already waiting, that one is returned (coalesced: true).

The build runs inside your own cluster: with the Dockerfile if the repository has one, otherwise with automatic detection (Railpack). It is capped at 30 minutes. One build runs at a time per cluster and up to 5 wait in the queue; a sixth is refused with 400 validation_failed. The image is stored by digest in the cluster registry (image), so rolling a stack back brings back the same bytes.

With deploy, a successful build is deployed as a new version of that stack service; the stack must already be deployed with that service, or the request fails with 400 validation_failed before anything is queued. A build that ends succeeded with an error built the image but could not deploy it.

Returns 202 with the build; poll GET /v1/caas/{id}/builds/{number} (or its /log) until it finishes. It is not an operation.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/sources/web/build \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.sources.build

POST /v1/caas/{id}/sources · scope caas:deploy · reversible

A source is a private repository this service builds from, by API or on every push.

  • github: the TruoCloud GitHub App must be installed on the repository and connected to this service (POST /v1/caas/{id}/github/install). Each build clones with a short-lived, read-only token.
  • git: any Git server over SSH. Add the returned deploy_key to the repository as a read-only deploy key, and point the server’s push webhook at webhook_url with the webhook_secret (HMAC signature on GitHub, Gitea, Forgejo, and Bitbucket; secret token on GitLab). The webhook_secret is shown only in this response. The server’s SSH host key is pinned on the first clone.

With auto_deploy on, a push to branch builds and, with deploy, deploys. A push while a build of the source is already queued does not queue another.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/sources \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

operationId: caas.sources.create

DELETE /v1/caas/{id}/sources/{name} · scope caas:deploy · destructive — cannot be undone · idempotent

Its queued builds are canceled; finished builds and their images stay. A git source loses its deploy key for good: remove it from the repository too.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/sources/web \
-X DELETE \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.sources.delete

GET /v1/caas/{id}/sources/{name} · scope caas:read

Never the webhook secret: if it was lost, rotate it.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/sources/web \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.sources.get

GET /v1/caas/{id}/sources · scope caas:read

The repositories this service builds from, with what each builds and where it deploys.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/sources \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.sources.list

POST /v1/caas/{id}/sources/{name}/webhook-secret · scope caas:deploy · reversible

git sources only (GitHub sources receive pushes through the app). Returns the new secret once; the previous one stops working immediately, so update the webhook on the Git server.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/sources/web/webhook-secret \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.sources.rotate_secret

PATCH /v1/caas/{id}/sources/{name} · scope caas:deploy · reversible · idempotent

What it builds (branch, path, dockerfile, image), where it deploys, and auto_deploy. The repository and the provider cannot change: delete the source and connect it again. Applies from the next build.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/sources/web \
-X PATCH \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

operationId: caas.sources.update

GET /v1/caas/{id}/stacks/{stack}/services/{service}/logs · scope caas:read

The latest lines from every replica, interleaved and timestamped. A snapshot, not a stream: to follow a service, call again with since.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/stacks/web/services/web/logs \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.stack_services.logs

POST /v1/caas/{id}/stacks/{stack}/services/{service}/restart · scope caas:write · reversible · idempotent

Replaces its replicas one at a time, the same way an update does: with two or more replicas the service keeps answering. Same image and configuration — to change either, deploy.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/stacks/web/services/web/restart \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.stack_services.restart

POST /v1/caas/{id}/stacks/{stack}/services/{service}/scale · scope caas:write · reversible · asynchronous · idempotent

Deploys the current version with the new replica count, as a new version (origin: scale): a later deploy of your compose file sets it back to what the file says.

Returns 202 with an operation. Fast outcomes come back already finished; otherwise wait on GET /v1/operations/{id}. Only one change runs at a time per cluster: requests queue, and a request during a rolling restart fails with 409 operation_in_progress.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/stacks/web/services/web/scale \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"replicas":1}'

operationId: caas.stack_services.scale

GET /v1/caas/{id}/stacks/{stack}/versions/{version} · scope caas:read

With the compose file exactly as it was sent. The last 20 versions of each stack are kept.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/stacks/web/versions/3 \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.stack_versions.get

DELETE /v1/caas/{id}/stacks/{stack} · scope caas:write · destructive — cannot be undone · asynchronous · idempotent

Destructive. Stops and removes every service of the stack. Its version history stays: deploying the same name again continues the numbering. Secrets, configs, and domains are not touched.

Returns 202 with an operation. Fast outcomes come back already finished; otherwise wait on GET /v1/operations/{id}. Only one change runs at a time per cluster: requests queue, and a request during a rolling restart fails with 409 operation_in_progress.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/stacks/web \
-X DELETE \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.stacks.delete

PUT /v1/caas/{id}/stacks/{stack} · scope caas:deploy · reversible · asynchronous · idempotent

Creates the stack or deploys a new version of it from a docker-compose file. Every deploy is a numbered version you can roll back to.

The compose is validated before anything runs; a rule it breaks comes back as 400 validation_failed with the reason, and nothing is changed. If the cluster rejects the deploy, the operation fails with deploy_failed and the previous version keeps running. A service whose healthcheck fails during the update is rolled back by the cluster on its own (update.state = rollback_completed).

Requires caas:deploy: deploying runs whatever the images contain.

Returns 202 with an operation. Fast outcomes come back already finished; otherwise wait on GET /v1/operations/{id}. Only one change runs at a time per cluster: requests queue, and a request during a rolling restart fails with 409 operation_in_progress.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/stacks/web \
-X PUT \
-H "Authorization: Bearer $TRUO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"compose":"<compose>"}'

operationId: caas.stacks.deploy

GET /v1/caas/{id}/stacks/{stack} · scope caas:read

The version running now with its compose file, the version history, each service with its replicas, and the tasks that are not running with their error — the first place to look when a deploy does not come up.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/stacks/web \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.stacks.get

GET /v1/caas/{id}/stacks · scope caas:read

What is declared, with what is running now. If the cluster does not answer, services comes back null and the rest is still accurate.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/stacks \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.stacks.list

POST /v1/caas/{id}/stacks/{stack}/rollback · scope caas:deploy · reversible · asynchronous · idempotent

Deploys the compose file of an earlier version as a new version (origin: rollback), so the history only grows and rolling back a rollback works the same way. Secrets and configs are the current ones, not the ones the old version had.

Returns 202 with an operation. Fast outcomes come back already finished; otherwise wait on GET /v1/operations/{id}. Only one change runs at a time per cluster: requests queue, and a request during a rolling restart fails with 409 operation_in_progress.

Terminal window
curl https://api.truo.cloud/v1/caas/svc_10432/stacks/web/rollback \
-X POST \
-H "Authorization: Bearer $TRUO_TOKEN"

operationId: caas.stacks.rollback