ThunderPhone 2.0 est disponible.En libre-service, à partir de 2 ¢/min.Découvrir l’annonce

Connect tools & data

Se connecter avec OAuth

Autorisez les clients MCP et l’interface de ligne de commande ThunderPhone sans partager de clé API.

OAuth permet à une application de se connecter à une organisation ThunderPhone avec les autorisations que vous approuvez. Les clients d'annuaire doivent utiliser OAuth par défaut. Les clés API d'organisation restent disponibles pour les clients qui nécessitent un jeton Bearer configuré manuellement.

Approuver une connexion

Démarrez la connexion dans votre client MCP. Connectez-vous à ThunderPhone, vérifiez le nom de l'application et les autorisations demandées, choisissez une organisation, puis sélectionnez Approuver. Sélectionnez Refuser si vous n'avez pas démarré la connexion ou si vous ne faites pas confiance à l'application. Les noms d'application sont fournis par leurs développeurs et ne constituent pas un badge de vérification.

Les autorisations de lecture donnent accès aux données indiquées, y compris aux enregistrements et aux transcriptions lorsque calls:read est demandé. Les autorisations d'écriture peuvent modifier ou supprimer des ressources ; les appels, les campagnes, les achats de numéros de téléphone et les déploiements peuvent entraîner des coûts ou affecter la production. Votre rôle dans l'organisation s'applique toujours.

Pour une connexion CLI, ouvrez le lien de vérification affiché dans votre terminal, comparez le code à huit caractères, sélectionnez votre organisation, puis approuvez. Le simple fait d'ouvrir le lien n'accorde pas l'accès. Les codes expirent après 15 minutes.

Déconnecter une application

Ouvrez Organisation → Clés API → Applications autorisées dans le tableau de bord, puis choisissez Révoquer. Cette action révoque l'autorisation sélectionnée pour l'organisation actuelle, y compris ses jetons d'accès et d'actualisation. Reconnectez-vous depuis l'application si vous souhaitez l'autoriser à nouveau.

Découverte pour les clients MCP

Utilisez l’URL du serveur https://api.thunderphone.com/v1/mcp. Une requête sans authentification valide reçoit 401 avec :

WWW-Authenticate: Bearer resource_metadata="https://api.thunderphone.com/.well-known/oauth-protected-resource"

Récupérez ce document, puis récupérez les métadonnées du serveur d’autorisation à https://api.thunderphone.com/.well-known/oauth-authorization-server. Les métadonnées de ressource sont également disponibles à /.well-known/oauth-protected-resource/v1/mcp. Utilisez les points de terminaison renvoyés au lieu de les construire. L’identifiant de ressource est https://api.thunderphone.com/v1/mcp.

Le serveur prend en charge le code d’autorisation avec S256 PKCE, les jetons d’actualisation rotatifs, l’enregistrement dynamique de clients publics, la révocation et le flux d’autorisation d’appareil. Il n’existe ni secrets client ni flux implicites. La découverte OpenID est également disponible à /.well-known/openid-configuration ; elle inclut les mêmes champs de serveur d’autorisation, ainsi que subject_types_supported: ["public"] et le point de terminaison userinfo. Les jetons ID et les documents de métadonnées d’ID client (CIMD) ne sont pas pris en charge.

Enregistrer un client public

Envoyez du JSON à POST /v1/oauth/register :

{
  "client_name": "My MCP client",
  "redirect_uris": ["http://127.0.0.1:8765/callback"],
  "token_endpoint_auth_method": "none",
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"]
}

Enregistrez le client_id renvoyé. Les redirections doivent utiliser HTTPS, ou HTTP sur 127.0.0.1 ou localhost. Enregistrez l’URI de rappel exacte, y compris son port et son chemin. Les fragments et les identifiants intégrés sont rejetés. Les éléments facultatifs client_uri et logo_uri doivent utiliser HTTPS ; ThunderPhone ne les récupère pas lors de l’enregistrement. L’enregistrement est limité en débit. Les clients enregistrés n’expirent pas et restent enregistrés lorsqu’une connexion est révoquée. Les rappels HTTPS incluent https://chatgpt.com/connector/oauth/<id> et https://chatgpt.com/connector_platform_oauth_redirect. Chaque connexion peut enregistrer son propre client.

Code d’autorisation

Ouvrez le point de terminaison d’autorisation découvert avec client_id, le redirect_uri exactement enregistré, response_type=code, un state aléatoire, scope, code_challenge, code_challenge_method=S256 et resource=https://api.thunderphone.com/v1/mcp. Calculez le challenge comme le condensat SHA-256 base64url non rembourré d’un vérificateur PKCE inédit à forte entropie. Vérifiez les valeurs state et iss renvoyées avant d’échanger le code. Chaque réponse d’autorisation, y compris les refus et les erreurs de protocole, identifie l’émetteur avec iss, correspondant exactement à l’issuer découvert. Les erreurs liées à un client ou un rappel non valide sont renvoyées localement sans redirection vers ce rappel.

Effectuez l’échange sur POST /v1/oauth/token avec un encodage de formulaire (JSON est également accepté) :

grant_type=authorization_code
client_id=<your client id>
code=<single-use authorization code>
redirect_uri=<exact registered redirect URI>
code_verifier=<original PKCE verifier>
resource=https://api.thunderphone.com/v1/mcp

Le paramètre facultatif resource est accepté dans les requêtes d’autorisation et de jeton, y compris les échanges d’actualisation et d’appareil. Lorsqu’il est omis, il utilise par défaut la ressource MCP découverte. Lorsqu’il est présent, il doit correspondre exactement à cette ressource ; les autres valeurs renvoient invalid_target. Les jetons d’accès portent cette audience, et MCP rejette les jetons dont l’audience est absente ou différente avec 401 et un challenge de découverte.

Les requêtes d’autorisation et les codes expirent après 10 minutes. Chaque réponse de jeton contient access_token, token_type (Bearer), expires_in (3600 secondes par défaut), refresh_token, scope, organization_id et organization_name. Envoyez les jetons d’accès uniquement via l’en-tête Authorization: Bearer. Ne placez jamais de jetons dans des URL, des journaux, le contrôle de source ou des discussions.

Actualiser et révoquer

Actualisez avec grant_type=refresh_token, client_id, refresh_token et resource au point de terminaison de jeton. Enregistrez le nouveau jeton d’actualisation de manière atomique et cessez d’utiliser l’ancien. Les jetons d’actualisation expirent après 30 jours sans actualisation réussie. Un scope facultatif peut restreindre les autorisations accordées. offline_access est toujours inclus et des jetons d’actualisation sont toujours émis. Une requête initiale sans scope accorde uniquement offline_access ; les clients doivent donc demander les autorisations dont ils ont besoin.

La réutilisation d’un code et la réutilisation d’un jeton d’actualisation rotatif révoquent l’intégralité de l’autorisation. Sérialisez les actualisations au sein d’un client ; rejouer un identifiant échangé avec succès n’est pas une stratégie de nouvelle tentative sûre.

Pour déconnecter, envoyez token et client_id à POST /v1/oauth/revoke. Révoquer l’un ou l’autre jeton révoque son autorisation, y compris tous les jetons émis à partir de celui-ci. Un jeton inconnu renvoie une réussite sans indiquer s’il existe. Les sessions du tableau de bord peuvent lister leurs propres autorisations avec GET /v1/oauth/grants et en révoquer une avec DELETE /v1/oauth/grants/<id>, X-ThunderPhone-Org sélectionnant l’organisation.

Autorisation d’appareil

L’autorisation d’appareil est limitée aux clients préenregistrés ; les clients enregistrés dynamiquement reçoivent unauthorized_client. Le client public préenregistré thunderphone-cli prend en charge l’autorisation d’appareil et l’actualisation. Envoyez client_id=thunderphone-cli et scope à POST /v1/oauth/device/code. Affichez user_code et verification_uri à l’utilisateur, ou ouvrez verification_uri_complete.

Interrogez le point de terminaison de jeton avec grant_type=urn:ietf:params:oauth:grant-type:device_code, client_id et device_code, en attendant au moins l’interval renvoyé (5 secondes). Continuez avec authorization_pending. En cas de slow_down, utilisez le nouvel interval renvoyé dans la réponse, augmenté de 5 secondes, pour chaque requête suivante. Arrêtez-vous sur access_denied, expired_token ou toute autre erreur. N’approuvez jamais automatiquement un code d’appareil.

Le client préenregistré thunderphone-mcp accepte http://127.0.0.1/callback et http://localhost/callback sur n’importe quel port. Le schéma, l’hôte, le chemin et la requête doivent correspondre ; l’échange de jeton doit utiliser l’URI de redirection exacte, y compris le port, issue de l’autorisation. Les clients enregistrés dynamiquement exigent une correspondance exacte de l’URI de redirection, y compris le port. Enregistrez dynamiquement un rappel différent si vous avez besoin d’un autre chemin.

Vérifications de l’identité du compte et du domaine de l’espace de travail

Demandez openid email en plus des scopes opérationnels dont votre client a besoin. Appelez le userinfo_endpoint découvert (GET /v1/oauth/userinfo) avec le jeton d’accès dans l’en-tête Bearer. Une réponse réussie contient :

{
  "sub": "123",
  "email": "person@example.com",
  "email_verified": true,
  "name": "Example User",
  "org_id": 456
}

sub est l’identifiant utilisateur stable ; org_id est l’organisation sélectionnée lors du consentement. Le point de terminaison exige les deux scopes d’identité et renvoie 403 si l’un d’eux est absent. Il renvoie 403 avec error=access_denied si le compte ne possède pas de profil d’adresse e-mail vérifiée, plutôt que d’affirmer qu’une adresse e-mail non vérifiée est fiable. Les jetons non valides, expirés, révoqués ou destinés à une mauvaise audience renvoient 401. Les jetons de session humaine et les clés API d’organisation ne peuvent pas appeler userinfo. Aucun jeton ID n’est émis.

Autorisations disponibles

FamillePortées
Agents et importations d’agentsagents:read, agents:write
Appelscalls:read, calls:write
Numéros de téléphone, appelants bloqués et VoIPnumbers:read, numbers:write
Connaissancesknowledge:read, knowledge:write
Campagnescampaigns:read, campaigns:write
Intégrations, points de terminaison webhook, serveurs MCPintegrations:read, integrations:write
Voixvoices:read
Scénarios de test, exécutions de test, validationtesting:read, testing:write
Facturationbilling:read
Identité du compte et e-mail vérifiéopenid, email (tous deux requis pour userinfo)
Connexion persistanteoffline_access (toujours inclus)

GET, HEAD et OPTIONS utilisent des scopes de lecture ; les autres méthodes utilisent des scopes d’écriture. Les modifications de voix et de facturation ne sont pas disponibles via OAuth ; POST /v1/voices/preview utilise voices:read car il prévisualise une voix sans modifier sa configuration. Les outils MCP appliquent le scope de leur opération REST sous-jacente. Les transferts entre organisations sont refusés, même lorsque l’utilisateur qui autorise appartient aux deux organisations. Les autres familles d’API, notamment la gestion des clés API et les paramètres des comptes humains, ne sont pas disponibles via OAuth. Une autorisation manquante sur une opération REST renvoie 403 avec WWW-Authenticate: Bearer error="insufficient_scope", scope="...". Les jetons d’accès non valides ou expirés renvoient 401.

Signaux d’authentification des outils MCP

Chaque outil dans tools/list inclut securitySchemes: [{"type": "oauth2", "scopes": ["agents:read"]}], avec le scope de l’opération REST de cet outil. Les outils de documentation publique utilisent une liste de scopes vide et nécessitent toujours une connexion authentifiée.

Un jeton valide auquel il manque le scope d’un outil reçoit HTTP 200 avec un result JSON-RPC contenant isError: true, un texte explicatif dans content et _meta["mcp/www_authenticate"]. Ce dernier est un tableau contenant un défi Bearer avec resource_metadata, error="insufficient_scope", error_description et le scope requis. L’outil n’est pas exécuté. Utilisez ce défi pour demander un consentement étendu. Une authentification absente ou non valide continue de renvoyer HTTP 401 avec WWW-Authenticate ; les échecs de scope REST continuent de renvoyer HTTP 403.

Conservation des identifiants

L’API exécute python manage.py oauth_cleanup toutes les heures dans les environnements de préproduction et de production. Cette commande supprime les demandes d’autorisation et les codes d’appareil expirés. Les jetons d’accès expirés, les codes d’autorisation et les hachages de jetons de rafraîchissement ne sont purgés qu’après la révocation de leur autorisation ou lorsque toute leur famille est inactive. Les hachages utilisés sont conservés tant que la famille dispose d’un jeton de rafraîchissement, d’un code d’autorisation, d’un code d’appareil approuvé ou d’un jeton d’accès utilisable, afin que le nettoyage ne puisse pas désactiver la détection des réutilisations.