API Structural Diff
Une API REST qui compare une transcription générée par IA avec la version post-éditée par l'annotateur — détectant les changements structurels au niveau des lignes (divisions, fusions, modifications, ajouts, suppressions), avec détail des différences par colonne, scores CER/WER/SER et une note de qualité composite par lot.
Démarrage rapide
Aucun SDK nécessaire. Envoyez une requête POST avec vos deux tableaux de lignes de transcription et recevez un diff complet en JSON. L'API est en phase de dégustation — demandez une clé API pour commencer.
1. Vérifiez que le service est actif :
curl https://structural-diff-engine.onrender.com/v1/health2. Lancez une comparaison :
curl -X POST https://structural-diff-engine.onrender.com/v1/diff \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"original": [
{ "speaker": "Alice", "start_time": 0, "end_time": 1, "transcript": "Hello world" },
{ "speaker": "Bob", "start_time": 1, "end_time": 3, "transcript": "Good morning everyone" }
],
"reworked": [
{ "speaker": "Alice", "start_time": 0, "end_time": 1, "transcript": "Hello there" },
{ "speaker": "Bob", "start_time": 1, "end_time": 2, "transcript": "Good morning" },
{ "speaker": "Bob", "start_time": 2, "end_time": 3, "transcript": "everyone" }
]
}'URL de base
Tous les points de terminaison sont préfixés par /v1.
https://structural-diff-engine.onrender.comAuthentification
Incluez votre clé API dans l'en-tête de requête x-api-key à chaque appel vers /v1/diff.
curl -H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" \
-X POST https://structural-diff-engine.onrender.com/v1/diff -d '{...}'Limites de débit
Deux niveaux indépendants sont appliqués par clé API, avec repli sur l'IP en l'absence de clé. Dépasser l'un ou l'autre renvoie 429 Too Many Requests.
| Niveau | Limite | En-tête de réponse |
|---|---|---|
| Rafale | 10 requêtes / minute | RateLimit-Limit |
| Fenêtre | 60 requêtes / 15 minutes | RateLimit-Remaining |
Points de terminaison
GET /v1/health
Sonde de disponibilité légère. Aucune authentification requise. Renvoie la version du service et le temps de fonctionnement.
/v1/health· Sans auth{ "status": "ok", "version": "1.0.0", "uptime": 42, "timestamp": "..." }POST /v1/diff
Comparez deux tableaux de lignes de transcription. Renvoie des résultats au niveau des lignes avec des scores de qualité. Charge utile max : 5 Mo · Lignes max : 30 000.
/v1/diff Auth requiseCorps de la requête
| Name | Type | Description |
|---|---|---|
original* | array | Objets de ligne de la version de référence / originale. |
reworked* | array | Objets de ligne à comparer. |
config | object | Surcharges optionnelles de l'algorithme. Voir . |
headers | string[] | Noms de colonnes — requis lors de l'utilisation d'un tableau 2D. |
columnMapping | object | Carte d'index de colonnes pour l'entrée en tableau 2D. Voir . |
Champs de l'objet ligne
Tous les champs sont optionnels sauf transcript. Les champs inconnus sont transmis sans modification.
| Name | Type | Description |
|---|---|---|
transcript* | string | Le contenu textuel de la ligne. |
speaker | string | Nom ou identifiant du locuteur. |
start_time | number|string | Heure de début du segment en secondes. |
end_time | number|string | Heure de fin du segment en secondes. |
non_speech_events | string | Annotations telles que [musique], [rires]. |
emotion | string | Étiquette d'émotion. |
language | string | Code de langue (ex. "fr", "ar"). |
locale | string | Code de locale (ex. "fr-FR"). |
accent | string | Étiquette d'accent. |
Structure de la réponse
Toutes les réponses réussies utilisent cette enveloppe :
{
"status": "success",
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-04-08T21:00:00.000Z",
"data": {
"results": [
{
"status": "MODIFIED",
"originalRow": { "transcript": "Hello world", ... },
"reworkedRow": { "transcript": "Hello there", ... },
"notes": "transcript changed"
},
{
"status": "SPLIT",
"originalRow": { "transcript": "Good morning everyone", ... },
"reworkedRows": [ { "transcript": "Good morning" }, { "transcript": "everyone" } ],
"notes": "split into 2 rows"
}
],
"scores": { "CER": 0.12, "WER": 0.18, "SER": 0.33, "cerT": 0.12, "werT": 0.18 },
"composite": { "score": 3.8, "grade": "B", "label": "Good" },
"meta": { "originalRows": 2, "reworkedRows": 3, "headers": [...] }
}
}Statuts de diff
| Statut | Signification |
|---|---|
| UNCHANGED | La ligne est identique dans les deux versions. |
| MODIFIED | La ligne existe dans les deux versions mais le contenu a changé. |
| ADDED | La ligne est uniquement présente dans la version révisée. |
| DELETED | La ligne est uniquement présente dans la version originale. |
| SPLIT | Une ligne originale a été divisée en deux lignes révisées ou plus. |
| MERGED | Deux lignes originales ou plus ont été combinées en une ligne révisée. |
Scores
| Name | Type | Description |
|---|---|---|
CER | number | Taux d'erreur de caractères dans toutes les colonnes (0–1, plus bas = meilleur). |
WER | number | Taux d'erreur de mots dans toutes les colonnes (0–1). |
SER | number | Taux d'erreur de segmentation — proportion de lignes divisées ou fusionnées. |
cerT | number | CER calculé uniquement sur la colonne de transcription. |
werT | number | WER calculé uniquement sur la colonne de transcription. |
Note composite
| Name | Type | Description |
|---|---|---|
score | number | Score de qualité pondéré (1,0–5,0, plus élevé = meilleur). |
grade | string | Note alphabétique : A, B, C, D ou F. |
label | string | Étiquette lisible — ex. "Excellent", "Bon", "À améliorer". |
Options de configuration
Passez un objet config dans le corps de la requête pour remplacer les valeurs par défaut de l'algorithme. Tous les champs sont optionnels.
| Name | Type | Description |
|---|---|---|
simpleMode | boolean | Désactiver la détection des divisions et fusions. Diff ligne par ligne pur. Défaut : false. |
enableSplits | boolean | Activer la détection des lignes divisées. Défaut : true. |
enableMerges | boolean | Activer la détection des lignes fusionnées. Défaut : true. |
enableCER | boolean | Calculer le taux d'erreur de caractères. Défaut : true. |
enableWER | boolean | Calculer le taux d'erreur de mots. Défaut : true. |
enableSER | boolean | Calculer le taux d'erreur de segmentation. Défaut : true. |
stripDiacritics | boolean | Normaliser les caractères arabes/accentués avant la comparaison. Défaut : true. |
positionalMode | boolean | Comparer les lignes strictement par position, sans alignement. Défaut : false. |
ignoreColNames | string[] | Noms de colonnes exclus de la détection MODIFIED. Défaut : []. |
enableInlineDiff | boolean | Inclure transcriptDiff dans les lignes MODIFIED. Mettre false pour ignorer le diff caractère par caractère et réduire la taille de réponse. Défaut : true. |
structuralTransforms | TransformRule[] | Règles find/replace appliquées aux deux côtés avant la comparaison par similarité (max 20 règles). Défaut : []. |
Mappage des colonnes
Lorsque original / reworked sont des tableaux 2D (tableaux de tableaux) plutôt que des objets, fournissez headers et/ou columnMapping pour indiquer au moteur quel index correspond à chaque champ.
{
"original": [[0, 1, "Alice", "Hello world"]],
"headers": ["start_time", "end_time", "speaker", "transcript"],
"columnMapping": { "transcript": 3, "speaker": 2, "start_time": 0, "end_time": 1 }
}| Name | Type | Description |
|---|---|---|
transcript* | integer | Index de colonne base 0 pour le champ de transcription. |
speaker | integer | Index de colonne base 0 pour le champ du locuteur. |
start_time | integer | Index de colonne base 0 pour l'heure de début. |
end_time | integer | Index de colonne base 0 pour l'heure de fin. |
nse | integer | Index de colonne base 0 pour les événements non-vocaux. |
extraCols | integer[] | Index de colonnes supplémentaires à inclure (max 20). |
Référence des erreurs
Toutes les erreurs utilisent une enveloppe uniforme :
{
"status": "error",
"requestId": "550e8400-...",
"timestamp": "2026-04-08T21:00:00.000Z",
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": [{ "field": "original", "message": "\"original\" is required" }]
}
}| HTTP | Code | Cause |
|---|---|---|
| 400 | BAD_REQUEST | Corps JSON malformé |
| 401 | UNAUTHORIZED | En-tête x-api-key manquant ou invalide |
| 404 | NOT_FOUND | Point de terminaison inconnu |
| 413 | PAYLOAD_TOO_LARGE | Corps de requête dépasse 5 Mo |
| 422 | VALIDATION_ERROR | Échec de la validation du schéma (voir tableau details) |
| 429 | RATE_LIMIT_EXCEEDED | Limite de débit par rafale ou par fenêtre atteinte |
| 500 | INTERNAL_ERROR | Erreur serveur ou moteur inattendue |
Traçage des requêtes
Fournissez un en-tête x-request-id pour corréler les requêtes dans votre système. Caractères alphanumériques, tirets et traits de soulignement uniquement, max 64 caractères. La valeur est renvoyée dans les en-têtes de réponse.
curl -H "x-request-id: job-2026-01-batch-3" \
-H "x-api-key: YOUR_KEY" \
-X POST https://structural-diff-engine.onrender.com/v1/diff -d '{...}'Obtenir un accès API
L'API est disponible pour les agences et équipes en phase de dégustation. Les clés sont provisionnées individuellement. Contactez-nous pour recevoir votre clé et commencer l'intégration.