# Domínios (referência)

## 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

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<object> | 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 |  |

```json
{
  "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

Corpo `{"error", "message", "details"?}` (veja [Autenticação e visão geral](/referencia/autenticacao/) e a [tabela de erros](/erros/tabela/)): `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`

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)

| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
| `hostname` | string | sim |  |
| `redirect_to` | string | não | Hostname para o qual redirecionar. |

### 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 |  |

```json
{
  "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

`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<string> | 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. |

```json
{
  "error": "invalid_request",
  "message": "Só serviços públicos aceitam domínio."
}
```

### 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<string> | 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

`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<string> | 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. |

```json
{
  "error": "quota_exceeded",
  "message": "Limite de serviços do plano atingido."
}
```

### Erros comuns

Corpo `{"error", "message", "details"?}` (veja [Autenticação e visão geral](/referencia/autenticacao/) e a [tabela de erros](/erros/tabela/)): `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}`

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

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 |  |

```json
{
  "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

Corpo `{"error", "message", "details"?}` (veja [Autenticação e visão geral](/referencia/autenticacao/) e a [tabela de erros](/erros/tabela/)): `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}`

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

Removido (ou já removido anteriormente: repetir é `204`).

### Erros comuns

Corpo `{"error", "message", "details"?}` (veja [Autenticação e visão geral](/referencia/autenticacao/) e a [tabela de erros](/erros/tabela/)): `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}`

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)

| 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

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 |  |

```json
{
  "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

`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<string> | 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

Corpo `{"error", "message", "details"?}` (veja [Autenticação e visão geral](/referencia/autenticacao/) e a [tabela de erros](/erros/tabela/)): `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`

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

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 |  |

```json
{
  "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

`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<string> | 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. |

```json
{
  "error": "rate_limited",
  "message": "Aguarde alguns segundos para verificar de novo.",
  "details": {
    "retry_after_seconds": 7
  }
}
```

### Erros comuns

Corpo `{"error", "message", "details"?}` (veja [Autenticação e visão geral](/referencia/autenticacao/) e a [tabela de erros](/erros/tabela/)): `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`.
