Scopes
Cada token de API carrega scopes granulares. A API valida o scope exigido em
toda rota protegida: se o token nao tiver o scope necessario, a chamada
retorna 403 scope_insufficient.
Princípio de menor privilegio: peca apenas os scopes que sua integracao usa.
Como funcionam
- Emissao (self-service no Portal): voce mesmo define os scopes permitidos
ao criar a credencial (
client_id/client_secret) em Integração → Tokens de API. Nao ha etapa de provisionamento pelo Backoffice — veja Como obter suas credenciais. - Emissao do token (
POST /v1/auth/token): voce pode pedir um subconjunto dos scopes da credencial pelo camposcopes. Se omitir, o token recebe todos os scopes permitidos da credencial. - Validacao: a resposta do token inclui o array
scopesconcedido. Cada endpoint exige o scope correspondente (tabela abaixo).
curl -X POST https://receivables-api-sandbox.zemocapital.com/v1/auth/token \
-H "Content-Type: application/json" \
-d '{"client_id": "zk_sbx_...", "client_secret": "sk_test_...", "scopes": ["simulation:create", "operation:create", "operation:read"]}'
# -> {"access_token": "eyJ...", "expires_in": 900, "scopes": [...]}
- Pedir um scope fora do permitido na credencial ->
403 scope_not_allowed(odetaillistaallowed_scopes). - Chamar um endpoint sem o scope exigido no token ->
403 scope_insufficient(odetaillistarequiredegranted).
Veja os dois erros em Codigos de Erro.
Tipos de credencial: SK x RK
Toda credencial tem um tipo, declarado explicitamente na emissao — ele nao
e deduzido do conjunto de scopes. O tipo aparece no prefixo do
client_secret e nao muda depois:
A tela de Tokens de API oferece a escolha explicita entre SK e RK na emissao — o default e RK, o tipo recomendado. Veja Tipos de chave.
| Tipo | Prefixo do secret | Scopes | Uso recomendado |
|---|---|---|---|
| SK (secret key) | sk_live_… | Exatamente as 11 do recorte self-service | Uma integracao unica que faz tudo |
| RK (restricted key) | rk_live_… | Um recorte que voce escolhe | Preferido: uma chave por consumidor, com o minimo necessario |
A tela de Tokens de API oferece 14 scopes: as 11 do recorte self-service mais
webhook:read, webhook:write e originator:read — estes tres so entram numa
RK (uma SK e exatamente as 11, nem mais nem menos).
A restricao da RK e verificada na emissao: ela nunca contem o catalogo
self-service completo (pedir todas as 11 com kind=RK volta 422), e pode
incluir scopes tecnicos especificos concedidos fora do PCP.
O client_id e zk_live_… nos dois casos — o prefixo muda apenas no secret,
para voce reconhecer a natureza da chave no cofre. Como o tipo e declarado (e nao
inferido), a chave que voce guardou como rk_live_… continua sendo uma RK mesmo
que o catalogo de scopes ofertado cresca depois.
Exemplo de escopo minimo. A emissao acontece no Portal (fluxo do
master_user, descrito em
Como obter suas credenciais) — nao
ha endpoint publico de emissao para o integrador. Um job que so consulta o
estoque e simula antecipacao nao precisa de nada alem destes dois scopes, e e
exatamente esse recorte que uma RK vai carregar:
| Campo do formulario | Valor |
|---|---|
| Rotulo | job-simulacao-noturna |
| Scopes | stock:read, simulation:create |
| Tipo | RK |
Se essa chave vazar, o raio de dano e o que ela pode fazer: ler estoque e simular.
Ela nao cria operacao, nao cadastra cedente e nao altera sacado — cada uma dessas
chamadas volta 403 scope_insufficient. E a razao de RK ser o padrao recomendado:
o teto de credenciais ativas por originador foi dimensionado para varias chaves
restritas, nao para uma unica chave plena.
Tabela de scopes
| Scope | Acesso concedido | Endpoints principais |
|---|---|---|
simulation:create | Simular antecipacao | POST /v1/simulate, POST /v1/stock/simulate-anticipation |
operation:read | Consultar operacoes | GET /v1/operations, GET /v1/operations/{id}, GET /v1/operations/{id}/titles |
operation:create | Criar operacoes (direta e via estoque) | POST /v1/operations/direct, POST /v1/stock/request-anticipation |
operation:cancel | Cancelar operacoes | POST /v1/operations/{id}/cancel |
contract:read | Acompanhar a assinatura: signatarios, status e sign_url (ver Assinatura embedded) | GET /v1/operations/{id}/contract/signers |
contract:send | Disparar o contrato da operacao (ver quando voce precisa dele) | POST /v1/operations/{id}/contract/send-for-signature |
stock:read | Consultar itens de estoque | GET /v1/stock, GET /v1/stock/{id} |
stock:write | Registrar / editar / cancelar / expirar itens de estoque | POST /v1/stock, PATCH /v1/stock/{id}, POST /v1/stock/{id}/cancel, POST /v1/stock/{id}/expire |
title:read | Consultar titulos | GET /v1/titles, GET /v1/titles/{id}, GET /v1/titles/{id}/balance-events |
assignor:read | Consultar cedentes | GET /v1/assignors, GET /v1/assignors/{id}, GET /v1/assignors/{id}/outstanding-balance |
assignor:write | Criar / editar cedentes | POST /v1/assignors, PATCH /v1/assignors/{id} |
payer:read | Consultar sacados | GET /v1/payers, GET /v1/payers/{id} |
payer:write | Criar / editar / remover sacados | POST /v1/payers, PATCH /v1/payers/{id}, DELETE /v1/payers/{id} |
webhook:read | Listar webhooks e suas entregas | GET /v1/webhooks, GET /v1/webhooks/{id}/deliveries |
webhook:write | Criar / editar / remover webhooks | POST /v1/webhooks, PATCH /v1/webhooks/{id}, DELETE /v1/webhooks/{id} |
bank-account:read | Consultar contas bancarias | GET /v1/bank-accounts |
originator:read | Consultar dados do originador | GET /v1/originators/me |
payable:read | Consultar payables de cedente e seus pagamentos | GET /v1/assignor-payables, GET /v1/assignor-payables/{id}, GET /v1/assignor-payables/{id}/payments |
payable:write | Criar payables, registrar pagamentos e baixas | POST /v1/assignor-payables, POST /v1/assignor-payables/{id}/payments, POST /v1/assignor-payables/{id}/write-off |
discount-credit:read | Consultar creditos de desconto e consumos | GET /v1/discount-credits, GET /v1/discount-credits/{id}/consumptions |
discount-credit:write | Criar creditos de desconto | POST /v1/discount-credits |
A tabela acima e exaustiva nos dois sentidos: toda rota publica que exige scope esta listada, e toda rota listada existe e exige exatamente o scope da linha. As rotas que nao exigem scope estao logo abaixo, em Endpoints sem scope.
contract:send e um opt-in de borda
Os dois scopes de contrato sao separados de proposito, e a maioria das integracoes so precisa do primeiro:
contract:read— o recorte tipico. Operacoes criadas pela API disparam o contrato automaticamente assim que sao aprovadas; o que voce faz e acompanhar (status de cada signatario esign_url, inclusive no modo embedded, para apresentar o link na sua propria tela).contract:send— o poder de disparar o contrato. Peca-o so se voce cair em uma destas bordas:- re-disparo apos falha (operacao em
CONTRACT_ERROR); - operacoes importadas do fluxo antigo (
created_via = BACKOFFICE), que nao passaram pelo auto-disparo; - operacao ja
APPROVED_DIRECTha mais de 48h sem contrato despachado; - o auto-disparo esta desligado (kill-switch) ou voce precisa sobrescrever
o modo
embeddeddeclarado na criacao da operacao; - voce quer o contrato imediatamente, sem esperar a varredura periodica.
- re-disparo apos falha (operacao em
Quem tem contract:read nao consegue disparar contrato, e quem tem
contract:send nao herda a leitura: sao dois scopes independentes. Uma
credencial que so acompanha assinatura nao emite documento de cessao — e a
razao da separacao.
Regra de derivacao (metodo -> scope)
Para a maioria dos recursos o scope segue o metodo HTTP:
GET/HEAD-> scope:readdo recurso (ex.:GET /v1/payers->payer:read).POST/PATCH/DELETE-> scope:writedo recurso (ex.:PATCH /v1/payers/{id}->payer:write).- Acoes
/cancele/expireexigem o scope de escrita do recurso pai. Operacoes usam o scope dedicadooperation:cancel. - O sub-recurso de contrato de uma operacao (
/v1/operations/{id}/contract/...) nao segue o metodo: cada rota tem scope proprio —contract:readpara/contract/signersecontract:sendpara/contract/send-for-signature.
PUT nao e usadoA API publica nao expoe nenhuma rota PUT. Atualizacao parcial e sempre
PATCH (cedente, sacado, item de estoque, webhook). A regra de derivacao aceita
PUT internamente, mas nenhum endpoint publico o registra.
Endpoints sem scope
Sete rotas publicas nao exigem scope nenhum — mas elas se dividem em duas categorias bem diferentes:
Abertas (nao exigem autenticacao alguma)
Chamaveis sem Authorization, sem client_id / client_secret:
| Endpoint | Para que serve |
|---|---|
POST /v1/auth/token | Troca client_id + client_secret por um JWT. E a porta de entrada — exigir token aqui seria circular. |
POST /v1/auth/login | Login de sessao (usuarios do Portal). |
GET /v1/health | Liveness probe. |
GET /v1/flow | Descricao estatica do fluxo de integracao. |
Autenticadas, porem sem scope
Exigem um token valido; qualquer scope serve:
| Endpoint | Para que serve |
|---|---|
GET /v1/auth/me | Introspeccao do proprio token (nao ha recurso alem do proprio principal). |
GET /v1/products | Catalogo de produtos financeiros. |
GET /v1/health/deep | Health com checagem de dependencias. |
Os scopes exigidos por cada endpoint individual tambem aparecem na Referencia Tecnica (OpenAPI/Scalar).