← Calendrier Fur

Documentation

Doc de référence de l'API, en markdown. Version interactive : /docs.

API Calendrier Fur

Liste de conventions furry dans le monde entier — scrapées sur furryguides.com, furrycons.com, consurf.net et highwaytotail.com, dédupliquées puis normalisées dans un seul format.

Les routes de lecture (/api/conventions, /api/calendar, /api/status) sont publiques, en lecture seule, et accessibles en CORS depuis les domaines autorisés. Les routes de gestion (création, édition, suppression, résolution de conflits) sont réservées au staff : elles exigent à la fois un token Cognito valide (groupe gestionconvsfur) et un header Origin correspondant exactement au dashboard de gestion — un token seul ne suffit jamais.

Spécification complète, testable en direct : /docs (Swagger UI) ou /api/openapi.json (OpenAPI 3.0 brut).

Credit obligatoire

Toute réutilisation publique de ces données (site, bot, application, export) doit créditer visiblement la source avec un lien vers electrothewolf.fr. Voir les conditions d'utilisation pour le détail.


Lecture publique

GET /api/conventions

Liste des conventions au format JSON, filtrable et paginable.

Paramètre Type Description
continent string Filtre par continent (Europe, North America, South America, Asia, Oceania, Africa)
country string Filtre par pays (nom complet ou code, insensible à la casse)
year string Filtre par année de début, ex 2026
future 0 | 1 Par défaut 1 — ne retourne que les événements à venir
q string Recherche floue sur le nom, la ville ou le pays
limit integer Nombre maximum de résultats
offset integer Décalage de pagination

Réponse 200

{
  "meta": { "total": 120, "filtered": 42, "offset": 0, "updatedAt": "2026-08-09T03:00:00.000Z" },
  "conventions": [ /* Convention[] */ ]
}

GET /api/conventions/{id}

Une seule convention à partir de son identifiant stable (slug du nom + date de début, ex furrydelphia-2026-08-06). 404 si non trouvée.

GET /api/calendar

Export .ics téléchargeable, filtrable comme /api/conventions (sans pagination — continent, country, year, future).

GET /api/status

Métadonnées : date de dernière mise à jour, nombre total de conventions, valeurs distinctes de continent/pays/année, et la liste complète des conventions.


Objet Convention

Champ Type Description
id string Identifiant stable, généré côté API
name string
startDate / endDate string (date)
location string Libellé complet du lieu
city / country / continent string
url string (uri) Site officiel
description string
source string Origine du scraping ou manual
address string | null
attendance string | null Ex "6.7k"
website string | null (uri)
price string | null Ex "$120" ou "€90 – €150" (best-effort)
registrationUrl string | null (uri) Lien d'inscription/billetterie détecté (best-effort)
registrationStatus unknown | open | closed | announced | null Best-effort, non garanti
registrationOpenDate string (date) | null Best-effort
registrationCheckedAt string (date-time) | null Dernière tentative d'enrichissement
logoUrl string | null (uri) og:image best-effort
manualFields string[] | null Champs corrigés à la main par le staff, jamais réécrasés par un scrape

Gestion (staff uniquement)

Toutes les routes ci-dessous exigent security: staffAuth — un Authorization: Bearer <id_token> Cognito du groupe gestionconvsfur, et un Origin égal au dashboard de gestion.

POST /api/conventions

Crée une convention manuellement. Enregistrée avec source: "manual", jamais écrasée par un scrape ultérieur. 409 si une convention avec le même nom + date de début existe déjà.

Champs requis : name, startDate, endDate, city, country, url, description.

PUT /api/conventions/{id}

Patch partiel — seuls les champs présents dans le corps sont modifiés. Un champ modifié parmi name/startDate/endDate/city/country/continent/url/description/address/price/registrationOpenDate est marqué dans manualFields et ne sera plus jamais écrasé par un futur scrape. Modifier name ou startDate recalcule l'id. Toute résolution de conflit en attente sur un champ modifié ici est automatiquement purgée.

DELETE /api/conventions/{id}

Supprime la convention et purge les conflits en attente qui lui sont liés.

GET /api/conflicts

Liste les conflits en attente d'arbitrage staff.

Un conflit apparaît quand un scrape trouve, pour startDate, endDate ou price, une valeur différente de celle déjà stockée — au lieu d'écraser silencieusement, l'ancienne et la nouvelle valeur sont mises en attente d'arbitrage.

POST /api/conflicts

Résout un conflit :

action Effet
accept Applique la valeur proposée par la source
reject Garde la valeur actuelle
override Applique une valeur saisie à la main (value requis)

Corps : { "conventionId": string, "field": "startDate" | "endDate" | "price", "action": "accept" | "reject" | "override", "value"?: string }


Rafraichissement des donnees

GET /api/scrape (alias POST)

Relance le scraping de toutes les sources et met à jour le stockage. Tourne automatiquement toutes les 24h via cron Vercel (non soumis au cooldown) ; les appels manuels sont limités à une fois toutes les 3h sauf ?force=true.

GET /api/enrich (alias POST)

Visite le site officiel des conventions à venir pour en extraire inscription/billetterie/logo (best-effort). Cooldown de 7 jours par convention sauf ?force=true ou ?id=<id> pour cibler une seule convention.


Codes d'erreur

Toutes les erreurs suivent le même format :

{ "ok": false, "error": "message" }
Code Signification
400 Champs requis manquants
401 Token manquant ou invalide
403 Origine non autorisée ou compte hors groupe staff
404 Ressource introuvable
409 Conflit (doublon nom + date de début)