API
Créez un lien pour chaque abonné au moment où il ouvre un numéro, publiez vos numéros depuis votre chaîne de production, lisez vos statistiques.
Authentification et permissions
Adresse : https://liseuse-pdf.com/api/gestion/v1. Chaque appel porte Authorization: Bearer lsp_…. Créez et révoquez vos clés dans Intégrations ; une clé voit les numéros de votre compte et rien d’autre. Elle reste sur votre serveur : jamais dans une page web ou une application mobile. Donnez un nom à votre outil dans User-Agent : les agents par défaut de certaines bibliothèques sont bloqués par le pare-feu.
| Permission | Donne accès à |
|---|---|
lecture | GET /publications, GET /numeros, GET /statistiques, GET /compte |
liens | POST /liens, POST /liens/revoquer |
publication | POST /televersements, POST /numeros, PATCH /numeros |
Spécification OpenAPI 3.1 : /docs/openapi.json, à importer dans Postman, Insomnia ou votre générateur de client.
POST /liens
Corps : id (obligatoire), jours (1 à 365, par défaut votre réglage), page, reference (votre identifiant d’abonné, 80 caractères parmi lettres, chiffres et _ . : @ + -). La référence n’apparaît pas en clair dans le lien : seule une empreinte y figure. Utilisez un identifiant interne plutôt qu’une adresse e-mail. Réponse 201.
curl -X POST https://liseuse-pdf.com/api/gestion/v1/liens \ -H "Authorization: Bearer lsp_…" -H "Content-Type: application/json" \ -H "User-Agent: mon-site/1.0" -H "Idempotency-Key: abonne-42-escales-12" \ -d '{"id": "liseuse-pdf.com:inklura-escales-n12", "jours": 1, "reference": "CLI-042"}'
{
"url": "https://liseuse-pdf.com/lire/…",
"expire_le": "2026-10-02T21:49:48.000Z",
"iframe": "<iframe src=\"…\" width=\"100%\" height=\"720\" …></iframe>"
}POST /liens/revoquer
Corps : {"reference": "CLI-042"}. Tous les liens créés avec cette référence, pour tous vos numéros, cessent de fonctionner (le lecteur voit « Ce lien de lecture a été désactivé » et la page publique). Les liens créés ensuite avec la même référence fonctionnent : appelez-le à la fin d’un abonnement, pas à son renouvellement. Disponible aussi sur la fiche de chaque numéro.
GET /publications
Paramètres : publication (code du titre), limite (1 à 200, 50 par défaut). GET /numeros?id=… renvoie un seul numéro sous la même forme.
{
"publications": [{
"id": "liseuse-pdf.com:inklura-escales-n12",
"titre": "Escales n°12 · octobre 2026",
"publication": { "code": "escales", "nom": "Escales" },
"date": "2026-10-01", "pages": 12, "acces": "abonnes",
"page_publique": "https://liseuse-pdf.com/apercu/inklura-escales-n12",
"lecture_libre": null,
"couverture": "https://liseuse-pdf.com/fichiers/escales-n12/couverture.jpg"
}]
}Publier un numéro
En deux temps : demandez où envoyer le fichier, envoyez-le, puis créez le numéro. Les fichiers sont identifiés par leur empreinte SHA-256 : un fichier déjà stocké n’est pas renvoyé (deja_present: true). Les SDK font tout en un appel (publier).
1. POST /televersements
Corps : type (pdf ou couverture, un JPEG), sha256, taille (octets), domaine (liseuse-pdf.com par défaut). Réponse : url (valable 1 heure), methode (PUT), en_tetes. Envoyez le fichier tel quel avec ces en-têtes.
2. POST /numeros
| Champ | Rôle |
|---|---|
sha256, taille | Le PDF envoyé (obligatoires) |
titre | Titre du numéro (obligatoire) |
publication ou nouvelle_publication | Code d’une publication existante, ou nom d’une nouvelle |
parution | Mois de parution, AAAA-MM |
acces | abonnes (par défaut) ou libre |
lien_achat | Lien du bouton de la page publique |
telechargement, impression | Booléens. Absents ou null : la règle du titre, sinon téléchargement non et impression oui |
adresse | Fin de l’adresse sur liseuse-pdf.com, ex. escales-n13 |
couverture_sha256, couverture_taille | Une couverture JPEG envoyée ; sans elle, la page 1 est rendue sous deux minutes ("couverture": "en_preparation") |
remplace | Identifiant d’un numéro dont on remplace le PDF : mêmes adresses, liens et intégrations |
publier_le | Parution programmée, date ISO 8601 à venir, ex. 2026-11-04T08:00:00+01:00 (un an au plus) |
Réponse 201 (200 pour un remplacement) : {"numero": {…}, "couverture": "prete" | "en_preparation"}. Les limites de votre formule s’appliquent (402 plan_limit).
PATCH /numeros?id=…
Champs, tous facultatifs : titre, acces, lien_achat (null pour le retirer), en_ligne (true publie aussi un numéro programmé), telechargement, impression (null : comme le titre), publication, publier_le (nouvelle date d’un numéro programmé). GET /numeros indique statut (en_ligne, programme, retire) et publier_le. Les numéros de l’ancienne liseuse se modifient depuis l’espace éditeur (409 not_editable).
GET /statistiques
Paramètres : id (obligatoire), depuis (AAAA-MM-JJ, 30 jours par défaut).
{
"id": "liseuse-pdf.com:inklura-escales-n12", "depuis": "2026-09-02",
"lectures": 412, "lectures_depuis_publication": 1290,
"par_jour": [{ "jour": "2026-09-30", "lectures": 18 }],
"temps_moyen_secondes": 402, "lu_jusqu_a_la_fin": 0.58,
"sources": [{ "source": "direct", "lectures": 260 }, { "source": "votre-site.fr", "lectures": 152 }]
}GET /compte
Formule, statut, échéance, limites et utilisation : {"compte": {"formule": "pro", "statut": "active", "limites": {…}, "utilisation": {…}}}.
Idempotence
Sur POST /liens et POST /numeros, l’en-tête Idempotency-Key (120 caractères au plus) garantit qu’une requête répétée dans les 24 heures, par exemple après une coupure réseau, renvoie la première réponse sans rien créer de plus. La réponse rejouée porte Idempotent-Replayed: true.
Erreurs, limites et en-têtes
| Code | Signification |
|---|---|
400 | Corps illisible ou champ invalide (bad_json, bad_reference…) |
401 | Clé absente, invalide ou révoquée |
402 | Abonnement terminé, ou limite de la formule atteinte |
403 | Permission manquante (forbidden_scope) |
404 | Numéro introuvable pour cette clé |
409 | Adresse déjà prise, ou numéro non modifiable par l’API |
413 | Fichier trop lourd pour votre formule |
429 | Plus de 300 appels par minute (voir Retry-After) |
Chaque réponse porte X-Request-Id (à nous donner en cas de question), X-RateLimit-Limit et X-RateLimit-Remaining. Les erreurs ont la forme {"error": {"code": "…", "message": "…"}}.