Api.Airforce
PROVEDOR OAUTH

Entrar com Airforce

Deixe seus usuários autorizarem seu app a acessar a conta Api.Airforce deles. Fluxo padrão OAuth 2.0 Authorization Code com PKCE.

Para quem é isto

Você está construindo um app (playground, agente, cliente mobile, …) e quer que seus usuários conectem a conta Airforce deles para que possam executar chat ou geração de imagens via sua UI sem compartilhar a chave API bruta com você. Use este fluxo.

Você vai receber um access_token opaco (24h TTL) restrito ao que seu app pediu e o usuário aprovou. Use-o como header Bearer contra os endpoints /v1/* ou /oauth/userinfo.

1. Obter um client_id + client_secret

A Fase 1 é um registro gerenciado pelo admin. Escreva para nós com:

  • Nome do app (mostrado na tela de consentimento aos seus usuários)
  • Descrição de uma frase
  • URL da homepage (opcional, mostrada no consentimento)
  • URL do logo quadrado (opcional)
  • Uma ou mais redirect_uri exatas (apenas https://, exceto http://localhost para dev)
  • Quais scopes você precisa (veja abaixo)

Nós enviamos de volta client_id e um client_secret. Guarde o secret no lado do servidor — se você é uma SPA pura / app nativo sem backend, pode pular o secret e confiar apenas no PKCE.

2. Scopes

ScopeO que ele concede
profileLê o objeto user via /oauth/userinfo (id, username, plan, emails vinculados quando verificados).
chatPOST /v1/chat/completions, /v1/messages, /v1/messages/count_tokens, /v1/responses.
imagesPOST /v1/images/generations.
keys:readReservado — lista as chaves API Airforce do usuário (Phase 2).
keys:write (SENSÍVEL)Reservado — cria + revoga as chaves API Airforce do usuário (Phase 2). Scope sensível.

Múltiplos scopes são separados por espaços no parâmetro de query scope : scope=profile chat images.

3. O fluxo

3.1 Gerar par PKCE

No seu cliente, antes de redirecionar para /oauth/authorize, gere um verifier aleatório e o challenge SHA-256 correspondente.

// In your app, before redirecting to /oauth/authorize:
const verifier = randomString(64); // 43..128 chars [A-Z][a-z][0-9]-._~
const challenge = base64UrlNoPad(sha256(verifier));
sessionStorage.setItem('airforce_pkce_verifier', verifier);

3.2 Redirecionar para /oauth/authorize

Construa a URL de autorização e mande o usuário para lá. Ele verá nossa tela de consentimento, decidirá e será redirecionado de volta para você.

https://api.airforce/oauth/authorize?
  response_type=code
  &client_id=airforce_xxxxxxxxxxxxxxxxxxxxxxxxx
  &redirect_uri=https://your.app/oauth/callback
  &scope=profile chat
  &state=<random opaque>
  &code_challenge=<base64url(sha256(verifier))>
  &code_challenge_method=S256

O usuário chega na nossa tela de consentimento, faz login (se ainda não estiver), e aprova ou recusa. Redirecionamos de volta para seu redirect_uri com um ?code=… de curta duração ao aprovar, ?error=access_denied ao recusar. Seu state original é enviado de volta — verifique se confere.

3.3 Trocar o code por access_token

Do seu backend, troque o code (mais o verifier PKCE) por um access token.

curl -X POST https://api.airforce/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "code=$CODE" \
  --data-urlencode "redirect_uri=https://your.app/oauth/callback" \
  --data-urlencode "code_verifier=$VERIFIER"

Resposta (24h TTL):

{
  "access_token": "airf_oat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "token_type": "Bearer",
  "expires_in": 86400,
  "scope": "profile chat"
}

3.4 Usar o token

Chame o endpoint userinfo ou qualquer rota /v1/* que os scopes concedidos permitirem:

# Profile lookup
curl https://api.airforce/oauth/userinfo \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# Chat (requires scope=chat)
curl https://api.airforce/v1/chat/completions \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Hi"}]}'

Resposta de /oauth/userinfo

{
  "id": "user-uuid",
  "username": "foo",
  "plan": "free",
  "is_admin": false,
  "email": "[email protected]",
  "email_verified": true,
  "github_email": "[email protected]",
  "discord_username": "foo#1234"
}

Campos como email, github_email, discord_username só aparecem quando o usuário realmente os verificou / vinculou. Planeje para presença e ausência.

Revogar um token

Quando um usuário sair do seu app, revogue o token para que não continue cobrando a conta dele em segundo plano:

curl -X POST https://api.airforce/oauth/revoke \
  --data-urlencode "token=$ACCESS_TOKEN"

RFC 7009. Sempre retorna 200 independentemente de o token existir (sem oracle).

Notas de segurança

  • PKCE é obrigatório para clientes públicos (sem client_secret no lado do servidor). Aceitamos apenas S256 — code_challenge_method=plain é rejeitado.
  • redirect_uri é correspondência exata. Sem correspondência por prefixo / wildcard. Se precisar de múltiplos ambientes, registre uma URI por ambiente.
  • Os tokens têm um TTL de 24h e ainda sem refresh tokens — quando expirar, mande o usuário passar por /oauth/authorize de novo. Para agentes de longa duração, peça no startup e guarde o token em armazenamento seguro.
  • Não armazene client_secret em código client-side. Se seu app é uma SPA só de navegador ou cliente nativo, registre sem servidor e confie no PKCE.
  • Os usuários podem revogar seu app a qualquer momento no dashboard deles → aba Apps. Trate o 401 reexecutando o fluxo OAuth.
  • Cobertura da Fase 1: Bearer tokens OAuth funcionam em /v1/chat/completions, /v1/messages, /v1/messages/count_tokens, /v1/responses, /v1/images/generations, e /oauth/userinfo. Os endpoints de áudio, vídeo, voz e character ainda exigem uma chave API Airforce regular na Fase 1.

Registrar-se

Email para [email protected] ou nos contate em Discord com os detalhes de registro listados acima. Enviaremos suas credenciais em poucas horas.

Travou na configuração ou quer uma chave gratuita? Pergunte à comunidade no nosso Discord.

Entre no nosso Discord