Documentation de l’API REST

API REST conv2pdf : convertissez, fusionnez, découpez, compressez, protégez et numérotez vos PDF depuis votre application — 14 outils exposés via 5 endpoints REST. Hébergement en France, RGPD respecté. Aucun service américain n’intervient dans le processus.

Démarrage rapide

  1. Créez un compte (gratuit, magic link par email)
  2. Depuis votre tableau de bord, créez une clé API (plan Dev gratuit, 300 conversions offertes pour tester, valables 12 mois, sans renouvellement)
  3. Authentifiez vos appels avec l’en-tête Authorization: Bearer cpdf_live_…

Base URL

https://api.conv2pdf.com/v1

SDK, OpenAPI & Postman

Authentification

Chaque requête doit inclure l’en-tête HTTP Authorization: Bearer <votre_clé>. Une clé révoquée ou inexistante renvoie un code 401. Un quota dépassé renvoie 429 avec les détails de réinitialisation.

Endpoints

GET /v1/tools

Renvoie la liste des outils disponibles, leurs limites et formats acceptés.

curl https://api.conv2pdf.com/v1/tools \
  -H "Authorization: Bearer cpdf_live_..."

POST /v1/convert/:tool

Effectue une conversion. Les fichiers sont envoyés en multipart/form-data.

14 outils disponibles. La liste machine à jour (formats acceptés, bornes de fichiers) est renvoyée par GET /v1/tools.

Outil (:tool)EntréeFichiersSortie
image-to-pdfPNG, JPG, WEBP, GIF, TIFF1PDF
heic-to-jpgHEIC, HEIF1JPG
heic-to-pdfHEIC, HEIF1PDF
office-to-pdfDOC(X/M), ODT, RTF, TXT, XLS(X/M), ODS, CSV, PPT(X/M), ODP, ODG, SXW/SXC/SXI/SXD, FODT/FODS/FODP/FODG1PDF
pdf-to-wordPDF1DOCX
pdf-to-imagePDF1ZIP (1 image/page)
merge-pdfPDF2 à 20PDF
split-pdfPDF1PDF
compress-pdfPDF1PDF
rotate-pdfPDF1PDF
protect-pdfPDF1PDF
unlock-pdfPDF1PDF
watermark-pdfPDF1PDF
page-numbers-pdfPDF1PDF

Paramètres optionnels (champs form-data) :

Exemple : Image → PDF (curl)

curl -X POST https://api.conv2pdf.com/v1/convert/image-to-pdf \
  -H "Authorization: Bearer cpdf_live_..." \
  -F "file=@photo.jpg"

Exemple : Fusion PDF (curl)

curl -X POST https://api.conv2pdf.com/v1/convert/merge-pdf \
  -H "Authorization: Bearer cpdf_live_..." \
  -F "file=@doc1.pdf" \
  -F "file=@doc2.pdf" \
  -F "file=@doc3.pdf"

Exemple : Compression (curl)

curl -X POST https://api.conv2pdf.com/v1/convert/compress-pdf \
  -H "Authorization: Bearer cpdf_live_..." \
  -F "file=@gros.pdf" \
  -F "quality=medium"

Exemple : PDF → Word (curl)

curl -X POST https://api.conv2pdf.com/v1/convert/pdf-to-word \
  -H "Authorization: Bearer cpdf_live_..." \
  -F "file=@rapport.pdf"

Renvoie un fichier .docx éditable. Un PDF scanné (sans couche texte) renvoie 422 pdf_scanned_needs_ocr : l'OCR existe pour les comptes Premium, sur le site uniquement, et n'est pas exposé par l'API ; au-delà de 500 pages, 422 pdf_too_many_pages.

Exemple : PDF → Image (curl)

curl -X POST https://api.conv2pdf.com/v1/convert/pdf-to-image \
  -H "Authorization: Bearer cpdf_live_..." \
  -F "file=@rapport.pdf" \
  -F "format=png"

Rend chaque page en image à 150 DPI et renvoie une archive .zip (une image par page). Champ format : png (défaut) ou jpg. Au-delà de 100 pages, 422 too_many_pages ; si le résultat dépasse la taille maximale, 422 output_too_large.

Exemple : Protection par mot de passe (curl)

curl -X POST https://api.conv2pdf.com/v1/convert/protect-pdf \
  -H "Authorization: Bearer cpdf_live_..." \
  -F "file=@confidentiel.pdf" \
  -F "password=secret123" \
  -F "prevent_print=on" \
  -F "prevent_copy=on"

Chiffrement AES-256. Le PDF généré demandera le mot de passe à l’ouverture et appliquera les restrictions cochées.

Réponse en cas de succès

L’objet quota n’est présent que pour les appels authentifiés par clé API.

{
  "job_id": "abc123…",
  "status": "success",
  "download_url": "/v1/download/abc123…",
  "size_bytes": 124533,
  "quota": {
    "plan": "starter",
    "quota": 1000,
    "used": 42,
    "soft_cap_limit": 1100,
    "status": "ok",
    "period_end": 1715789012345
  }
}

GET /v1/download/:jobId

Télécharge le fichier converti. Le fichier est servi avec son type MIME (application/pdf, le format DOCX pour PDF → Word, ou application/zip pour PDF → Image) et Cache-Control: no-store. Disponible une heure après la conversion.

curl https://api.conv2pdf.com/v1/download/abc123… \
  -H "Authorization: Bearer cpdf_live_..." \
  -o sortie.pdf

GET /v1/job/:jobId

Renvoie le statut et les métadonnées d’un job (status, taille, dates). Pratique pour vérifier qu’une conversion est prête avant de la télécharger.

curl https://api.conv2pdf.com/v1/job/abc123… \
  -H "Authorization: Bearer cpdf_live_..."

DELETE /v1/job/:jobId

Supprime immédiatement un job et son fichier, sans attendre l’expiration automatique (1 h).

curl -X DELETE https://api.conv2pdf.com/v1/job/abc123… \
  -H "Authorization: Bearer cpdf_live_..."

Exemples : Node.js

import { readFile } from 'node:fs/promises';

const file = await readFile('./photo.jpg');
const formData = new FormData();
formData.append('file', new Blob([file]), 'photo.jpg');

const res = await fetch('https://api.conv2pdf.com/v1/convert/image-to-pdf', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer cpdf_live_...' },
  body: formData
});
const data = await res.json();
console.log(data.download_url);

Exemples : Python

import requests

with open('photo.jpg', 'rb') as f:
    r = requests.post(
        'https://api.conv2pdf.com/v1/convert/image-to-pdf',
        headers={'Authorization': 'Bearer cpdf_live_...'},
        files={'file': f}
    )
print(r.json()['download_url'])

Exemples : PHP

SDK officiel (recommandé)

Installez le SDK : composer require conv2pdf/php. Voir le repo et ses exemples.

use Conv2pdf\Conv2pdf;

$c = new Conv2pdf('cpdf_live_...');
$job = $c->convert('image-to-pdf', 'photo.jpg');
$c->download($job['download_url'], 'photo.pdf');

Sans dépendance (requête brute)

$ch = curl_init('https://api.conv2pdf.com/v1/convert/image-to-pdf');
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['Authorization: Bearer cpdf_live_...'],
  CURLOPT_POSTFIELDS => ['file' => new CURLFile('photo.jpg')],
]);
$data = json_decode(curl_exec($ch), true);
echo $data['download_url'];

Codes d’erreur

Toute réponse d’erreur porte un champ error : un code stable, sur lequel brancher du code. Les champs supplémentaires listés ci-dessous disent quoi corriger. Les refus à l’entrée (upload, plan, contenu) portent aussi plan ; les erreurs survenues pendant la conversion portent job_id et status (rejected pour un verdict sur le fichier, failed pour une panne).

CodeErreurCause
400not_enough_files / too_many_filesNombre de fichiers hors bornes pour l’outil. Le corps porte min et provided, ou max.
400field_requiredChamp obligatoire absent ou vide : ranges sur split-pdf, text sur watermark-pdf. Le corps porte field, et example quand la forme attendue n’est pas évidente.
400invalid_rotation / invalid_page_range / invalid_quality / invalid_formatParamètre hors des valeurs admises. Le corps porte ce qui est accepté (allowed, valid) et, pour une plage de pages, range avec total_pages.
400password_too_short / password_too_longMot de passe hors bornes sur protect-pdf. Le corps porte min ou max.
400bad_requestCorps multipart refusé par le parseur : nom de champ interdit, champ JSON invalide, ou corps coupé en vol (code: "malformed_multipart"). Le corps porte code.
401missing_bearer_token / invalid_api_key / account_not_provisionedAuth manquante, clé invalide ou révoquée, ou clé sans compte API rattaché.
402plan_limit_filesPlus de fichiers que le plan n’en autorise par conversion : 1 sur le plan Dev, 20 sur les plans payants. Le corps porte plan et max_allowed — la limite réellement appliquée, plus haute sur un outil qui exige plusieurs fichiers (merge-pdf en accepte 2 même en Dev).
402credits_expiredCrédits d’essai du plan Dev passés leur date de validité (12 mois depuis leur octroi), quel que soit le reliquat. Le corps porte expired_at et upgrade.
403forbiddenJob appartient à une autre clé
404tool_not_found / job_not_foundOutil ou job inexistant
409job_not_readyLe job existe mais n’a pas de sortie : conversion en cours, échouée ou rejetée. Le corps porte status (pending / failed / rejected).
410file_expired / job_deletedRessource partie définitivement : TTL de 1 h dépassé, ou job supprimé via DELETE /v1/job/:jobId. Inutile de retenter.
413file_too_largeFichier au-delà de la limite du plan : 10 Mo sur le plan Dev, 200 Mo sur les plans payants. Quand un plan supérieur accepterait le fichier, la réponse porte upgrade avec ce plan, son prix mensuel HT et son plafond.
413payload_too_largeRequête entière au-delà de 220 Mo, tous fichiers et champs confondus. Le corps porte max_bytes.
413too_many_partsTrop d’éléments dans le multipart : 20 fichiers, 10 champs, 32 parts au total. Le corps porte limit (la borne franchie) et max.
415unsupported_media_typeLe Content-Type de la requête n’est pas parsable. Les conversions s’envoient en multipart/form-data ; tout le reste tombe ici — corps brut (application/pdf, application/octet-stream…), application/json, application/x-www-form-urlencoded, en-tête absent, ou multipart/form-data sans boundary. Le refus intervient avant la lecture du corps. La réponse porte le type reçu (received) et la liste des types parsables (accepted).
415unsupported_contentLe contenu du fichier ne correspond pas à l’outil. Le type est déterminé au CONTENU, jamais à l’extension du nom : un PDF valide est accepté même sans extension, et un fichier renommé en .pdf est refusé. La réponse porte file, le type détecté (detected_type) et bytes.
415unsupported_formatimage-to-pdf : image dans un format que l’outil ne sait pas lire. Le corps porte received et accepted.
422empty_fileFichier vide (0 octet). Le corps porte file.
422password_protectedFichier protégé par mot de passe d’ouverture (chiffré) sur un outil qui ne sait pas le déchiffrer ; retirer la protection avant conversion. Le corps porte file.
422needs_password / wrong_passwordPDF chiffré sur un outil qui sait le traiter : mot de passe absent, ou refusé par le fichier. Envoyer le champ password. Ni job ni quota ne sont consommés.
422pdf_not_protected / pdf_already_protectedunlock-pdf sur un PDF sans protection, ou protect-pdf sur un PDF déjà chiffré.
422pdf_scanned_needs_ocrPDF → Word : document scanné sans couche texte. L'OCR est réservé au site, pour les comptes Premium ; l'API renvoie toujours ce code.
422pdf_too_many_pages / too_many_pagesPDF → Word : plus de 500 pages. Les autres outils PDF ont leur propre plafond, rendu dans max_pages.
422unsupported_characterswatermark-pdf : le texte contient des caractères que les polices embarquées ne savent pas rendre. Le corps porte field.
422output_too_largeLa sortie dépasserait le plafond de l’outil (pdf-to-image sur un document trop lourd). Le corps porte max_bytes.
422source_unreadableFichier du bon type, mais que le moteur n’arrive pas à ouvrir : corrompu, tronqué, ou structure hors norme. Le corps porte engine.
429rate_limitedDébit dépassé : 20 conversions par minute et par clé sur POST /v1/convert/:tool, 300 requêtes par minute et par IP sur les autres endpoints. La réponse porte retry_after (secondes) et l’en-tête Retry-After ; le quota mensuel n’est pas décompté.
429quota_exceededQuota atteint. Sur les plans payants, le corps porte quota_period_end, date du prochain rechargement : inutile de retenter avant. Sur le plan Dev, quota_period_end ET period_end valent null — les conversions offertes ne se renouvellent pas, et un essai n’est pas facturé — et le corps porte upgrade, le plan qui rouvre l’accès.
500conversion_failedLe moteur a échoué. Le corps porte job_id, status: "failed" et, quand il est identifié, engine. Le quota est remboursé : une panne de notre côté ne se facture pas.
500internal_errorPanne hors conversion. Aucun détail n’est publié — les 5xx sont masqués côté serveur.
503server_busyFile de conversion saturée (retry recommandé sous 5 s, header Retry-After)
504conversion_timeoutBudget de temps du moteur dépassé. Le corps porte engine et timeout_ms, et le job est failed. Le quota est remboursé.

Quotas et réinitialisation

Chaque compte a un quota selon son plan (voir tarifs API), partagé par toutes ses clés. Sur les plans payants, le quota est mensuel et se réinitialise à chaque échéance anniversaire (et non au 1er du mois) : le timestamp de la prochaine remise à zéro est renvoyé dans quota_period_end, et le compteur used repart de zéro. Sur le plan Dev, les 300 conversions offertes à l’inscription sont valables 12 mois depuis leur octroi (credits_expire_at) et ne se renouvellent pas (quota_period_end à null, comme period_end : un essai n’est pas facturé). Un email vous prévient à 80 % du quota puis à épuisement, sur tous les plans, et 30 jours avant l’expiration des crédits d’essai. Un léger dépassement est toléré (soft_cap_limit, +10 %) avant le blocage en 429.

Confidentialité

Aucun fichier (entrée ou sortie) n’est conservé au-delà d’une heure : cette API n’a aucune exception à cette règle. Une seule chose peut prolonger la vie d’un fichier, et elle passe par le site : depuis le tableau de bord, le titulaire du compte peut créer un lien de partage pour un job — y compris produit par l’API — auquel cas la copie partagée vit jusqu’à l’échéance du lien (sept jours au plus en Gratuit, trente en Premium) ou jusqu’à sa révocation. Aucun résultat n’est mis en cache. L’intégralité du traitement a lieu sur des serveurs en France (OVH Gravelines). Voir notre politique de confidentialité pour le détail.

Support

Pour toute question technique, utilisez notre formulaire de contact (sujet « Question technique »). Plans Business et Sur-mesure : support prioritaire avec SLA contractuel.