Deploys (referência)
POST /v1/projects/{p}/deploy
Seção intitulada “POST /v1/projects/{p}/deploy”Deploy do projeto (grupo)
Implanta vários serviços em ordem de dependência (${{svc.VAR}}), em camadas: a camada N só começa quando a N-1 está ready; dependente de um que falhou fica blocked. services vazio ou omitido = todos os serviços de aplicação que têm o que implantar: o serviço sem fonte (p.ex. o web de um projeto novo, sem upload nem git/imagem) entra no grupo como item skipped, com reason, e não faz o grupo falhar; um grupo em que tudo é skipped termina ready. Listar o serviço em services não o pula: sem fonte, o deploy dele falha. Faça polling em GET …/group-deployments/{g}. Referências inexistentes ou em ciclo são recusadas antes de criar qualquer coisa (422). Conta um deployment por serviço no limite por hora do time (429 rate_limited + Retry-After).
Escopo exigido: deploy.
Escopo exigido: deploy · operationId: deployGroup
| Parâmetro | Em | Tipo | Obrig. | Descrição |
|---|---|---|---|---|
p |
path | string | sim | Id (26 caracteres) ou slug do projeto. Projeto de outro time ou fora dos project_ids do token ⇒ 404. |
Idempotency-Key |
header | string | não | Chave de idempotência (8 a 128 caracteres [A-Za-z0-9._:-]; use um UUID). Mesma chave + mesmo pedido em 24 h ⇒ a mesma resposta, com Idempotent-Replay: true; mesma chave + pedido diferente ⇒ 422 idempotency_conflict. Falhas nunca são gravadas, então a repetição executa de verdade. |
Corpo (application/json)
Seção intitulada “Corpo (application/json)”| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
services |
array |
não | Ids ou nomes (até 100); vazio ou omitido = todos os serviços de aplicação. |
Resposta 202
Seção intitulada “Resposta 202”Deploy de grupo aceito.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
id |
string | sim | |
project_id |
string | sim | |
status |
enum(running, ready, failed, canceled, superseded) | sim | |
error |
string | não | Motivo, quando failed. |
items |
array | sim | |
items[].service_id |
string | sim | |
items[].deployment_id |
string | não | Ausente para itens blocked e skipped. |
items[].status |
enum(queued, building, deploying, ready, failed, blocked, canceled, skipped) | sim | Status do deployment do item, blocked (dependência falhou) ou skipped (serviço sem fonte para implantar; veja reason). |
items[].reason |
string | não | Motivo, presente só nos itens skipped. |
items[].layer |
integer | sim | Camada de dependência (0 = sem dependências). |
{ "id": "01jb7k7a5q8r7t2v4w6x8y0a5f", "project_id": "01jb7k3m5q8r7t2v4w6x8y0a1b", "status": "running", "items": [ { "service_id": "01jb7k4a5q8r7t2v4w6x8y0a9z", "deployment_id": "01jb7k5a5q8r7t2v4w6x8y0a3d", "status": "ready", "layer": 0 }, { "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "deployment_id": "01jb7k5a5q8r7t2v4w6x8y0a8k", "status": "building", "layer": 1 } ]}Resposta 422
Seção intitulada “Resposta 422”unresolved_reference, reference_cycle ou idempotency_conflict.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
error |
enum(unauthorized, forbidden, not_found, payload_too_large, quota_exceeded, unsupported_type, class_not_allowed, extension_mismatch, malware_detected, svg_unsafe, archive_encrypted, archive_bomb, archive_unsupported, rate_limited, unavailable, idempotency_conflict, invalid_request, unsupported_media_type, bad_json, too_large, authz_unavailable, database_unavailable, restore_not_removable, gallery_not_empty, bad_body, internal, name_taken, slug_taken, project_quota_exceeded, project_not_empty, deploy_in_progress, nothing_to_rollback, not_cancelable, sensitive_lowered, duplicate_variable, domain_taken, volume_exists, volume_in_use, volume_attached, backup_not_ready, unresolved_reference, reference_cycle, invalid_reference, reference_too_deep, value_too_large) | sim | Código estável para tratamento programático. A tabela completa está na descrição geral. |
message |
string | sim | Mensagem legível em pt-BR. |
details |
object | não | Presente em alguns 422 (ex.: unresolved_reference e reference_cycle trazem details.references). |
details.references |
array |
não | Referências problemáticas (só nomes, nunca valores). |
details.retry_after_seconds |
integer | não | Em 422 rate_limited (ex.: verificação manual de domínio): segundos até poder tentar de novo. |
{ "error": "unresolved_reference", "message": "Há referências para variáveis ou serviços que não existem.", "details": { "references": [ "db.MYSQL_HOST" ] }}Erros comuns
Seção intitulada “Erros comuns”Corpo {"error", "message", "details"?} (veja Autenticação e visão geral e a tabela de erros): 400 Entrada inválida (nome de arquivo fora das regras, cursor malformado, formulário sem file, nome de galeria vazio ou longo); 401 Token ausente, inválido, expirado ou revogado. A resposta é genérica de propósito; 403 O token não tem o escopo exigido pela operação; 404 Recurso inexistente ou pertencente a outro time (indistinguíveis de propósito); 413 Corpo JSON acima do limite da rota (too_large); 415 O corpo precisa ser application/json (unsupported_media_type); 429 Limite de requisições excedido. Espere Retry-After segundos; 500 Falha interna (internal). O detalhe fica só no log do servidor; repita depois, e informe o Idempotency-Key ao suporte se persistir; 503 Serviço (ex.: scanner ou borda) temporariamente indisponível. Tente de novo após Retry-After.
GET /v1/projects/{p}/group-deployments/{g}
Seção intitulada “GET /v1/projects/{p}/group-deployments/{g}”Consulta um deploy de grupo (polling)
Estado do grupo e de cada serviço (items, com a layer).
Escopo exigido: projects:read.
Escopo exigido: projects:read · operationId: getGroupDeployment
| Parâmetro | Em | Tipo | Obrig. | Descrição |
|---|---|---|---|---|
p |
path | string | sim | Id (26 caracteres) ou slug do projeto. Projeto de outro time ou fora dos project_ids do token ⇒ 404. |
g |
path | string | sim | Id do deploy de grupo. |
Resposta 200
Seção intitulada “Resposta 200”Grupo.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
id |
string | sim | |
project_id |
string | sim | |
status |
enum(running, ready, failed, canceled, superseded) | sim | |
error |
string | não | Motivo, quando failed. |
items |
array | sim | |
items[].service_id |
string | sim | |
items[].deployment_id |
string | não | Ausente para itens blocked e skipped. |
items[].status |
enum(queued, building, deploying, ready, failed, blocked, canceled, skipped) | sim | Status do deployment do item, blocked (dependência falhou) ou skipped (serviço sem fonte para implantar; veja reason). |
items[].reason |
string | não | Motivo, presente só nos itens skipped. |
items[].layer |
integer | sim | Camada de dependência (0 = sem dependências). |
{ "id": "01jb7k7a5q8r7t2v4w6x8y0a5f", "project_id": "01jb7k3m5q8r7t2v4w6x8y0a1b", "status": "running", "items": [ { "service_id": "01jb7k4a5q8r7t2v4w6x8y0a9z", "deployment_id": "01jb7k5a5q8r7t2v4w6x8y0a3d", "status": "ready", "layer": 0 }, { "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "deployment_id": "01jb7k5a5q8r7t2v4w6x8y0a8k", "status": "building", "layer": 1 } ]}Erros comuns
Seção intitulada “Erros comuns”Corpo {"error", "message", "details"?} (veja Autenticação e visão geral e a tabela de erros): 401 Token ausente, inválido, expirado ou revogado. A resposta é genérica de propósito; 403 O token não tem o escopo exigido pela operação; 404 Recurso inexistente ou pertencente a outro time (indistinguíveis de propósito); 429 Limite de requisições excedido. Espere Retry-After segundos; 500 Falha interna (internal). O detalhe fica só no log do servidor; repita depois, e informe o Idempotency-Key ao suporte se persistir; 503 Serviço (ex.: scanner ou borda) temporariamente indisponível. Tente de novo após Retry-After.
POST /v1/projects/{p}/group-deployments/{g}/cancel
Seção intitulada “POST /v1/projects/{p}/group-deployments/{g}/cancel”Cancela um deploy de grupo
Cancela o que ainda não terminou. Um grupo finalizado volta inalterado.
Escopo exigido: deploy.
Escopo exigido: deploy · operationId: cancelGroupDeployment
| Parâmetro | Em | Tipo | Obrig. | Descrição |
|---|---|---|---|---|
p |
path | string | sim | Id (26 caracteres) ou slug do projeto. Projeto de outro time ou fora dos project_ids do token ⇒ 404. |
g |
path | string | sim | Id do deploy de grupo. |
Resposta 202
Seção intitulada “Resposta 202”Grupo (cancelado ou inalterado).
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
id |
string | sim | |
project_id |
string | sim | |
status |
enum(running, ready, failed, canceled, superseded) | sim | |
error |
string | não | Motivo, quando failed. |
items |
array | sim | |
items[].service_id |
string | sim | |
items[].deployment_id |
string | não | Ausente para itens blocked e skipped. |
items[].status |
enum(queued, building, deploying, ready, failed, blocked, canceled, skipped) | sim | Status do deployment do item, blocked (dependência falhou) ou skipped (serviço sem fonte para implantar; veja reason). |
items[].reason |
string | não | Motivo, presente só nos itens skipped. |
items[].layer |
integer | sim | Camada de dependência (0 = sem dependências). |
{ "id": "01jb7k7a5q8r7t2v4w6x8y0a5f", "project_id": "01jb7k3m5q8r7t2v4w6x8y0a1b", "status": "running", "items": [ { "service_id": "01jb7k4a5q8r7t2v4w6x8y0a9z", "deployment_id": "01jb7k5a5q8r7t2v4w6x8y0a3d", "status": "ready", "layer": 0 }, { "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "deployment_id": "01jb7k5a5q8r7t2v4w6x8y0a8k", "status": "building", "layer": 1 } ]}Erros comuns
Seção intitulada “Erros comuns”Corpo {"error", "message", "details"?} (veja Autenticação e visão geral e a tabela de erros): 401 Token ausente, inválido, expirado ou revogado. A resposta é genérica de propósito; 403 O token não tem o escopo exigido pela operação; 404 Recurso inexistente ou pertencente a outro time (indistinguíveis de propósito); 429 Limite de requisições excedido. Espere Retry-After segundos; 500 Falha interna (internal). O detalhe fica só no log do servidor; repita depois, e informe o Idempotency-Key ao suporte se persistir; 503 Serviço (ex.: scanner ou borda) temporariamente indisponível. Tente de novo após Retry-After.
GET /v1/projects/{p}/services/{s}/deployments
Seção intitulada “GET /v1/projects/{p}/services/{s}/deployments”Lista os deployments do serviço
Deployments do mais novo para o mais antigo.
Escopo exigido: projects:read.
Escopo exigido: projects:read · operationId: listDeployments
| Parâmetro | Em | Tipo | Obrig. | Descrição |
|---|---|---|---|---|
p |
path | string | sim | Id (26 caracteres) ou slug do projeto. Projeto de outro time ou fora dos project_ids do token ⇒ 404. |
s |
path | string | sim | Id ou nome do serviço dentro do projeto. |
cursor |
query | string | não | Cursor opaco devolvido em next_cursor da página anterior. |
limit |
query | integer | não | Itens por página (1 a 200). |
Resposta 200
Seção intitulada “Resposta 200”Página (mais novo/antigo primeiro conforme o recurso).
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
next_cursor |
string|null | sim | Passe em cursor para a próxima página; null ao fim. |
has_more |
boolean | sim | Há mais páginas. |
items |
array | sim | |
items[].id |
string | sim | |
items[].service_id |
string | sim | |
items[].group_deployment_id |
string | não | |
items[].status |
enum(queued, building, deploying, ready, failed, blocked, canceled, superseded) | sim | canceled e deploying podem ainda aparecer como failed/building em instalações antigas. |
items[].trigger |
enum(api, git, dash, rollback, template, manual) | sim | Quem disparou. manual é o que o servidor devolve para disparos feitos pelo painel quando a origem não foi registrada. |
items[].source_ref |
string | não | SHA/branch (git) ou referência da imagem. |
items[].image_digest |
string | não | |
items[].error |
object | não | |
items[].error.code |
string | sim | Código estável da falha: deploy_failed (genérico), unresolved_reference, reference_cycle, image_requires_root, crashed_after_start e os do build: build_clone_failed, build_detect_failed, build_install_failed, build_script_failed, build_copy_failed, build_activate_failed, activate_readonly_write (o app tentou gravar sob /app, somente leitura: use um volume nessa pasta ou /tmp), activate_app_crashed (o app encerrou logo ao iniciar; a mensagem traz a primeira linha de erro do log), activate_oom (o app usou mais memória que o limite do serviço e foi encerrado), activate_no_http (o app estável e rodando não respondeu na porta esperada), team_app_limit (o time já roda o máximo de apps do plano; a mensagem traz N de M: pare ou remova um app, ou peça ao operador para ampliar o limite), build_volume_unavailable, build_oom, build_timeout, build_storage_error (falha interna de armazenamento da plataforma, não do repositório), build_disk_full (espaço de build cheio) e build_storage_unavailable (nenhum armazenamento de build utilizável na plataforma; não é falta de espaço). O código vem gravado com o deploy; message traz a causa em português (sem segredos nem caminhos do servidor). |
items[].error.message |
string | sim | |
items[].error.details |
any | não | Dados extras do erro (qualquer JSON). |
items[].created_at |
string | sim | |
items[].started_at |
string | não | |
items[].finished_at |
string | não |
{ "items": [ { "id": "01jb7k5a5q8r7t2v4w6x8y0a3d", "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "group_deployment_id": "01jb7k7a5q8r7t2v4w6x8y0a5f", "status": "building", "trigger": "api", "source_ref": "main", "created_at": "2026-10-10T14:03:11Z", "started_at": "2026-10-10T14:03:11Z" } ], "next_cursor": "MDFqYjdrNWE1cThyN3QydjR3NnU4eTBhM2Q", "has_more": true}Erros comuns
Seção intitulada “Erros comuns”Corpo {"error", "message", "details"?} (veja Autenticação e visão geral e a tabela de erros): 400 Entrada inválida (nome de arquivo fora das regras, cursor malformado, formulário sem file, nome de galeria vazio ou longo); 401 Token ausente, inválido, expirado ou revogado. A resposta é genérica de propósito; 403 O token não tem o escopo exigido pela operação; 404 Recurso inexistente ou pertencente a outro time (indistinguíveis de propósito); 429 Limite de requisições excedido. Espere Retry-After segundos; 500 Falha interna (internal). O detalhe fica só no log do servidor; repita depois, e informe o Idempotency-Key ao suporte se persistir; 503 Serviço (ex.: scanner ou borda) temporariamente indisponível. Tente de novo após Retry-After.
POST /v1/projects/{p}/services/{s}/deployments
Seção intitulada “POST /v1/projects/{p}/services/{s}/deployments”Dispara um deploy do serviço
Dispara um deployment do serviço e devolve 202 com o deployment (o trabalho é assíncrono: faça polling em GET …/deployments/{d}).
Corpo: {} (último commit da branch ou a imagem do serviço), {"ref":"<sha|branch>"} (git), {"image":"repo@sha256:…"} (imagem), ou multipart com o campo file (tar.gz ou zip, até 512 MB) para enviar o código-fonte.
Referências ${{svc.VAR}} são validadas no disparo: inexistentes ou em ciclo ⇒ 422 unresolved_reference / reference_cycle com details.references; se só aparecerem no build, ficam em deployment.error.
Estados: queued → building → deploying → ready, ou failed / blocked / canceled / superseded. Faça polling com backoff (comece em 2 s, dobre até 15 s). Não há webhooks neste ciclo.
Limite por hora: cada time pode criar no máximo N deployments (todos os projetos somados) em uma janela deslizante de 1 hora (GET /v1/limits → deploys_per_hour); acima disso, 429 rate_limited com Retry-After (segundos até liberar uma vaga).
Imagem com USER root roda como 65534; se o container encerrar nos primeiros 30 s depois de iniciar, o deployment falha com error.code=image_requires_root e a mensagem pede para declarar build.user (uid[:gid], nunca root) no serviço. Corpo ausente (sem Content-Type) vale {}; com corpo, é JSON (ou multipart). Armazenamento de builds da plataforma cheio ou indisponível ⇒ 503 unavailable com details.deployment_id (um deployment failed fica no histórico com error.code build_disk_full ou build_storage_unavailable) e details.error_code; repita em alguns minutos.
Escopo exigido: deploy.
Escopo exigido: deploy · operationId: createDeployment
| Parâmetro | Em | Tipo | Obrig. | Descrição |
|---|---|---|---|---|
p |
path | string | sim | Id (26 caracteres) ou slug do projeto. Projeto de outro time ou fora dos project_ids do token ⇒ 404. |
s |
path | string | sim | Id ou nome do serviço dentro do projeto. |
Idempotency-Key |
header | string | não | Chave de idempotência (8 a 128 caracteres [A-Za-z0-9._:-]; use um UUID). Mesma chave + mesmo pedido em 24 h ⇒ a mesma resposta, com Idempotent-Replay: true; mesma chave + pedido diferente ⇒ 422 idempotency_conflict. Falhas nunca são gravadas, então a repetição executa de verdade. |
Corpo (application/json)
Seção intitulada “Corpo (application/json)”Corpo (multipart/form-data)
Seção intitulada “Corpo (multipart/form-data)”| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
file |
string | sim | Arquivo .tar.gz ou .zip com o código. |
Resposta 202
Seção intitulada “Resposta 202”Deployment aceito.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
id |
string | sim | |
service_id |
string | sim | |
group_deployment_id |
string | não | |
status |
enum(queued, building, deploying, ready, failed, blocked, canceled, superseded) | sim | canceled e deploying podem ainda aparecer como failed/building em instalações antigas. |
trigger |
enum(api, git, dash, rollback, template, manual) | sim | Quem disparou. manual é o que o servidor devolve para disparos feitos pelo painel quando a origem não foi registrada. |
source_ref |
string | não | SHA/branch (git) ou referência da imagem. |
image_digest |
string | não | |
error |
object | não | |
error.code |
string | sim | Código estável da falha: deploy_failed (genérico), unresolved_reference, reference_cycle, image_requires_root, crashed_after_start e os do build: build_clone_failed, build_detect_failed, build_install_failed, build_script_failed, build_copy_failed, build_activate_failed, activate_readonly_write (o app tentou gravar sob /app, somente leitura: use um volume nessa pasta ou /tmp), activate_app_crashed (o app encerrou logo ao iniciar; a mensagem traz a primeira linha de erro do log), activate_oom (o app usou mais memória que o limite do serviço e foi encerrado), activate_no_http (o app estável e rodando não respondeu na porta esperada), team_app_limit (o time já roda o máximo de apps do plano; a mensagem traz N de M: pare ou remova um app, ou peça ao operador para ampliar o limite), build_volume_unavailable, build_oom, build_timeout, build_storage_error (falha interna de armazenamento da plataforma, não do repositório), build_disk_full (espaço de build cheio) e build_storage_unavailable (nenhum armazenamento de build utilizável na plataforma; não é falta de espaço). O código vem gravado com o deploy; message traz a causa em português (sem segredos nem caminhos do servidor). |
error.message |
string | sim | |
error.details |
any | não | Dados extras do erro (qualquer JSON). |
created_at |
string | sim | |
started_at |
string | não | |
finished_at |
string | não |
{ "id": "01jb7k5a5q8r7t2v4w6x8y0a3d", "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "group_deployment_id": "01jb7k7a5q8r7t2v4w6x8y0a5f", "status": "building", "trigger": "api", "source_ref": "main", "created_at": "2026-10-10T14:03:11Z", "started_at": "2026-10-10T14:03:11Z"}Resposta 409
Seção intitulada “Resposta 409”deploy_in_progress: já há um deploy em andamento neste serviço.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
error |
enum(unauthorized, forbidden, not_found, payload_too_large, quota_exceeded, unsupported_type, class_not_allowed, extension_mismatch, malware_detected, svg_unsafe, archive_encrypted, archive_bomb, archive_unsupported, rate_limited, unavailable, idempotency_conflict, invalid_request, unsupported_media_type, bad_json, too_large, authz_unavailable, database_unavailable, restore_not_removable, gallery_not_empty, bad_body, internal, name_taken, slug_taken, project_quota_exceeded, project_not_empty, deploy_in_progress, nothing_to_rollback, not_cancelable, sensitive_lowered, duplicate_variable, domain_taken, volume_exists, volume_in_use, volume_attached, backup_not_ready, unresolved_reference, reference_cycle, invalid_reference, reference_too_deep, value_too_large) | sim | Código estável para tratamento programático. A tabela completa está na descrição geral. |
message |
string | sim | Mensagem legível em pt-BR. |
details |
object | não | Presente em alguns 422 (ex.: unresolved_reference e reference_cycle trazem details.references). |
details.references |
array |
não | Referências problemáticas (só nomes, nunca valores). |
details.retry_after_seconds |
integer | não | Em 422 rate_limited (ex.: verificação manual de domínio): segundos até poder tentar de novo. |
Resposta 413
Seção intitulada “Resposta 413”Código-fonte (multipart) acima do limite.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
error |
enum(unauthorized, forbidden, not_found, payload_too_large, quota_exceeded, unsupported_type, class_not_allowed, extension_mismatch, malware_detected, svg_unsafe, archive_encrypted, archive_bomb, archive_unsupported, rate_limited, unavailable, idempotency_conflict, invalid_request, unsupported_media_type, bad_json, too_large, authz_unavailable, database_unavailable, restore_not_removable, gallery_not_empty, bad_body, internal, name_taken, slug_taken, project_quota_exceeded, project_not_empty, deploy_in_progress, nothing_to_rollback, not_cancelable, sensitive_lowered, duplicate_variable, domain_taken, volume_exists, volume_in_use, volume_attached, backup_not_ready, unresolved_reference, reference_cycle, invalid_reference, reference_too_deep, value_too_large) | sim | Código estável para tratamento programático. A tabela completa está na descrição geral. |
message |
string | sim | Mensagem legível em pt-BR. |
details |
object | não | Presente em alguns 422 (ex.: unresolved_reference e reference_cycle trazem details.references). |
details.references |
array |
não | Referências problemáticas (só nomes, nunca valores). |
details.retry_after_seconds |
integer | não | Em 422 rate_limited (ex.: verificação manual de domínio): segundos até poder tentar de novo. |
Resposta 422
Seção intitulada “Resposta 422”unresolved_reference, reference_cycle, invalid_reference, reference_too_deep, value_too_large (com details) ou idempotency_conflict.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
error |
enum(unauthorized, forbidden, not_found, payload_too_large, quota_exceeded, unsupported_type, class_not_allowed, extension_mismatch, malware_detected, svg_unsafe, archive_encrypted, archive_bomb, archive_unsupported, rate_limited, unavailable, idempotency_conflict, invalid_request, unsupported_media_type, bad_json, too_large, authz_unavailable, database_unavailable, restore_not_removable, gallery_not_empty, bad_body, internal, name_taken, slug_taken, project_quota_exceeded, project_not_empty, deploy_in_progress, nothing_to_rollback, not_cancelable, sensitive_lowered, duplicate_variable, domain_taken, volume_exists, volume_in_use, volume_attached, backup_not_ready, unresolved_reference, reference_cycle, invalid_reference, reference_too_deep, value_too_large) | sim | Código estável para tratamento programático. A tabela completa está na descrição geral. |
message |
string | sim | Mensagem legível em pt-BR. |
details |
object | não | Presente em alguns 422 (ex.: unresolved_reference e reference_cycle trazem details.references). |
details.references |
array |
não | Referências problemáticas (só nomes, nunca valores). |
details.retry_after_seconds |
integer | não | Em 422 rate_limited (ex.: verificação manual de domínio): segundos até poder tentar de novo. |
{ "error": "unresolved_reference", "message": "Há referências para variáveis ou serviços que não existem.", "details": { "references": [ "db.MYSQL_HOST" ] }}Erros comuns
Seção intitulada “Erros comuns”Corpo {"error", "message", "details"?} (veja Autenticação e visão geral e a tabela de erros): 400 Entrada inválida (nome de arquivo fora das regras, cursor malformado, formulário sem file, nome de galeria vazio ou longo); 401 Token ausente, inválido, expirado ou revogado. A resposta é genérica de propósito; 403 O token não tem o escopo exigido pela operação; 404 Recurso inexistente ou pertencente a outro time (indistinguíveis de propósito); 415 O corpo precisa ser application/json (unsupported_media_type); 429 Limite de requisições excedido. Espere Retry-After segundos; 500 Falha interna (internal). O detalhe fica só no log do servidor; repita depois, e informe o Idempotency-Key ao suporte se persistir; 503 Serviço (ex.: scanner ou borda) temporariamente indisponível. Tente de novo após Retry-After.
GET /v1/projects/{p}/services/{s}/deployments/{d}
Seção intitulada “GET /v1/projects/{p}/services/{s}/deployments/{d}”Consulta um deployment (polling)
Estado atual do deployment. Quando failed, error traz code, message e details.
Escopo exigido: projects:read.
Escopo exigido: projects:read · operationId: getDeployment
| Parâmetro | Em | Tipo | Obrig. | Descrição |
|---|---|---|---|---|
p |
path | string | sim | Id (26 caracteres) ou slug do projeto. Projeto de outro time ou fora dos project_ids do token ⇒ 404. |
s |
path | string | sim | Id ou nome do serviço dentro do projeto. |
d |
path | string | sim | Id do deployment (do serviço da rota). |
Resposta 200
Seção intitulada “Resposta 200”Deployment.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
id |
string | sim | |
service_id |
string | sim | |
group_deployment_id |
string | não | |
status |
enum(queued, building, deploying, ready, failed, blocked, canceled, superseded) | sim | canceled e deploying podem ainda aparecer como failed/building em instalações antigas. |
trigger |
enum(api, git, dash, rollback, template, manual) | sim | Quem disparou. manual é o que o servidor devolve para disparos feitos pelo painel quando a origem não foi registrada. |
source_ref |
string | não | SHA/branch (git) ou referência da imagem. |
image_digest |
string | não | |
error |
object | não | |
error.code |
string | sim | Código estável da falha: deploy_failed (genérico), unresolved_reference, reference_cycle, image_requires_root, crashed_after_start e os do build: build_clone_failed, build_detect_failed, build_install_failed, build_script_failed, build_copy_failed, build_activate_failed, activate_readonly_write (o app tentou gravar sob /app, somente leitura: use um volume nessa pasta ou /tmp), activate_app_crashed (o app encerrou logo ao iniciar; a mensagem traz a primeira linha de erro do log), activate_oom (o app usou mais memória que o limite do serviço e foi encerrado), activate_no_http (o app estável e rodando não respondeu na porta esperada), team_app_limit (o time já roda o máximo de apps do plano; a mensagem traz N de M: pare ou remova um app, ou peça ao operador para ampliar o limite), build_volume_unavailable, build_oom, build_timeout, build_storage_error (falha interna de armazenamento da plataforma, não do repositório), build_disk_full (espaço de build cheio) e build_storage_unavailable (nenhum armazenamento de build utilizável na plataforma; não é falta de espaço). O código vem gravado com o deploy; message traz a causa em português (sem segredos nem caminhos do servidor). |
error.message |
string | sim | |
error.details |
any | não | Dados extras do erro (qualquer JSON). |
created_at |
string | sim | |
started_at |
string | não | |
finished_at |
string | não |
{ "id": "01jb7k5a5q8r7t2v4w6x8y0a3d", "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "group_deployment_id": "01jb7k7a5q8r7t2v4w6x8y0a5f", "status": "building", "trigger": "api", "source_ref": "main", "created_at": "2026-10-10T14:03:11Z", "started_at": "2026-10-10T14:03:11Z"}Erros comuns
Seção intitulada “Erros comuns”Corpo {"error", "message", "details"?} (veja Autenticação e visão geral e a tabela de erros): 401 Token ausente, inválido, expirado ou revogado. A resposta é genérica de propósito; 403 O token não tem o escopo exigido pela operação; 404 Recurso inexistente ou pertencente a outro time (indistinguíveis de propósito); 429 Limite de requisições excedido. Espere Retry-After segundos; 500 Falha interna (internal). O detalhe fica só no log do servidor; repita depois, e informe o Idempotency-Key ao suporte se persistir; 503 Serviço (ex.: scanner ou borda) temporariamente indisponível. Tente de novo após Retry-After.
POST /v1/projects/{p}/services/{s}/deployments/{d}/cancel
Seção intitulada “POST /v1/projects/{p}/services/{s}/deployments/{d}/cancel”Cancela um deployment
Cancela um deployment queued/building/deploying. Um deployment já terminado volta inalterado. Só cancela jobs enfileirados no processo atual (409 not_cancelable nos demais).
Escopo exigido: deploy.
Escopo exigido: deploy · operationId: cancelDeployment
| Parâmetro | Em | Tipo | Obrig. | Descrição |
|---|---|---|---|---|
p |
path | string | sim | Id (26 caracteres) ou slug do projeto. Projeto de outro time ou fora dos project_ids do token ⇒ 404. |
s |
path | string | sim | Id ou nome do serviço dentro do projeto. |
d |
path | string | sim | Id do deployment (do serviço da rota). |
Resposta 202
Seção intitulada “Resposta 202”Deployment (cancelado ou inalterado).
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
id |
string | sim | |
service_id |
string | sim | |
group_deployment_id |
string | não | |
status |
enum(queued, building, deploying, ready, failed, blocked, canceled, superseded) | sim | canceled e deploying podem ainda aparecer como failed/building em instalações antigas. |
trigger |
enum(api, git, dash, rollback, template, manual) | sim | Quem disparou. manual é o que o servidor devolve para disparos feitos pelo painel quando a origem não foi registrada. |
source_ref |
string | não | SHA/branch (git) ou referência da imagem. |
image_digest |
string | não | |
error |
object | não | |
error.code |
string | sim | Código estável da falha: deploy_failed (genérico), unresolved_reference, reference_cycle, image_requires_root, crashed_after_start e os do build: build_clone_failed, build_detect_failed, build_install_failed, build_script_failed, build_copy_failed, build_activate_failed, activate_readonly_write (o app tentou gravar sob /app, somente leitura: use um volume nessa pasta ou /tmp), activate_app_crashed (o app encerrou logo ao iniciar; a mensagem traz a primeira linha de erro do log), activate_oom (o app usou mais memória que o limite do serviço e foi encerrado), activate_no_http (o app estável e rodando não respondeu na porta esperada), team_app_limit (o time já roda o máximo de apps do plano; a mensagem traz N de M: pare ou remova um app, ou peça ao operador para ampliar o limite), build_volume_unavailable, build_oom, build_timeout, build_storage_error (falha interna de armazenamento da plataforma, não do repositório), build_disk_full (espaço de build cheio) e build_storage_unavailable (nenhum armazenamento de build utilizável na plataforma; não é falta de espaço). O código vem gravado com o deploy; message traz a causa em português (sem segredos nem caminhos do servidor). |
error.message |
string | sim | |
error.details |
any | não | Dados extras do erro (qualquer JSON). |
created_at |
string | sim | |
started_at |
string | não | |
finished_at |
string | não |
{ "id": "01jb7k5a5q8r7t2v4w6x8y0a3d", "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "group_deployment_id": "01jb7k7a5q8r7t2v4w6x8y0a5f", "status": "building", "trigger": "api", "source_ref": "main", "created_at": "2026-10-10T14:03:11Z", "started_at": "2026-10-10T14:03:11Z"}Resposta 409
Seção intitulada “Resposta 409”not_cancelable.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
error |
enum(unauthorized, forbidden, not_found, payload_too_large, quota_exceeded, unsupported_type, class_not_allowed, extension_mismatch, malware_detected, svg_unsafe, archive_encrypted, archive_bomb, archive_unsupported, rate_limited, unavailable, idempotency_conflict, invalid_request, unsupported_media_type, bad_json, too_large, authz_unavailable, database_unavailable, restore_not_removable, gallery_not_empty, bad_body, internal, name_taken, slug_taken, project_quota_exceeded, project_not_empty, deploy_in_progress, nothing_to_rollback, not_cancelable, sensitive_lowered, duplicate_variable, domain_taken, volume_exists, volume_in_use, volume_attached, backup_not_ready, unresolved_reference, reference_cycle, invalid_reference, reference_too_deep, value_too_large) | sim | Código estável para tratamento programático. A tabela completa está na descrição geral. |
message |
string | sim | Mensagem legível em pt-BR. |
details |
object | não | Presente em alguns 422 (ex.: unresolved_reference e reference_cycle trazem details.references). |
details.references |
array |
não | Referências problemáticas (só nomes, nunca valores). |
details.retry_after_seconds |
integer | não | Em 422 rate_limited (ex.: verificação manual de domínio): segundos até poder tentar de novo. |
Erros comuns
Seção intitulada “Erros comuns”Corpo {"error", "message", "details"?} (veja Autenticação e visão geral e a tabela de erros): 401 Token ausente, inválido, expirado ou revogado. A resposta é genérica de propósito; 403 O token não tem o escopo exigido pela operação; 404 Recurso inexistente ou pertencente a outro time (indistinguíveis de propósito); 429 Limite de requisições excedido. Espere Retry-After segundos; 500 Falha interna (internal). O detalhe fica só no log do servidor; repita depois, e informe o Idempotency-Key ao suporte se persistir; 503 Serviço (ex.: scanner ou borda) temporariamente indisponível. Tente de novo após Retry-After.
POST /v1/projects/{p}/services/{s}/deployments/{d}/rollback
Seção intitulada “POST /v1/projects/{p}/services/{s}/deployments/{d}/rollback”Volta para um deployment anterior
Cria um novo deployment (trigger=rollback) que reimplanta {d} com as variáveis dele. Corpo: {} ou vazio. Conta no limite de deployments por hora do time (429 rate_limited + Retry-After).
Escopo exigido: deploy.
Escopo exigido: deploy · operationId: rollbackDeployment
| Parâmetro | Em | Tipo | Obrig. | Descrição |
|---|---|---|---|---|
p |
path | string | sim | Id (26 caracteres) ou slug do projeto. Projeto de outro time ou fora dos project_ids do token ⇒ 404. |
s |
path | string | sim | Id ou nome do serviço dentro do projeto. |
d |
path | string | sim | Id do deployment (do serviço da rota). |
Idempotency-Key |
header | string | não | Chave de idempotência (8 a 128 caracteres [A-Za-z0-9._:-]; use um UUID). Mesma chave + mesmo pedido em 24 h ⇒ a mesma resposta, com Idempotent-Replay: true; mesma chave + pedido diferente ⇒ 422 idempotency_conflict. Falhas nunca são gravadas, então a repetição executa de verdade. |
Resposta 202
Seção intitulada “Resposta 202”Rollback aceito (novo deployment).
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
id |
string | sim | |
service_id |
string | sim | |
group_deployment_id |
string | não | |
status |
enum(queued, building, deploying, ready, failed, blocked, canceled, superseded) | sim | canceled e deploying podem ainda aparecer como failed/building em instalações antigas. |
trigger |
enum(api, git, dash, rollback, template, manual) | sim | Quem disparou. manual é o que o servidor devolve para disparos feitos pelo painel quando a origem não foi registrada. |
source_ref |
string | não | SHA/branch (git) ou referência da imagem. |
image_digest |
string | não | |
error |
object | não | |
error.code |
string | sim | Código estável da falha: deploy_failed (genérico), unresolved_reference, reference_cycle, image_requires_root, crashed_after_start e os do build: build_clone_failed, build_detect_failed, build_install_failed, build_script_failed, build_copy_failed, build_activate_failed, activate_readonly_write (o app tentou gravar sob /app, somente leitura: use um volume nessa pasta ou /tmp), activate_app_crashed (o app encerrou logo ao iniciar; a mensagem traz a primeira linha de erro do log), activate_oom (o app usou mais memória que o limite do serviço e foi encerrado), activate_no_http (o app estável e rodando não respondeu na porta esperada), team_app_limit (o time já roda o máximo de apps do plano; a mensagem traz N de M: pare ou remova um app, ou peça ao operador para ampliar o limite), build_volume_unavailable, build_oom, build_timeout, build_storage_error (falha interna de armazenamento da plataforma, não do repositório), build_disk_full (espaço de build cheio) e build_storage_unavailable (nenhum armazenamento de build utilizável na plataforma; não é falta de espaço). O código vem gravado com o deploy; message traz a causa em português (sem segredos nem caminhos do servidor). |
error.message |
string | sim | |
error.details |
any | não | Dados extras do erro (qualquer JSON). |
created_at |
string | sim | |
started_at |
string | não | |
finished_at |
string | não |
{ "id": "01jb7k5a5q8r7t2v4w6x8y0a3d", "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "group_deployment_id": "01jb7k7a5q8r7t2v4w6x8y0a5f", "status": "building", "trigger": "api", "source_ref": "main", "created_at": "2026-10-10T14:03:11Z", "started_at": "2026-10-10T14:03:11Z"}Resposta 409
Seção intitulada “Resposta 409”nothing_to_rollback ou deploy_in_progress.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
error |
enum(unauthorized, forbidden, not_found, payload_too_large, quota_exceeded, unsupported_type, class_not_allowed, extension_mismatch, malware_detected, svg_unsafe, archive_encrypted, archive_bomb, archive_unsupported, rate_limited, unavailable, idempotency_conflict, invalid_request, unsupported_media_type, bad_json, too_large, authz_unavailable, database_unavailable, restore_not_removable, gallery_not_empty, bad_body, internal, name_taken, slug_taken, project_quota_exceeded, project_not_empty, deploy_in_progress, nothing_to_rollback, not_cancelable, sensitive_lowered, duplicate_variable, domain_taken, volume_exists, volume_in_use, volume_attached, backup_not_ready, unresolved_reference, reference_cycle, invalid_reference, reference_too_deep, value_too_large) | sim | Código estável para tratamento programático. A tabela completa está na descrição geral. |
message |
string | sim | Mensagem legível em pt-BR. |
details |
object | não | Presente em alguns 422 (ex.: unresolved_reference e reference_cycle trazem details.references). |
details.references |
array |
não | Referências problemáticas (só nomes, nunca valores). |
details.retry_after_seconds |
integer | não | Em 422 rate_limited (ex.: verificação manual de domínio): segundos até poder tentar de novo. |
Resposta 422
Seção intitulada “Resposta 422”idempotency_conflict.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
error |
enum(unauthorized, forbidden, not_found, payload_too_large, quota_exceeded, unsupported_type, class_not_allowed, extension_mismatch, malware_detected, svg_unsafe, archive_encrypted, archive_bomb, archive_unsupported, rate_limited, unavailable, idempotency_conflict, invalid_request, unsupported_media_type, bad_json, too_large, authz_unavailable, database_unavailable, restore_not_removable, gallery_not_empty, bad_body, internal, name_taken, slug_taken, project_quota_exceeded, project_not_empty, deploy_in_progress, nothing_to_rollback, not_cancelable, sensitive_lowered, duplicate_variable, domain_taken, volume_exists, volume_in_use, volume_attached, backup_not_ready, unresolved_reference, reference_cycle, invalid_reference, reference_too_deep, value_too_large) | sim | Código estável para tratamento programático. A tabela completa está na descrição geral. |
message |
string | sim | Mensagem legível em pt-BR. |
details |
object | não | Presente em alguns 422 (ex.: unresolved_reference e reference_cycle trazem details.references). |
details.references |
array |
não | Referências problemáticas (só nomes, nunca valores). |
details.retry_after_seconds |
integer | não | Em 422 rate_limited (ex.: verificação manual de domínio): segundos até poder tentar de novo. |
{ "error": "idempotency_conflict", "message": "Esta Idempotency-Key já foi usada com outro conteúdo. Gere uma chave nova."}Erros comuns
Seção intitulada “Erros comuns”Corpo {"error", "message", "details"?} (veja Autenticação e visão geral e a tabela de erros): 400 Entrada inválida (nome de arquivo fora das regras, cursor malformado, formulário sem file, nome de galeria vazio ou longo); 401 Token ausente, inválido, expirado ou revogado. A resposta é genérica de propósito; 403 O token não tem o escopo exigido pela operação; 404 Recurso inexistente ou pertencente a outro time (indistinguíveis de propósito); 429 Limite de requisições excedido. Espere Retry-After segundos; 500 Falha interna (internal). O detalhe fica só no log do servidor; repita depois, e informe o Idempotency-Key ao suporte se persistir; 503 Serviço (ex.: scanner ou borda) temporariamente indisponível. Tente de novo após Retry-After.