/t/{token} que registram o Clique e redirecionam o visitante ao destino, e pode ter Cupons de desconto que atribuem comissões em canais sem clique (podcast, evento, rádio). Esta página descreve os tokens globalmente únicos, deep linking, a whitelist de domínios de destino, a reserva de token por 12 meses e a sincronização de cupons com o gateway de pagamento.
O vínculo é sempre Link → Afiliado → Programa: um Link pertence a exatamente um Afiliado, que pertence a exatamente um Programa. O mesmo vale para o Cupom. O programId nunca é informado pelo cliente, e sim derivado do Afiliado.
Links rastreáveis
Um Link tem o identificadorlink_ + ULID e os campos principais:
Token globalmente único
O token é único entre todos os Programas e todas as organizações, não apenas dentro de um Programa. Isso é exigido pela rota públicaGET /t/{token}, que resolve o Link apenas pelo token e descobre a organização a partir do Link encontrado.
Tokens são case-insensitive: BRUNO-PROMO e bruno-promo são o mesmo token. A entrada é normalizada para minúsculas antes da validação de unicidade e do redirect.
Ao criar um Link sem token custom, o token é gerado a partir do nome do Afiliado: acentos removidos, minúsculas, sequências não alfanuméricas viram hífen, hífens das pontas aparados, corte em 50 caracteres. Slugs com menos de 3 caracteres ganham o prefixo aff- (ex.: “Li” → aff-li). Em caso de colisão, são tentados alguns candidatos com sufixo aleatório (<base>-<sufixo>); esgotadas as tentativas, a criação falha com 409 conflict.
Link padrão automático
Todo Afiliado que entra no statusapproved recebe automaticamente um Link com isDefault: true, tanto na criação já aprovada quanto na primeira aprovação via mudança de status. A operação é idempotente: se o default já existe (ex.: re-aprovação), o Link existente é retornado sem criar outro. Veja Afiliados.
Sub-campanhas e deep linking
OsubId segmenta campanhas do próprio Afiliado. Ele é gravado no Clique como sub-identificador padrão, mas pode ser sobrescrito por Clique via ?sub= no redirect. No momento do Clique, o subId efetivo é ?sub= ?? link.subId. Detalhes do redirect e do registro de Clique vivem em Tracking.
O destinationUrl permite enviar o visitante direto para uma página específica. Quando ausente, o redirect usa a landingUrl do Programa como fallback.
O
token já identifica o Afiliado na URL /t/{token}. Para sobrescrever a sub-campanha na divulgação, acrescente ?sub=. Exemplo de URL completa de um Afiliado: https://api.userepass.com/t/bruno-promo?sub=newsletter.Whitelist de domínios de destino
Para impedir que o redirect do Repass seja usado como open redirector, tododestinationUrl precisa apontar para um domínio autorizado da organização. A whitelist é configurada por organização:
- Cada entrada autoriza o domínio exato e seus subdomínios (
example.comautorizaapp.example.com). - Máximo de 50 domínios; normalizados para minúsculas e deduplicados na gravação.
- Whitelist vazia ou não configurada ⇒ qualquer
destinationUrlé bloqueado com403 not_allowed.
destinationUrl (enviando null no PATCH) não consulta a whitelist e faz o redirect voltar a usar a landingUrl do Programa.
Ciclo de vida do Link
active: Link operacional./t/{token}registra Clique e redireciona.inactive: Link desativado./t/{token}responde410 Gone. O token fica reservado por 12 meses (365 dias exatos) a contar dedeactivatedAt. Desativar um Link já inativo retorna409 conflict.
POST /links/{linkId}/reactivate volta o Link a active e limpa deactivatedAt, desde que o token ainda não tenha sido aposentado e o Afiliado não esteja no teto de Links ativos.
Reserva de token por 12 meses
Tokens não são reutilizáveis de imediato. O token de um Link inativo da própria organização fica reservado por exatamente 365 dias a partir dedeactivatedAt, evitando que um Afiliado herde tráfego residual de outro.
Quando um novo Link tenta reivindicar um token já existente, o resultado depende do estado atual do token:
Após a expiração, quando outro Link da mesma organização reivindica o token, o Link antigo é aposentado (liberando o slug) e o evento
link.token_retired é emitido. Reativar um Link cujo token já foi aposentado retorna 409 conflict: não há mais slug a restaurar.
Limite de Links por Afiliado
Cada Afiliado pode ter no máximoprogram.maxLinksPerAffiliate Links no Programa (default 50, configurável por Programa). A contagem considera apenas Links ativos: desativar libera vaga, reativar volta a ocupá-la (a reativação revalida o teto). Exceder o limite retorna 409 conflict.
Endpoints de Links
Todas as rotas exigem autenticação (sessão ou API key) e operam no escopo da organização ativa; nenhuma exige papel específico. Veja a aba Referência da API para o contrato completo de cada endpoint.
GET /affiliates/{affiliateId}/links retorna { "data": [...] } com todos os Links do Afiliado (mais recentes primeiro), sem paginação por cursor: o teto prático é o maxLinksPerAffiliate do Programa.
Eventos de Link
Cada mudança de estado emite um evento que você pode assinar via webhook ou consultar pela API de auditoria (veja Event store):Cupons
O Cupom (coup_ + ULID) é um método de atribuição alternativo para canais sem clique: quando uma Conversão chega informando o código do cupom (mesmo sem nenhum Clique rastreado), a Comissão é atribuída ao Afiliado dono do Cupom. Um Cupom pertence a no máximo um Afiliado; não há Cupom genérico sem dono.
Na criação via API, o desconto percentual é informado como decimal (
20 = 20%, 0,01 a 100, duas casas) e convertido para bps na persistência (20 → 2000). O desconto fixo é informado e persistido em centavos (inteiro ≥ 1). Na resposta, discountValue volta a decimal para percentuais e permanece em centavos para fixos.Status do Cupom
pending: recém-criado, ainda não sincronizado. Estado inicial, mas a criação encadeia a sincronização imediatamente, então raramente é observável.active: sincronizado com sucesso; único status que atribui Conversões.sync_failed: sincronização com o gateway falhou; o Cupom fica bloqueado até um resync bem-sucedido.inactive: desativado manualmente; não atribui mais.
Sincronização com o gateway
Todo Cupom criado no Repass é sincronizado automaticamente com o gateway de pagamento (como o Stripe) para que o desconto exista de fato no checkout. O Cupom só fica utilizável (active) após a sincronização bem-sucedida.
A criação sempre retorna 201, mesmo quando a sincronização falha: você distingue o resultado pelos campos status e providerSync na resposta. O Cupom nasce em pending e emite o evento coupon.created; em seguida o resultado da sincronização (active ou sync_failed) é aplicado, com seu próprio evento.
O objeto providerSync traz provider, status (synced ou failed), syncedAt (quando synced) e error (quando failed).
Resposta 201 (sync bem-sucedida)
Resposta 201 (sync falhou)
sync_failed (ou pending) pode ser reenviado com POST /coupons/{couponId}/resync. Resync de um Cupom active ou inactive é rejeitado com 409 conflict.
Desativação
POST /coupons/{couponId}/deactivate leva qualquer Cupom (≠ inactive) para inactive, define deactivatedAt e propaga a desativação ao gateway. A desativação local acontece independentemente do resultado do gateway. Desativar um Cupom já inactive retorna 409 conflict. Não há reativação de Cupom: uma vez inactive, não há transição de volta.
Atribuição por Cupom
Na Conversão, o código é normalizado para maiúsculas e o Cupom precisa estaractive. Cupom inexistente ou em qualquer outro status retorna 404 com param: couponCode. O conflito entre Cupom e Clique é resolvido pela política do Programa (couponAttributionPolicy):
coupon_wins(default): 100% ao Afiliado do Cupom.click_wins: 100% ao Afiliado do Clique.split_50_50: divide 5000/5000 bps, com o Cupom como primário.
Endpoints de Cupons
A listagem
GET /coupons usa paginação por cursor (limit 1 a 100, default 25; starting_after/ending_before) com filtros opcionais program_id, affiliate_id, status.
Eventos de Cupom
Erros comuns
409 conflict em token de Link
409 conflict em token de Link
Token em uso por Link ativo, token de outra organização, token reservado (12 meses), limite de Links do Programa atingido (criação ou reativação), Link já desativado/ativo, ou token já aposentado na reativação. Conflitos de token trazem
param: "token".403 not_allowed em destinationUrl
403 not_allowed em destinationUrl
A whitelist de domínios está vazia ou o hostname não está autorizado. Configure a whitelist em
PUT /settings/destination-domains antes de usar deep links.409 conflict em Cupom
409 conflict em Cupom
Código duplicado no Programa (
param: code), Afiliado banido na criação, resync de Cupom active/inactive, ou desativar um Cupom já inactive.404 resource_not_found
404 resource_not_found
Afiliado inexistente na organização, Link/Cupom inexistente, ou (na Conversão)
couponCode que não corresponde a um Cupom active.Idempotency-Key em Idempotência.
Próximos passos
Tracking
Como o redirect
/t/{token} registra o Clique e o cookie de visitante.Atribuição
Janelas, precedência e a política de conflito Cupom × Clique.
Afiliados
Aprovação do Afiliado e criação do Link padrão automático.
Conversões e fraude
Como uma Conversão com
couponCode gera a Comissão.