Documentación de autenticación SingleFax
Claves API, OAuth para MCP y Agent Auth delegado.
Guía de autenticación para agentes de IA y desarrolladores.
Cómo se autentican los agentes en SingleFax. Instalación HTML: https://singlefax.com/agents
Este archivo es el destino agent_auth.skill anunciado en los metadatos RFC 8414 de /.well-known/oauth-authorization-server.
SingleFax admite el registro Auth.md anonymous y service_auth, con aprobación del usuario y afirmaciones de identidad firmadas por el servicio. Las credenciales anónimas no permiten acceder a ninguna cuenta antes de la aprobación. No se aceptan ID-JAG de proveedores externos. El flujo anterior de JWT de host/agente de Better Auth se documenta por separado en la vía C.
Registro Auth.md e intercambio de tokens
Dirigido a agentes de IA que se registran para actuar en nombre de una cuenta existente de SingleFax. Todos los métodos de registro requieren una inscripción emitida por el propietario. Las solicitudes públicas sin un token de inscripción válido se rechazan antes de crear el registro. El emisor OAuth es https://api.singlefax.com/api/auth; el recurso es https://singlefax.com/mcp. El registro nunca envía correos ni faxes, ni realiza cobros.
Métodos de registro admitidos: anonymous y service_auth. Credenciales: identity_assertion y Bearer access_token. El propietario de la cuenta inicia sesión en SingleFax, revisa los permisos solicitados e introduce el código de seis dígitos de su agente. Los ámbitos admitidos son fax:read, fax:draft, fax:send, inbox:read, credits:read y credits:checkout. Los permisos predeterminados son fax:read y credits:read; solicita expresamente cualquier ámbito adicional.
- El propietario inicia sesión en https://singlefax.com/dashboard/agent-access, elige el nombre del agente y los permisos permitidos, y crea expresamente un token de inscripción. Este secreto de corta duración se muestra una sola vez, caduca a los diez minutos y solo permite registrar un agente. Entrégaselo a ese agente. El aprovisionamiento por API usa la sesión propia del propietario en el navegador en
POST https://singlefax.com/api/auth/agent/identity/managecon{ "action": "enroll", "name": "My agent", "scopes": ["fax:read", "credits:read"] }. Las cookies del navegador nunca se comparten con el agente. Los propietarios pueden revocar los tokens sin usar en la misma página. - Regístrate mediante
POST https://api.singlefax.com/api/auth/agent/identityconContent-Type: application/jsony{ "type": "service_auth", "enrollment_token": "<owner-issued token>", "login_hint": "<enrolling owner email>" }. Se devuelvenregistration_id, un secretoclaim_token, la caducidad yclaimconuser_code,verification_uriy un intervalo de consulta de cinco segundos. No se emite ninguna afirmación antes de la aprobación. - También puedes registrarte con
{ "type": "anonymous", "enrollment_token": "<owner-issued token>" }. Aquí, anónimo describe la credencial anterior a la vinculación, no un registro público abierto. Se devuelven inmediatamente unidentity_assertionfirmado y unclaim_token. Intercambiar esa afirmación previa a la vinculación proporciona un token sin ámbitos que no permite acceder a ninguna cuenta. Inicia su aprobación mediantePOST https://api.singlefax.com/api/auth/agent/identity/claimcon{ "claim_token": "<secret>", "email": "<account email>" }; lee elclaim_attemptdevuelto. - Muestra el código por separado y abre
verification_uripara el usuario. La URL contiene un token secreto del intento de vinculación; no incluyas el código en esa URL. Solo puede aprobar la cuenta verificada que emitió la inscripción. El propietario fija el nombre; los ámbitos solicitados pueden reducirse, pero no pueden superar los permisos de inscripción. El indicio de correo y el correo de vinculación deben coincidir con los del propietario que emitió la inscripción. El usuario puede rechazarla. Los intentos de vinculación caducan a los diez minutos; uno nuevo invalida el enlace anterior. No se crea ninguna cuenta automáticamente. - Consulta
POST https://api.singlefax.com/api/auth/oauth2/tokenconContent-Type: application/x-www-form-urlencodedygrant_type=urn:workos:agent-auth:grant-type:claim&claim_token=<secret>&resource=https%3A%2F%2Fsinglefax.com%2Fmcp. Gestionaauthorization_pending,slow_down(aumenta el intervalo en cinco segundos),expired_tokenyaccess_denied. La aprobación devuelve unaccess_tokenopaco,token_type,expires_in,scope,identity_assertionyassertion_expires. Los tokens y las afirmaciones anteriores a la vinculación se invalidan al aprobar. - Usa
Authorization: Bearer <access_token>en MCP o A2A con los ámbitos concedidos. Los tokens duran como máximo una hora. Para renovarlos, usa el mismo endpoint de tokens congrant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<identity_assertion>&resource=https%3A%2F%2Fsinglefax.com%2Fmcp. No se emite ningún token de actualización. Las afirmaciones pueden volver a intercambiarse durante un máximo de 30 días salvo que se revoque el registro. Sus firmas EdDSA usan el/jwksdel emisor;typesoauth-id-jag+jwt, y tantoisscomoaudson iguales al emisor. - Revoca un token con
POST https://api.singlefax.com/api/auth/oauth2/revoke, cuerpo de formulariotoken=<access_token>&token_type_hint=access_token. Esta operación es idempotente y deja utilizable la afirmación. Revoca el registro conPOST https://api.singlefax.com/api/auth/agent/identity/revoke, JSON{ "identity_assertion": "<identity_assertion>" }; se detienen todos los tokens de acceso y los intercambios posteriores.
El propietario de la cuenta puede revisar y revocar las autorizaciones en https://singlefax.com/dashboard/agent-access. Revocar un registro detiene todos los tokens de acceso asociados y la renovación mediante afirmaciones.
Las respuestas de vinculación y aprobación son privadas y nunca se pueden almacenar en caché. Mantén en secreto los tokens de vinculación, las afirmaciones y los tokens de acceso. La emisión de inscripciones está limitada por propietario entre todas las réplicas de la API, con un máximo de cinco tokens activos sin usar. Las solicitudes públicas sin inscripción no consumen el cupo de registros del propietario. Los tokens ausentes devuelven enrollment_required; los caducados, revocados o consumidos devuelven invalid_enrollment. Un registro fallido no consume el token de inscripción. No sondees los endpoints de registro durante comprobaciones pasivas de disponibilidad.
Descubrimiento
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
Metadatos del recurso protegido (RFC 9728): el documento raíz describe el origen (resource https://singlefax.com); /.well-known/oauth-protected-resource/mcp describe el servidor MCP (resource https://singlefax.com/mcp, al que apunta la URL WWW-Authenticate). Ambos indican authorization_servers (emisor https://api.singlefax.com/api/auth) y scopes_supported. Solicita 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
Los metadatos del servidor de autorización incluyen issuer, authorization_endpoint, token_endpoint, registration_endpoint, jwks_uri, scopes_supported y agent_auth (skill apunta aquí).
El origen de la API https://api.singlefax.com sirve los mismos documentos well-known.
Vía A. MCP OAuth (aplicaciones de chat)
Usa esta opción para Cursor, Claude, ChatGPT, Codex y VS Code.
- Añade MCP
https://singlefax.com/mcp(Streamable HTTP). - Ante un 401, lee
WWW-Authenticatey obtén los PRM anteriores. - Registro dinámico de clientes:
POST {issuer}/oauth2/register(PKCE S256,token_endpoint_auth_method=nonepara clientes públicos). - Código de autorización + PKCE en
{issuer}/oauth2/authorize. - Token en
{issuer}/oauth2/token. POST /mcpconAuthorization: Bearer. Para un documento habitual, llama acreate_upload, entrega al usuariouploadPageUrly después usacreate_fax_draftcontoyuploadToken.base64solo sirve para archivos muy pequeños. PUT auploadUrlusa el token HMAC de la ruta, sin cabecera OAuth. Envía el Word, Excel, PDF o imagen original; no lo conviertas antes a PDF.
Ámbitos: openid, profile, email, offline_access, fax:read, fax:draft, fax:send, inbox:read, credits:read, credits:checkout. Solicita expresamente credits:checkout para las compras de saldo mediante AP2; cada cargo sigue requiriendo una aprobación independiente con clave de acceso.
Sin autenticación, POST /mcp solo acepta server/discover. initialize, tools/list y tools/call requieren OAuth.
Vía A2. A2A (agente a agente)
Tarjeta del agente: GET https://singlefax.com/.well-known/agent-card.json (A2A 1.0). Endpoint: POST https://singlefax.com/a2a (JSON-RPC: SendMessage, GetTask, CancelTask; también funcionan los nombres de 0.3 message/send, tasks/get, tasks/cancel).
- Usa el mismo servidor OAuth, ámbitos y tokens que en la vía A (solicita el recurso
https://singlefax.com/mcp). EnvíaAuthorization: Bearer. No se aceptan tokens vinculados a DPoP en/a2a. - Envía una sola parte de datos:
{ "skill": "<skill id from the card>", "arguments": { ... } }. No se interpreta el texto libre. - Las habilidades de fax y números devuelven un enlace de Stripe Checkout (
checkoutUrl). A2A nunca gasta el saldo de la cuenta ni las páginas del plan. Un borrador pendiente de pago tiene el estado de tareainput-required. Consulta su estado conGetTask.
Para comprar saldo mediante AP2, solicita credits:checkout y negocia la extensión del comercio. Los mandatos firmados de carrito y pago, la aprobación independiente del propietario con clave de acceso, el canje de Stripe Shared Payment Token y los recibos confirmados en el libro de movimientos se documentan en https://singlefax.com/ap2.md.
GetTask con fax:read sigue la entrega del fax para borradores de fax y el pago/aprovisionamiento para compras de números. Una tarea de número termina cuando el número se activa. La compra de un paquete de saldo no tiene una tarea asociada a un pedido que se pueda consultar; comprueba el saldo después del pago.
Vía B. Clave API (backends y CLI)
- Crea una clave en https://singlefax.com/dashboard/api-keys (
sf_live_…). - Compra saldo de prepago.
Authorization: Bearer sf_live_…enhttps://singlefax.com/api/v1/…(ohttps://api.singlefax.com/api/v1/…).- CLI:
npx @singlefax/cli send FILE --to +E164conSINGLEFAX_API_KEY. Usa el Word, Excel, PDF o imagen original; no lo conviertas antes a PDF.
Ejemplos por lenguaje (curl, Node, Python, Go, PHP): https://singlefax.com/developers.md
OpenAPI: https://singlefax.com/openapi.json
Vía C. JWT delegados de host/agente de Better Auth
Las capacidades delegadas (validate_fax, send_fax, get_fax_status, get_credits, create_credit_checkout) usan aprobación de dispositivo.
- Lee
GET https://api.singlefax.com/.well-known/agent-configurationpara conocer los algoritmos, endpoints, modos y métodos de aprobación. Su emisor de Agent Auth eshttps://api.singlefax.com, distinto del emisor OAuth terminado en/api/auth. Usa este origen como audiencia JWT. Genera claves de firma independientes para el host y el agente con un algoritmo admitido; mantén las claves privadas en secreto. - Aprovisiona primero el host. El registro dinámico de hosts está desactivado. El propietario de la cuenta debe iniciar sesión en SingleFax y llamar a
POST https://singlefax.com/api/auth/host/create(equivalente en el origen API: https://api.singlefax.com/api/auth/host/create) desde su sesión propia del navegador. Proporciona{ "name": "My agent host", "public_key": <host public JWK>, "default_capabilities": [] }. ElhostIdde la respuesta identifica el host registrado. Los valores predeterminados vacíos garantizan que las capacidades requieran una aprobación independiente. También puedes omitirpublic_keypara recibir unenrollmentTokende un solo uso y con caducidad; después el host llama aPOST https://api.singlefax.com/api/auth/host/enrollcon{ "token": <enrollment token>, "public_key": <host public JWK>, "name": "My agent host" }. Nunca compartas cookies del navegador ni claves de firma privadas con un agente. - Regístrate en
POST https://api.singlefax.com/api/auth/agent/register. EnvíaAuthorization: Bearer <signed host+jwt>y JSON{ "name": "My agent", "mode": "delegated", "capabilities": ["validate_fax", "get_fax_status", "get_credits"], "preferred_method": "device_authorization", "force_approval": true }. La cabecera JWT usatyp: "host+jwt"y unalgadmitido (y elkidde la JWK de firma, si existe). Las declaraciones incluyeniss: <registered hostId>,aud: "https://api.singlefax.com", unjtinuevo,iatactual,expdentro de 60 segundos yagent_public_key: <agent public JWK>. Firma con la clave del host aprovisionado. Se rechazan los identificadores JWT reutilizados. - El registro devuelve
agent_id,host_id, el estado, las capacidades concedidas y un objetoapprovalcuando sea necesario. Muestra su código de dispositivo y abre suverification_uri_completeen el sitio de SingleFax. El usuario inicia sesión y aprueba en la URL de verificación devuelta. El registro, el aprovisionamiento y la aprobación modifican el estado de la cuenta; los escáneres pasivos solo deben leer los documentos de descubrimiento. - Consulta
GET https://api.singlefax.com/api/auth/agent/status?agent_id=<registered id>con un JWT de host nuevo (iss: <host_id>). Tras la aprobación, firma JWT de agente con la clave privada del agente: cabeceratyp: "agent+jwt",alg/kidadmitidos; declaracionesiss: <host_id>,sub: <agent_id>,aud: "https://api.singlefax.com",iatactual,expdentro de 60 segundos y unjtinuevo. Llama aPOST https://api.singlefax.com/api/auth/capability/executeconAuthorization: Bearer <signed agent+jwt>y{ "capability": "get_credits", "arguments": {} }, o a otra capacidad concedida con sus argumentos documentados. Estas credenciales son pruebas firmadas, no claves API ni tokens de acceso OAuth. - Para obtener un nuevo código de dispositivo para un agente registrado, usa
POST https://api.singlefax.com/api/auth/agent/device/codecon{ "agent_id": "<registered id>" }y un JWT de host firmado. Este endpoint no permite registrar un agente. Revoca mediantePOST https://api.singlefax.com/api/auth/agent/revokecon{ "agent_id": "<registered id>" }y el JWT del host propietario o la sesión del propietario.send_faxrequiere verificación del usuario con una clave de acceso; no es autónomo.
No envíes ID-JAG ni { "type": "anonymous" } mediante POST aquí. No se admiten esos tipos de identidad.
Pagos de máquina (sin OAuth)
El pago autónomo usa MPP HTTP 402 en POST /api/v1/machine/faxes con un Stripe Shared Payment Token o Tempo USDC. Consulta https://singlefax.com/mpp.md. Cursor no puede generar un SPT; usa Stripe Link CLI con esa URL REST, no con /mcp. Las carteras Tempo pagan el desafío Tempo en la misma URL.
HIPAA
No envíes PHI mediante MCP, MPP ni la API pública. Las entidades cubiertas usan el modo HIPAA Secure del sitio web con un BAA electrónico.