Documentação de autenticação SingleFax

Chaves de API, OAuth para MCP e Agent Auth delegado.

Guia de autenticação para agentes de IA e desenvolvedores.

Como os agentes se autenticam no SingleFax. Instalação HTML: https://singlefax.com/agents

Este arquivo é o destino agent_auth.skill anunciado nos metadados RFC 8414 em /.well-known/oauth-authorization-server.

O SingleFax aceita registro Auth.md anonymous e service_auth, com aprovação do usuário e asserções de identidade assinadas pelo serviço. Credenciais anônimas não têm acesso a contas antes da aprovação. ID-JAGs de provedores externos não são aceitos. O fluxo anterior de JWT de host/agente do Better Auth está documentado separadamente no Caminho C.

Registro Auth.md e troca de tokens

Público: agentes de IA que se registram para agir em nome de uma conta SingleFax existente. Todos os métodos de registro exigem uma inscrição emitida pelo proprietário. Solicitações públicas sem um token de inscrição válido são rejeitadas antes da criação de um registro. O emissor OAuth é https://api.singlefax.com/api/auth; o recurso é https://singlefax.com/mcp. O registro nunca envia e-mails ou faxes nem realiza cobranças.

Métodos de registro aceitos: anonymous e service_auth. Credenciais: identity_assertion e Bearer access_token. O proprietário da conta entra no SingleFax, revisa as permissões solicitadas e informa o código de seis dígitos do agente. Os escopos aceitos são fax:read, fax:draft, fax:send, inbox:read, credits:read e credits:checkout. As permissões padrão são fax:read e credits:read; solicite escopos adicionais explicitamente.

  1. O proprietário entra em https://singlefax.com/dashboard/agent-access, escolhe o nome do agente e as permissões permitidas e cria explicitamente um token de inscrição. Esse segredo temporário é exibido uma única vez, expira após dez minutos e só pode registrar um agente. Entregue-o a esse agente. O provisionamento pela API usa a sessão própria do proprietário no navegador em POST https://singlefax.com/api/auth/agent/identity/manage com { "action": "enroll", "name": "My agent", "scopes": ["fax:read", "credits:read"] }. Os cookies do navegador nunca são compartilhados com o agente. O proprietário pode revogar tokens não utilizados na mesma página.
  2. Registre usando POST https://api.singlefax.com/api/auth/agent/identity com Content-Type: application/json e { "type": "service_auth", "enrollment_token": "<owner-issued token>", "login_hint": "<enrolling owner email>" }. Isso retorna registration_id, um segredo claim_token, a expiração e claim com user_code, verification_uri e intervalo de consulta de cinco segundos. Nenhuma asserção é emitida antes da aprovação.
  3. Como alternativa, registre com { "type": "anonymous", "enrollment_token": "<owner-issued token>" }. Aqui, anônimo descreve a credencial anterior à vinculação, e não um cadastro público aberto. Isso retorna imediatamente um identity_assertion assinado e um claim_token. Trocar essa asserção anterior à vinculação gera um token sem escopos, que não pode acessar nenhuma conta. Inicie sua aprovação usando POST https://api.singlefax.com/api/auth/agent/identity/claim com { "claim_token": "<secret>", "email": "<account email>" }; leia o claim_attempt retornado.
  4. Mostre o código separadamente e abra verification_uri para o usuário. A URL contém um token secreto da tentativa de vinculação; não inclua o código nessa URL. Somente a conta verificada que emitiu a inscrição pode aprovar. O nome é definido pelo proprietário; os escopos solicitados podem ser reduzidos, mas não podem exceder as permissões da inscrição. A indicação de e-mail e o e-mail de vinculação devem corresponder ao proprietário que emitiu a inscrição. O usuário pode recusar. As tentativas de vinculação expiram após dez minutos; uma nova tentativa invalida o link anterior. Nenhuma conta é criada automaticamente.
  5. Consulte POST https://api.singlefax.com/api/auth/oauth2/token com Content-Type: application/x-www-form-urlencoded e grant_type=urn:workos:agent-auth:grant-type:claim&claim_token=<secret>&resource=https%3A%2F%2Fsinglefax.com%2Fmcp. Trate authorization_pending, slow_down (aumente o intervalo em cinco segundos), expired_token e access_denied. A aprovação retorna um access_token opaco, token_type, expires_in, scope, identity_assertion e assertion_expires. Tokens e asserções anteriores à vinculação são invalidados na aprovação.
  6. Use Authorization: Bearer <access_token> no MCP ou A2A com os escopos concedidos. Os tokens duram no máximo uma hora. Para renovar, use o mesmo endpoint de tokens com grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<identity_assertion>&resource=https%3A%2F%2Fsinglefax.com%2Fmcp. Não é emitido um token de atualização. As asserções podem ser trocadas novamente por até 30 dias, a menos que o registro seja revogado. Suas assinaturas EdDSA usam o /jwks do emissor; typ é oauth-id-jag+jwt, e iss/aud são ambos iguais ao emissor.
  7. Revogue um token com POST https://api.singlefax.com/api/auth/oauth2/revoke, corpo de formulário token=<access_token>&token_type_hint=access_token. A operação é idempotente e mantém a asserção utilizável. Revogue o registro com POST https://api.singlefax.com/api/auth/agent/identity/revoke, JSON { "identity_assertion": "<identity_assertion>" }; todos os tokens de acesso e as trocas posteriores são interrompidos.

O proprietário da conta pode revisar e revogar concessões em https://singlefax.com/dashboard/agent-access. Revogar um registro interrompe todos os tokens de acesso associados e a renovação por asserções.

As respostas de vinculação e aprovação são privadas e nunca podem ser armazenadas em cache. Mantenha em segredo os tokens de vinculação, as asserções e os tokens de acesso. A emissão de inscrições é limitada por proprietário entre todas as réplicas da API, com no máximo cinco tokens ativos não utilizados. Solicitações públicas sem inscrição não consomem a cota de registros do proprietário. Tokens ausentes retornam enrollment_required; tokens expirados, revogados ou consumidos retornam invalid_enrollment. Um registro malsucedido não consome o token de inscrição. Não sonde endpoints de registro durante verificações passivas de prontidão.

Descoberta

Servidor de recursos (MCP + API BFF): https://singlefax.com

GET https://singlefax.com/.well-known/oauth-protected-resource
GET https://singlefax.com/.well-known/oauth-protected-resource/mcp

Metadados do recurso protegido (RFC 9728): o documento raiz descreve a origem (resource https://singlefax.com); /.well-known/oauth-protected-resource/mcp descreve o servidor MCP (resource https://singlefax.com/mcp, para o qual aponta a URL WWW-Authenticate). Ambos listam authorization_servers (emissor https://api.singlefax.com/api/auth) e scopes_supported. Solicite tokens para https://singlefax.com/mcp.

GET https://singlefax.com/.well-known/oauth-authorization-server
GET https://singlefax.com/.well-known/oauth-authorization-server/api/auth

Os metadados do servidor de autorização incluem issuer, authorization_endpoint, token_endpoint, registration_endpoint, jwks_uri, scopes_supported e agent_auth (skill aponta para cá).

A origem da API https://api.singlefax.com disponibiliza os mesmos documentos well-known.

Caminho A. MCP OAuth (aplicativos de chat)

Use esta opção para Cursor, Claude, ChatGPT, Codex e VS Code.

  1. Adicione MCP https://singlefax.com/mcp (Streamable HTTP).
  2. Ao receber 401, leia WWW-Authenticate e obtenha os PRM acima.
  3. Registro dinâmico de clientes: POST {issuer}/oauth2/register (PKCE S256, token_endpoint_auth_method=none para clientes públicos).
  4. Código de autorização + PKCE em {issuer}/oauth2/authorize.
  5. Token em {issuer}/oauth2/token.
  6. POST /mcp com Authorization: Bearer. Para um documento comum, chame create_upload, forneça uploadPageUrl ao usuário e depois create_fax_draft com to e uploadToken. base64 serve apenas para arquivos muito pequenos. PUT para uploadUrl usa o token HMAC no caminho, sem cabeçalho OAuth. Envie o Word, Excel, PDF ou imagem original; não converta para PDF antes.

Escopos: openid, profile, email, offline_access, fax:read, fax:draft, fax:send, inbox:read, credits:read, credits:checkout. Solicite credits:checkout explicitamente para compras de créditos pré-pagos por AP2; cada cobrança ainda exige uma aprovação separada com chave de acesso.

Sem autenticação, POST /mcp aceita apenas server/discover. initialize, tools/list e tools/call exigem OAuth.

Caminho A2. A2A (agente para agente)

Cartão do agente: GET https://singlefax.com/.well-known/agent-card.json (A2A 1.0). Endpoint: POST https://singlefax.com/a2a (JSON-RPC: SendMessage, GetTask, CancelTask; os nomes da versão 0.3 message/send, tasks/get, tasks/cancel também funcionam).

  1. Use o mesmo servidor OAuth, escopos e tokens do Caminho A (solicite o recurso https://singlefax.com/mcp). Envie Authorization: Bearer. Tokens vinculados a DPoP não são aceitos em /a2a.
  2. Envie uma única parte de dados: { "skill": "<skill id from the card>", "arguments": { ... } }. Texto livre não é interpretado.
  3. As habilidades de fax e números retornam um link do Stripe Checkout (checkoutUrl). O A2A nunca gasta créditos pré-pagos da conta nem páginas do plano. Um rascunho aguardando pagamento tem o estado de tarefa input-required. Consulte com GetTask.

Para comprar créditos pré-pagos por AP2, solicite credits:checkout e negocie a extensão do comerciante. Os mandatos assinados de carrinho e pagamento, a aprovação separada do proprietário com chave de acesso, o resgate de Stripe Shared Payment Token e os recibos confirmados no livro de movimentações estão documentados em https://singlefax.com/ap2.md.

GetTask com fax:read acompanha a entrega de fax para rascunhos de fax e o pagamento/provisionamento para compras de números. Uma tarefa de número termina quando o número fica ativo. A compra de um pacote de créditos pré-pagos não tem tarefa vinculada a pedido para consultar; confira o saldo após o pagamento.

Caminho B. Chave de API (backends e CLI)

  1. Crie uma chave em https://singlefax.com/dashboard/api-keys (sf_live_…).
  2. Compre créditos pré-pagos.
  3. Authorization: Bearer sf_live_… em https://singlefax.com/api/v1/… (ou https://api.singlefax.com/api/v1/…).
  4. CLI: npx @singlefax/cli send FILE --to +E164 com SINGLEFAX_API_KEY. Use o Word, Excel, PDF ou imagem original; não converta para PDF antes.

Exemplos por linguagem (curl, Node, Python, Go, PHP): https://singlefax.com/developers.md

OpenAPI: https://singlefax.com/openapi.json

Caminho C. JWTs delegados de host/agente do Better Auth

As capacidades delegadas (validate_fax, send_fax, get_fax_status, get_credits, create_credit_checkout) usam aprovação de dispositivo.

  1. Leia GET https://api.singlefax.com/.well-known/agent-configuration para ver os algoritmos, endpoints, modos e métodos de aprovação. Seu emissor do Agent Auth é https://api.singlefax.com, diferente do emissor OAuth terminado em /api/auth. Use essa origem como audiência do JWT. Gere chaves de assinatura separadas para host e agente usando um algoritmo aceito; mantenha as chaves privadas em segredo.
  2. Provisione o host primeiro. O registro dinâmico de hosts está desativado. O proprietário da conta deve entrar no SingleFax e chamar POST https://singlefax.com/api/auth/host/create (equivalente na origem da API: https://api.singlefax.com/api/auth/host/create) usando sua sessão própria do navegador. Forneça { "name": "My agent host", "public_key": <host public JWK>, "default_capabilities": [] }. O hostId da resposta identifica o host registrado. Os padrões vazios garantem que as capacidades exijam aprovação separada. Como alternativa, omita public_key para receber um enrollmentToken de uso único com expiração; o host então chama POST https://api.singlefax.com/api/auth/host/enroll com { "token": <enrollment token>, "public_key": <host public JWK>, "name": "My agent host" }. Nunca compartilhe cookies do navegador nem chaves privadas de assinatura com um agente.
  3. Registre em POST https://api.singlefax.com/api/auth/agent/register. Envie Authorization: Bearer <signed host+jwt> e JSON { "name": "My agent", "mode": "delegated", "capabilities": ["validate_fax", "get_fax_status", "get_credits"], "preferred_method": "device_authorization", "force_approval": true }. O cabeçalho JWT usa typ: "host+jwt" e um alg aceito (e o kid da JWK de assinatura, se houver). As declarações incluem iss: <registered hostId>, aud: "https://api.singlefax.com", um jti novo, iat atual, exp dentro de 60 segundos e agent_public_key: <agent public JWK>. Assine com a chave do host provisionado. Identificadores JWT reutilizados são rejeitados.
  4. O registro retorna agent_id, host_id, status, concessões de capacidades e um objeto approval quando necessário. Mostre seu código de dispositivo e abra seu verification_uri_complete no site do SingleFax. O usuário entra e aprova na URL de verificação retornada. Registro, provisionamento e aprovação alteram o estado da conta; scanners passivos devem ler apenas documentos de descoberta.
  5. Consulte GET https://api.singlefax.com/api/auth/agent/status?agent_id=<registered id> usando um JWT de host novo (iss: <host_id>). Após a aprovação, assine JWTs de agente com a chave privada do agente: cabeçalho typ: "agent+jwt", alg/kid aceitos; declarações iss: <host_id>, sub: <agent_id>, aud: "https://api.singlefax.com", iat atual, exp dentro de 60 segundos e um jti novo. Chame POST https://api.singlefax.com/api/auth/capability/execute com Authorization: Bearer <signed agent+jwt> e { "capability": "get_credits", "arguments": {} }, ou outra capacidade concedida com os argumentos documentados. Essas credenciais são provas assinadas, não chaves de API nem tokens de acesso OAuth.
  6. Para um novo código de dispositivo em um agente registrado, use POST https://api.singlefax.com/api/auth/agent/device/code com { "agent_id": "<registered id>" } e um JWT de host assinado. Este endpoint não pode registrar um agente. Revogue por POST https://api.singlefax.com/api/auth/agent/revoke com { "agent_id": "<registered id>" } e o JWT do host proprietário ou a sessão do proprietário. send_fax exige verificação do usuário com chave de acesso; não é autônomo.

Não envie ID-JAGs nem { "type": "anonymous" } via POST aqui. Esses tipos de identidade não são aceitos.

Pagamentos de máquina (sem OAuth)

O pagamento autônomo usa MPP HTTP 402 em POST /api/v1/machine/faxes com um Stripe Shared Payment Token ou Tempo USDC. Veja https://singlefax.com/mpp.md. O Cursor não pode gerar um SPT; use o Stripe Link CLI com essa URL REST, e não com /mcp. Carteiras Tempo pagam o desafio Tempo na mesma URL.

HIPAA

Não envie PHI pelo MCP, MPP ou API pública. Entidades cobertas usam o modo HIPAA Secure no site com um BAA eletrônico.