API ArtAI
REST · JSON · authentification par jeton Bearer. Base URL : https://www.artai.fr
Introduction
L'API ArtAI expose l'indice de valeur des artistes (ArtScore) et le pipeline complet de
certification des œuvres. Toutes les réponses sont en JSON. Les endpoints de lecture
(GET) sont publics ; les écritures requièrent un jeton Bearer.
Les réponses d'erreur suivent le format { "error", "message", "status" }.
L'API est entièrement gratuite : aucun crédit, aucun quota, aucun abonnement. Le jeton Bearer sert uniquement à identifier l'auteur des écritures, jamais à les facturer. Pour nous soutenir, rendez visite à notre partenaire montmartre-nft.fr.
🔑 Authentification
Obtenez un jeton d'accès JWT via /api/auth/token, puis passez-le dans l'en-tête Authorization: Bearer <token>. Le jeton expire après 3600 secondes. L'inscription et l'usage de l'API sont gratuits, sans limite de crédits.
Créer un compte et recevoir un JWT.
{ "email": "you@studio.art", "password": "secret", "displayName": "Studio" } Se connecter et obtenir un jeton d'accès JWT.
{ "email": "you@studio.art", "password": "secret" } // 200 { "token": "eyJ0eXAi...", "tokenType": "Bearer", "expiresIn": 3600 } Utilisateur authentifié courant.
🎟️ Jetons personnels
Créer un jeton d'API personnel (serveur-à-serveur, préfixe sk_).
{ "name": "gallery-integration", "scopes": ["artwork:write"], "expiresInDays": 90 } Lister ses jetons personnels.
🧑🎨 Artistes
Rechercher des artistes. Filtres cumulables : q (nom ou pays), nature (human|ai|hybrid), country, category (les artistes qui travaillent dans cette discipline — cf. /api/categories), minScore, sort (score|name|recent), page/perPage. C'est exactement la recherche de la page « Voir une cote ». Les clés data et total ne changent pas, et ?limit reste un alias de perPage.
Créer un artiste. Le site accepte un domaine nu (« marinareyes.art » → https://marinareyes.art) ; socials est un objet { plateforme: identifiant }.
{ "name": "Marina Reyes", "nature": "human", "country": "Espagne", "website": "marinareyes.art", "bio": "Sculptrice contemporaine.", "socials": {"instagram": "@marina"} } Mettre à jour le profil d'un artiste (propriétaire ou curateur/admin). PATCH : seuls les champs envoyés changent ; le slug (donc l'URL publique) ne change jamais. Le site accepte un domaine nu.
{ "country": "France", "website": "marinareyes.art", "bio": "…" } Définir la photo de référence de l'artiste (fichier multipart « photo »). Propriétaire ou curateur/admin.
multipart: photo=@marina.jpg Détail d'un artiste (id, uuid ou slug).
📊 ArtScore & marché
Indice ArtScore d'un artiste et détail des sous-scores. ?fresh=1 pour recalculer.
// 200 { "index": { "score": 87.4, "grade": "A+", "components": { ... } } } ArtScore de l'ŒUVRE elle-même : les sept mêmes familles pondérées que l'indice artiste (physique, marché, reconnaissance, engagement, avis, traçabilité, rareté), notées sur cette seule pièce, quelle que soit sa discipline. Calculé à la volée puis mis en cache ; ?fresh=1 pour recalculer.
// 200 { "index": { "score": 84.6, "grade": "A", "scope": "artwork", "components": { ... } } } Progression de la cote dans le temps. Points réels relevés à chaque recalcul (un par jour, le dernier calcul du jour). Les artistes de démonstration renvoient simulated:true sur la série et sur chaque point — une courbe fabriquée n'est jamais présentée comme un historique.
// 200 { "granularity": "month", "simulated": false, "points": [ { "d": "2026-05", "s": 71.2, "g": "A", "simulated": false } ] } Forcer le recalcul du score. Enregistre aussi le point du jour dans l'historique.
Synthèse des signaux de marché (ventes, pic, timeline).
Enregistrer une vente / signal de marché.
{ "type": "auction", "price": 4200, "currency": "EUR", "source": "Christies", "soldAt": "2026-03-01" } Soumettre une reconnaissance (expo, prix, presse…). Toujours créée en « pending » — le champ verified est ignoré.
{ "type": "press", "title": "Portrait", "institution": "Le Monde", "url": "https://www.lemonde.fr/..." } 📐 Cote au point
Table de référence des châssis traditionnels français (N° 0-120, F/P/M) et règles de la cote au point.
Ramener des dimensions libres (cm) au format standard le plus proche. Carrés/double-carrés assimilés ; n°0 = 0,8 point.
{ "width": 92, "height": 73 } // 200 { "number": 30, "category": "F", "standard": "92×73 cm", "points": 30, "exact": true } Cote au point de l'artiste : prix au point dérivé de l'ArtScore + grille d'exemples. Valeur potentielle indicative, jamais un prix fixe.
// 200 { "cote": { "pricePerPointEur": 2, "beginner": true, "exampleGrid": [ ... ] } } Estimation indicative d'une œuvre = prix au point × points(format) × multiplicateur physique (matériaux, temps, surface/volume) + valeur du cadre (déclarée ou dérivée du type × périmètre). Le format est déduit des dimensions.
// 200 { "estimate": { "adjustedEstimateEur": 79.44, "frame": { "type": "bois doré", "addedValueEur": 264 }, "estimateEur": 343.44 } } 🔒 Confiance & vérification
Lister TOUS les signaux à valider (marché, reconnaissance, avis). Réservé ROLE_CURATOR ou jeton scope signal:verify.
Valider/rejeter un signal (kind = market|recognition|rating). Contrôle de la source (tout site présentant l'œuvre) : liste blanche par catégorie, joignabilité, présence du nom, crédibilité IA. Réservé ROLE_CURATOR ou jeton scope signal:verify.
{ "decision": "verify", "proofUrl": "https://opensea.io/..." } ⭐ Évaluations
Soumettre une évaluation pondérée (publique). Le poids dépend du type d'évaluateur.
{ "artist": "ada-lovelace", "raterType": "gallerist", "stars": 5, "criteria": { "originality": 90, "technique": 85 } } 🖼️ Œuvres & pipeline
Référentiel des disciplines : pour chaque catégorie, son groupe, le rôle de média par défaut et ceux autorisés, la méthode de cote, et le type de fichier source attendu. C'est ce qui pilote un formulaire de dépôt.
Lister les œuvres, plus récentes d'abord. Filtrable par discipline.
Déposer une œuvre et lancer le pipeline complet (représentation, stéganographie, C2PA, IPFS, NFT, certificat). Deux champs pilotent tout : category (la discipline — cf. /api/categories) et mediaRole (ce que l'image EST par rapport à l'œuvre : original = elle est l'œuvre ; documentation = elle la montre — sculpture, céramique, mode ; representation = elle la symbolise — musique, texte, vidéo). Omis, mediaRole prend la valeur par défaut de la discipline. Une œuvre non visuelle se dépose avec sourceFile : c'est LUI qui est certifié, et ArtAI en dérive une représentation reproductible. Champs physiques optionnels : materials, materialQuality (0-100), creationHours, depthCm, framed/frameType/frameValue (œuvres planes), durationSeconds, wordCount.
multipart: image=@face.jpg, title=Torse, artistName=Ada, category=sculpture, dimensions=40x50 cm, depthCm=40, materials=bronze, creationHours=80
# œuvre non visuelle — le fichier source est l'œuvre :
multipart: sourceFile=@nocturne.wav, title=Nocturne, artistName=Ada, category=music Détail d'une œuvre avec provenance complète. Renvoie category, mediaRole, imageIs (ce que l'image est) et artScore (l'indice propre de l'œuvre) dans la forme courte ; certifiedHash (l'empreinte réellement scellée — celle du fichier source pour une œuvre non visuelle), scoreBreakdown, source et views dans la forme complète.
Relancer / reprendre le pipeline de certification.
{ "steps": { "nft": false } } 🔢 Éditions & unicité
Pré-contrôle d'un dépôt SANS enregistrer : doublon exact (SHA-256), quasi-doublon (hash perceptuel dHash), empreinte visuelle + score de similarité. La question posée dépend du mediaRole : « même image ? » (original), « même objet physique ? » (documentation — le hash perceptuel n'y est qu'un indice, deux angles d'un bronze ne sont pas deux œuvres), « même fichier source ? » (representation). Décision : new_edition / add_piece / edition_full / needs_review.
multipart: artist=ada-lovelace, image=@art.png, category=ceramics, editionSize=10 Registre public d'une édition : taille, pièces émises, restantes, et la liste numérotée.
📱 Engagement (QR)
Enregistrer une interaction QR — l'acte de présence. Public. La présence est dédupliquée par visiteur et par jour : reflasher renvoie newPresence:false, pas une seconde présence. Pose un cookie visiteur au 1er scan et renvoie un voteToken à courte durée qui autorise UN avis de ce visiteur sur l'œuvre. C'est ce qui rend la fréquentation authentifiée — sans la déduplication, n'importe quel téléphone gonflait l'engagement à chaque requête.
{ "action": "scan", "country": "FR", "city": "Paris", "durationSeconds": 42 } Avis d'un VISITEUR sur l'œuvre qu'il vient de flasher — une seule fois par visiteur. Public, mais exige le voteToken renvoyé par /scan (corps ou en-tête X-Vote-Token) : pas de scan, pas d'avis. Un vote rejoué renvoie 409 already_rated. Le poids est fixé au niveau « visiteur » et ne peut pas surpondérer l'ArtScore. Limite honnête : un navigateur ne donne pas d'identifiant matériel stable, l'ancre est un cookie — navigation privée = nouveau visiteur ; la garantie est qu'un visiteur normal vote une fois et que tricher demande un effort délibéré.
{ "voteToken": "<du POST /scan>", "stars": 5, "comment": "magnifique" } Attacher un avis QUALIFIÉ (professionnel) à une œuvre. Exige un compte authentifié — c'est le chemin galeriste/critique/acheteur, pas celui du visiteur anonyme (cf. /visitor-rating). Non dédupliqué par appareil : un pro peut légitimement noter plusieurs œuvres.
{ "raterType": "collector", "stars": 4, "criteria": { "emotionalImpact": 80 } } Fréquentation authentifiée et tunnel de conversion.
🎫 Certificats
Générer le certificat d'authenticité PDF.
{ "artwork": "<uuid>" } Récupérer un certificat par son numéro de série.
✅ Vérification
Vérifier l'authenticité d'une œuvre depuis son jeton QR. Réextrait la signature stéganographique et revalide le C2PA en direct.
// 200 { "authentic": true, "trustScore": 100, "checks": { ... } } Provenance C2PA : manifeste enregistré (assertions signées au dépôt) + revérification live via c2patool --detailed.
// 200 { "status": "signed", "recordedManifest": {...}, "liveVerification": { "valid": true, "manifest": {...} } } 🤝 Partenaires
ArtAI est une infrastructure B2B : des plateformes tierces
(galeries, sites culturels, marketplaces NFT — p.ex. montmartre-nft.fr, antenne-culture.fr)
intègrent ArtAI. Le partenaire possède ses propres utilisateurs ;
l'accès à l'API est gratuit et illimité — aucun quota, aucune mesure d'usage facturée.
sk_)- Candidature — le partenaire s'inscrit (POST
/apply) et reçoit un challenge DNS TXT. - Preuve de domaine — il publie le TXT, puis
/verify-domainconfirme qu'il possède le domaine. - Validation — vous (ROLE_ADMIN) approuvez via
/approveouphp bin/console app:partner:approve: provisioning du compte de service et d'un jeton 🔒 scopé (affiché une seule fois). - Self-service — le partenaire consulte son profil (
/me) et peut choisir son propre réseau blockchain (/me/blockchain).
Gratuité : aucun crédit n'est décompté, aucun quota n'est appliqué. Un partenaire suspendu (abus) voit son jeton immédiatement rejeté.
Candidature d'un partenaire revendeur (galerie, plateforme culturelle…). Crée une demande « pending » et renvoie un challenge DNS TXT à publier pour prouver la propriété du domaine. Public.
{ "name": "Antenne Culture", "domain": "antenne-culture.fr", "contactEmail": "tech@antenne-culture.fr", "expectedVolume": 300 } // 200 { "partner": { "uuid": "…", "status": "pending" }, "domainVerification": { "record": { "type": "TXT", "value": "artai-verify=…" } } } Revérifie le challenge DNS TXT. Une fois prouvé, un admin peut valider. Public.
Statut public d'une candidature (id, uuid ou domaine).
Valide un partenaire : provisionne un compte de service et un jeton d'API scopé (usage gratuit et illimité). Renvoie le jeton une seule fois. ROLE_ADMIN.
{ "force": false } // 200 { "apiToken": "sk_…", "scopes": ["artwork:write", …] } Suspend un partenaire ; son jeton d'API est immédiatement rejeté. ROLE_ADMIN.
Partenaire courant : profil et réseau blockchain. Authentifié avec le jeton sk_ du partenaire.
// 200 { "partner": { "uuid": "…", "status": "active" }, "blockchain": { "ownChain": false } } 🩺 Meta
État du service et capacités (IPFS, C2PA, NFT).
Spécification OpenAPI 3.1 (JSON).
Exemple complet (cURL)
# 1. Obtenir un jeton
TOKEN=$(curl -s -X POST https://www.artai.fr/api/auth/token \
-H "Content-Type: application/json" \
-d '{"email":"you@studio.art","password":"secret"}' | jq -r .token)
# 2. Déposer une œuvre (lance tout le pipeline)
curl -X POST https://www.artai.fr/api/artworks \
-H "Authorization: Bearer $TOKEN" \
-F "image=@artwork.png" -F "title=Aurora" -F "artistName=Ada Lovelace" \
-F "creationType=ai" -F "aiModel=Midjourney v6" -F "price=1200"
# 3. Vérifier publiquement
curl https://www.artai.fr/api/qrcode/<token>/verify
🔌 Serveur MCP (agents IA)
ArtAI expose un serveur Model Context Protocol (MCP) qui transforme l'API ci-dessus en outils utilisables directement depuis un assistant IA (Claude Desktop, Claude Code, ou tout client compatible MCP). Un galeriste, un collectionneur ou un agent tiers peut ainsi demander « Quel est l'ArtScore et la cote de l'artiste X ? » ou « Cette œuvre est-elle authentifiée ? » — ArtAI répond comme source de vérité vérifiée.
Portée : 14 outils de lecture (score, cote, estimation,
formats, vérification QR/C2PA…) accessibles anonymement, plus 1 outil d'écriture protégé
artai_certify_artwork (pipeline de certification) qui exige un jeton
🔒 artwork:write et une confirmation explicite avant toute mutation.
Chaque outil correspond 1:1 à un endpoint REST ; aucune logique n'est dupliquée. La liste complète est décrite dans le mcp/README.md du dépôt.
artai_save_artist crée ou met à jour le profil d'un artiste (pays, site de référence, bio, réseaux, nature) ; artai_certify_artwork lance le pipeline de certification. Sans confirm:true, chaque outil renvoie un aperçu (dry-run) sans rien modifier — garde-fou humain contre les actions irréversibles (ancrage IPFS, mint NFT).
Brancher le serveur (Claude Desktop / Claude Code)
# build
cd mcp && npm install && npm run build
# Claude Code
claude mcp add artai -- node /chemin/vers/mcp/dist/index.js
# Claude Desktop — claude_desktop_config.json
{
"mcpServers": {
"artai": {
"command": "node",
"args": ["/chemin/vers/mcp/dist/index.js"],
"env": { "ARTAI_BASE_URL": "https://www.artai.fr" }
}
}
}