Authentification et conventions

Cette page décrit les règles communes à tous les endpoints de l'API REST Ormuz : authentification, format des identifiants, réponses et gestion des erreurs.

URL de base

Les contrats REST métier sont exposés sous le préfixe https://api.ormuz.io/v1/. L’échange d’une clé API contre un bearer token utilise l’endpoint séparé POST https://api.ormuz.io/api/token.

SurfacePréfixe
Token pour clé APIhttps://api.ormuz.io/api/token
API REST publiquehttps://api.ormuz.io/v1/

Authentification

L'API utilise une authentification en deux étapes. Vous échangez d'abord votre clé API contre un token JWT à courte durée de vie, puis vous envoyez ce token dans l'en-tête Authorization de toutes vos requêtes.

Étape 1 — Obtenir un token

HTTP
POST https://api.ormuz.io/api/token
Content-Type: application/json
{1 item
"api_key":"ormuz_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
{
  "api_key": "ormuz_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Réponse 200

JSON
{1 item
"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
}
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
}

Le token contient sa propre expiration JWT. La configuration standard est de 24 heures, mais un déploiement peut utiliser une durée plus courte. Votre client doit donc se fier à l’expiration du token et obtenir un nouveau token lorsque nécessaire. Une clé API révoquée, suspendue ou expirée ne permet plus d’obtenir un token valide.

Étape 2 — Utiliser le token

HTTP
GET https://api.ormuz.io/v1/invoices
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

L'en-tête Authorization est obligatoire sur tous les endpoints /v1/ à l'exception des chemins publics listés ci-dessous.

Chemins sans authentification

Ces endpoints n'exigent pas de token — ils sont accessibles sans en-tête Authorization.

CheminUsage
/v1/extension-assets/*Ressources de présentation publiques déclarées par les extensions.
/v1/extension-webhooks/*Réception des webhooks entrants des providers. Chaque extension applique son propre contrat d’authentification ou de vérification.
/v1/journey-access/validateValidation de la capacité d’accès temporaire à un parcours utilisateur.
/v1/approval-requests/assignments/*Actions effectuées depuis une capacité d’approbation destinée à un assignment précis.

Erreurs d'authentification

MessageCause
Missing bearer tokenEn-tête Authorization absent ou mal formé.
Invalid bearer tokenToken invalide, signature incorrecte ou expiré.
API key is not active or unknownLa clé associée au token a été révoquée, suspendue ou n’existe plus.
API key has expiredLa clé API a une date d'expiration dépassée.
Gestion des clés API : préfixes, statuts, droits et expiration.
La console présente les préfixes des clés et leurs droits par marchand, sans afficher les secrets complets. Agrandir

Permissions

Chaque clé API porte un ou plusieurs permission sets. Chaque set associe une portée — compte ou marchand — à une liste de permissions de la forme ressource:action, par exemple invoice:read ou company:write.

Un permission set peut être limité à un marchand précis. Les permissions de niveau compte sont déclarées sur un set sans merchant_id. Une clé ne peut lire ou modifier que les ressources couvertes par ses sets. Lorsqu’une ressource appartient à un marchand hors périmètre, l’API masque son existence et répond normalement comme pour une ressource absente.

Un 403 explicite est retourné quand la clé est valide mais qu'une action spécifique (par exemple invoice:write) n'est pas accordée.

Identifiants

Les ressources Ormuz qui utilisent un identifiant canonique suivent la forme prefix_hex. Le préfixe identifie le type d’objet et la partie hexadécimale contient 32 caractères représentant 16 octets générés aléatoirement. Certaines ressources directement adossées à un service externe, comme un endpoint webhook sortant, peuvent exposer l’identifiant fourni par ce service.

cmp_0123456789abcdef0123456789abcdef   // Company
inv_0123456789abcdef0123456789abcdef   // Invoice
pci_0123456789abcdef0123456789abcdef   // Process instance
evt_0123456789abcdef0123456789abcdef   // Event occurrence

Traitez tous les identifiants comme opaques : ne leur attribuez ni ordre, ni date de création, ni sémantique au-delà du préfixe documenté. Les identifiants canoniques générés par Ormuz utilisent des préfixes et une partie hexadécimale en minuscules.

PréfixeObjetPréfixeObjet
acc_Compteprd_Définition de processus
mer_Marchandpdr_Révision de processus
cmp_Companypci_Instance de processus
ctc_Contactpua_Action utilisateur
ord_Commandepln_Launcher
inv_Factureapk_Clé API (identité publique de la ressource)
pay_Paiementevt_Événement
psp_Paiement PSPfrm_Formulaire

Format des requêtes

Toutes les requêtes avec un corps doivent envoyer du JSON avec l'en-tête Content-Type: application/json. Les corps malformés retournent un 400.

Le paramètre merchant_id est requis dans la plupart des requêtes de création. Il doit contenir l'identifiant du marchand (mer_...). L'API le résout en interne et retourne 400 si le marchand est introuvable.

Envoyez uniquement les champs documentés par le contrat de l’endpoint. Un champ supplémentaire ne doit jamais être utilisé comme mécanisme de persistance implicite : s’il ne fait pas partie du contrat public, ne supposez ni qu’il sera conservé ni qu’il sera renvoyé.

Metadata

Tout champ nommé metadata suit le même contrat Ormuz : une map plate dont les clés sont des chaînes non vides et les valeurs uniquement des string, nombres finis ou booléens. Les objets imbriqués, tableaux et valeurs null sont interdits.

Une map contient au maximum 50 clés, une clé mesure au plus 64 caractères, une valeur texte au plus 2 048 octets UTF-8, et la représentation JSON complète au plus 16 384 octets. Un dépassement retourne 400 ; l'API ne tronque jamais silencieusement.

À la création, metadata est optionnel et peut être null. Sur une mise à jour de ressource, les clés fournies sont fusionnées superficiellement avec la map existante ; les clés absentes sont conservées et null est refusé. Pour remplacer la map ou supprimer une clé, utilisez respectivement PUT /v1/<resource>/:id/metadata et DELETE /v1/<resource>/:id/metadata/:key.

La metadata est une surface non protégée : elle n'embarque aucune annotation de subtype ou de classification. Dans un processus, écrire une donnée protégée dans une clé de metadata constitue donc une déclassification explicite et demande le même consentement que les autres baisses de protection. Elle ne remplace jamais un stockage de secrets.

Le concepteur peut néanmoins conserver le type d'une valeur jusqu'à l'écriture : un binding ou une expression vers un common.amount persiste son entier JSON, alors qu'un template produit toujours une chaîne. Le subtype est ensuite effacé. Le node Get metadata valuepermet de réaffirmer un type scalaire attendu à la lecture ; il valide la valeur sans la convertir.

La metadata ne doit pas porter de donnée système dont Ormuz dépend pour son comportement. Un JSON structuré de provider ou de configuration doit porter un nom explicite, par exemple provider_metadata, config ou raw_response.

Format des réponses

Objet unique

Toute réponse représentant un objet unique inclut un champ object qui identifie son type.

JSON
"invoice":{9 items
"id":"inv_0123456789abcdef0123456789abcdef"
"object":"invoice"
"merchant_id":"mer_0123456789abcdef0123456789abcdef"
"status":"issued"
"settlement_status":"unpaid"
"amount_including_tax":125000
"currency":"eur"
"created_at":"2026-06-18T10:15:30.000Z"
"updated_at":"2026-06-18T10:15:30.000Z"
}
{
  "id": "inv_0123456789abcdef0123456789abcdef",
  "object": "invoice",
  "merchant_id": "mer_0123456789abcdef0123456789abcdef",
  "status": "issued",
  "settlement_status": "unpaid",
  "amount_including_tax": 125000,
  "currency": "eur",
  "created_at": "2026-06-18T10:15:30.000Z",
  "updated_at": "2026-06-18T10:15:30.000Z"
}

Liste

Les endpoints de liste retournent une enveloppe stable avec object: "list", un tableau data, un booléen has_more et unnext_cursor opaque.

JSON
"list":{4 items
"object":"list"
"data":[2 items
0:{...}2 items
1:{...}2 items
]
"has_more":true
"next_cursor":"eyJ2IjoxLCJvIjoyMH0"
}
{
  "object": "list",
  "data": [
    { "id": "inv_0123456789abcdef0123456789abcdef", "object": "invoice" },
    { "id": "inv_fedcba9876543210fedcba9876543210", "object": "invoice" }
  ],
  "has_more": true,
  "next_cursor": "eyJ2IjoxLCJvIjoyMH0"
}

Dates

Les champs publics de type date/heure sont exposés au format ISO 8601 UTC. Par exemple :

JSON
{1 item
"created_at":"2026-06-18T10:15:30.000Z"
}
{
  "created_at": "2026-06-18T10:15:30.000Z"
}

Montants

Les montants typés common.amount sont des entiers exprimés dans l’unité mineure de la devise. Pour EUR, 125000 représente donc 1 250,00 €. Ne supposez pas qu’une unité mineure vaut toujours un centième : son exposant dépend de la devise.

Pagination

Les listes potentiellement volumineuses utilisent une pagination par cursor opaque. Le client ne calcule jamais une position lui-même : il renvoie simplement lenext_cursor reçu dans la page précédente.

ParamètreDéfautMaximumDescription
limit10100Nombre maximal d'items à retourner.
cursor——Cursor opaque retourné par next_cursor. Ne le décodez pas et ne le modifiez pas.
HTTP
GET /v1/invoices?limit=20&cursor=eyJ2IjoxLCJvIjoyMH0

Si has_more est true, utilisez next_cursortel quel pour la requête suivante. Lorsqu'il vaut false,next_cursor vaut null.

Idempotence des écritures

Les créations et commandes à effet métier qui peuvent être rejouées en cas d'incertitude réseau acceptent un header Idempotency-Key. Utilisez une valeur opaque unique par intention métier et réutilisez exactement la même clé lorsque vous ne savez pas si la première requête a abouti.

HTTP
POST /v1/invoices
Authorization: Bearer …
Idempotency-Key: invoice-import-2026-09-27-0042
Content-Type: application/json

Ormuz conserve le premier résultat pendant 24 heures. La même clé avec la même requête rejoue ce résultat ; la réponse contient alors Idempotent-Replayed: true. Réutiliser la même clé avec un payload différent retourne 409. La présence du header et son caractère obligatoire ou optionnel sont déclarés opération par opération dans OpenAPI.

Erreurs

Les erreurs utilisent une enveloppe stable. type décrit la famille d'erreur, code fournit un identifiant machine, etrequest_id permet de corréler un appel avec l'observabilité Ormuz. Les erreurs de validation ajoutent param et des détails structurés.

JSON
{1 item
"error":{7 items
"type":"invalid_request"
"code":"invalid_request"
"message":"body.currency: must be an uppercase 3-letter ISO 4217 code"
"param":"body.currency"
"details":{...}1 item
"request_id":"4e36d289-9fd4-44af-86ec-a32f2a6e9350"
"correlation_id":"4e36d289-9fd4-44af-86ec-a32f2a6e9350"
}
}
{
  "error": {
    "type": "invalid_request",
    "code": "invalid_request",
    "message": "body.currency: must be an uppercase 3-letter ISO 4217 code",
    "param": "body.currency",
    "details": {
      "issues": [
        {
          "code": "invalid_format",
          "path": "body.currency",
          "message": "must be an uppercase 3-letter ISO 4217 code"
        }
      ]
    },
    "request_id": "4e36d289-9fd4-44af-86ec-a32f2a6e9350",
    "correlation_id": "4e36d289-9fd4-44af-86ec-a32f2a6e9350"
  }
}
Code HTTPSignification
400Corps de requête invalide, champ manquant ou valeur incorrecte.
401Token absent, invalide ou expiré, ou clé API devenue inactive. Renouvelez le token s’il a expiré ; une clé révoquée, suspendue ou expirée doit être corrigée côté configuration avant toute nouvelle tentative.
403Permission manquante pour cette action. Le message indique quelle permission est requise.
404Ressource introuvable — ou accessible mais non autorisée pour ce marchand.
409Conflit d'état : ressource déjà dans cet état, doublon sur une contrainte d'unicité, ou configuration ambiguë nécessitant une sélection explicite.
500Erreur interne. Ne rejouez automatiquement une écriture que si son contrat rend le rejeu sûr ou idempotent ; sinon diagnostiquez l’état de l’opération avant une nouvelle tentative.