Skip to Content
Intégration

Intégration

Ce guide présente le cycle de vie d’une intégration avec l’API externe v2. L’API est régionale : utilisez la base de votre région.

RégionBase URL
Europe (EU)https://api.eu.mearchiver.com/api/external/v2
Amérique (US)https://api.us.mearchiver.com/api/external/v2

Restriction de type & provenance. Une clé peut être restreinte à certains types d’archives : elle ne voit et n’agit que dans ce périmètre. De plus, une clé ne peut modifier ou alimenter que les archives qu’elle a elle-même créées (provenance). La lecture est liée au plan souscrit (feature external_api).

Découvrir les types autorisés (et leurs natures)

Avant tout dépôt, listez les types d’archives autorisés pour votre clé. Chaque type inclut directement ses natures de document valides (natures) — c’est de là que vient le documentNatureId obligatoire à l’upload. Récupérez aussi les champs du type (scope external:archives:read) :

curl -s "https://api.eu.mearchiver.com/api/external/v2/archive-types" \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET" curl -s "https://api.eu.mearchiver.com/api/external/v2/archive-types/{typeId}/fields" \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET"
{ "success": true, "data": [ { "id": "3a2b1c0d-1111-2222-3333-444455556666", "label": "Contrats", "natures": [ { "id": "7e6d5c40-aaaa-bbbb-cccc-ddddeeee0000", "label": "Contrat signé", "is_required": true }, { "id": "8f7e6d51-bbbb-cccc-dddd-eeeeffff1111", "label": "Annexe", "is_required": false } ] } ] }

Les field_key (endpoint /fields) servent à construire dynamic_fields ; tout champ is_required doit être fourni au dépôt. Une liste natures vide signifie que le tenant n’a pas encore associé de natures à ce type.

Pagination

GET /archives accepte offset (≥ 0, défaut 0), limit (1–200, défaut 50), search (plein-texte : titre + mots-clés du dossier ET contenu OCR des documents), type (UUID d’un type d’archive) et external_ref (résolution par référence ERP). La recherche reste limitée aux dossiers du périmètre de la clé (validés, types autorisés). La réponse porte un objet paginé :

{ "success": true, "data": { "items": [], "total": 200, "offset": 0, "limit": 50 } }

Itérez en incrémentant offset de limit jusqu’à couvrir total. Seules les archives validées et actives sont retournées.

Filtrer par champ dynamique : ajoutez field.<field_key>=<valeur> (répétable), ex. ?field.annee=2026&field.service=Achats. Correspondance exacte, sémantique ET. Les field_key proviennent de /archive-types/{typeId}/fields.

1. Déposer une archive (avec son premier document)

Une archive naît toujours avec du contenu : il n’existe pas de création « à blanc ». On dépose l’archive et son premier document en une seule requête multipart/form-data via POST /archives/with-document (transaction atomique, rollback si une étape échoue → jamais d’archive vide). Scope external:documents:write.

Contraintes : le archiveTypeId doit faire partie des types autorisés ; si le tenant a un plan de classement publié, classificationNodeId est obligatoire ; tous les champs is_required du type doivent figurer dans dynamicFieldsJson ; le fichier passe l’antivirus (refus 503 si indisponible). Les champs structurés (keywords, dynamic_fields) sont transmis en JSON sérialisé.

Le contenu se fournit soit en file (multipart direct, adapté aux fichiers jusqu’à ~8 Mio), soit via stagedUploadId pour les fichiers volumineux — voir Gros fichiers : versement chunké.

curl -s -X POST https://api.eu.mearchiver.com/api/external/v2/archives/with-document \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET" \ -F "title=Contrats fournisseurs 2026" \ -F "archiveExternalRef=ERP-DOSSIER-7741" \ -F "archiveTypeId=3a2b1c0d-1111-2222-3333-444455556666" \ -F "classificationNodeId=9c8b7a60-aaaa-bbbb-cccc-ddddeeeeffff" \ -F 'dynamicFieldsJson={"annee":"2026","service":"Achats"}' \ -F "documentNatureId=7e6d5c40-aaaa-bbbb-cccc-ddddeeee0000" \ -F "externalRef=ERP-DOC-5512" \ -F "[email protected];type=application/pdf"

Idempotence (anti-doublon). Fournissez archiveExternalRef (la référence de votre dossier côté ERP) et externalRef (celle du document). En cas de retry ou de ré-ingestion, MEA réutilise le dossier existant (réponse 200 au lieu de 201) et déduplique le document par sa référence — jamais de doublon. Si la référence de dossier appartient à une autre clé : 409 ARCHIVE_EXTERNAL_REF_CONFLICT. Vous pouvez aussi résoudre un dossier par sa référence : GET /archives?external_ref=ERP-DOSSIER-7741.

{ "success": true, "data": { "archive_id": "8f1c0e2a-3b4d-4e5f-9a0b-1c2d3e4f5a6b", "document_id": "2d7b9f10-aa11-4c22-8d33-44e55f66a778", "submission_status": "IN_VALIDATION" }, "message": "Archive et document déposés." }

L’archive est auto-soumise à validation si son type a un workflow actif (IN_VALIDATION) ; sinon elle reste AWAITING_SUBMISSION en attendant qu’un administrateur configure le workflow. Un champ obligatoire manquant renvoie 422 ARCHIVE_REQUIRED_FIELD_MISSING ; l’absence de classement alors qu’un plan est publié renvoie 422 ARCHIVE_CLASSIFICATION_REQUIRED ; un type non autorisé renvoie 403 EXTERNAL_ARCHIVE_TYPE_FORBIDDEN.

2. Ajouter d’autres documents

Pour ajouter des documents supplémentaires au même dossier, répétez l’appel ci-dessous — un fichier par requête (chaque fichier est scanné, tracé et limité indépendamment). Scope external:documents:write. Le corps est multipart/form-data avec file et documentNatureId obligatoires (et externalRef optionnel). Le dépôt ne fonctionne que sur une archive créée par cette clé. Tout fichier passe l’antivirus ; si le scanner est indisponible, la requête est refusée (503 DOCUMENT_AV_UNAVAILABLE).

curl -s -X POST \ "https://api.eu.mearchiver.com/api/external/v2/archives/8f1c0e2a-3b4d-4e5f-9a0b-1c2d3e4f5a6b/documents" \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET" \ -F "[email protected];type=application/pdf" \ -F "documentNatureId=7e6d5c40-aaaa-bbbb-cccc-ddddeeee0000" \ -F "externalRef=ERP-DOC-5512"

Pour un fichier volumineux, remplacez file par stagedUploadId (voir la section suivante). Si ni file ni stagedUploadId n’est fourni : 400 DOCUMENT_UPLOAD_NO_FILE. Les documents créés ici sont toujours non chiffrés (is_encrypted=false).

Gros fichiers : versement chunké (avec reprise)

Une requête multipart porte un fichier jusqu’à ~8 Mio. Au-delà — et jusqu’à la taille maximale d’un document (200 Mio) — déposez le fichier en morceaux (chunks) via une session de versement, puis référencez-la avec stagedUploadId dans with-document ou /archives/{archiveId}/documents, à la place du champ file. Le versement est repreneable : un chunk qui échoue se réémet seul, sans tout recommencer. Scope external:documents:write.

1. Ouvrir la sessionPOST /uploads (corps JSON) :

curl -s -X POST https://api.eu.mearchiver.com/api/external/v2/uploads \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET" \ -H "Content-Type: application/json" \ -d '{ "file_name": "scan-volumineux.pdf", "mime_type": "application/pdf" }'
{ "success": true, "data": { "upload_id": "f0e1d2c3-4b5a-6978-8c9d-0a1b2c3d4e5f", "chunk_size": 8388608 } }

Découpez le fichier en tranches de chunk_size octets (8 Mio).

2. Envoyer chaque chunkPUT /uploads/{uploadId}/chunks/{index} (index à partir de 0), corps = octets bruts de la tranche, en-tête X-Chunk-Sha256 = SHA-256 hexadécimal de la tranche (recommandé, vérifié côté serveur) :

curl -s -X PUT \ "https://api.eu.mearchiver.com/api/external/v2/uploads/f0e1d2c3-4b5a-6978-8c9d-0a1b2c3d4e5f/chunks/0" \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET" \ -H "Content-Type: application/octet-stream" \ -H "X-Chunk-Sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" \ --data-binary @chunk-000.bin
{ "success": true, "data": { "state": "PENDING", "chunk_size": 8388608, "received_chunks": [0] } }

3. Reprise (optionnel)GET /uploads/{uploadId} renvoie received_chunks : après une coupure, ne réémettez que les index manquants.

4. FinaliserPOST /uploads/{uploadId}/complete (corps JSON). La session passe à l’état STAGED :

curl -s -X POST \ "https://api.eu.mearchiver.com/api/external/v2/uploads/f0e1d2c3-4b5a-6978-8c9d-0a1b2c3d4e5f/complete" \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET" \ -H "Content-Type: application/json" \ -d '{ "total_chunks": 13, "total_size": 104857600, "sha256": null }'

5. Consommer — fournissez stagedUploadId à la place de file au dépôt :

curl -s -X POST https://api.eu.mearchiver.com/api/external/v2/archives/with-document \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET" \ -F "title=Contrats fournisseurs 2026" \ -F "archiveTypeId=3a2b1c0d-1111-2222-3333-444455556666" \ -F "documentNatureId=7e6d5c40-aaaa-bbbb-cccc-ddddeeee0000" \ -F "stagedUploadId=f0e1d2c3-4b5a-6978-8c9d-0a1b2c3d4e5f"

Sécurité identique au dépôt direct. Les octets passent par les mêmes contrôles au moment de la consommation : antivirus, validation format/poids, quota. Un fichier infecté ou un scanner indisponible est donc refusé à l’appel with-document / documents (503 DOCUMENT_AV_UNAVAILABLE), pas pendant l’envoi des chunks. Une session appartient à la clé qui l’a ouverte (une autre clé reçoit 404 UPLOAD_NOT_FOUND), expire après 48 h, et chaque clé est limitée à 50 sessions actives (429 RATE_LIMIT_EXCEEDED). Codes : UPLOAD_NOT_FOUND (404), UPLOAD_CHUNK_INVALID (422), UPLOAD_INVALID_STATE (409).

3. Relire un document

Les documents sont imbriqués sous leur archive. Métadonnées (scope external:documents:read) :

curl -s \ "https://api.eu.mearchiver.com/api/external/v2/archives/8f1c0e2a-3b4d-4e5f-9a0b-1c2d3e4f5a6b/documents/2d7b9f10-aa11-4c22-8d33-44e55f66a778" \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET"

Contenu binaire :

curl -s -L -o contrat.pdf \ "https://api.eu.mearchiver.com/api/external/v2/archives/8f1c0e2a-3b4d-4e5f-9a0b-1c2d3e4f5a6b/documents/2d7b9f10-aa11-4c22-8d33-44e55f66a778/content" \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET"

Si le document est chiffré de bout en bout, le téléchargement renvoie 403 DOCUMENT_E2EE_PROTECTED (voir concepts).

4. Lister et mettre à jour

Lister les documents d’une archive :

curl -s \ "https://api.eu.mearchiver.com/api/external/v2/archives/8f1c0e2a-3b4d-4e5f-9a0b-1c2d3e4f5a6b/documents" \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET"

Mettre à jour une archive créée par cette clé (scope external:archives:write) :

curl -s -X PUT \ "https://api.eu.mearchiver.com/api/external/v2/archives/8f1c0e2a-3b4d-4e5f-9a0b-1c2d3e4f5a6b" \ -H "X-Api-Key: mea_ext_a1b2c3_VOTRE_SECRET" \ -H "Content-Type: application/json" \ -d '{ "title": "Contrats fournisseurs 2026 (révisé)" }'

Une mise à jour sur une archive d’une autre clé renvoie 403 EXTERNAL_ARCHIVE_NOT_OWNED.

Migration v1 → v2. L’ancienne API /api/external/v1 est retirée : tous ses endpoints renvoient 410 Gone (EXTERNAL_API_V1_GONE). Elle ne portait pas les contrôles de v2 (restriction de type, provenance, lecture limitée aux dossiers validés). Le changement majeur de chemin : le contenu d’un document passe de /documents/{id}/content à /archives/{archiveId}/documents/{documentId}/content.

La référence API externe décrit chaque endpoint, schéma et réponse en détail.