# Sincronizando a carteira

Criar uma dívida é fácil. Manter milhares delas coerentes entre o seu sistema e a Quyta,
todo dia, é o trabalho de verdade. Este guia trata dessa parte.

## O princípio: quem manda em quê

A regra que evita conflito de dados:

| Informação | Fonte da verdade |
| --- | --- |
| Existência da dívida, valor original, vencimento, cliente | **Seu sistema** — envie por API. |
| Status da dívida, `today_value`, acordos, parcelas | **A Quyta** — receba por webhook. |

Seu sistema **nunca** deve tentar escrever o status de uma dívida: não há endpoint para
isso, porque o status é consequência da cobrança. Da mesma forma, não recalcule
`today_value` do seu lado — juros e multa seguem a política configurada na Quyta.

## Carga inicial

Na primeira integração você tem uma carteira inteira para subir. A ordem importa:

1. **Liste os grupos de dívidas** (`GET /debtgroups`) e monte o mapa entre as suas
   carteiras e os `debt_group_id` da Quyta.
2. **Crie os clientes** (`POST /customers`), guardando o `id` retornado ao lado do seu
   próprio identificador de devedor.
3. **Crie as dívidas** (`POST /debts`), sempre com `external_id` preenchido.

Suba a carteira em lotes e registre o progresso. Se a rotina cair no meio, você precisa
saber de onde recomeçar.

:::warning
A API **não é idempotente**: repetir um `POST /debts` com o mesmo `external_id` cria uma
segunda dívida. Antes de reprocessar um lote, verifique o que já subiu com
`GET /debts?external_id=...` — ou mantenha, do seu lado, o registro de quais títulos já
foram enviados.
:::

## Atualização contínua

Depois da carga inicial, a rotina diária costuma ter três movimentos:

**Novos títulos vencidos** → `POST /debts`. Para cada devedor, verifique antes se o cliente
já existe (`GET /customers?document=...`); se existir, reaproveite o `id` em vez de tentar
criá-lo de novo.

**Correções em títulos existentes** → `PUT /debts/{id}`, que aceita `debt_group_id`,
`original_value`, `due_date`, `description`, `external_id` e `origin_date`. Use quando o
valor foi corrigido ou o título precisa migrar de carteira.

**Novos canais de contato** → `POST /customers/{id}/phones` e `POST /customers/{id}/emails`.
Quando um telefone se revela inválido, remova-o com
`DELETE /customers/phones/{phoneId}` para não desperdiçar disparos da régua.

### E quando o título é pago fora da Quyta?

Acontece: o devedor paga direto no seu caixa. Nesse caso a dívida precisa sair da régua de
cobrança — caso contrário ele continuará sendo cobrado por algo que já quitou. Isso é
feito **no painel da Quyta**, pausando (`ON_HOLD`) ou arquivando (`ARCHIVED`) a dívida.
Não há endpoint para essa transição.

## Paginação

Todos os endpoints de listagem paginam com `page` e `per_page` (padrão: 15 itens) e
devolvem a mesma estrutura:

```json
{
  "data": [ /* ... */ ],
  "meta": {
    "total": 1287,
    "per_page": 100,
    "current_page": 1,
    "total_pages": 13
  }
}
```

Para varrer uma lista inteira, itere até `current_page` alcançar `total_pages`:

```bash
page=1
while :; do
  resp=$(curl -s "$QUYTA_API/debts?status=PENDING&per_page=100&page=$page" \
    -H "Authorization: Bearer $QUYTA_TOKEN")
  echo "$resp" | jq -c '.data[]'
  total=$(echo "$resp" | jq '.meta.total_pages')
  [ "$page" -ge "$total" ] && break
  page=$((page + 1))
done
```

Filtre no servidor sempre que puder, em vez de puxar tudo e filtrar localmente.
`GET /debts` aceita `status`, `customer_id`, `document`, `external_id`, `is_collectable` e
`is_contractable`; `GET /customers` aceita `document`.

## Respeitando o limite de requisições

O limite é de **1.000 requisições por minuto** por token. Estourá-lo devolve
`429 Too Many Requests`.

Mil por minuto é folgado para a maior parte das rotinas, mas uma carga inicial de dezenas
de milhares de títulos chega perto. Algumas práticas:

- **Aumente `per_page`** nas listagens: buscar 100 itens por página em vez de 15 corta o
  número de chamadas por um fator de sete.
- **Serialize as escritas** em vez de disparar centenas de `POST` em paralelo.
- **Trate o 429 com espera exponencial** — aguarde, dobre o intervalo, tente de novo:

```javascript
async function comRetry(fn, tentativas = 5) {
  for (let i = 0; i < tentativas; i++) {
    const resposta = await fn();
    if (resposta.status !== 429) return resposta;
    await new Promise((r) => setTimeout(r, 2 ** i * 1000));
  }
  throw new Error("Limite de requisições excedido após várias tentativas");
}
```

- **Prefira webhooks a consultas em laço.** Um endpoint que recebe `contract.installment.paid`
  substitui uma varredura periódica de `GET /debts` inteira — e chega antes.

## Evite consultar em laço

É tentador rodar um cron que lista todas as dívidas de hora em hora para descobrir o que
mudou. Isso consome o limite de requisições, atrasa a informação e cresce mal com a
carteira.

Os [webhooks](/webhooks/introducao) existem justamente para isso: a Quyta avisa o seu
sistema no instante em que algo acontece. Reserve as listagens para reconciliação
periódica — uma varredura diária para conferir que nada se perdeu, e não como mecanismo
principal de atualização.
