> ## Documentation Index
> Fetch the complete documentation index at: https://userepass.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Expand

> Carregue recursos relacionados com o parâmetro expand.

Por padrão, a API retorna apenas os campos do próprio recurso: relações aparecem como IDs (`clickId`, `affiliateId`, …). Use o parâmetro de query `expand[]` para materializar uma relação como objeto aninhado na mesma resposta, evitando uma segunda chamada.

`expand` é restrito a uma **lista branca por endpoint**: cada endpoint declara quais relações podem ser expandidas. Pedir um valor fora dessa lista é rejeitado na validação com `400 parameter_invalid`.

<Note>
  `expand` nunca muda o recurso retornado: só adiciona campos. Um recurso sem `expand` e o mesmo recurso com `expand` têm exatamente os mesmos campos base; o `expand` apenas acrescenta o objeto da relação.
</Note>

## Sintaxe

`expand` é um parâmetro repetível. Para expandir mais de uma relação, repita a chave:

```bash theme={null}
curl "https://api.userepass.com/conversions/conv_01J9Z3K8N2QF4T7B9XP0WMD5RC?expand=click&expand=affiliate" \
  -H "Authorization: Bearer rstr_..."
```

Um único valor (`?expand=click`) também é aceito e normalizado internamente para uma lista de um item. As duas formas abaixo são equivalentes:

<CodeGroup>
  ```bash Uma relação theme={null}
  curl "https://api.userepass.com/conversions/conv_01J9Z3K8N2QF4T7B9XP0WMD5RC?expand=click" \
    -H "Authorization: Bearer rstr_..."
  ```

  ```bash Várias relações theme={null}
  curl "https://api.userepass.com/conversions/conv_01J9Z3K8N2QF4T7B9XP0WMD5RC?expand=click&expand=affiliate" \
    -H "Authorization: Bearer rstr_..."
  ```
</CodeGroup>

<ParamField query="expand[]" type="string[]">
  Lista de relações a materializar na resposta. Cada endpoint aceita apenas os valores da sua lista branca; um valor fora dela retorna `400 parameter_invalid`. Default: `[]` (nenhuma relação expandida).
</ParamField>

## Endpoints que suportam expand

O padrão é uniforme: endpoints de **leitura de um recurso** (`GET /<recurso>/{id}`) declaram as relações que sabem resolver. Os endpoints atualmente expansíveis:

| Endpoint                | Valor de `expand` | Relação materializada                                                                                                       |
| ----------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `GET /conversions/{id}` | `click`           | O Clique atribuído à Conversão (`clk_…`), ou `null` se a Conversão não tiver Clique associado (p.ex. atribuição por Cupom). |
| `GET /conversions/{id}` | `affiliate`       | O Afiliado dono da Conversão (`aff_…`).                                                                                     |
| `GET /payouts/{id}`     | `commissions`     | A lista de Comissões agregadas no Payout (`comm_…`).                                                                        |

<Info>
  Para saber exatamente quais valores um endpoint aceita, consulte a aba **Referência da API** do endpoint: a lista branca é declarada lá. Pedir um valor não suportado retorna um erro de validação claro, então é seguro tentar.
</Info>

## Resposta com objetos aninhados

Quando você expande uma relação, o objeto completo daquela relação é embutido na resposta sob uma chave de nome igual ao valor de `expand`. Sem `expand`, a chave simplesmente não aparece (você ainda tem o ID, p.ex. `clickId`).

<CodeGroup>
  ```json Sem expand theme={null}
  {
    "id": "conv_01J9Z3K8N2QF4T7B9XP0WMD5RC",
    "affiliateId": "aff_01J9Z2M4P8K1V3N5R7T9XB0WQE",
    "clickId": "clk_01J9Z1A3B5C7D9E1F3G5H7J9KM",
    "status": "approved",
    "amountCents": 12990,
    "occurredAt": "2026-06-13T14:02:11.000Z"
  }
  ```

  ```json expand=click&expand=affiliate theme={null}
  {
    "id": "conv_01J9Z3K8N2QF4T7B9XP0WMD5RC",
    "affiliateId": "aff_01J9Z2M4P8K1V3N5R7T9XB0WQE",
    "clickId": "clk_01J9Z1A3B5C7D9E1F3G5H7J9KM",
    "status": "approved",
    "amountCents": 12990,
    "occurredAt": "2026-06-13T14:02:11.000Z",
    "click": {
      "id": "clk_01J9Z1A3B5C7D9E1F3G5H7J9KM",
      "linkId": "link_01J9Z0Q2W4E6R8T0Y2U4I6O8PA",
      "affiliateId": "aff_01J9Z2M4P8K1V3N5R7T9XB0WQE",
      "occurredAt": "2026-06-13T13:58:40.000Z"
    },
    "affiliate": {
      "id": "aff_01J9Z2M4P8K1V3N5R7T9XB0WQE",
      "name": "Acme Partners",
      "status": "active"
    }
  }
  ```
</CodeGroup>

Para coleções, a relação vem como **array**. Em `GET /payouts/{id}?expand=commissions`, o campo `commissions` carrega a lista de comissões agregadas naquele payout:

```json expand=commissions theme={null}
{
  "id": "pay_01J9ZB7K3M5N7P9R1T3V5X7Z9A",
  "affiliateId": "aff_01J9Z2M4P8K1V3N5R7T9XB0WQE",
  "amountCents": 45970,
  "status": "scheduled",
  "commissions": [
    {
      "id": "comm_01J9ZA1B3C5D7E9F1G3H5J7K9M",
      "conversionId": "conv_01J9Z3K8N2QF4T7B9XP0WMD5RC",
      "amountCents": 12990,
      "status": "approved"
    },
    {
      "id": "comm_01J9ZA2C4D6E8F0G2H4J6K8L0N",
      "conversionId": "conv_01J9Z5L0P2QF4T7B9XP0WMD5SD",
      "amountCents": 32980,
      "status": "approved"
    }
  ]
}
```

<Warning>
  Uma relação opcional ausente vem como `null` (ou é omitida), não como erro. Por exemplo, uma conversão sem clique atribuído (atribuída por cupom, sem rastreamento de clique) retorna `"click": null` quando você pede `expand=click`.
</Warning>

## Como o expand resolve as relações

O fluxo é o mesmo em todos os endpoints: a resposta base é montada primeiro; cada valor de `expand` aceito dispara a busca da relação correspondente, escopada à mesma organização do recurso.

```mermaid theme={null}
sequenceDiagram
    participant C as Cliente
    participant API as API Repass
    C->>API: GET /conversions/{id}?expand=click&expand=affiliate
    API->>API: carrega a conversão (escopo da organização)
    alt expand inclui "click"
        API->>API: busca o clique por clickId (ou null)
    end
    alt expand inclui "affiliate"
        API->>API: busca o afiliado por affiliateId
    end
    API-->>C: 200 { ...conversão, click, affiliate }
```

Por ser escopado à organização, o `expand` nunca atravessa tenants: você só vê relações que pertencem à sua própria organização.

## Boas práticas

<AccordionGroup>
  <Accordion title="Use expand para evitar chamadas N+1">
    Ao listar e detalhar conversões, expandir `affiliate` na chamada de detalhe poupa uma ida ao endpoint de afiliados. Expanda apenas o que vai usar: cada relação expandida é uma busca adicional no servidor.
  </Accordion>

  <Accordion title="Trate relações opcionais como nulas">
    Campos como `click` em uma conversão podem ser `null` quando a atribuição não envolveu clique (p.ex. atribuição por cupom). Programe defensivamente para esse caso.
  </Accordion>

  <Accordion title="Não dependa de expand para campos base">
    Os IDs de relação (`clickId`, `affiliateId`, …) sempre estão presentes na resposta base. Use `expand` só quando precisar do objeto inteiro; caso contrário, o ID basta para uma busca posterior.
  </Accordion>
</AccordionGroup>

## Próximos passos

<CardGroup cols={2}>
  <Card title="IDs e recursos" icon="fingerprint" href="/docs/convencoes/ids-e-recursos">
    Como os identificadores com prefixo + ULID identificam cada relação.
  </Card>

  <Card title="Paginação" icon="list" href="/docs/convencoes/paginacao">
    Liste recursos por cursor antes de detalhar e expandir um deles.
  </Card>

  <Card title="Conversões e fraude" icon="receipt" href="/docs/conceitos/conversoes-e-fraude">
    O recurso de conversão e suas relações com clique e afiliado.
  </Card>

  <Card title="Payouts" icon="money-bill-transfer" href="/docs/conceitos/payouts">
    O payout e as comissões agregadas que você pode expandir.
  </Card>
</CardGroup>
