API & données ouvertes

Syngas est une base communautaire : les fiches série qu'elle contient sont librement réutilisables. Trois façons d'y accéder selon ce que vous voulez faire — les deux premières ne demandent ni compte ni clé.

Tout récupérer d'un coup — export JSON

Ouvert à tous

Un export complet de toutes les fiches série publiques est disponible à une URL fixe, sans authentification ni compte, régénéré automatiquement à chaque changement dans la base :

https://concepts.esenjin.xyz/syngas/export/series.json

C'est le point d'entrée le plus simple pour toute exploration, tout script personnel ou toute application tierce qui veut parcourir ou filtrer les séries de Syngas — aucune limite de débit, aucun enregistrement préalable. Le fichier contient :

  • generated_at — date de génération de l'export (ISO 8601).
  • count — nombre total de séries qu'il contient.
  • series — tableau des fiches, avec les mêmes champs que GET /series/{id} ci-dessous (voir détail des champs).

Seules les fiches validées et publiques y figurent — aucune donnée de compte, d'instance ou de modération n'y apparaît jamais.

Interroger la base à la demande — sans clé API

Ouvert à tous

Pour chercher une série précise, filtrer par auteur/genre/statut ou consulter une fiche à la volée plutôt que de télécharger tout l'export, GET /series/search, GET /series/browse et GET /series/{id} (détaillés plus bas) sont utilisables directement, sans clé ni compte. Par exemple, depuis un terminal :

curl "https://concepts.esenjin.xyz/syngas/api/v1/series/search?q=Naruto"

Limité en débit par adresse IP (30 requêtes/minute par défaut — voir Erreurs communes) plutôt que par clé, puisqu'il n'y a justement pas de clé pour identifier l'appelant. Pour un usage intensif ou répété, l'export complet ci-dessus reste plus adapté et n'a aucune limite.

S'intégrer activement — API pour les instances Lengas

Clé API requise

Les endpoints qui font évoluer la base (proposer une nouvelle série, proposer une modification, suivre le devenir d'une soumission) restent réservés à une instance Lengas enregistrée : chaque appel doit alors présenter une clé API valide. La recherche et la consultation de fiche (juste au-dessus) acceptent aussi une clé si vous en avez déjà une — elle compte alors sur votre propre quota d'instance plutôt que sur celui, plus restreint, de votre IP.

Base de l'API : https://concepts.esenjin.xyz/syngas/api/v1/. Authentification par en-tête X-Syngas-Key: <clé> sur tous les appels sauf /instances/register, /sante, /series/search, /series/browse et /series/{id}.

Obtenir une clé

POST /instances/register

Sans authentification — c'est justement cet appel qui délivre la clé.

{
  "site_name": "...",
  "admin_pseudo": "...",
  "instance_url": "https://..."
}

Réponse 201 avec { "api_key": "..." }. La clé n'est jamais réaffichée ensuite : conservez-la précieusement, une instance qui la perd doit se réenregistrer. Si le domaine (extrait de instance_url) porte un bannissement actif, la réponse est 403 avec { "error": "banned", "reason": "..." }.

Endpoints de lecture — ouverts, sans clé

GET /sante

Sans authentification. Sonde de disponibilité.

200 { "statut": "ok", "version": "1.0.0" }
GET /series/search?q=...&type=manga|light-novel

Recherche par nom, 5 résultats maximum — pensée pour un pré-remplissage instantané pendant la saisie. Le paramètre type est facultatif. Une clé API (X-Syngas-Key) reste acceptée si vous en avez une — voir Erreurs communes pour la limite de débit selon le cas. Pour explorer la base plus largement (par contributeur, genre, statut…) ou récupérer plus de 5 résultats, voir GET /series/browse ci-dessous.

200 {
  "results": [
    { "id": "...", "type": "manga", "name": "...",
      "author": "Akira Toriyama (Auteur), Shueisha (Éditeur)",
      "contributors": [
        { "name": "Akira Toriyama", "role": "auteur", "role_custom": "",
          "personality_id": "...", "personality_url": "..." },
        { "name": "Shueisha", "role": "editeur", "role_custom": "",
          "personality_id": "...", "personality_url": "..." }
      ],
      "thumbnail_url": "...", "public_url": "..." }
  ]
}

author est un résumé texte purement cosmétique (aperçu compact), construit automatiquement depuis contributors — voir le format contributors ci-dessous pour le détail structuré.

GET /series/browse?q=...&contributor=...&genre=...&status=...

Explore la base avec des filtres combinables et une pagination complète — pour tout récupérer selon un critère donné, pas seulement les meilleurs résultats. Même statut d'authentification facultative que /series/search ci-dessus.

  • q — recherche libre, porte sur le titre et les noms de contributeurs.
  • type — manga ou light-novel.
  • contributor — filtre partiel sur les noms de contributeurs, tous rôles confondus.
  • genre — un des genres de la liste fermée de Syngas (mêmes genres que les fiches, ex. Action, Seinen…). Une valeur inconnue renvoie une erreur 400.
  • status — En cours, En pause, Terminée ou Abandonnée.
  • mature — 0 ou 1, pour exclure ou isoler le contenu marqué mature.
  • page — page demandée, défaut 1.
  • per_page — résultats par page, défaut 24, plafonné à 100.

Tous les filtres sont combinables et facultatifs — un appel sans aucun paramètre liste toute la base, paginée.

curl "https://concepts.esenjin.xyz/syngas/api/v1/series/browse?genre=Seinen&status=En%20cours"
200 {
  "results": [
    { "id": "...", "type": "manga", "name": "...",
      "contributors": [
        { "name": "Akira Toriyama", "role": "auteur", "role_custom": "",
          "personality_id": "...", "personality_url": "..." },
        { "name": "Shueisha", "role": "editeur", "role_custom": "",
          "personality_id": "...", "personality_url": "..." }
      ],
      "synopsis": "...",
      "genres": "Seinen, Drame", "volumes_count": 12,
      "status": "En cours", "mangaupdates_url": "...", "babelio_url": "...",
      "mature": false, "thumbnail_url": "...", "public_url": "...",
      "created_at": "...", "updated_at": "..." }
  ],
  "page": 1, "per_page": 24, "total": 137, "total_pages": 6
}

Pour récupérer toute la base d'un coup plutôt que de paginer, l'export JSON complet (voir plus haut) reste le meilleur point d'entrée — sans limite de débit ni de pagination.

GET /series/{id}

Fiche complète d'une série.

200 {
  "id": "...", "type": "manga", "name": "...",
  "contributors": [
    { "name": "Akira Toriyama", "role": "auteur", "role_custom": "",
      "personality_id": "...", "personality_url": "..." },
    { "name": "Shueisha", "role": "editeur", "role_custom": "",
      "personality_id": "...", "personality_url": "..." }
  ],
  "synopsis": "...",
  "genres": "Action,Aventure", "volumes_count": 12,
  "status": "En cours", "mangaupdates_url": "...", "babelio_url": "...",
  "mature": false, "thumbnail_url": "...", "public_url": "...",
  "created_at": "...", "updated_at": "..."
}

status vaut En cours, En pause, Terminée, Abandonnée, ou null si inconnu. contributors[].personality_id/personality_url pointent vers la fiche personnalité correspondante (voir ci-dessous), null si elle a été supprimée entre-temps.

Personnalités — ouvert à tous

Chaque nom de contributeur (contributors[].name) a sa propre fiche, créée automatiquement dès sa première apparition dans une série — photo et biographie sont ajoutées séparément depuis le site public ou l'administration de Syngas. Lecture seule pour l'API : une instance Lengas peut proposer un nom de contributeur (via contributors dans POST /series/submit/propose-edit), jamais une photo ni une biographie.

GET /contributors/browse?q=...&page=...&per_page=...

Liste paginée des fiches personnalité, en résumé. q filtre par nom.

200 {
  "results": [
    { "id": "...", "name": "Akira Toriyama", "photo_url": "...", "public_url": "..." }
  ],
  "page": 1, "per_page": 24, "total": 812, "total_pages": 34
}
GET /contributors/{id}

Fiche complète, avec la liste des séries et le(s) rôle(s) sur chacune.

200 {
  "id": "...", "name": "Akira Toriyama", "aliases": [],
  "bio": "...", "photo_url": "...", "public_url": "...",
  "series": [
    { "id": "...", "type": "manga", "name": "...",
      "thumbnail_url": "...", "public_url": "...",
      "roles": [ { "role": "auteur", "role_custom": "", "label": "Auteur" } ] }
  ],
  "created_at": "...", "updated_at": "..."
}

Le format contributors

Depuis la migration « Personnalités », les anciens champs texte author, publisher et other_contributors sont remplacés par un unique champ contributors : une liste d'objets, partout où une fiche série complète apparaît dans cette API (GET /series/browse, GET /series/{id}, l'export JSON, le corps de POST /series/submit et POST /series/{id}/propose-edit).

"contributors": [
  { "name": "Akira Toriyama", "role": "auteur", "role_custom": "" },
  { "name": "Shueisha",       "role": "editeur", "role_custom": "" },
  { "name": "Jean Dupont",    "role": "traducteur", "role_custom": "" },
  { "name": "Marie Martin",   "role": "autre", "role_custom": "Storyboard" }
]
  • name (obligatoire) — nom de la personne ou de l'entité.
  • role — une des clés du registre fermé ci-dessous, ou une chaîne vide "" si le rôle n'est pas connu (toléré, jamais une erreur).
  • role_custom — uniquement significatif quand role vaut "autre" ; vide dans tous les autres cas.

Registre fermé des rôles reconnus :

  • auteur — Auteur
  • scenariste — Scénariste
  • dessinateur — Dessinateur
  • illustrateur — Illustrateur
  • coloriste — Coloriste
  • traducteur — Traducteur
  • adaptateur — Adaptateur
  • lettreur — Lettreur
  • editeur — Éditeur
  • autre — Autre

Une valeur de role hors de ce registre et différente de "autre" est traitée comme un rôle vide (tolérant, jamais bloquant). Le champ author présent dans le résumé de GET /series/search reste un texte purement cosmétique, construit automatiquement depuis contributors — voir plus haut.

Chaque nom retrouve ou crée automatiquement sa propre fiche personnalité (voir la section « Personnalités » plus bas) dès qu'il apparaît dans contributors — aucune action supplémentaire n'est nécessaire côté Lengas. En revanche, la photo et la biographie d'une fiche personnalité ne sont jamais transmissibles via l'API : Lengas n'a connaissance que du nom et du rôle par série.

Endpoints d'écriture — instances Lengas, clé requise

POST /series/submit

Propose une nouvelle série, mise en attente de modération. Corps : les champs de la fiche (sans id), plus thumbnail_source_url (URL de la vignette proposée, récupérée seulement si la soumission est validée — voir la note sécurité du README).

{
  "type": "manga", "name": "...",
  "contributors": [
    { "name": "Akira Toriyama", "role": "auteur", "role_custom": "" },
    { "name": "Shueisha", "role": "editeur", "role_custom": "" }
  ],
  "synopsis": "...",
  "genres": "Action,Aventure",
  "volumes_count": 12, "status": "En cours",
  "mangaupdates_url": "...", "babelio_url": "...", "mature": false,
  "thumbnail_source_url": "https://..."
}
202 { "submission_id": "...", "status": "en_attente" }

Peut être désactivé temporairement côté Syngas (403 { "error": "submissions_disabled" }).

POST /series/{id}/propose-edit

Propose une modification sur une fiche existante — jamais écrite directement, toujours revue par un modérateur. Corps : uniquement les champs qui diffèrent de la fiche actuelle (mêmes clés que POST /series/submit, sans type : le type d'une fiche existante ne se change pas par une proposition).

202 { "proposal_id": "..." }
GET /submissions/{id}

Suivi du statut d'une soumission déposée par l'instance appelante (via POST /series/submit). Scopé strictement à cette instance : l'identifiant d'une soumission déposée par une autre instance, ou par un compte du site public, renvoie 404 exactement comme un identifiant inexistant.

200 {
  "submission_id": "...",
  "status": "en_attente|creee|fusionnee|rejetee",
  "series": { ... } | null,
  "reviewed_at": "..." | null,
  "created_at": "..."
}

Erreurs communes

  • 401 { "error": "unauthorized", "message": "..." } — clé fournie mais absente ou invalide (endpoints d'écriture, ou /series/search//series/{id} si une clé a été envoyée).
  • 403 { "error": "banned", "reason": "...", "banned_at": "..." } — instance bannie.
  • 403 { "error": "reads_disabled", "message": "..." } — consultation publique sans clé temporairement désactivée côté Syngas ; l'export JSON reste disponible dans ce cas.
  • 404 { "error": "not_found", "message": "..." } — ressource introuvable (ou hors du périmètre de la clé fournie).
  • 426 { "error": "upgrade_required", "message": "...", "minimum_version": "..." } — en-tête X-Lengas-Version trop ancien pour le contrat contributors actuel (voir ci-dessus) : mettez à jour l'instance Lengas appelante.
  • 429 { "error": "rate_limited", "retry_after": <secondes> } — débit dépassé, avec l'en-tête Retry-After correspondant : 600 requêtes/minute par clé sur les endpoints authentifiés, 30 requêtes/minute par IP sur /series/search et /series/{id} appelés sans clé (valeurs par défaut, réglables).