Aller au contenu

OAuth pour les applications

Votre application se connecte au compte Cord d’une entreprise en un clic, sans que personne ne copie de clé.

Quand l’utiliser

Si vous construisez une application que de nombreuses entreprises connecteront à leur compte Cord — un connecteur, un module complémentaire, une plateforme d’automatisation —, utilisez OAuth 2.0 au lieu de leur demander une clé API. La personne donne son autorisation sur un écran de Cord, choisit l’espace de travail et peut révoquer l’accès à tout moment. C’est le même mécanisme qu’utilisent les applications de Cord sur Zapier et Make, ainsi que le module complémentaire Cord pour Gmail.

Pour une intégration propre à votre entreprise, une clé API est plus simple.

Enregistrer votre application

L’enregistrement des clients OAuth n’est pas encore en libre-service. Écrivez-nous à contacto@cordhq.app en indiquant le nom de votre application, son domaine et les adresses de retour (redirect_uri) exactes. Nous vous fournissons un client_id et un client_secret. Conservez le secret sur votre serveur : Cord n’en garde que l’empreinte et ne peut plus vous l’afficher.

Les adresses de retour doivent être en https (ou http://localhost pour le développement) et sont comparées à l’identique, sans caractères génériques.

1. Demandez l’autorisation

Envoyez la personne vers :

https://cordhq.app/oauth/authorize
  ?response_type=code
  &client_id=cord_oc_...
  &redirect_uri=https://yourapp.com/cord/callback
  &scope=write
  &state=RANDOM_VALUE
  &code_challenge=...            (facultatif, PKCE)
  &code_challenge_method=S256    (facultatif, PKCE)
Paramètre Détail
scope read pour la lecture seule ; write pour la lecture et l’écriture (inclut read). Sans scope, Cord demande read. Vous pouvez séparer les valeurs par une espace, une virgule ou + ; toute autre valeur renvoie invalid_scope.
state Une valeur aléatoire que votre application vérifie au retour. Elle empêche un tiers de vous injecter une autorisation.
code_challenge PKCE : BASE64URL(SHA256(code_verifier)), 43 caractères sans remplissage. Toujours recommandé ; seul code_challenge_method=S256 est accepté.

Si la personne n’est pas connectée, Cord lui demande de se connecter puis revient au même écran. Seule une personne disposant du droit Paramètres dans un espace de travail peut y autoriser des applications. L’écran indique ce que votre application pourra faire et ce qu’elle ne pourra pas faire.

Après l’autorisation, Cord revient vers votre redirect_uri avec ?code=...&state=.... Si la personne annule, le retour se fait avec ?error=access_denied&state=....

2. Échangez le code

Le code est valable 5 minutes et ne sert qu’une seule fois. Échangez-le depuis votre serveur :

curl -X POST "https://cordhq.app/api/oauth/token" \
     -d grant_type=authorization_code \
     -d code=cord_ac_... \
     -d redirect_uri=https://yourapp.com/cord/callback \
     -d client_id=cord_oc_... \
     -d client_secret=cord_cs_... \
     -d code_verifier=...

Vous pouvez aussi envoyer les identifiants du client avec l’authentification HTTP Basic.

{ "access_token": "cord_at_...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "cord_rt_...", "scope": "write" }

3. Appelez l’API

L’access_token fonctionne comme une clé dans toute l’API v1 et dans le serveur MCP :

curl "https://cordhq.app/api/v1/me" -H "Authorization: Bearer cord_at_..."

4. Renouvelez l’accès

L’access token est valable 1 heure. Renouvelez-le avec le refresh token, valable 180 jours :

curl -X POST "https://cordhq.app/api/oauth/token" \
     -d grant_type=refresh_token \
     -d refresh_token=cord_rt_... \
     -d client_id=cord_oc_... \
     -d client_secret=cord_cs_...

Chaque renouvellement fournit un nouveau refresh token et le précédent cesse de fonctionner. Enregistrez toujours le nouveau. Si un refresh token déjà utilisé est présenté à nouveau plus de 30 secondes après, Cord le traite comme un vol potentiel et révoque toute la connexion ; la personne devra donner à nouveau son autorisation.

5. Révoquez

curl -X POST "https://cordhq.app/api/oauth/revoke" \
     -d token=cord_rt_... -d client_id=cord_oc_... -d client_secret=cord_cs_...

La réponse est 200 même si le jeton n’existe pas, afin de ne pas révéler quels jetons sont valides. La personne peut aussi révoquer votre application dans l’onglet Clés API du Cord Workbench, où elle apparaît comme Connexion autorisée.

PKCE

PKCE empêche qu’un code intercepté puisse être échangé. Générez un code_verifier aléatoire de 43 à 128 caractères (A-Z, a-z, 0-9, -, ., _, ~), conservez-le dans la session de votre serveur et envoyez son empreinte lors de l’autorisation :

import { createHash, randomBytes } from 'node:crypto';

const codeVerifier = randomBytes(48).toString('base64url'); // 64 caractères
const codeChallenge = createHash('sha256').update(codeVerifier).digest('base64url'); // 43 caractères
// Dans /oauth/authorize : code_challenge=<codeChallenge>&code_challenge_method=S256
// Dans /api/oauth/token : code_verifier=<codeVerifier>

Si vous avez envoyé code_challenge lors de l’autorisation, l’échange exige le code_verifier correspondant. Sinon, l’échange ne doit pas contenir de code_verifier : un code_verifier inattendu renvoie lui aussi invalid_grant.

Erreurs d’autorisation

Il existe deux catégories d’erreur sur /oauth/authorize, et elles se comportent différemment à dessein.

Cord ne revient pas vers votre application lorsqu’il ne peut pas faire confiance à l’adresse de retour. La personne voit une page d’erreur de Cord et aucune redirection n’a lieu :

Situation Ce qui se passe
Un client_id qui n’existe pas Page d’erreur de Cord (unknown_client).
Une redirect_uri qui ne correspond pas exactement à une adresse enregistrée Page d’erreur de Cord. Vérifiez la casse, la barre oblique finale et le port.

Cord revient vers votre redirect_uri avec error et votre state lorsque le client et l’adresse sont valides mais que la requête ne l’est pas :

error Quand
unsupported_response_type response_type n’est pas code.
invalid_scope scope contient une valeur autre que read ou write.
invalid_request code_challenge mal formé, ou code_challenge_method autre que S256.
access_denied La personne a annulé, ou a choisi un espace de travail dans lequel elle ne peut pas autoriser d’applications.
https://yourapp.com/cord/callback?error=invalid_scope&state=RANDOM_VALUE

Ces redirections ne contiennent pas d’error_description. Vérifiez toujours que state correspond à celui que vous avez envoyé avant d’afficher l’erreur.

Erreurs d’échange et de renouvellement

POST /api/oauth/token accepte le corps au format application/x-www-form-urlencoded ou JSON, et répond toujours en JSON avec error et error_description :

{ "error": "invalid_grant", "error_description": "El código o el token no es válido, ya se usó o venció." }
Code error error_description Quand
401 invalid_client Las credenciales de la aplicación no son válidas. client_id ou client_secret incorrect, via Basic ou dans le corps.
400 invalid_request El cuerpo de la petición no se pudo leer. Le corps n’est ni un formulaire ni un JSON valide.
400 invalid_request Faltan code o redirect_uri. Échange sans code ou sans redirect_uri.
400 invalid_request Falta refresh_token. Renouvellement sans refresh_token.
400 invalid_request Este espacio ya tiene demasiadas conexiones de esta aplicación… L’espace de travail compte déjà 25 connexions actives de votre application. La personne doit révoquer celles qu’elle n’utilise pas.
400 unsupported_grant_type Solo se admite authorization_code y refresh_token. Tout autre grant_type.
400 invalid_grant El código o el token no es válido, ya se usó o venció. Code expiré ou déjà utilisé, redirect_uri différente de celle de l’autorisation, code_verifier qui ne correspond pas, ou refresh token expiré, déjà utilisé ou appartenant à un autre client.
429 — — Plus de 300 requêtes par minute depuis la même IP. Respectez Retry-After.

error_description est rédigé en espagnol et peut changer : basez vos décisions sur error.

POST /api/oauth/revoke renvoie 401 avec error: "invalid_client" si les identifiants du client ne sont pas valides, et 200 dans tous les autres cas.

Quota

Les appels effectués avec un jeton OAuth sont décomptés du quota d’API de l’offre de l’entreprise, comme pour une clé. La seule exception est le module complémentaire Cord pour Gmail, qui est une surface de Cord elle-même : ses appels ne consomment pas le quota mensuel, mais ils comptent dans les limites par minute.