Domínios (referência)
GET /v1/projects/{p}/services/{s}/domains
Seção intitulada “GET /v1/projects/{p}/services/{s}/domains”Lista os domínios do serviço
Domínios próprios anexados ao serviço, com o estado de verificação.
Escopo exigido: projects:read.
Escopo exigido: projects:read · operationId: listDomains
| 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[].hostname |
string | sim | |
items[].service_id |
string | sim | |
items[].status |
enum(pending_dns, verifying, active, error) | sim | |
items[].dns |
object | sim | |
items[].dns.type |
string | sim | |
items[].dns.name |
string | sim | |
items[].dns.value |
string | sim | |
items[].verification |
object | sim | |
items[].verification.type |
string | sim | |
items[].verification.name |
string | sim | |
items[].verification.value |
string | sim | |
items[].error |
string | não | Motivo (misconfigured, conflict, txt_missing, wrong_target, dns_error…). |
items[].redirect_to |
string | não | |
items[].created_at |
string | sim |
{ "items": [ { "id": "01jb7k6a5q8r7t2v4w6x8y0a4e", "hostname": "www.exemplo.test", "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "status": "pending_dns", "dns": { "type": "CNAME", "name": "www.exemplo.test", "value": "loja.nebularapps.com" }, "verification": { "type": "TXT", "name": "_nebular-challenge.www.exemplo.test", "value": "nebular-verify=8f2c1d" }, "created_at": "2026-10-10T14:03:11Z" } ], "next_cursor": null, "has_more": false}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}/domains
Seção intitulada “POST /v1/projects/{p}/services/{s}/domains”Anexa um domínio
Cria o domínio em pending_dns e devolve as instruções: o registro dns (CNAME/A) apontando para a plataforma e o verification TXT que prova a posse. Crie os dois no seu DNS e consulte o domínio até active.
Só serviços públicos (visibility=public) aceitam domínio: num serviço privado a resposta é 400 invalid_request.
Se o hostname já é de um domínio deste mesmo projeto que ficou sem site (o serviço dele foi apagado; fica em revisão), ele é religado a este serviço em vez de responder 409 domain_taken. Hostname de outro projeto ou de um domínio ligado a outro site continua 409.
Escopo exigido: domains:write.
Escopo exigido: domains:write · operationId: createDomain
| 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)”| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
hostname |
string | sim | |
redirect_to |
string | não | Hostname para o qual redirecionar. |
Resposta 201
Seção intitulada “Resposta 201”Domínio criado.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
id |
string | sim | |
hostname |
string | sim | |
service_id |
string | sim | |
status |
enum(pending_dns, verifying, active, error) | sim | |
dns |
object | sim | |
dns.type |
string | sim | |
dns.name |
string | sim | |
dns.value |
string | sim | |
verification |
object | sim | |
verification.type |
string | sim | |
verification.name |
string | sim | |
verification.value |
string | sim | |
error |
string | não | Motivo (misconfigured, conflict, txt_missing, wrong_target, dns_error…). |
redirect_to |
string | não | |
created_at |
string | sim |
{ "id": "01jb7k6a5q8r7t2v4w6x8y0a4e", "hostname": "www.exemplo.test", "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "status": "pending_dns", "dns": { "type": "CNAME", "name": "www.exemplo.test", "value": "loja.nebularapps.com" }, "verification": { "type": "TXT", "name": "_nebular-challenge.www.exemplo.test", "value": "nebular-verify=8f2c1d" }, "created_at": "2026-10-10T14:03:11Z"}Resposta 400
Seção intitulada “Resposta 400”invalid_request: hostname ausente/inválido, ou o serviço não é público (visibility=private não aceita domínio).
| 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": "invalid_request", "message": "Só serviços públicos aceitam domínio."}Resposta 409
Seção intitulada “Resposta 409”domain_taken: o hostname já está em uso (por outro projeto ou por um domínio ligado a outro site).
| 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”quota_exceeded (limite de domínios do projeto) 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": "quota_exceeded", "message": "Limite de serviços do plano atingido."}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); 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}/services/{s}/domains/{d}
Seção intitulada “GET /v1/projects/{p}/services/{s}/domains/{d}”Consulta um domínio
Estado (pending_dns, verifying, active, error) e as instruções de DNS e de verificação.
Escopo exigido: projects:read.
Escopo exigido: projects:read · operationId: getDomain
| 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 domínio (do serviço da rota). |
Resposta 200
Seção intitulada “Resposta 200”Domínio.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
id |
string | sim | |
hostname |
string | sim | |
service_id |
string | sim | |
status |
enum(pending_dns, verifying, active, error) | sim | |
dns |
object | sim | |
dns.type |
string | sim | |
dns.name |
string | sim | |
dns.value |
string | sim | |
verification |
object | sim | |
verification.type |
string | sim | |
verification.name |
string | sim | |
verification.value |
string | sim | |
error |
string | não | Motivo (misconfigured, conflict, txt_missing, wrong_target, dns_error…). |
redirect_to |
string | não | |
created_at |
string | sim |
{ "id": "01jb7k6a5q8r7t2v4w6x8y0a4e", "hostname": "www.exemplo.test", "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "status": "pending_dns", "dns": { "type": "CNAME", "name": "www.exemplo.test", "value": "loja.nebularapps.com" }, "verification": { "type": "TXT", "name": "_nebular-challenge.www.exemplo.test", "value": "nebular-verify=8f2c1d" }, "created_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.
DELETE /v1/projects/{p}/services/{s}/domains/{d}
Seção intitulada “DELETE /v1/projects/{p}/services/{s}/domains/{d}”Remove um domínio
Desanexa o domínio. Idempotente: repetir para um domínio que este time removeu pela API devolve 204.
Escopo exigido: domains:write.
Escopo exigido: domains:write · operationId: deleteDomain
| 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 domínio (do serviço da rota). |
Resposta 204
Seção intitulada “Resposta 204”Removido (ou já removido anteriormente: repetir é 204).
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.
PATCH /v1/projects/{p}/services/{s}/domains/{d}
Seção intitulada “PATCH /v1/projects/{p}/services/{s}/domains/{d}”Define ou remove o redirecionamento do domínio
Faz o domínio redirecionar (301) para outro domínio verificado do mesmo serviço (redirect_to = id desse domínio) ou para de redirecionar (redirect_to: null). O campo é obrigatório: ausente ou vazio é 400 invalid_request.
Escopo exigido: domains:write.
Escopo exigido: domains:write · operationId: updateDomain
| 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 domínio (do serviço da rota). |
Corpo (application/json)
Seção intitulada “Corpo (application/json)”| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
redirect_to |
string|null | sim | Id de outro domínio verificado deste serviço para redirecionar (301), ou null para parar de redirecionar. |
Resposta 200
Seção intitulada “Resposta 200”Domínio atualizado.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
id |
string | sim | |
hostname |
string | sim | |
service_id |
string | sim | |
status |
enum(pending_dns, verifying, active, error) | sim | |
dns |
object | sim | |
dns.type |
string | sim | |
dns.name |
string | sim | |
dns.value |
string | sim | |
verification |
object | sim | |
verification.type |
string | sim | |
verification.name |
string | sim | |
verification.value |
string | sim | |
error |
string | não | Motivo (misconfigured, conflict, txt_missing, wrong_target, dns_error…). |
redirect_to |
string | não | |
created_at |
string | sim |
{ "id": "01jb7k6a5q8r7t2v4w6x8y0a4e", "hostname": "www.exemplo.test", "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "status": "pending_dns", "dns": { "type": "CNAME", "name": "www.exemplo.test", "value": "loja.nebularapps.com" }, "verification": { "type": "TXT", "name": "_nebular-challenge.www.exemplo.test", "value": "nebular-verify=8f2c1d" }, "created_at": "2026-10-10T14:03:11Z"}Resposta 400
Seção intitulada “Resposta 400”invalid_request: redirect_to ausente, vazio ou de outro tipo, ou o alvo não é um domínio verificado deste 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. |
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}/domains/{d}/verify
Seção intitulada “POST /v1/projects/{p}/services/{s}/domains/{d}/verify”Verifica o domínio agora
Roda na hora a checagem de DNS e do TXT de posse (sem corpo) e devolve o domínio com o estado novo. Há um intervalo mínimo entre verificações manuais do mesmo domínio: antes dele a resposta é 422 rate_limited com details.retry_after_seconds.
Escopo exigido: domains:write.
Escopo exigido: domains:write · operationId: verifyDomain
| 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 domínio (do serviço da rota). |
Resposta 200
Seção intitulada “Resposta 200”Domínio após a verificação.
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
id |
string | sim | |
hostname |
string | sim | |
service_id |
string | sim | |
status |
enum(pending_dns, verifying, active, error) | sim | |
dns |
object | sim | |
dns.type |
string | sim | |
dns.name |
string | sim | |
dns.value |
string | sim | |
verification |
object | sim | |
verification.type |
string | sim | |
verification.name |
string | sim | |
verification.value |
string | sim | |
error |
string | não | Motivo (misconfigured, conflict, txt_missing, wrong_target, dns_error…). |
redirect_to |
string | não | |
created_at |
string | sim |
{ "id": "01jb7k6a5q8r7t2v4w6x8y0a4e", "hostname": "www.exemplo.test", "service_id": "01jb7k4a5q8r7t2v4w6x8y0a2c", "status": "pending_dns", "dns": { "type": "CNAME", "name": "www.exemplo.test", "value": "loja.nebularapps.com" }, "verification": { "type": "TXT", "name": "_nebular-challenge.www.exemplo.test", "value": "nebular-verify=8f2c1d" }, "created_at": "2026-10-10T14:03:11Z"}Resposta 422
Seção intitulada “Resposta 422”rate_limited: verificação manual recente; tente de novo após details.retry_after_seconds.
| 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": "rate_limited", "message": "Aguarde alguns segundos para verificar de novo.", "details": { "retry_after_seconds": 7 }}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.