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égion | Base 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) etexternalRef(celle du document). En cas de retry ou de ré-ingestion, MEA réutilise le dossier existant (réponse200au lieu de201) 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 session — POST /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 chunk — PUT /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. Finaliser — POST /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çoit404 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/v1est retirée : tous ses endpoints renvoient410 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.