Como funciona a integração
Visão end-to-end do fluxo OAuth 2.0 (Authorization Code + PKCE) que um parceiro usa para agir em nome do usuário no OrbitSender.
O OrbitSender usa OAuth 2.0 Authorization Code com PKCE (método S256). Nesse fluxo, o usuário autoriza o seu app numa tela de consentimento do próprio OrbitSender; o seu backend troca um código temporário por tokens; e você chama a API em nome do usuário usando um access_token do tipo Bearer.
Nada de pedir senha ao usuário: as credenciais dele nunca passam pelo seu app.
Os 5 passos do fluxo
1. Registrar e aprovar o app
Crie o app no Portal do Dev, defina uma ou mais redirect_uri, escolha os scopes com justificativa e envie para revisão. Cada scope é revisado por-scope por um superadmin. O app só passa a funcionar no /authorize quando está com status approved.
Detalhes em Criar e configurar o app e Referência de permissões.
2. Redirecionar o usuário para o consentimento
Envie o navegador do usuário (logado no OrbitSender) para a página de consentimento do app — no host do app, não da API. Ela mostra o logo e o nome do seu app e a lista de scopes solicitados.
GET https://app.orbitsender.com/oauth/authorize
?response_type=code
&client_id=cli_abc123
&redirect_uri=https://seu-app.com/callback
&scope=statistics:read campaigns:read
&state=xyz_opaco_anti_csrf
&code_challenge=BASE64URL_SHA256_DO_VERIFIER
&code_challenge_method=S256É a página do app, não a URL da API
Redirecione o navegador para https://app.orbitsender.com/oauth/authorize (a tela de consentimento do painel). O endpoint GET https://api.orbitsender.com/api/oauth/authorize é a API que alimenta essa tela (responde JSON, não HTML) — não o abra diretamente no navegador. O POST /api/oauth/authorize/decision é interno do painel; o parceiro nunca o chama.
| Parâmetro | Observação |
|---|---|
response_type | Sempre code. |
client_id | Identificador público do app (ex.: cli_abc123). |
redirect_uri | Precisa dar match exato com uma URI registrada. |
scope | Separado por espaço; precisa ser subconjunto dos scopes aprovados. |
state | Valor opaco anti-CSRF (recomendado). |
code_challenge | BASE64URL(SHA256(code_verifier)). |
code_challenge_method | Somente S256. |
3. O usuário permite e volta ao seu redirect_uri
Se o usuário clicar em Permitir, o OrbitSender redireciona de volta com um código temporário e o mesmo state:
https://seu-app.com/callback?code=orb_ac_...&state=xyz_opaco_anti_csrfSe o usuário negar, o retorno traz um erro (e o state):
https://seu-app.com/callback?error=access_denied&state=xyz_opaco_anti_csrfValide que o state recebido é igual ao que você enviou antes de prosseguir.
4. O backend troca o código por tokens
O código orb_ac_... é de uso único e vale 60 segundos. O seu servidor (nunca o navegador) faz a troca em POST https://api.orbitsender.com/api/oauth/token, enviando o code_verifier do PKCE. A resposta traz access_token (orb_at_..., ~1h) e refresh_token (orb_rt_..., rotativo).
Passo a passo completo, com refresh e revoke, em Do código temporário ao token.
5. Chamar a API em nome do usuário
Use o access_token no header Authorization:
GET https://api.orbitsender.com/api/external/partner/statistics?days=30
Authorization: Bearer orb_at_...As respostas passam por uma máscara (sem PII, sem cadência anti-ban, ids de canal viram referências opacas). Veja Chamar a API em nome do usuário.
O que o /authorize valida
Antes de exibir a tela de consentimento (e antes de emitir o código), o OrbitSender checa três invariantes:
- App aprovado — o
client_idexiste e está com statusapproved. Caso contrário:unauthorized_client. redirect_uriexato — precisa bater, caractere a caractere, com uma URI registrada no app.- Scope aprovado — o
scopesolicitado precisa ser um subconjunto dos scopes aprovados. Um scope não aprovado gerainvalid_scope.
PKCE não é opcional para apps public
Para apps public (sem client_secret), o PKCE é obrigatório. Para apps confidential, ele continua sendo recomendado. O code_challenge é BASE64URL(SHA256(code_verifier)) e o único método aceito é S256. Entenda em PKCE em detalhe.
Sempre use state
O state é um valor opaco que você gera antes do redirect e confere no retorno. Ele protege contra CSRF e ajuda a correlacionar a resposta com a sessão de quem iniciou o fluxo. É recomendado em todo pedido de autorização.