API — Intégrations M2M V1
contrat serveur-à-serveur pour scopes opaques, Media V1, projections et KG workspace
Cette référence décrit le contrat V1 permettant à un backend partenaire de provisionner un périmètre opaque, publier des projections métier, gérer des médias autorisés et construire ou lire un Knowledge Graph isolé.
Les schémas exhaustifs restent dans openapi.json.
Invariants de sécurité
- Authentification OIDC OAuth2
client_credentialsobligatoire. - Le principal doit être classé machine et lié au
caller_appparNEXUS_M2M_CALLER_APP_CLIENTS. - Dans le contrat actuel,
source_appdoit être égal àcaller_app. nexus.ingestetcan_writeprotègent les mutations.nexus.queryetcan_readprotègent les lectures.external_scope_idest un UUID opaque appartenant à l'application cliente. Nexus résout seul leworkspacecanonique.- Le client ne fournit jamais de
tenant_idet ne choisit pas un workspace Nexus arbitraire. - Une ressource d'un autre tenant, caller ou scope est non énumérable.
Séquence recommandée
- Obtenir un bearer M2M à durée courte.
- Vérifier le principal avec
GET /api/auth/oidc/me. - Appeler
POST /api/v1/integration-scopes/ensure. - Utiliser le même
external_scope_idpour les médias, projections et routes KG workspace. - Réconcilier périodiquement les projections, sans lire les stores internes de Nexus.
Périmètres d'intégration
| Méthode | Endpoint | Scope | Effet |
|---|---|---|---|
POST | /api/v1/integration-scopes/ensure | nexus.ingest | Crée ou rejoue le mapping opaque et les projets canoniques |
GET | /api/v1/integration-scopes/{external_scope_id} | nexus.query | Lit un mapping actif du caller courant |
Exemple de provisioning :
{
"caller_app": "partner_app",
"source_app": "partner_app",
"external_scope_id": "8e02a671-8604-49d1-9ebf-28a60475e91e",
"projects": ["entities", "relations", "media"]
}ensure est rejouable. Une liste de projets invalide renvoie 422. Un scope
inactif ou inaccessible reste masqué par 404. L'absence de binding M2M côté
Nexus renvoie 503 et doit être corrigée par un opérateur, pas contournée par
le client.
Media V1
| Méthode | Endpoint | Scope | Usage |
|---|---|---|---|
POST | /api/v1/media/upload/init | nexus.ingest | Initialise un upload présigné |
POST | /api/v1/media/upload/direct | nexus.ingest | Upload multipart serveur-à-serveur |
POST | /api/v1/media/upload/commit | nexus.ingest | Vérifie et finalise l'objet |
GET | /api/v1/media/{external_scope_id}/{media_id} | nexus.query | Lit le statut et les métadonnées sûres |
GET | /api/v1/media/{external_scope_id}/{media_id}/content | nexus.query | Diffuse une variante autorisée |
POST | /api/v1/media/{media_id}/access | nexus.query | Produit un accès signé court |
POST | /api/v1/media/{media_id}/revoke | nexus.ingest | Révocation logique avec version optimiste |
Les usages V1 sont profile et content. Les types déclarables sont exposés
dans OpenAPI ; les limites opérationnelles sont contrôlées côté Nexus et
résumées dans le guide API général. Le format réel
est validé à partir du contenu lors du commit.
expected_checksum_sha256, expected_byte_size, object_id et
object_version_id empêchent de confondre deux versions.
Disponibilité actuelle
Le chemin est générique, mais l'adaptateur Media V1 actuellement livré réutilise
le stockage privé Narrélia et son autorisation M2M. Il est donc exploitable par
le client Narrélia autorisé. L'ouverture à une autre application nécessite une
validation Nexus dédiée de son binding, de ses usages, limites et règles de
stockage ; le seul changement de caller_app dans le payload ne suffit pas.
Les routes historiques /api/narrelia/media/* restent disponibles pour
compatibilité. Les nouvelles intégrations ne doivent pas les utiliser.
Projections domaine
| Méthode | Endpoint | Scope | Effet |
|---|---|---|---|
POST | /api/v1/domain-projections/entities | nexus.ingest | Upsert d'une entité reconstruisible |
POST | /api/v1/domain-projections/relations | nexus.ingest | Upsert d'une relation entre entités actives |
GET | /api/v1/domain-projections/{projection_kind}/{aggregate_type}/{aggregate_id} | nexus.query | Lecture de l'état courant |
POST | .../{aggregate_id}/retract | nexus.ingest | Retrait logique versionné |
POST | .../{aggregate_id}/restore | nexus.ingest | Restauration logique versionnée |
POST | /api/v1/domain-projections/reconcile | nexus.query | Réconciliation bornée à 500 références |
Chaque mutation utilise contract_version="1.0", command_id,
idempotency_key, aggregate_version et le scope opaque. Un replay strictement
identique retourne le résultat initial. Nexus renvoie notamment :
409 idempotency_conflictsi une clé est réutilisée avec une autre commande ;409 version_conflictpour une version ancienne ou incohérente ;409 projection_reference_unavailablesi une relation référence une entité inactive ou hors scope ;404 projection_unavailablepour une projection non visible.
Une projection est une copie reconstruisible ; l'application cliente reste propriétaire de la vérité métier.
Knowledge Graph workspace
| Méthode | Endpoint | Scope | Effet |
|---|---|---|---|
POST | /api/v1/knowledge-graph/rebuild | nexus.ingest | Reconstruit une version du workspace résolu |
GET | /api/v1/knowledge-graph/overview | nexus.query | Métadonnées de la dernière version prête |
GET | /api/v1/knowledge-graph/search | nexus.query | Recherche textuelle d'entités |
GET | /api/v1/knowledge-graph/subgraph | nexus.query | Sous-graphe filtré et borné |
GET | /api/v1/knowledge-graph/neighbors/{node_id} | nexus.query | Voisinage d'un nœud du scope |
Toutes les lectures portent caller_app, source_app et external_scope_id.
Nexus dérive une clé de graphe workspace ; aucune absence de graphe workspace ne
retombe sur le graphe global. Une reconstruction building ou failed ne
remplace pas la dernière version ready.
Le détail du modèle de graphe est dans
55-Knowledge-Graph.md.
Erreurs et reprise
| Statut | Interprétation client |
|---|---|
401 | bearer absent ou invalide ; renouveler le token |
403 | principal, scope OAuth ou permission source insuffisant |
404 | ressource inexistante ou volontairement non énumérable |
409 | conflit de version/idempotence, graphe désactivé ou état incompatible |
422 | payload hors contrat ; ne pas retenter sans correction |
503 | binding M2M Nexus absent ; intervention opérateur nécessaire |
Ne jamais journaliser le bearer, le secret client, les contenus médias ou les payloads métier complets. Les preuves d'intégration doivent se limiter aux IDs opaques, statuts, codes d'erreur contrôlés et identités de client non secrètes.