Enregistrer ou mettre à jour un salarié
const url = 'https://example.com/entreprise/v1/entreprises/example/salaries:upsert';const options = { method: 'POST', headers: { 'X-Tenant-Id': 'example', 'X-Correlation-Id': 'example', 'Idempotency-Key': 'example', Authorization: 'Bearer <token>', 'Content-Type': 'application/json' }, body: '{"source":{"systeme":"example","emetteurId":"example","referenceSalarie":"example","version":"example","dateObservation":"2026-04-15T12:00:00Z"},"personneDeclaree":{"nomNaissance":"example","nomUsage":"example","prenoms":["example"],"dateNaissance":"2026-04-15","lieuNaissance":{"codePays":"example","codeCommune":"example"},"identifiantsDeclares":[{"type":"example","valeur":"example","niveauVerification":"example"}]},"emploi":{"etablissementId":"example","matricule":"example","natureLien":"example","dateDebut":"2026-04-15","dateFin":"2026-04-15","statut":"example","categorie":"example","college":"example"},"donneesSociales":{"periode":"example","remunerationBrute":{"montant":"example","devise":"example"}},"modeMiseAJour":"DELTA","dateEffet":"2026-04-15"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/entreprise/v1/entreprises/example/salaries:upsert \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: example' \ --header 'X-Correlation-Id: example' \ --header 'X-Tenant-Id: example' \ --data '{ "source": { "systeme": "example", "emetteurId": "example", "referenceSalarie": "example", "version": "example", "dateObservation": "2026-04-15T12:00:00Z" }, "personneDeclaree": { "nomNaissance": "example", "nomUsage": "example", "prenoms": [ "example" ], "dateNaissance": "2026-04-15", "lieuNaissance": { "codePays": "example", "codeCommune": "example" }, "identifiantsDeclares": [ { "type": "example", "valeur": "example", "niveauVerification": "example" } ] }, "emploi": { "etablissementId": "example", "matricule": "example", "natureLien": "example", "dateDebut": "2026-04-15", "dateFin": "2026-04-15", "statut": "example", "categorie": "example", "college": "example" }, "donneesSociales": { "periode": "example", "remunerationBrute": { "montant": "example", "devise": "example" } }, "modeMiseAJour": "DELTA", "dateEffet": "2026-04-15" }'Au moins personneDeclaree ou emploi doit être présent. Pour créer un lien sans epargnantId connu, les attributs minimaux de résolution sont exigés. Le tenant vient du contexte sécurisé, jamais du corps.
Autorisations
Section intitulée « Autorisations »Paramètres
Section intitulée « Paramètres »Paramètres (path)
Section intitulée « Paramètres (path) »L’entreprise portant le lien d’emploi — résolue dans le tenant courant.
Paramètres (header)
Section intitulée « Paramètres (header) »Le teneur de compte — injecté et signé par la passerelle, dérivé de l’identité authentifiée. Il n’est jamais fourni comme valeur libre dans l’URL ou le corps.
La corrélation de bout en bout — propagée jusqu’aux événements.
La clé d’idempotence, de portée tenant + appelant + route + clé. Même clé et même corps : la réponse initiale. Même clé, corps différent : 409.
Corps de la requêterequired
Section intitulée « Corps de la requêterequired »Au moins personneDeclaree ou emploi est présent. Les montants sont des chaînes décimales ; les dates sont ISO 8601 et les instants portent leur décalage.
object
object
La source déclarée et autorisée — par exemple DSN, SIRH_GROUPE.
L’identifiant stable du salarié dans la source (matricule).
La version ou séquence comparable selon la politique de la source.
Les données transmises au domaine Épargnant pour la résolution. Elles ne deviennent jamais des colonnes métier de personne dans Entreprise.
object
object
Un identifiant sensible (NIR) est chiffré au repos et masqué dans les interfaces et les journaux ; il n’apparaît jamais en clair.
object
object
Une date de fin ne supprime pas le lien : elle clôt sa période (RM-018).
object
La période de référence, par exemple 2026-07.
object
Chaîne décimale — jamais un flottant, pour éviter la perte de précision.
En DELTA, un champ absent ne modifie rien et un null explicite efface si le champ l’autorise. En FULL_SNAPSHOT, le contenu est l’état complet connu de la source pour le périmètre annoncé. Dans les deux modes, une absence ne supprime jamais implicitement une personne ni un lien d’emploi.
La date à laquelle le fait métier est valable.
Réponses
Section intitulée « Réponses »La demande est validée et enregistrée ; le traitement se poursuit. Le rejeu d’une même clé et d’un même corps retourne cette même réponse.
object
object
Example
{ "statut": "RECU"}Le lien de suivi de l’opération.
JSON invalide ou champ obligatoire absent (INVALID_REQUEST).
Le format d’erreur du § 21.2 — application/problem+json.
object
object
Examplegenerated
{ "type": "example", "title": "example", "status": 1, "code": "example", "detail": "example", "instance": "example", "correlationId": "example", "errors": [ { "path": "example", "code": "example" } ]}Identité absente ou invalide (UNAUTHENTICATED).
Droit insuffisant (FORBIDDEN) — les 403 croisés entre familles sont prouvés par les tests d’assemblage.
Ressource absente dans le tenant courant — y compris une ressource d’un autre tenant, dont l’existence n’est jamais confirmée (404, jamais 403).
Le format d’erreur du § 21.2 — application/problem+json.
object
object
Examplegenerated
{ "type": "example", "title": "example", "status": 1, "code": "example", "detail": "example", "instance": "example", "correlationId": "example", "errors": [ { "path": "example", "code": "example" } ]}IDEMPOTENCY_KEY_REUSED (même clé, corps différent), SOURCE_VERSION_CONFLICT (version incompatible) ou conflit d’empreinte d’import.
Le format d’erreur du § 21.2 — application/problem+json.
object
object
Examplegenerated
{ "type": "example", "title": "example", "status": 1, "code": "example", "detail": "example", "instance": "example", "correlationId": "example", "errors": [ { "path": "example", "code": "example" } ]}BUSINESS_RULE_VIOLATION ou IMPORT_SCOPE_VIOLATION — demande syntaxiquement valide mais incohérente au regard du métier ou du périmètre annoncé.
Le format d’erreur du § 21.2 — application/problem+json.
object
object
Examplegenerated
{ "type": "example", "title": "example", "status": 1, "code": "example", "detail": "example", "instance": "example", "correlationId": "example", "errors": [ { "path": "example", "code": "example" } ]}Capacité momentanément dépassée (RATE_LIMITED).
Demande non enregistrable ; le client peut rejouer (SERVICE_UNAVAILABLE). Une indisponibilité survenant APRÈS l’enregistrement n’est jamais rendue ici : elle conduit à ECHEC_REPRENABLE.