Intégration au logiciel métier
Notifications de fin de traitement
Recevoir le résultat par webhook, télécharger les pièces et reprendre en cas de livraison manquée.
Votre logiciel métier peut recevoir le résultat d’une demande par un POST JSON envoyé par Raydocs à une URL de votre choix. Il peut aussi suivre la demande par polling. Les deux modes donnent accès au résultat métier complet et aux liens de téléchargement de ses pièces.
Activer la notification pour une demande
La notification est configurée sur le workflow d’intégration publié fourni par Raydocs. Elle reste facultative pour chaque demande : seul l’envoi d’une URL de réception l’active pour cette demande.
Lors de l’envoi des documents, ajoutez le champ texte notification_url, au singulier, dans le même multipart/form-data que les fichiers files[]. Il n’est pas obligatoire. S’il est absent, vide ou composé uniquement d’espaces, Raydocs n’effectue aucun appel de notification ; le suivi par /status et /output reste utilisable.
Seul le workflow parent envoie la notification. Les sous-workflows ne reçoivent pas notification_url : le logiciel métier suit une demande avec un seul run_id, celui du parent.
Préparer l’URL de réception
La destination doit être une URL HTTPS publique sur le port 443. Les adresses internes ou privées et les redirections sont refusées : fournissez directement l’URL finale du récepteur.
Sécuriser le retour vers le logiciel métier
Bonne pratique : fournissez une URL unique par demande, signée et temporaire. Votre endpoint de notification est accessible depuis Internet : son URL ne doit pas permettre à un tiers de soumettre librement un résultat à votre logiciel métier.
Le logiciel métier génère cette URL avant l’envoi des documents et la rattache à la demande. Il peut signer l’identifiant de la demande et une date d’expiration avec un secret conservé côté serveur. À chaque réception, il vérifie la signature, l’échéance et la correspondance avec la demande avant d’accepter le résultat. Un simple identifiant de dossier dans l’URL ne protège pas cet accès.
Exemple fictif, dont les paramètres et le mécanisme de signature sont définis par votre logiciel métier :
https://logiciel-metier.example.com/raydocs/notifications?job=12345&expires={EXPIRATION_NOTIFICATION}&signature={SIGNATURE_NOTIFICATION}Choisissez une durée de validité couvrant le traitement et les tentatives de livraison, avec une marge adaptée. Cette durée est définie par le logiciel métier et est indépendante des dix minutes de validité des liens de téléchargement Raydocs. Le logiciel métier refuse les appels dont la signature est invalide ou l’URL expirée. Si le traitement dépasse cette échéance, récupérez le résultat par polling.
Une URL unique par demande ne signifie pas un lien consommable une seule fois : pendant sa validité, acceptez les nouvelles tentatives légitimes avec un 2xx, tout en dédupliquant le traitement par run_id.
Raydocs conserve les paramètres de cette URL et ne transmet aucun token API Raydocs au destinataire. Traitez l’URL signée comme un secret d’accès : toute personne qui la possède pourrait appeler ce récepteur pendant sa validité. Évitez de l’exposer dans les journaux ou dans une interface publique.
Il existe deux signatures distinctes : celle de notification_url est produite et vérifiée par votre logiciel métier ; celle des download_url est produite par Raydocs pour autoriser le téléchargement des fichiers. La signature de l’URL du logiciel métier ne constitue pas une signature Raydocs du corps JSON.
Enveloppe reçue
Raydocs envoie un POST avec Content-Type: application/json :
| Champ | Signification |
|---|---|
run_id | Identifiant du run parent, égal à l’id retourné lors de l’envoi des documents. À conserver pour le suivi et la déduplication. |
status | success pour un traitement réussi, failed pour un échec. |
output | Résultat métier complet en succès, ou objet contenant le statut et l’erreur publique en échec. |
Les métadonnées de suivi ne sont pas ajoutées automatiquement au callback : l’enveloppe ne contient ni client_id, ni metadata, ni event_id. Conservez le lien entre votre client et le run_id parent lors de l’envoi. Le statut success dans la notification correspond à completed dans l’API de suivi. Il indique la réussite du traitement Raydocs ; le téléchargement et l’import dans le logiciel métier doivent encore être vérifiés.
Cette enveloppe et notification_url appartiennent à la convention de transport Raydocs. Le standard CDJ Connect décrit le contenu métier de output, sans imposer ce protocole à tous les échanges. Ne placez pas run_id, status et output dans le schéma métier. Sur l’endpoint GET /output, la réponse reste directement le JSON métier, sans cette enveloppe.
Exemple de succès
Exemple fictif : output contient ici un lot JSON CDJ Connect 1.2 complet, enrichi des champs de téléchargement Raydocs. Les identifiants, dates et URL sont illustratifs ; le lien ne permet pas de télécharger un fichier réel. Les lots ZIP téléchargeables restent disponibles pour tester un import avec des pièces fictives.
{
"run_id": "dc817ceb-bcf4-4ae4-8a1c-596b885ed036",
"status": "success",
"output": {
"version_format": "1.2",
"en_tete": {
"id_lot": "LOT-20260520-0001",
"date_lot": "2026-05-20T10:30:00+02:00",
"environnement": "recette",
"sens_transmission": "EMETTEUR_VERS_ERP",
"type_flux": "IMPORT_DOSSIERS",
"emetteur": {
"type": "PRESTATAIRE",
"code": "RAYDOCS",
"nom": "Raydocs"
},
"destinataire": {
"type": "ERP",
"code": "ETUDE_DUPONT",
"nom": "SCP Dupont",
"logiciel": "LOGICIEL_METIER"
}
},
"service_destinataire": {
"code": "SVC-CONTENTIEUX",
"libelle": "Contentieux"
},
"dossiers": [
{
"reference_client": "CLI-12345",
"reference_dossier_destinataire": null,
"references_externes": [],
"nature_dossier": "INJONCTION_DE_PAYER",
"libelle_nature_dossier": "Injonction de payer",
"code_nature_dossier_externe": null,
"source_code_nature_dossier": null,
"evenements": [
{
"code_evenement": "OUVERTURE_DOSSIER",
"date_effet": "2026-05-20",
"libelle": "Ouverture dossier"
}
],
"pieces_jointes": [
{
"reference_piece": "DECISION-01",
"nom": "Décision judiciaire fictive",
"chemin": "pieces/decision.pdf",
"type": "PDF",
"file_id": "5ef9bd1f-25d5-4ff2-a2c4-a31039aae174",
"download_url": "https://api.raydocs.com/exemple/download?expires=1779267000&signature=SIGNATURE_FICTIVE",
"download_url_expires_at": "2026-05-20T08:50:00Z"
}
]
}
]
}
}
Raydocs conserve le résultat métier complet dans output. En succès, les pièces exposent file_id, download_url et download_url_expires_at. Les URL sont signées juste avant chaque tentative d’envoi, sans que Raydocs télécharge les octets des fichiers pour les générer. Deux livraisons du même résultat peuvent donc contenir des liens différents.
Exemple d’échec
{
"run_id": "dc817ceb-bcf4-4ae4-8a1c-596b885ed036",
"status": "failed",
"output": {
"status": "failed",
"error": {
"code": "CHILD_WORKFLOW_FAILED",
"message": "Le sous-workflow n'a pas pu finaliser le dossier."
}
}
}
Le code et le message correspondent à l’erreur publique du run. Les erreurs publiques remontées par un sous-workflow sont notifiées au niveau parent. Les diagnostics techniques internes sont masqués par le code WORKFLOW_RUN_FAILED et un message générique. Un échec ne fournit pas de lot métier à importer ; conservez le run_id et l’erreur pour le diagnostic. Voir les erreurs métier.
Recevoir et dédupliquer
Répondez rapidement avec un statut HTTP 2xx, puis traitez le résultat. Aucun format n’est imposé au corps de cet accusé de réception ; une réponse 204 sans corps convient. Le récepteur doit d’abord enregistrer durablement la notification, pour éviter de perdre une demande après l’avoir acquittée.
Nouvelles tentatives
Lorsque la notification est configurée, Raydocs prévoit les tentatives de livraison suivantes :
| Paramètre | Valeur |
|---|---|
| Nombre maximal d’envois | 3 tentatives au total, soit l’envoi initial et jusqu’à 2 nouvelles tentatives. |
| Timeout par tentative | 15 secondes. |
| Attente entre deux tentatives | 1 seconde. |
| Accusé de réception attendu | Un statut HTTP 2xx. |
Une réponse perdue ou trop lente peut conduire à recevoir plusieurs fois le même résultat. Dédupliquez sur run_id, y compris si le résultat a aussi été récupéré par polling. Une notification déjà enregistrée doit également recevoir un 2xx. Les liens de téléchargement sont signés à nouveau juste avant chaque tentative.
Après un échec de livraison, le résultat et l’erreur d’origine restent disponibles : reprenez via /status et /output, sans relancer le traitement.
Exemple de récepteur
Exemple de réception en pseudocode JavaScript, à adapter à votre serveur et à votre base de données. Les fonctions de signature, de validation et de stockage ci-dessous sont des fonctions de votre application, pas des API Raydocs :
async function recevoirNotification(req, res) {
// Vérifie la signature et sa validité ; retrouve la demande du logiciel métier liée à l’URL.
const demande = await verifierUrlSigneeNotification(req.url);
if (!demande) return res.status(403).end();
const notification = req.body;
// Vérifie run_id, status, output et la correspondance avec la demande.
if (!validerNotification(notification, demande)) {
return res.status(400).end();
}
try {
await base.transaction(async (tx) => {
// Contrainte UNIQUE(run_id) en base, pas un Set en mémoire.
// En cas de doublon : conserve le travail déjà en cours ou terminé.
// Si encore en attente, peut rafraîchir ses liens depuis cette livraison.
await tx.enregistrerReceptionSiAbsente({
run_id: notification.run_id,
demande_id: demande.id,
status: notification.status,
output: notification.output,
etat: "a_traiter"
});
});
} catch {
// Rien n’est acquitté sans stockage durable : autorise une nouvelle tentative.
return res.status(503).end();
}
return res.status(204).end();
}
Un worker reprend ensuite les réceptions a_traiter depuis cette base durable. Il réserve chaque travail de façon atomique, télécharge rapidement les pièces et effectue l’import de façon idempotente avec run_id. Il marque le résultat comme traité seulement après réussite ; un échec doit rester reprenable, y compris après un redémarrage. Un résultat failed sert à enregistrer l’erreur, sans import de dossier.
La contrainte unique empêche les réceptions simultanées de créer deux travaux. Elle ne suffit pas, à elle seule, à empêcher un double import après une interruption du worker : l’opération d’import doit elle aussi reconnaître le run_id déjà appliqué. Utilisez le même registre pour les résultats récupérés par polling.
Créez la demande et son URL signée avant l’envoi des fichiers, puis associez le RUN_ID retourné au 202. Si un callback arrive avant l’enregistrement de cette réponse, conservez-le en attente de rapprochement avec la demande ; ne rejetez pas définitivement ce résultat et ne l’importez pas avant vérification de la correspondance.
Télécharger les pièces et renouveler un lien
Dès réception d’un succès, parcourez output.dossiers[].pieces_jointes[] et téléchargez directement chaque pièce avec download_url, sans token API Raydocs. Ces liens sont valides 10 minutes après leur génération. Les redirections de téléchargement peuvent être suivies ; le refus des redirections concerne la destination de notification.
Conservez run_id et file_id comme références durables, ainsi que la référence métier reference_piece. Si un lien expire, demandez un nouveau lien via /file, ou relisez /output, sans relancer le traitement. Le renouvellement ne prolonge pas la conservation du fichier et ne restaure pas un fichier supprimé.
Reprendre si aucune notification n’arrive
Une livraison échouée ne remplace ni le JSON métier ni l’erreur initiale. Avec le RUN_ID conservé, consultez /status, puis /output pour récupérer le résultat ou l’erreur. Prévoyez cette reprise même lorsque la notification est activée ; aucune durée maximale de traitement n’est garantie par les délais de livraison ci-dessus.
Une requête rejetée avant la création d’un run, par exemple HTTP 422, n’a pas de callback. Corrigez la requête d’envoi. Aucune notification n’est garantie pour une annulation manuelle : le statut cancelled se constate via l’API de suivi.
Retrouvez le parcours d’intégration complet et les bonnes pratiques de reprise.