Authentification#

EnConvert propose deux types de clé API, et c'est l'endroit où votre code s'exécute qui décide de celui que vous utilisez. Une clé privée (sk_) se place dans l'en-tête X-API-Key depuis un serveur que vous contrôlez ; une clé publique (pk_) s'échange contre un JWT de courte durée que le code du navigateur envoie dans Authorization: Bearer <token>.


Choisir un type de clé#

Clé privée Clé publique + JWT
Préfixe sk_ pk_
Envoyée comme X-API-Key: sk_your_private_key Authorization: Bearer <token>
S'exécute dans serveurs, scripts, jobs CI, conteneurs navigateurs, widgets embarqués, tout ce qui est livré à un client
Rejetée quand la requête porte un en-tête Origin (403) elle appelle autre chose que /v1/auth/token ou /v1/auth/branding (403)
Portée tous les endpoints : sync, async, batch, webhooks un élément par requête, synchrone, téléchargement présigné
Restrictions allowed_endpoints en option allowed_domains plus allowed_endpoints
Durée de vie clé valide jusqu'à révocation clé valide jusqu'à révocation, jeton d'accès 1 heure, cookie de rafraîchissement 7 jours

Choisissez selon la cible de déploiement. Un service backend, un script, une tâche cron ou un outil interne prend une clé privée. Une application navigateur ou un widget embarqué prend une clé publique avec JWT. Il n'existe aucun moyen de cacher une clé privée dans du code frontend : la passerelle la rejette sur la seule présence d'un en-tête Origin, avant même de vérifier quoi que ce soit d'autre.

Une clé, c'est son préfixe suivi d'un jeton aléatoire, soit 46 caractères au total. Les noms d'espace réservé des exemples ci-dessous (sk_your_private_key, pk_your_public_key) remplacent ce jeton ; une vraie clé ne contient aucun segment d'environnement du type live ou test. Toute valeur de moins de 45 caractères est rejetée avec 401 Invalid API Key format avant même que le préfixe soit lu.

Seul un hachage SHA-256 de chaque clé est stocké sur le serveur, accompagné d'un fragment de préfixe de sept caractères qui vous permet de distinguer vos clés dans le tableau de bord.


Clés privées#

Les clés privées sont destinées aux applications côté serveur où votre clé API peut rester secrète. Elles offrent un accès complet à tous les endpoints et fonctionnalités de l'API.

  • En-tête : X-API-Key: sk_your_private_key
  • Accès : Accès complet à tous les endpoints, y compris les opérations synchrones et asynchrones, le traitement par lots et tous les types de conversion.
  • Sécurité : Les clés sont stockées sous forme de hachages SHA-256 sur le serveur. La clé en clair n'est affichée qu'une seule fois, au moment de la création.

Aucun échange de jeton ni gestion de session n'est requis. Incluez la clé dans chaque requête :

curl -X POST https://api.enconvert.com/v1/convert/url-to-pdf \
  -H "X-API-Key: sk_your_private_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'

Format de l'en-tête#

Incluez votre clé privée dans l'en-tête X-API-Key à chaque requête :

X-API-Key: sk_your_private_key

Les clés privées commencent toujours par le préfixe sk_. Vous pouvez générer et gérer vos clés depuis le tableau de bord EnConvert.

Exemple : conversion de fichier#

Convertissez un fichier JSON en XML à l'aide d'une clé privée :

curl -X POST https://api.enconvert.com/v1/convert/json-to-xml \
  -H "X-API-Key: sk_your_private_key" \
  -F "[email protected]"

Réponse :

{
  "presigned_url": "https://econverter.nyc3.cdn.digitaloceanspaces.com/...",
  "object_key": "live/files/12345/json-to-xml/data_20250202_120530123.xml",
  "filename": "data_20250202_120530123.xml",
  "file_size": 1024,
  "conversion_time_seconds": 0.45
}
  • presigned_url : une URL temporaire et téléchargeable permettant de récupérer le fichier converti.
  • object_key : le chemin de stockage du fichier converti (par exemple, live/files/12345/json-to-xml/...). Ce n'est pas une URL.
  • filename : le nom de fichier généré pour le fichier converti.
  • file_size : la taille du fichier de sortie en octets.
  • conversion_time_seconds : le temps nécessaire pour effectuer la conversion.

Ces URL de téléchargement sont de courte durée. Leurs règles d'expiration et de rétention figurent sur URL signées.

Restrictions d'endpoints#

Par défaut, une clé privée a accès à tous les endpoints de l'API. Vous pouvez éventuellement restreindre une clé à des endpoints spécifiques à l'aide du paramètre allowed_endpoints au moment de sa création.

Lorsque allowed_endpoints est configuré, la clé ne pourra appeler que les endpoints répertoriés. Les requêtes vers tout autre endpoint seront rejetées avec une erreur 403 Forbidden : Endpoint '{path}' not allowed for this API key.

Exemple de configuration :

{
  "allowed_endpoints": [
    "/v1/convert/url-to-pdf",
    "/v1/convert/json-to-xml",
    "/v1/convert/html-to-pdf"
  ]
}

C'est utile lorsque vous souhaitez émettre une clé à portée limitée, par exemple une clé qui ne peut effectuer que des conversions PDF.

Quelques chemins restent accessibles quoi que dise la liste, parce qu'une clé capable de lancer une tâche doit pouvoir la mener à son terme :

  • /v1/auth/token, /v1/auth/verify et /v1/whoami
  • /v1/convert/status/{job_id}, /v1/convert/batch/{batch_id} et /v1/convert/download/{object_key}
  • /v1/extension/*, pour les requêtes authentifiées par JWT
  • les chemins V2 par tâche de perceive, ingest et watch

Une clé créée avec l'unique entrée ["*"] signifie tous les endpoints, y compris ceux qui seront livrés après la création de la clé.

La liste est figée au moment de la création. Aucun appel ne permet de modifier les restrictions d'une clé existante : restreindre ou élargir la portée d'une clé revient donc à en créer une nouvelle et à révoquer l'ancienne. Voir Protéger vos clés.

N'utilisez pas de clés privées dans du code côté client. L'API détecte l'en-tête Origin envoyé par les navigateurs et rejettera les requêtes effectuées avec une clé privée depuis un environnement navigateur avec 403 Private API keys cannot be used from browsers. Pour les intégrations côté client, utilisez plutôt une clé publique avec JWT.

Clés publiques et JWT#

L'authentification par clé publique et JWT permet aux applications côté client (navigateur) d'appeler l'API EnConvert : vous échangez votre clé publique (pk_) contre un jeton d'accès JWT de courte durée via POST /v1/auth/token, puis vous envoyez ce jeton dans l'en-tête Authorization: Bearer <token> sur les requêtes API. Comme une clé publique est visible par les utilisateurs finaux, elle ne peut pas appeler l'API directement. Seule, elle atteint exactement deux chemins, /v1/auth/token et /v1/auth/branding. Tout le reste renvoie 403 avec un message vous invitant à échanger d'abord la clé contre un jeton.

  1. Échangez votre clé publique (pk_) contre un jeton d'accès JWT en appelant POST /v1/auth/token.
  2. Utilisez le jeton JWT dans l'en-tête Authorization: Bearer <token> sur les requêtes API.
  3. Rafraîchissez le jeton automatiquement avant son expiration à l'aide de POST /v1/auth/refresh.
  4. La liste blanche de domaines garantit que seules les requêtes provenant de vos domaines autorisés sont acceptées.

Étape 1 : échanger la clé publique contre un JWT#

POST /v1/auth/token
En-tête Valeur Description
X-API-Key pk_your_public_key Votre clé API publique

L'endpoint attend un objet JSON dans le corps de la requête. N'envoyer aucun corps renvoie 422 avec {"type":"missing","loc":["body"],"msg":"Field required"} : envoyez donc {} quand vous n'avez rien à transmettre. Le seul champ optionnel est turnstile_token, vérifié uniquement pour les requêtes provenant de l'origine du widget EnConvert et ignoré partout ailleurs.

async function getToken() {
  const response = await fetch("https://api.enconvert.com/v1/auth/token", {
    method: "POST",
    headers: {
      "X-API-Key": "pk_your_public_key",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({}),
    credentials: "include",
  });

  if (!response.ok) {
    throw new Error(`Token exchange failed: ${response.status}`);
  }

  const data = await response.json();
  return data.token;
}
Important : Vous devez inclure credentials: "include" dans les options du fetch. Cela garantit que le cookie du jeton de rafraîchissement est stocké par le navigateur, ce qui est nécessaire pour le rafraîchissement automatique du jeton.

Réponse :

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600
}

La réponse définit également un cookie HttpOnly contenant le jeton de rafraîchissement. Ce cookie est géré automatiquement par le navigateur et utilisé lors du rafraîchissement du jeton d'accès.

Une clé privée envoyée à cet endpoint est refusée avec 400 Only public API keys can exchange for tokens. Private keys should be used directly. C'est l'API qui vous dit de supprimer l'étape d'échange, pas une clé cassée.

Étape 2 : utiliser le jeton JWT#

Incluez le jeton JWT dans l'en-tête Authorization en tant que jeton Bearer sur toutes les requêtes API suivantes.

async function convertUrlToPdf(token, url) {
  const response = await fetch("https://api.enconvert.com/v1/convert/url-to-pdf", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ url }),
  });

  return await response.json();
}

// Usage
const token = await getToken();
const result = await convertUrlToPdf(token, "https://example.com");
console.log(result.presigned_url);

Étape 3 : rafraîchissement automatique du jeton#

Les jetons d'accès expirent au bout d'une heure. Utilisez l'endpoint de rafraîchissement pour obtenir un nouveau jeton d'accès sans obliger l'utilisateur à se ré-authentifier.

POST /v1/auth/refresh

Le jeton de rafraîchissement est envoyé automatiquement via le cookie HttpOnly défini lors de l'échange de jeton initial. Aucun corps de requête ni en-tête supplémentaire n'est nécessaire.

class EnconvertClient {
  constructor(publicKey) {
    this.publicKey = publicKey;
    this.token = null;
    this.tokenExpiry = null;
  }

  async getToken() {
    const response = await fetch("https://api.enconvert.com/v1/auth/token", {
      method: "POST",
      headers: {
        "X-API-Key": this.publicKey,
        "X-Parent-Origin": window.location.origin,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({}),
      credentials: "include",
    });

    const data = await response.json();
    this.token = data.token;
    // Set expiry to 55 minutes (refresh before the 1-hour expiry)
    this.tokenExpiry = Date.now() + 55 * 60 * 1000;
    return this.token;
  }

  async refreshToken() {
    const response = await fetch("https://api.enconvert.com/v1/auth/refresh", {
      method: "POST",
      credentials: "include",
    });

    if (!response.ok) {
      // Refresh token expired, re-authenticate
      return await this.getToken();
    }

    const data = await response.json();
    this.token = data.token;
    this.tokenExpiry = Date.now() + 55 * 60 * 1000;
    return this.token;
  }

  async getValidToken() {
    if (!this.token || Date.now() >= this.tokenExpiry) {
      if (this.token) {
        return await this.refreshToken();
      }
      return await this.getToken();
    }
    return this.token;
  }

  async convert(endpoint, body) {
    const token = await this.getValidToken();
    const response = await fetch(`https://api.enconvert.com${endpoint}`, {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${token}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    });

    return await response.json();
  }
}

// Usage
const client = new EnconvertClient("pk_your_public_key");
const result = await client.convert("/v1/convert/url-to-pdf", {
  url: "https://example.com",
});

Quatre choses à savoir avant de déboguer un rafraîchissement qui échoue :

  • Le rafraîchissement retrouve votre projet à partir du cookie, puis cherche n'importe quelle clé publique active sur ce projet. Révoquez toutes les clés publiques et le rafraîchissement se met à renvoyer 401, même si le cookie est encore dans ses sept jours.
  • La route de rafraîchissement ne revérifie pas la liste blanche de domaines. Cette vérification a lieu au moment où le jeton est émis.
  • Le rafraîchissement ne relie pas le nouveau jeton à la clé que vous aviez utilisée au départ. Si le projet détient plusieurs clés publiques, le jeton rafraîchi peut revenir avec les restrictions d'une autre clé.
  • L'émission et le rafraîchissement de jetons ont leur propre limitation par IP, distincte des limites de débit de votre offre. Un client coincé dans une boucle de rafraîchissement s'en apercevra.

Durées de vie des jetons#

Jeton Durée de vie Stockage
Jeton d'accès 1 heure Renvoyé dans le corps de la réponse JSON ; à stocker en mémoire
Jeton de rafraîchissement 7 jours Défini en tant que cookie HttpOnly ; géré par le navigateur

Liste blanche de domaines#

Les clés publiques sont restreintes à des domaines spécifiques configurés dans votre tableau de bord.

La correspondance ne compare que l'hôte et le port. Le schéma est d'abord retiré des deux côtés, si bien que https://example.com et http://example.com désignent la même origine du point de vue de la liste blanche. Le port, lui, n'est pas retiré et fait partie de la comparaison.

  • Correspondance exacte : https://example.com correspond à l'hôte nu example.com quel que soit le schéma.
  • Sous-domaines génériques : https://*.example.com correspond à https://app.example.com, https://staging.example.com, et aussi au domaine apex https://example.com.
  • Spécifique à un port : http://localhost:3000 ne correspond qu'à cet hôte et ce port.
Entrée de la liste blanche Correspond à Ne correspond pas à
https://example.com https://example.com, http://example.com https://www.example.com
https://*.example.com https://app.example.com, https://dev.example.com, https://example.com https://example.net
http://localhost:3000 http://localhost:3000 http://localhost:8080

Une requête provenant d'une origine absente de la liste reçoit 403 Domain {origin} not authorized, et le propriétaire du projet en est averti par e-mail (au plus une fois par clé et par 24 heures). Si votre boîte de réception se remplit, la cause habituelle est une entrée obsolète dans la liste.

Deux origines échappent complètement à la vérification de domaine : une origine chrome-extension://..., pour que les extensions de navigateur puissent appeler l'API, et l'origine du widget EnConvert, où la vérification est remplacée par la validation de l'en-tête X-Parent-Origin du widget.

Fonctionnalités de sécurité#

  • Jetons de courte durée : Les jetons d'accès expirent au bout d'1 heure, ce qui limite la fenêtre d'exposition en cas de compromission d'un jeton.
  • Cookies de rafraîchissement HttpOnly : Les jetons de rafraîchissement sont stockés dans des cookies HttpOnly, ce qui les rend inaccessibles au JavaScript et résistants aux attaques XSS.
  • Restrictions de domaine : Les jetons ne sont délivrés que lorsque la requête provient d'un domaine autorisé.
  • Pas d'accès direct à l'API : Les clés publiques seules ne peuvent pas appeler les endpoints de conversion. Un JWT valide est toujours requis.

Restrictions de la clé publique#

L'authentification par clé publique présente les limitations suivantes par rapport aux clés privées :

  • Synchrone uniquement : Seuls les endpoints de conversion synchrones sont disponibles. Le mode asynchrone et les rappels webhook ne le sont pas ; notification_email et callback_url sont effacés sur les conversions effectuées avec une clé navigateur.
  • Un seul élément par requête : Chaque requête ne peut convertir qu'une seule URL ou qu'un seul fichier. L'envoi d'un tableau renvoie 400 Public keys only support a single URL input.
  • Téléchargement direct : Les réponses fournissent une presigned_url pour un téléchargement immédiat. Il n'existe aucune option pour des destinations de stockage personnalisées.
  • Statut de tâche oui, statut de lot non : GET /v1/convert/status/{job_id} fonctionne avec un jeton navigateur, ce qui permet au widget de récupérer un résultat après une connexion interrompue. GET /v1/convert/batch/{batch_id} est refusé avec 403 Batch status requires a private API key.

La soumission de lots elle-même dépend de la limite de lots de votre offre plutôt que du type de clé, mais comme une clé navigateur est plafonnée à un élément par requête, les lots exigent en pratique une clé privée. Voir Traitement par lots.

Bonnes pratiques :
  • Stockez toujours les jetons d'accès uniquement en mémoire. Ne les persistez jamais dans localStorage ou sessionStorage.
  • Mettez en place le rafraîchissement automatique des jetons pour éviter les interruptions pendant les sessions utilisateur.
  • Gardez votre liste de domaines autorisés aussi précise que possible. Évitez les caractères génériques trop larges.
  • Utilisez credentials: "include" sur toutes les requêtes fetch pour garantir l'envoi et la réception corrects des cookies.
  • Gérez les échecs de rafraîchissement de jeton avec élégance en revenant à une ré-authentification complète avec la clé publique.

Si vous voulez le flux navigateur sans en écrire une ligne, le widget intégrable émet et rafraîchit ses propres jetons. Voir Widgets web.


Vérifier vos identifiants#

GET /v1/auth/verify vérifie si votre authentification actuelle est valide et rapporte ce que l'API croit qu'elle est. Il fonctionne avec les clés privées envoyées dans l'en-tête X-API-Key et avec les jetons JWT Bearer envoyés dans l'en-tête Authorization. Une requête valide renvoie votre project_id, tier, key_type, ainsi que toute restriction de domaine ou d'endpoint ; une clé ou un jeton invalide ou expiré renvoie 401 Unauthorized.

GET /v1/auth/verify
En-tête Valeur Description
X-API-Key sk_your_private_key S'authentifier avec une clé privée
Authorization Bearer <token> S'authentifier avec un jeton JWT

Utilisez l'un des deux en-têtes ci-dessus, pas les deux.

Vous ne pouvez pas vérifier une clé publique directement. Envoyer X-API-Key: pk_... à cet endpoint renvoie 403, car une clé publique ne peut appeler que /v1/auth/token et /v1/auth/branding. Émettez d'abord un jeton, puis vérifiez le jeton. C'est le seul cas où un 403 ici ne signifie pas que votre clé est cassée.

Avec une clé privée :

curl https://api.enconvert.com/v1/auth/verify \
  -H "X-API-Key: sk_your_private_key"

Avec un jeton JWT :

curl https://api.enconvert.com/v1/auth/verify \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Réponse :

{
  "authenticated": true,
  "project_id": "12345",
  "tier": "pro",
  "key_type": "public",
  "allowed_domains": ["https://example.com", "https://*.example.com"],
  "allowed_endpoints": ["/v1/convert/url-to-pdf", "/v1/convert/jpeg-to-png"]
}
Champ Type Description
authenticated boolean Toujours true pour une requête valide
project_id string L'identifiant de votre projet
tier string Votre niveau d'abonnement (par exemple, free, starter, pro, business)
key_type string private, public ou dashboard
allowed_domains array or null Domaines autorisés (clés publiques uniquement, null sinon)
allowed_endpoints array or null Endpoints restreints (clés publiques uniquement, null sinon)

Deux détails font trébucher. key_type a une troisième valeur, dashboard, que le backend émet pour une session connectée du tableau de bord ou du playground ; comme une clé privée, elle renvoie null pour les deux listes. Et tier est le slug de l'offre, pas le nom affiché sur la page des tarifs : un abonnement Studio renvoie "tier": "pro". Les slugs free, starter, pro, business et enterprise correspondent à Founding, Indie, Studio, Production et Enterprise.

Si la clé ou le jeton est invalide ou expiré, l'API renvoie une erreur 401 Unauthorized à la place. La liste complète des messages d'erreur d'authentification figure dans Erreurs.

GET /v1/whoami#

Il existe un second endpoint d'identité, plus réduit. Il exige une clé privée :

curl https://api.enconvert.com/v1/whoami \
  -H "X-API-Key: sk_your_private_key"
{
  "project_id": "12345",
  "plan_slug": "pro"
}

Il ne renvoie rien d'autre, et c'est délibéré : pas de type de clé, pas de domaines, pas de limites. Un JWT ou une clé publique reçoit 403 GET /v1/whoami requires a private API key (sk_...). Plusieurs intégrations s'en servent comme test d'identifiants, dont le nœud n8n.

Cas d'usage#

  • Tester des clés API : Confirmez qu'une clé nouvellement créée est active et correctement configurée.
  • Vérifier les restrictions de domaine : Vérifiez quels domaines sont autorisés pour une clé publique.
  • Déboguer des problèmes d'authentification : Déterminez si l'échec d'une requête est dû à l'authentification ou à autre chose.

Protéger vos clés#

  • Stockage haché : Les clés privées sont stockées sur le serveur sous forme de hachages SHA-256. La clé en clair n'est affichée qu'une seule fois, au moment de sa création. Si vous la perdez, vous devez générer une nouvelle clé.
  • Variables d'environnement : Stockez votre clé dans une variable d'environnement (par exemple, ENCONVERT_API_KEY) plutôt que de la coder en dur dans votre code source.
  • Portée définie à la création : allowed_endpoints et allowed_domains sont définis à la création de la clé et ne peuvent plus être modifiés ensuite. Décidez de la portée avant de cliquer sur créer.

Faire tourner une clé#

La rotation consiste à créer puis révoquer, et dans cet ordre elle ne coûte aucune interruption :

  1. Créez la nouvelle clé dans le tableau de bord avec la portée voulue.
  2. Déployez-la, puis confirmez que la nouvelle clé est active avec GET /v1/auth/verify.
  3. Révoquez l'ancienne clé.

Les deux clés fonctionnent pendant l'étape 2, il n'existe donc aucune fenêtre où votre service n'est pas authentifié. Comme les restrictions sont immuables, changer la portée d'une clé suit exactement la même procédure que sa rotation.

Si une clé fuite#

Révoquez-la d'abord, mesurez l'ampleur des dégâts ensuite. La révocation est le seul coupe-circuit, car la portée d'une clé active ne peut pas être réduite ; une clé révoquée est rejetée avec 401 API Key revoked.

  • Une clé privée ayant fuité peut appeler tous les endpoints couverts par sa portée et consomme vos opérations mensuelles. Révoquez-la, créez une clé de remplacement, et vérifiez dans le tableau de bord si votre consommation contient des appels que vous n'avez pas faits.
  • Une clé publique ayant fuité est moins urgente, par conception. Elle ne peut pas du tout appeler les endpoints de conversion, et elle n'émet des jetons que pour les origines de sa liste blanche. Resserrer cette liste implique de créer une clé plus étroite et de révoquer celle qui a fuité, puisque la liste d'une clé existante ne peut pas être modifiée.
  • Un jeton d'accès ayant fuité meurt dans l'heure et ne peut pas être utilisé depuis une autre origine que celle pour laquelle il a été émis. Son cookie de rafraîchissement est le problème de plus longue durée : le rafraîchissement réussit tant que le projet possède au moins une clé publique active, donc révoquer la clé dont vient le jeton ne tue pas le cookie, sauf si c'était votre dernière clé publique.
Une clé poussée sur git est déjà publique. Révoquez-la dans le tableau de bord avant de réécrire l'historique. Supprimer le commit ne dépublie pas la clé.

Questions fréquentes#

Comment m'authentifier à une API REST avec un en-tête X-API-Key ?#

Envoyez votre clé privée dans l'en-tête X-API-Key à chaque requête, par exemple X-API-Key: sk_your_private_key. Les clés privées donnent un accès complet à tous les endpoints (y compris les opérations synchrones et asynchrones, le traitement par lots et tous les types de conversion) sans nécessiter d'échange de jeton.

Quelle est la différence entre les clés API sk_ et pk_ ?#

Les clés avec le préfixe sk_ sont des clés privées destinées à un usage serveur à serveur et donnent un accès complet à l'API via l'en-tête X-API-Key. Les clés avec le préfixe pk_ sont des clés publiques destinées aux applications côté client (navigateur) : elles ne peuvent pas appeler l'API directement et doivent d'abord être échangées contre un JWT de courte durée via POST /v1/auth/token.

Puis-je utiliser ma clé API privée (sk_) dans un navigateur ou une application mobile ?#

Non. L'API détecte l'en-tête Origin envoyé par les navigateurs et rejette les requêtes effectuées avec des clés privées depuis des environnements navigateur avec 403 Private API keys cannot be used from browsers. Utilisez plutôt une clé publique (pk_) avec le flux JWT pour les intégrations côté client.

Comment obtenir un jeton JWT Bearer pour l'authentification API côté client ?#

Échangez votre clé publique (pk_) contre un JWT en appelant POST /v1/auth/token avec la clé dans l'en-tête X-API-Key et {} comme corps JSON. Utilisez le jeton renvoyé dans l'en-tête Authorization: Bearer <token> des requêtes API, et actualisez-le avant son expiration via POST /v1/auth/refresh.

Puis-je restreindre une clé API privée à des endpoints spécifiques ?#

Oui. Configurez allowed_endpoints au moment où vous créez la clé, en listant des chemins comme /v1/convert/url-to-pdf. Les requêtes vers tout endpoint non listé sont rejetées avec une erreur 403 Forbidden, à l'exception des chemins d'authentification, de statut, de téléchargement et par tâche, qui restent accessibles à toutes les clés.

Que se passe-t-il si je perds ma clé API privée ?#

Les clés privées sont stockées sur le serveur sous forme de hachages SHA-256, et la clé en clair n'est affichée qu'une seule fois, au moment de sa création. Si vous la perdez, vous devez en générer une nouvelle. Vous pouvez créer plusieurs clés et révoquer les anciennes depuis le tableau de bord sans interruption de service.

Combien de temps durent les jetons d'accès et les jetons de rafraîchissement ?#

Les jetons d'accès expirent au bout d'1 heure et doivent être stockés uniquement en mémoire. Les jetons de rafraîchissement durent 7 jours et sont définis en tant que cookie HttpOnly géré par le navigateur.

Pourquoi le rafraîchissement de mon jeton échoue-t-il sans credentials: "include" ?#

Le jeton de rafraîchissement est stocké dans un cookie HttpOnly défini lors de l'échange de jeton initial, et POST /v1/auth/refresh repose sur l'envoi automatique de ce cookie par le navigateur. Si vous omettez credentials: "include" de vos requêtes fetch, le cookie n'est ni enregistré ni envoyé. En cas d'échec du rafraîchissement, revenez à une ré-authentification complète avec votre clé publique.

Puis-je utiliser des sous-domaines génériques dans la liste blanche de domaines ?#

Oui. https://*.example.com correspond à https://app.example.com, https://staging.example.com, et au domaine apex https://example.com. Les hôtes exacts et les origines spécifiques à un port comme http://localhost:3000 sont également pris en charge. La correspondance ignore le schéma, mais pas le port.

Puis-je utiliser une clé publique pour des conversions asynchrones ou par lots ?#

Non. L'authentification par clé publique ne prend en charge que les endpoints de conversion synchrones, avec une seule URL ou un seul fichier par requête ; le mode asynchrone, les webhooks et l'interrogation du statut des lots nécessitent une clé privée. Les réponses fournissent une presigned_url pour un téléchargement immédiat.

Comment tester si ma clé API est valide ?#

Envoyez une requête à GET /v1/auth/verify avec une clé privée dans l'en-tête X-API-Key, ou un JWT dans l'en-tête Authorization. Un identifiant valide renvoie authenticated: true ainsi que votre project_id et votre tier ; un identifiant invalide ou expiré renvoie 401 Unauthorized. Une clé publique ne peut pas être vérifiée de cette façon et renvoie 403.

Pourquoi allowed_domains et allowed_endpoints sont-ils null dans la réponse de vérification ?#

Les deux champs ne sont renseignés que pour les clés publiques et renvoient null pour les clés privées et pour les sessions de tableau de bord. Pour les clés publiques, allowed_domains liste les domaines autorisés et allowed_endpoints liste les éventuelles restrictions d'endpoints.

Quelle méthode d'authentification dois-je choisir pour mon intégration ?#

Utilisez une clé privée (sk_) pour les services backend, scripts ou outils internes : c'est plus simple et cela donne un accès complet. Utilisez une clé publique (pk_) avec JWT pour les applications ou widgets basés sur le navigateur, car cela protège les identifiants et limite l'accès aux domaines autorisés.