Documentation d’authentification SingleFax
Clés API, OAuth pour MCP et Agent Auth déléguée.
Guide d’authentification pour les agents IA et les développeurs.
Authentification des agents auprès de SingleFax. Installation HTML : https://singlefax.com/agents
Ce fichier est la cible agent_auth.skill annoncée dans les métadonnées RFC 8414 sur /.well-known/oauth-authorization-server.
SingleFax prend en charge l’inscription Auth.md par anonymous et service_auth, avec approbation de l’utilisateur et attestations d’identité signées par le service. Les identifiants anonymes n’accèdent à aucun compte avant approbation. Les ID-JAG externes ne sont pas acceptés. L’ancien parcours JWT hôte/agent Better Auth est décrit séparément au parcours C.
Inscription Auth.md et échange de jetons
Public : agents IA s’inscrivant pour agir pour un compte SingleFax existant. Chaque méthode exige une autorisation d’inscription émise par le titulaire. Les requêtes publiques sans jeton d’inscription valide sont rejetées avant toute création. L’émetteur OAuth est https://api.singlefax.com/api/auth ; la ressource, https://singlefax.com/mcp. L’inscription n’envoie ni e-mail ni fax et ne déclenche aucun paiement.
Méthodes prises en charge : anonymous et service_auth. Identifiants : identity_assertion et Bearer access_token. Le titulaire se connecte, examine les permissions et saisit le code à six chiffres de l’agent. Portées : fax:read, fax:draft, fax:send, inbox:read, credits:read et credits:checkout. Permissions par défaut : fax:read et credits:read ; demandez explicitement les autres.
- Le titulaire se connecte à https://singlefax.com/dashboard/agent-access, choisit le nom de l’agent et ses permissions, puis crée explicitement un jeton d’inscription. Ce secret affiché une seule fois expire après dix minutes et ne peut inscrire qu’un agent. Remettez-le à cet agent. Le provisionnement API utilise la session navigateur propriétaire sur
POST https://singlefax.com/api/auth/agent/identity/manageavec{ "action": "enroll", "name": "My agent", "scopes": ["fax:read", "credits:read"] }. Les cookies ne sont jamais partagés avec l’agent. Les jetons inutilisés peuvent être révoqués sur cette page. - Inscrivez avec
POST https://api.singlefax.com/api/auth/agent/identity,Content-Type: application/jsonet{ "type": "service_auth", "enrollment_token": "<owner-issued token>", "login_hint": "<enrolling owner email>" }. La réponse contientregistration_id, un secretclaim_token, l’expiration etclaimavecuser_code,verification_uriet un intervalle d’interrogation de cinq secondes. Aucune attestation n’est émise avant approbation. - Autre méthode :
{ "type": "anonymous", "enrollment_token": "<owner-issued token>" }. « Anonyme » désigne ici l’identifiant avant rattachement, pas une inscription publique libre. Vous recevez aussitôt unidentity_assertionsigné et unclaim_token. L’échange de cette attestation donne un jeton sans portée et sans accès à un compte. Lancez l’approbation parPOST https://api.singlefax.com/api/auth/agent/identity/claimavec{ "claim_token": "<secret>", "email": "<account email>" }et lisezclaim_attempt. - Affichez le code séparément et ouvrez
verification_uripour l’utilisateur. L’URL contient un jeton secret de tentative de rattachement ; n’y ajoutez pas le code. Seul le compte vérifié ayant autorisé l’inscription peut approuver. Le nom est fixé par ce titulaire ; les portées peuvent être réduites, sans dépasser les permissions accordées. L’indication d’e-mail et l’adresse de rattachement doivent correspondre au titulaire. L’utilisateur peut refuser. Les demandes expirent après dix minutes ; une nouvelle tentative invalide l’ancien lien. Aucun compte n’est créé automatiquement. - Interrogez
POST https://api.singlefax.com/api/auth/oauth2/tokenavecContent-Type: application/x-www-form-urlencodedetgrant_type=urn:workos:agent-auth:grant-type:claim&claim_token=<secret>&resource=https%3A%2F%2Fsinglefax.com%2Fmcp. Gérezauthorization_pending,slow_down, en augmentant l’intervalle de cinq secondes,expired_tokenetaccess_denied. L’approbation renvoie unaccess_tokenopaque,token_type,expires_in,scope,identity_assertionetassertion_expires. Les jetons et attestations antérieurs au rattachement sont invalidés. - Utilisez
Authorization: Bearer <access_token>sur MCP ou A2A avec les portées accordées. Les jetons durent au maximum une heure. Pour renouveler, utilisez le même point avecgrant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<identity_assertion>&resource=https%3A%2F%2Fsinglefax.com%2Fmcp. Aucun jeton de renouvellement n’est émis. Les attestations restent échangeables pendant 30 jours maximum sauf révocation. Leurs signatures EdDSA utilisent le/jwksde l’émetteur ;typvautoauth-id-jag+jwt, etiss/audcorrespondent tous deux à l’émetteur. - Révoquez un jeton avec
POST https://api.singlefax.com/api/auth/oauth2/revoke, corps de formulairetoken=<access_token>&token_type_hint=access_token. L’opération est idempotente et laisse l’attestation utilisable. Révoquez l’inscription avecPOST https://api.singlefax.com/api/auth/agent/identity/revoke, JSON{ "identity_assertion": "<identity_assertion>" }: tous les jetons et échanges ultérieurs sont arrêtés.
Le titulaire peut examiner et révoquer les autorisations sur https://singlefax.com/dashboard/agent-access. Révoquer une inscription arrête tous les jetons associés et renouvellements d’attestation.
Les réponses de rattachement et d’approbation sont privées et jamais mises en cache. Gardez secrets jetons, attestations et accès. L’émission est limitée par titulaire sur toutes les répliques API, avec cinq jetons actifs inutilisés maximum. Les requêtes publiques sans autorisation ne consomment pas son quota. Un jeton absent renvoie enrollment_required ; expiré, révoqué ou consommé, invalid_enrollment. Un échec d’inscription ne consomme pas le jeton. Ne testez pas les points d’inscription lors d’analyses passives de disponibilité.
Découverte
Serveur de ressources, MCP et API BFF : https://singlefax.com
GET https://singlefax.com/.well-known/oauth-protected-resource
GET https://singlefax.com/.well-known/oauth-protected-resource/mcp
Métadonnées des ressources protégées, RFC 9728 : le document racine décrit l’origine, resource https://singlefax.com ; /.well-known/oauth-protected-resource/mcp décrit le serveur MCP, resource https://singlefax.com/mcp, cible de WWW-Authenticate. Les deux indiquent authorization_servers, émetteur https://api.singlefax.com/api/auth, et scopes_supported. Demandez les jetons pour https://singlefax.com/mcp.
GET https://singlefax.com/.well-known/oauth-authorization-server
GET https://singlefax.com/.well-known/oauth-authorization-server/api/auth
Les métadonnées du serveur d’autorisation comprennent issuer, authorization_endpoint, token_endpoint, registration_endpoint, jwks_uri, scopes_supported et agent_auth ; skill pointe ici.
L’origine API https://api.singlefax.com sert les mêmes documents well-known.
Parcours A. OAuth MCP pour les applications de chat
À utiliser avec Cursor, Claude, ChatGPT, Codex et VS Code.
- Ajoutez MCP
https://singlefax.com/mcp, Streamable HTTP. - Sur 401, lisez
WWW-Authenticateet récupérez les PRM ci-dessus. - Inscription dynamique du client :
POST {issuer}/oauth2/register, PKCE S256 ettoken_endpoint_auth_method=nonepour les clients publics. - Code d’autorisation avec PKCE sur
{issuer}/oauth2/authorize. - Jeton sur
{issuer}/oauth2/token. POST /mcpavecAuthorization: Bearer. Pour un document classique, appelezcreate_upload, remettezuploadPageUrlà l’utilisateur, puiscreate_fax_draftavectoetuploadToken.base64sert uniquement aux très petits fichiers. Le PUT versuploadUrlutilise le jeton HMAC du chemin, sans en-tête OAuth. Envoyez l’original Word, Excel, PDF ou image sans conversion préalable.
Portées : openid, profile, email, offline_access, fax:read, fax:draft, fax:send, inbox:read, credits:read, credits:checkout. Demandez explicitement credits:checkout pour les achats de crédits AP2 ; chaque débit exige toujours une approbation distincte par passkey.
Sans authentification, POST /mcp accepte uniquement server/discover. initialize, tools/list et tools/call exigent OAuth.
Parcours A2. A2A, agent à agent
Carte d’agent : GET https://singlefax.com/.well-known/agent-card.json, A2A 1.0. Point d’accès : POST https://singlefax.com/a2a, JSON-RPC SendMessage, GetTask, CancelTask ; les noms 0.3 message/send, tasks/get, tasks/cancel fonctionnent aussi.
- Utilisez le serveur OAuth, les portées et jetons du parcours A, ressource
https://singlefax.com/mcp. EnvoyezAuthorization: Bearer. Les jetons liés à DPoP ne sont pas acceptés sur/a2a. - Envoyez une partie de données :
{ "skill": "<skill id from the card>", "arguments": { ... } }. Le texte libre n’est pas interprété. - Les fonctions fax et numéro renvoient un lien Stripe Checkout,
checkoutUrl. A2A ne dépense jamais les crédits ni les pages du forfait. Un brouillon en attente de paiement porte l’étatinput-required. Interrogez avecGetTask.
Pour les achats AP2, demandez credits:checkout et négociez l’extension marchand. Mandats de panier et paiement signés, approbation séparée par passkey, utilisation du Stripe Shared Payment Token et reçus confirmés au registre sont documentés sur https://singlefax.com/ap2.md.
GetTask avec fax:read suit la livraison des brouillons fax et le paiement ou l’activation des numéros. Une tâche de numéro se termine à l’activation. L’achat de crédits n’a pas de tâche liée à une commande à interroger ; vérifiez le solde après paiement.
Parcours B. Clé API pour backends et CLI
- Créez une clé sur https://singlefax.com/dashboard/api-keys,
sf_live_…. - Achetez des crédits prépayés.
Authorization: Bearer sf_live_…surhttps://singlefax.com/api/v1/…ouhttps://api.singlefax.com/api/v1/….- CLI :
npx @singlefax/cli send FILE --to +E164avecSINGLEFAX_API_KEY. Envoyez l’original Word, Excel, PDF ou image sans conversion préalable.
Exemples par langage, curl, Node, Python, Go, PHP : https://singlefax.com/developers.md
OpenAPI : https://singlefax.com/openapi.json
Parcours C. JWT hôte et agent délégués Better Auth
Les capacités déléguées, validate_fax, send_fax, get_fax_status, get_credits, create_credit_checkout, utilisent l’approbation de l’appareil.
- Lisez
GET https://api.singlefax.com/.well-known/agent-configurationpour les algorithmes, points d’accès, modes et approbations. L’émetteur Agent Auth esthttps://api.singlefax.com, distinct de l’émetteur OAuth finissant par/api/auth. Utilisez cette origine comme audience JWT. Générez des clés de signature distinctes pour hôte et agent avec un algorithme accepté et gardez les clés privées secrètes. - Provisionnez d’abord l’hôte. L’inscription dynamique des hôtes est désactivée. Le titulaire se connecte à SingleFax et appelle
POST https://singlefax.com/api/auth/host/create, équivalent API https://api.singlefax.com/api/auth/host/create, avec sa session navigateur propriétaire. Fournissez{ "name": "My agent host", "public_key": <host public JWK>, "default_capabilities": [] }. LehostIdretourné identifie l’hôte. Les valeurs vides par défaut imposent une approbation distincte des capacités. Sinon, omettezpublic_keypour recevoir unenrollmentTokentemporaire à usage unique ; l’hôte appelle ensuitePOST https://api.singlefax.com/api/auth/host/enrollavec{ "token": <enrollment token>, "public_key": <host public JWK>, "name": "My agent host" }. Ne partagez jamais cookies ni clés privées avec l’agent. - Inscrivez sur
POST https://api.singlefax.com/api/auth/agent/register. EnvoyezAuthorization: Bearer <signed host+jwt>et le JSON{ "name": "My agent", "mode": "delegated", "capabilities": ["validate_fax", "get_fax_status", "get_credits"], "preferred_method": "device_authorization", "force_approval": true }. L’en-tête JWT utilisetyp: "host+jwt"et unalgaccepté, ainsi quekiddu JWK de signature s’il existe. Les claims comprennentiss: <registered hostId>,aud: "https://api.singlefax.com", un nouveaujti, leiatactuel,expdans les 60 secondes etagent_public_key: <agent public JWK>. Signez avec la clé de l’hôte provisionné. Les identifiants JWT réutilisés sont rejetés. - L’inscription renvoie
agent_id,host_id, statut, capacités et un objetapprovalsi nécessaire. Affichez son code appareil et ouvrezverification_uri_completesur SingleFax. L’utilisateur se connecte et approuve à l’URL retournée. Inscription, provisionnement et approbation changent le compte ; les analyses passives doivent seulement lire les documents de découverte. - Interrogez
GET https://api.singlefax.com/api/auth/agent/status?agent_id=<registered id>avec un nouveau JWT hôte,iss: <host_id>. Après approbation, signez les JWT agent avec sa clé privée : en-têtetyp: "agent+jwt",alg/kidaccepté ; claimsiss: <host_id>,sub: <agent_id>,aud: "https://api.singlefax.com",iatactuel,expdans les 60 secondes et nouveaujti. AppelezPOST https://api.singlefax.com/api/auth/capability/executeavecAuthorization: Bearer <signed agent+jwt>et{ "capability": "get_credits", "arguments": {} }, ou une autre capacité accordée avec ses arguments documentés. Ces identifiants sont des preuves signées, pas des clés API ni des jetons OAuth. - Pour un nouveau code appareil d’un agent inscrit, utilisez
POST https://api.singlefax.com/api/auth/agent/device/codeavec{ "agent_id": "<registered id>" }et un JWT hôte signé. Ce point ne peut pas inscrire un agent. Révoquez viaPOST https://api.singlefax.com/api/auth/agent/revokeavec{ "agent_id": "<registered id>" }et le JWT de l’hôte propriétaire ou sa session.send_faxexige une vérification par passkey ; ce n’est pas autonome.
N’envoyez pas d’ID-JAG ni de { "type": "anonymous" } ici par POST. Ces types d’identité ne sont pas pris en charge.
Paiements machine, sans OAuth
Le paiement autonome utilise MPP HTTP 402 sur POST /api/v1/machine/faxes, avec Stripe Shared Payment Token ou Tempo USDC. Voir https://singlefax.com/mpp.md. Cursor ne génère pas de SPT ; utilisez Stripe Link CLI sur cette URL REST, pas /mcp. Les portefeuilles Tempo paient la demande sur la même URL.
HIPAA
N’envoyez pas de PHI via MCP, MPP ou l’API publique. Les organismes concernés utilisent HIPAA Secure Mode sur le site avec un BAA électronique.