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

# Início rápido

> Integre com a API do Repass em poucos passos: crie um Programa, aprove um Afiliado, gere um Link, registre uma Conversão e consulte a Comissão.

O Repass é uma plataforma multi-tenant de gestão de programas de afiliados. Este guia leva você do zero a uma comissão calculada: você cria um Programa, recruta e aprova um Afiliado, gera um Link rastreável, registra uma Conversão server-to-server e consulta a Comissão gerada, tudo via API REST.

Toda a integração server-to-server usa uma [API key](/docs/autenticacao) com prefixo `rstr_` no header `Authorization: Bearer`. A base URL é `https://api.userepass.com`.

<Note>
  Antes de começar, vale conhecer as [convenções da API](/docs/convencoes/ids-e-recursos): IDs são opacos com prefixo de tipo + ULID (`prog_`, `aff_`, `link_`, `conv_`, `comm_`), dinheiro é sempre inteiro em centavos e percentuais em basis points (`10000 bps = 100%`). Todo POST aceita o header [`Idempotency-Key`](/docs/convencoes/idempotencia).
</Note>

<Tip>
  Usa TypeScript/Node? O [SDK oficial `@repass/sdk`](/docs/sdk/visao-geral) faz tudo deste guia de forma tipada, com retries, idempotência e paginação automáticas. Veja o [Início rápido do SDK](/docs/sdk/inicio-rapido).
</Tip>

## Visão do fluxo

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant You as Sua integração (rstr_)
    participant API as API Repass
    participant V as Visitante

    You->>API: POST /programs
    API-->>You: prog_…
    You->>API: POST /programs/{id}/affiliates
    API-->>You: aff_… (pending)
    You->>API: POST /affiliates/{id}/approve
    API-->>You: aff_… (approved)
    You->>API: POST /affiliates/{id}/links
    API-->>You: link_… (token)
    V->>API: GET /t/{token} → 302 destino (+ cookie)
    You->>API: POST /conversions (S2S)
    API-->>You: conv_… + commission.created
    You->>API: GET /commissions?conversion_id=…
    API-->>You: comm_… (pending)
```

## Pré-requisitos

<Steps>
  <Step title="Tenha uma organização e uma API key">
    A organização é o seu tenant. Todo recurso é escopado por ela. Gere uma API key server-to-server (formato `rstr_…`) no painel da organização. A key herda a role do membro dono; para os passos abaixo, use uma key com role `admin` ou `owner`.

    Guarde a key em local seguro: ela é mostrada uma única vez. Detalhes completos em [Autenticação](/docs/autenticacao).

    ```bash Exporte a key theme={null}
    export REPASS_KEY="rstr_..."
    export REPASS_BASE="https://api.userepass.com"
    ```

    <Warning>
      Nunca exponha uma `rstr_` em código de frontend ou em repositórios públicos. Ela é uma credencial de servidor com os mesmos poderes do membro dono.
    </Warning>
  </Step>
</Steps>

## Passos

<Steps>
  <Step title="Crie um programa">
    Um [Programa](/docs/conceitos/programas-e-regras) define moeda (atualmente BRL), modelo e janela de [atribuição](/docs/conceitos/atribuicao), hold de comissão e modo de aprovação de afiliados.

    ```bash cURL theme={null}
    curl -X POST "$REPASS_BASE/programs" \
      -H "Authorization: Bearer $REPASS_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: prog-quickstart-001" \
      -d '{
        "name": "Programa de Indicações",
        "currency": "BRL",
        "attributionModel": "last_click",
        "approvalMode": "manual"
      }'
    ```

    ```json Resposta 201 theme={null}
    {
      "id": "prog_01J9Z3K8M4QF2N7XB5RC0WPTQA",
      "name": "Programa de Indicações",
      "currency": "BRL",
      "attributionModel": "last_click",
      "approvalMode": "manual",
      "status": "active"
    }
    ```

    <Tip>
      Crie uma [regra de comissão](/docs/conceitos/comissoes) versionada para o programa com `POST /programs/{id}/commission-rules` (ex.: percentual em basis points com recorrência). A regra é imutável: alterar significa publicar uma nova versão. Sem uma regra vigente, a conversão até é atribuída, mas a comissão não tem como ser calculada.
    </Tip>
  </Step>

  <Step title="Crie e aprove um afiliado">
    O [Afiliado](/docs/conceitos/afiliados) é identificado por e-mail dentro do programa. O `mode` define o status inicial: `direct` (padrão) já nasce `approved`; `invite` respeita o `approvalMode` do programa. Com `manual`, nasce `pending` e precisa ser aprovado. Usamos `invite` para ilustrar o fluxo de aprovação.

    ```bash cURL (criar) theme={null}
    curl -X POST "$REPASS_BASE/programs/prog_01J9Z3K8M4QF2N7XB5RC0WPTQA/affiliates" \
      -H "Authorization: Bearer $REPASS_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: aff-quickstart-001" \
      -d '{ "email": "parceiro@exemplo.com", "name": "Parceiro Exemplo", "mode": "invite" }'
    ```

    ```json Resposta 201 theme={null}
    {
      "id": "aff_01J9Z3M2P0RD8K4VC1XN6YHTBE",
      "programId": "prog_01J9Z3K8M4QF2N7XB5RC0WPTQA",
      "email": "parceiro@exemplo.com",
      "name": "Parceiro Exemplo",
      "status": "pending",
      "tier": null
    }
    ```

    Aprove o afiliado. A aprovação muda `pending → approved` e, nesse momento, o Repass cria automaticamente um [Link](/docs/conceitos/links-e-cupons) default para ele.

    ```bash cURL (aprovar) theme={null}
    curl -X POST "$REPASS_BASE/affiliates/aff_01J9Z3M2P0RD8K4VC1XN6YHTBE/approve" \
      -H "Authorization: Bearer $REPASS_KEY" \
      -H "Content-Type: application/json"
    ```

    ```json Resposta 200 theme={null}
    {
      "id": "aff_01J9Z3M2P0RD8K4VC1XN6YHTBE",
      "status": "approved"
    }
    ```

    <Note>
      O afiliado pode precisar aceitar uma versão dos [termos](/docs/conceitos/termos) do programa antes de divulgar. A máquina de estados completa (pending, approved, paused, rejected, banned) está em [Afiliados](/docs/conceitos/afiliados).
    </Note>
  </Step>

  <Step title="Gere um link rastreável">
    Cada Afiliado pode ter vários Links. O token é único globalmente e imutável; você pode opcionalmente informar um `subId` para segmentar a divulgação. O destino (`destinationUrl`) precisa estar na whitelist de domínios da organização.

    ```bash cURL theme={null}
    curl -X POST "$REPASS_BASE/affiliates/aff_01J9Z3M2P0RD8K4VC1XN6YHTBE/links" \
      -H "Authorization: Bearer $REPASS_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: link-quickstart-001" \
      -d '{
        "destinationUrl": "https://app.exemplo.com/signup",
        "subId": "newsletter"
      }'
    ```

    ```json Resposta 201 theme={null}
    {
      "id": "link_01J9Z3N7R2SF9M5WD2YP4ZKUCG",
      "affiliateId": "aff_01J9Z3M2P0RD8K4VC1XN6YHTBE",
      "token": "k3y9q2",
      "destinationUrl": "https://app.exemplo.com/signup",
      "subId": "newsletter",
      "status": "active"
    }
    ```

    O afiliado divulga a URL pública de redirect `https://api.userepass.com/t/{token}`. Quando um visitante acessa, o Repass registra o [Clique](/docs/conceitos/tracking) (visitante, geo, detecção de bot), seta um cookie first-party e responde `302` para o destino.

    ```bash Redirect público (chamado pelo visitante) theme={null}
    curl -i "$REPASS_BASE/t/k3y9q2"
    # HTTP/1.1 302 Found
    # Location: https://app.exemplo.com/signup?repass_cid=...
    # Set-Cookie: repass_vid=...
    ```

    <Tip>
      Cupons sincronizados com o gateway de pagamento são uma forma alternativa de atribuição (sem clique). Veja [Links e cupons](/docs/conceitos/links-e-cupons).
    </Tip>
  </Step>

  <Step title="Registre uma conversão server-to-server">
    Quando a venda acontece, registre a [Conversão](/docs/conceitos/conversoes-e-fraude) via `POST /conversions`. A API roda [atribuição](/docs/conceitos/atribuicao) (resolvendo a qual afiliado a venda pertence) e o score de [fraude](/docs/conceitos/conversoes-e-fraude) de forma síncrona, e retorna a decisão completa.

    O `customer.id` (identificador estável do cliente no seu sistema) é obrigatório. Para o matching, informe o `clickId` quando você o tiver, ou sinais alternativos (`visitorId`, `emailHash`, `fingerprint`, `couponCode` ou `customer.email`). Ao menos um é exigido. O `sourceEventId` torna a chamada idempotente por fato de negócio: o mesmo `sourceEventId` retorna a conversão existente com o header `Idempotent-Replay: true`.

    ```bash cURL theme={null}
    curl -X POST "$REPASS_BASE/conversions" \
      -H "Authorization: Bearer $REPASS_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "sourceEventId": "order_8842",
        "type": "one_time_purchase",
        "amountCents": 9990,
        "customer": { "id": "cus_8842", "email": "cliente@exemplo.com" },
        "visitorId": "vis_01J9Z3P9T4UG0N6XE3ZQ5ALVDH"
      }'
    ```

    A resposta sempre traz o envelope `{ attributed, deduplicated, replayed, conversion }`. Quando há atribuição e a conversão é nova, o status é `201` e a conversão vem em `conversion`.

    ```json Resposta 201 (atribuída) theme={null}
    {
      "attributed": true,
      "deduplicated": false,
      "replayed": false,
      "conversion": {
        "id": "conv_01J9Z3Q5V6WH1P7YF4AR6BMWEI",
        "programId": "prog_01J9Z3K8M4QF2N7XB5RC0WPTQA",
        "affiliateId": "aff_01J9Z3M2P0RD8K4VC1XN6YHTBE",
        "type": "one_time_purchase",
        "amountCents": 9990,
        "currency": "BRL",
        "status": "pending",
        "matchMethod": "visitor_id",
        "fraudDecision": "approve",
        "attributionSnapshot": { "model": "last_click", "windowDays": 30 }
      }
    }
    ```

    Se o matching não encontra um afiliado, a API responde `200` com `attributed: false` e `conversion: null`. Sem afiliado não há vínculo a registrar, então **nada é persistido**.

    ```json Resposta 200 (sem atribuição) theme={null}
    {
      "attributed": false,
      "deduplicated": false,
      "replayed": false,
      "conversion": null
    }
    ```

    <Note>
      Atribuição, regra e fraude são congelados em snapshots na conversão no momento do registro. O cálculo nunca é relido das tabelas vivas. Para o passo a passo completo desse fluxo, veja o [guia de conversões server-to-server](/docs/guias/conversoes-server-to-server).
    </Note>
  </Step>

  <Step title="Consulte a comissão gerada">
    Ao registrar uma conversão atribuída, o Repass cria automaticamente a [Comissão](/docs/conceitos/comissoes) do primeiro ciclo de cobrança. Liste as comissões filtrando pela conversão.

    ```bash cURL theme={null}
    curl "$REPASS_BASE/commissions?conversion_id=conv_01J9Z3Q5V6WH1P7YF4AR6BMWEI" \
      -H "Authorization: Bearer $REPASS_KEY"
    ```

    ```json Resposta 200 theme={null}
    {
      "data": [
        {
          "id": "comm_01J9Z3R1X8YJ2Q8ZG5BS7CNXFJ",
          "conversionId": "conv_01J9Z3Q5V6WH1P7YF4AR6BMWEI",
          "affiliateId": "aff_01J9Z3M2P0RD8K4VC1XN6YHTBE",
          "type": "standard",
          "billingCycle": 1,
          "amountCents": 999,
          "status": "pending"
        }
      ],
      "hasMore": false
    }
    ```

    A comissão nasce `pending` e fica em hold até ser aprovada (`pending → approved → paid`). O detalhe (`GET /commissions/{id}`) traz o cálculo aberto: base, percentual em basis points, versão da regra aplicada. O ciclo de vida completo, incluindo clawbacks, está em [Comissões](/docs/conceitos/comissoes).

    <Check>
      Pronto: você registrou uma venda e o Repass calculou a comissão devida ao afiliado. A partir daqui, as comissões aprovadas são agregadas num [payout](/docs/conceitos/payouts) no fechamento de ciclo.
    </Check>
  </Step>
</Steps>

## Idempotência e erros

POSTs aceitam o header `Idempotency-Key` (escopo por organização + usuário, TTL de 24h): repetir a mesma chave com o mesmo corpo devolve a resposta original e o header `Idempotent-Replay: true`. Veja [Idempotência](/docs/convencoes/idempotencia).

Erros seguem um envelope único `{ "error": { "type", "code", "message", "param?" } }` com status HTTP semântico:

```json Exemplo de erro 404 theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "resource_not_found",
    "message": "Affiliate not found."
  }
}
```

O mapeamento completo de códigos está em [Erros](/docs/convencoes/erros).

## Próximos passos

<CardGroup cols={2}>
  <Card title="Autenticação" icon="key" href="/docs/autenticacao">
    API keys `rstr_`, roles e escopo da organização.
  </Card>

  <Card title="Conversões S2S" icon="bolt" href="/docs/guias/conversoes-server-to-server">
    O fluxo completo de matching, atribuição e fraude.
  </Card>

  <Card title="Comissões" icon="coins" href="/docs/conceitos/comissoes">
    Cálculo inteiro, recorrência, tiers, clawback e estados.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/docs/webhooks/visao-geral">
    Receba eventos de domínio assinados em tempo real.
  </Card>
</CardGroup>
