# Logs

Escopo: `logs:read`. Segredos (valores sensíveis das variáveis) são mascarados nos logs.

## Log de build de um deploy

`GET /v1/projects/{p}/services/{s}/deployments/{d}/logs?cursor=`. Lista paginada por cursor: siga `next_cursor` enquanto `has_more` for `true`. Use quando o deploy terminar em `failed`.

```bash
SUF=$(date +%s)-$RANDOM
H="Authorization: Bearer $NEBULAR_TOKEN"
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \
  -d "{\"name\": \"lg1-$SUF\"}" | jq -r .id)
S=$(curl -sS -X PATCH "$NEBULAR_API/v1/projects/$P/services/web" -H "$H" -H "Content-Type: application/json" \
  -d '{"source": {"type": "image", "ref": "ghcr.io/org/app:1.0"}}' | jq -r .id)
D=$(curl -sS -X POST "$NEBULAR_API/v1/projects/$P/services/$S/deployments" -H "$H" \
  -H "Content-Type: application/json" -d '{}' | jq -r .id)

curl -sS "$NEBULAR_API/v1/projects/$P/services/$S/deployments/$D/logs" \
  -H "$H"
```
```json
{"text": "[build] fetching source\n", "next_cursor": "Mw", "done": false}
```

Para o próximo trecho: `...logs?cursor=$NEXT_CURSOR`, sem alterar o cursor (é opaco).

## Log de runtime de um serviço

`GET /v1/projects/{p}/services/{s}/logs?since=&cursor=`. `since` limita ao que veio depois de um instante (RFC 3339 em UTC).

```bash
SUF=$(date +%s)-$RANDOM
H="Authorization: Bearer $NEBULAR_TOKEN"
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \
  -d "{\"name\": \"lg2-$SUF\"}" | jq -r .id)
S=$(curl -sS -X PATCH "$NEBULAR_API/v1/projects/$P/services/web" -H "$H" -H "Content-Type: application/json" \
  -d '{"source": {"type": "image", "ref": "ghcr.io/org/app:1.0"}}' | jq -r .id)

curl -sS -G "$NEBULAR_API/v1/projects/$P/services/$S/logs" \
  --data-urlencode "since=2026-10-10T12:00:00Z" \
  -H "$H"
```
```json
{"text": "boot service=web\n", "next_cursor": "Mg", "done": false}
```

## Se algo falhar

| Resposta | O que fazer |
|---|---|
| `403 forbidden` | Falta `logs:read`. |
| `404 not_found` | Serviço ou deploy inexistente ou fora do seu acesso. |
| `400 invalid_request` | `since` ou `cursor` malformado. |
| `429` | Espere `Retry-After`; não faça polling mais rápido que 2 s. |

Diagnóstico: [Fluxo de diagnóstico](/erros/fluxo-de-diagnostico/).
