Aller au contenu principal

Attribution de numéros et KYC

Ce document décrit le cycle de vie complet de l’attribution d’un numéro de téléphone via la plateforme Audact, de la remise des documents de connaissance du client (KYC, « Know-Your-Customer ») jusqu’à la passation de commandes auprès de l’opérateur et à la gestion des numéros dans le pool.

La plateforme Audact gère les numéros pour le compte des tenants en s’appuyant sur l’opérateur Telnyx. Les numéros sont commandés, stockés et affectés à des agents selon un modèle en libre-service de KYC au nom du tenant : le tenant téléverse des documents de conformité réglementaire (par exemple une immatriculation d’entreprise, un justificatif de domicile), Audact les chiffre au repos et les soumet à Telnyx pour approbation ; une fois l’approbation obtenue, le tenant peut commander des numéros pour toute combinaison pays/type couverte par cette approbation. Les numéros sont facturés via le compte Telnyx de la plateforme Audact ; la connexion et la facturation sont rattachées automatiquement par la plateforme et ne sont jamais fournies par le client.

Le processus se déroule en cinq étapes logiques :

  1. Documents KYC — Téléverser, chiffrer et suivre les documents de conformité réglementaire
  2. Ensembles de documents — Regrouper les documents en ensembles d’exigences, mis en correspondance avec les exigences réglementaires de Telnyx
  3. Commandes de numéros — Passer des commandes auprès de l’opérateur pour des ensembles approuvés ; recevoir les DID dans le pool
  4. Affectation et routage — Affecter les numéros à des agents et gérer la suspension et la reprise
  5. Libération et suppression — Remettre des numéros dans le pool ou les supprimer définitivement (et les libérer auprès de l’opérateur)

Étape 1 : documents KYC

POST /v1/kyc/documents — Téléverser un document de conformité (par exemple une immatriculation d’entreprise, un justificatif de domicile).

La requête doit être de type multipart/form-data avec :

  • document (champ fichier, obligatoire) — les octets bruts du document (PDF, image, etc. ; 15 MiB maximum par document)
  • doc_type (champ de formulaire, obligatoire) — le type d’exigence réglementaire Telnyx que ce document satisfait (par exemple "business_registration", "certificate_of_authority")
  • filename (champ de formulaire, facultatif) — nom de fichier lisible ; par défaut, le nom du fichier téléversé s’il n’est pas fourni

La réponse comprend :

  • id (chaîne) — UUID unique du document
  • doc_type (chaîne) — le type tel que fourni
  • filename (chaîne) — le nom du fichier
  • content_type (chaîne) — type MIME (par exemple "application/pdf")
  • size_bytes (entier) — taille non compressée du fichier d’origine
  • sha256 (chaîne) — empreinte SHA-256 en hexadécimal minuscule des octets d’origine (valeur qui ne change pas, pour le contrôle d’intégrité)
  • telnyx_document_id (chaîne, nullable) — l’ID attribué par Telnyx si ce document a été envoyé à Telnyx
  • created_at (horodatage ISO-8601) — heure de téléversement générée par le serveur
  • updated_at (horodatage ISO-8601) — heure de la dernière modification

Important : les octets des documents ne sont JAMAIS renvoyés par l’API — seulement les métadonnées. Tous les documents sont chiffrés au repos avec la clé de chiffrement des documents KYC (DEK) du tenant ; le chiffrement est lié au tenant et à l’ID du document, de sorte que les textes chiffrés ne peuvent pas être rejoués sous une autre identité.

GET /v1/kyc/documents — Lister tous les documents KYC du tenant.

Renvoie une liste paginée de métadonnées de documents (tous les champs de la réponse POST, hors octets du fichier).

GET /v1/kyc/documents/{id} — Récupérer les métadonnées d’un seul document.

PUT /v1/kyc/documents/{id} — Remplacer un document (par exemple pour téléverser à nouveau une version corrigée ou mise à jour).

Le corps de la requête est à nouveau de type multipart/form-data, avec document et, facultativement, filename et doc_type. Le remplacement va :

  • Rechiffrer les nouveaux octets avec la version actuelle de la DEK
  • Si ce document appuie un ensemble de documents déjà soumis ou approuvé, soumettre à nouveau l’ensemble complet à Telnyx pour vérification (en envoyant les métadonnées mises à jour au groupe d’exigences)
  • Renvoyer 409 Conflict si une commande de numéros en cours fait actuellement référence à cet ensemble de documents

DELETE /v1/kyc/documents/{id} — Supprimer un document.

Renvoie 409 Conflict si une commande de numéros fait actuellement référence à l’ensemble de documents qui contient ce document (le garde-fou contre la suppression en cours de traitement évite d’orpheliner une commande). Sinon, la suppression réussit et se propage aux ensembles de documents qui utilisaient ce document.

Étape 2 : ensembles de documents et couverture des exigences

GET /v1/kyc/requirements — Consulter les exigences réglementaires en vigueur chez Telnyx pour un pays et un type de numéro.

Paramètres de requête :

  • country (obligatoire, ISO 3166-1 alpha-2 sur 2 lettres, par exemple "US")
  • number_type (obligatoire, par exemple "local" ou "mobile")

Réponse :

json

{
  "requirements": [
    {
      "requirement_id": "string",
      "doc_type": "string",
      "description": "string"
    }
  ]
}

Validation de la couverture : trois issues sont possibles :

  1. Telnyx a des exigences. La réponse énumère chaque doc_type requis. Votre ensemble de documents doit comporter au moins un document correspondant à chaque type.
  2. La récupération auprès de Telnyx a échoué. Si la plateforme ne parvient pas à joindre Telnyx pour consulter les exigences, la réponse est 503 Service Unavailable (repli en mode fermé, fail-closed). Réessayez le point de terminaison dès que Telnyx est joignable.
  3. Aucune exigence. Certaines combinaisons pays/type n’exigent aucun document (par exemple les DID existants d’un revendeur). La réponse est 200 avec un tableau requirements vide ; c’est une issue légitime, pas une erreur.

POST /v1/kyc/document-sets — Créer un ensemble de documents.

Corps de la requête :

json

{
  "country": "US",
  "number_type": "local",
  "documents": [
    {
      "requirement_id": "reg-001",
      "document_id": "uuid-of-uploaded-document"
    },
    {
      "requirement_id": "reg-002",
      "document_id": "uuid-of-another-document"
    }
  ]
}

La plateforme vérifie que :

  1. Chaque requirement_id figure dans les exigences Telnyx en vigueur pour (country, number_type)
  2. Chaque document_id fait référence à un document existant appartenant à ce tenant
  3. Chaque exigence Telnyx de la paire est satisfaite par au moins un document de l’ensemble (aucune lacune)
  4. L’ensemble n’est pas vide

Si la validation réussit, l’ensemble est soumis à Telnyx comme « groupe d’exigences » (requirement group), et la réponse comprend :

  • id (chaîne) — UUID de l’ensemble
  • country (chaîne) — code pays
  • number_type (chaîne) — le type
  • status (chaîne) — toujours "submitted" à la création
  • telnyx_requirement_group_id (chaîne) — l’ID de ce groupe chez Telnyx
  • documents (tableau) — les documents associés, avec leurs métadonnées
  • created_at (horodatage ISO-8601)
  • updated_at (horodatage ISO-8601)

Cas d’échec :

  • 400 Bad Request si les types de documents ou d’exigences sont invalides ou si la couverture est incomplète
  • 422 Unprocessable Entity si Telnyx rejette la soumission (par exemple en raison de la qualité des documents)
  • 503 Service Unavailable si Telnyx est injoignable (repli en mode fermé ; réessayez plus tard)

Approbation asynchrone : après la création, Telnyx vérifie les documents de manière asynchrone. Lorsque la vérification est terminée (en quelques heures ou quelques jours), Telnyx envoie un webhook authentifié avec event_type: "requirement_group.verified", et la plateforme met à jour atomiquement le statut de l’ensemble :

  • "approved" — Telnyx a accepté tous les documents ; l’ensemble est désormais utilisable pour des commandes de numéros
  • "rejected" — Telnyx a rejeté un ou plusieurs documents ; l’ensemble ne peut pas être utilisé ; consultez le motif du rejet et utilisez PUT pour soumettre à nouveau les documents

GET /v1/kyc/document-sets — Lister tous les ensembles de documents du tenant.

Renvoie une liste paginée comprenant, pour chacun, le statut ("submitted", "approved" ou "rejected"), le pays, number_type et les documents associés.

GET /v1/kyc/document-sets/{id} — Récupérer les détails d’un seul ensemble.

Comprend la liste complète des emplacements d’exigences et le document associé à chaque emplacement.

DELETE /v1/kyc/document-sets/{id} — Supprimer un ensemble de documents.

Renvoie 409 Conflict si une commande de numéros fait actuellement référence à cet ensemble (le garde-fou contre la suppression en cours de traitement). Sinon, la suppression réussit et se propage pour libérer le groupe d’exigences chez Telnyx.

Étape 3 : commandes de numéros

GET /v1/numbers/available — Consulter les numéros disponibles à la commande.

Paramètres de requête :

  • country (obligatoire, par exemple "US")
  • number_type (obligatoire, par exemple "local")
  • limit (facultatif, 10 par défaut)
  • area_code (facultatif, pour les numéros américains ; filtre sur un NPA précis)

La réponse renvoie une liste de DID disponibles pour une attribution immédiate :

json

{
  "available_numbers": [
    {
      "number": "+1415...",
      "region": "San Francisco, CA",
      "features": ["sms", "voice", "mms"]
    }
  ]
}

Les numéros sont récupérés en direct auprès de Telnyx à chaque requête et n’apparaîtront plus dès qu’une commande y fait référence.

POST /v1/numbers/orders — Passer une commande de numéros.

Corps de la requête :

json

{
  "document_set_id": "uuid-of-approved-set",
  "country": "US",
  "number_type": "local",
  "quantity": 5,
  "area_code": "415"
}

Paramètres :

  • document_set_id — UUID d’un ensemble de documents approuvé (statut = "approved")
  • country et number_type — doivent correspondre au pays et au type de l’ensemble (erreur de validation en cas de divergence)
  • quantity — nombre de DID à commander (généralement de 1 à 10)
  • area_code — facultatif ; filtre propre aux États-Unis

Idempotence : passez l’en-tête Idempotency-Key (n’importe quelle valeur de chaîne) ; si une requête antérieure avec la même clé a abouti, la réponse identique est rejouée. Cela garantit que des commandes passées sur un réseau instable ne produisent pas de commandes en double.

En cas de succès, la réponse est :

json

{
  "order_id": "uuid",
  "status": "pending",
  "country": "US",
  "number_type": "local",
  "quantity": 5,
  "requested_numbers": [],
  "ordered_numbers": [],
  "created_at": "2025-01-20T...",
  "updated_at": "2025-01-20T..."
}

La commande démarre au statut "pending". La plateforme soumet immédiatement la commande à l’API de Telnyx, et le statut évolue selon le cycle de vie suivant, piloté par l’envoi des webhooks Telnyx :

StatutSignification
pendingCommande acceptée localement ; en attente de traitement par Telnyx
requirement_reviewTelnyx examine la couverture de l’ensemble de documents pour le pays/type de cette commande (rare)
orderingTelnyx acquiert les numéros dans son inventaire (en cours)
successTous les numéros demandés ont été alloués ; les numéros sont désormais dans le pool
failureTelnyx n’a pas pu allouer tout ou partie des numéros (par exemple indicatif régional épuisé) ; aucun numéro n’a été créé

Cas d’échec :

  • 400 Bad Request si le pays ou le number_type sont invalides
  • 404 Not Found si l’ensemble de documents n’existe pas
  • 409 Conflict si l’ensemble de documents n’est pas approuvé (statut != "approved")
  • 422 Unprocessable Entity si la validation de la couverture échoue (par exemple documents d’exigence manquants)
  • 503 Service Unavailable si Telnyx est injoignable (repli en mode fermé ; la commande n’est pas créée)

Nouvelle validation de la couverture : avant de passer la commande, la plateforme vérifie à nouveau que l’ensemble de documents couvre toujours toutes les exigences réglementaires Telnyx en vigueur pour (country, number_type). Cela permet de repérer les changements réglementaires survenus entre l’approbation de l’ensemble et le moment de la commande. Si la couverture est désormais incomplète (Telnyx a ajouté une exigence après l’approbation de l’ensemble), la commande échoue avec 422.

Connexion et facturation automatiques : lorsque la commande atteint le statut "success" et que les numéros sont insérés dans le pool, la plateforme Audact :

  • Configure la connexion de trunk (trunk SIP Telnyx) pour ce tenant
  • Rattache la facturation au compte Telnyx géré par Audact pour le tenant
  • Définit les valeurs de routage par défaut (au départ, tous les DID sont inactifs tant qu’ils ne sont pas explicitement affectés à un agent)

Le client ne fournit ni paramètres de connexion ni informations de facturation ; la plateforme s’en charge de manière transparente.

GET /v1/numbers/orders — Lister toutes les commandes du tenant.

Renvoie une liste paginée avec le statut, le pays, le type, la quantité et les horodatages.

GET /v1/numbers/orders/{id} — Récupérer le statut d’une seule commande.

Comprend le statut complet du cycle de vie et la liste actuelle ordered_numbers (renseignée dès que le statut atteint "success").

Étape 4 : affectation et routage

Dès qu’un numéro arrive dans le pool (statut = "success" dans sa commande), il n’achemine pas encore d’appels. L’affectation rend un numéro actif pour un agent précis.

GET /v1/numbers — Lister tous les numéros du pool du tenant.

Paramètres de requête :

  • status (facultatif, filtre par état : "available", "assigned", "suspended")

La réponse comprend :

  • id — UUID du numéro
  • number — le DID au format E.164 (par exemple "+1415...")
  • country, number_type — origine
  • status — l’une des valeurs "available", "assigned" ou "suspended"
  • assigned_agent_id (nullable) — l’UUID de l’agent en cas d’affectation
  • created_at, updated_at

POST /v1/numbers/{id}/assign — Affecter un numéro à un agent.

Corps de la requête :

json

{
  "agent_id": "uuid-of-agent"
}

Réponse 200 en cas de succès, 404 si le numéro ou l’agent n’existe pas, 409 si le numéro est déjà affecté à un autre agent.

Une fois le numéro affecté, les appels entrants vers ce numéro sont acheminés vers cet agent.

DELETE /v1/numbers/{id}/assign — Retirer l’affectation d’un numéro à un agent.

Le numéro repasse à "available" et les appels ne sont plus acheminés (il reste dans le pool, mais inactif).

POST /v1/numbers/{id}/suspend — Suspendre le routage d’un numéro.

Le numéro passe au statut "suspended" ; les appels vers ce numéro sont rejetés (ils ne sont plus acheminés vers son agent, le cas échéant). Le routage peut être repris sans perdre l’affectation.

POST /v1/numbers/{id}/resume — Reprendre un numéro suspendu.

Le numéro revient à son statut antérieur ("assigned" s’il était affecté, ou "available" s’il ne l’était pas) et le routage est rétabli.

Étape 5 : libération et suppression

Il existe deux opérations de retrait distinctes :

DELETE /v1/numbers/{id}/release — Remettre le numéro dans le pool (suppression logique).

  • Efface l’affectation à l’agent (le cas échéant)
  • Passe au statut "available"
  • Ne supprime PAS définitivement le numéro et ne libère PAS le DID chez Telnyx
  • Le numéro reste utilisable pour une future affectation

Cette opération s’utilise lorsqu’un agent n’a plus besoin du numéro mais que vous souhaitez le conserver dans votre pool pour le réaffecter ou pour planifier.

DELETE /v1/numbers/{id} — Supprimer définitivement le numéro (suppression définitive).

  • Retire entièrement le numéro du pool
  • Remet le DID dans l’inventaire de Telnyx (irréversible)
  • Met fin immédiatement à la facturation de ce numéro
  • Le DID ne pourra plus jamais être appelé

Cette opération est irréversible ; utilisez release si vous souhaitez que le numéro reste joignable pour une future réaffectation. Une fois supprimé, le numéro disparaît de la plateforme et du pool de l’opérateur.


Sémantique des erreurs et idempotence

Repli en mode fermé et repli en mode ouvert (fail-closed et fail-open)

Toutes les opérations de KYC et de commande sont en repli en mode fermé (fail-closed) : si la plateforme ne peut pas joindre Telnyx (erreur réseau, délai dépassé, panne de Telnyx), la requête échoue avec 503 Service Unavailable. Aucun état partiel n’est créé ; une nouvelle tentative une fois Telnyx joignable ne produit pas de doublons (grâce à la prise en charge d’Idempotency-Key sur les points de terminaison qui modifient l’état).

Idempotency-Key

Passez l’en-tête Idempotency-Key sur :

  • POST /v1/kyc/documents — téléverser un document
  • PUT /v1/kyc/documents/{id} — remplacer un document
  • POST /v1/numbers/orders — passer une commande

Deux requêtes quelconques ayant la même clé dans un délai de 24 heures (ou de la fenêtre d’idempotence que vous avez configurée) renvoient la même réponse. Cela permet de rejouer des requêtes en toute sécurité après une panne réseau, sans créer de doublons.

Conflit d’utilisation (409)

Les ensembles de documents et les documents sont protégés contre la suppression tant qu’une commande en cours y fait référence :

  • DELETE /v1/kyc/documents/{id} renvoie 409 si l’un de ses ensembles a une commande active
  • DELETE /v1/kyc/document-sets/{id} renvoie 409 si une commande active fait référence à l’ensemble

Une commande « active » est une commande dont le statut est dans {pending, requirement_review, ordering} ; dès qu’une commande atteint un statut terminal (success ou failure), l’ensemble n’est plus « en cours de traitement » et peut être supprimé sans risque.

Portée de la couverture (422)

  • POST /v1/kyc/document-sets renvoie 422 si la couverture est incomplète (une exigence Telnyx n’a aucun document correspondant)
  • POST /v1/numbers/orders renvoie 422 si la couverture a changé depuis l’approbation de l’ensemble (Telnyx a ajouté une nouvelle exigence)

Ces deux cas sont modélisés comme des entités non traitables (Unprocessable Entity) afin de les distinguer de 400 (paramètres de requête incorrects) et de 503 (backend indisponible).

Type inconnu (400)

  • POST /v1/kyc/documents avec un doc_type invalide renvoie 400 Bad Request
  • POST /v1/kyc/document-sets avec un ID d’exigence invalide ou une combinaison pays/type invalide renvoie 400

Ce sont des requêtes mal formées, pas des problèmes de couverture.

Telnyx injoignable (503)

Chaque fois que Telnyx est injoignable :

  • Le téléversement POST /v1/kyc/documents (avant le chiffrement) renvoie 503 si la récupération ultérieure des métadonnées auprès de Telnyx échoue
  • PUT /v1/kyc/documents/{id} (pendant la nouvelle vérification) renvoie 503 si Telnyx est injoignable
  • GET /v1/kyc/requirements renvoie 503 si Telnyx ne peut pas être interrogé
  • POST /v1/kyc/document-sets renvoie 503 si la soumission à Telnyx échoue
  • POST /v1/numbers/orders renvoie 503 si la soumission de la commande à Telnyx échoue

Dans tous les cas, la plateforme n’entre pas dans un état partiel ; réessayez une fois Telnyx joignable.

Source mise à jour: 19 octobre 2026