HTTP API v1
Accès programmatique aux numéros de téléphone, appels, SMS, messageries vocales et fonctionnalités IA. JSON via HTTPS. Idempotent là où ça compte. Pas de SDK requis, mais nous en fournissons 5.
Introduction
L'API NoKYCNumber est organisée autour de REST. Nous utilisons des URLs orientées ressources prévisibles, acceptons et retournons des corps encodés en JSON, et utilisons des codes de réponse HTTP standard, l'authentification et les verbes.
URL de base
https://api.nokycnumber.com/v1/Toutes les requêtes doivent être effectuées via HTTPS. Les appels en HTTP simple échoueront avec 301 Moved Permanently. Les requêtes sans authentification échoueront avec 401 Unauthenticated.
Convention JSON
- Toutes les requêtes avec un corps utilisent
Content-Type: application/json. Les corps encodés en formulaire sont rejetés avec415. - Les horodatages sont retournés sous forme de chaînes ISO-8601 UTC (
2026-04-26T14:23:00Z) et acceptés dans le même format. - Les numéros de téléphone sont retournés en format E.164 avec un
+initial (+33647189022) et formatés lisiblement dansdisplaysi pertinent. - Les identifiants d'objets sont préfixés par leur ressource :
num_,call_,sms_,vm_,whk_,evt_.
Authentification
Authentifiez-vous avec une clé bearer émise depuis votre panel sous Paramètres → Clés API. Deux types de clés existent :
sk_live_…— secret côté serveur. Accès complet lecture/écriture. Ne jamais exposer dans le code client.pk_live_…— clé publique. Actuellement réservée ; non utilisée par aucun endpoint pour l'instant.
Format d'en-tête
Authorization: Bearer sk_live_5f3a8b2c4d1e9f6a7b8c2d1e9f6a7b8c
Content-Type: application/json
NoKYC-Version: 2026-04-01Utilisez l'en-tête NoKYC-Version pour vous fixer à une version spécifique de l'API (voir Versionnement). Si omis, le défaut fixé de votre compte est utilisé.
Portées
Les clés sont émises avec l'une des trois portées :
| Portée | Méthodes autorisées | Cas d'usage |
|---|---|---|
read | GET | Reporting, tableaux de bord de surveillance. |
read_write | GET · POST · PATCH | La majorité des intégrations côté serveur. |
admin | Tout y compris DELETE | Automatisation du provisionnement, gestion de compte. |
Les clés peuvent être renouvelées à tout moment. Les anciennes clés restent valides 5 minutes après le renouvellement pour permettre un déploiement sans interruption.
Erreurs
L'API utilise des codes de statut HTTP conventionnels. 2xx signifie succès, 4xx signifie un problème avec votre requête, 5xx signifie que nous avons commis une erreur et nous voulons en être informés.
Enveloppe d'erreur
{
"error": {
"type": "invalid_request_error",
"code": "parameter_missing",
"message": "Required parameter `country` is missing.",
"param": "country",
"request_id": "req_8a4c2f1e9b3d4a7c"
}
}Codes de statut
| Code | Signification |
|---|---|
200 | OK · requête réussie |
201 | Created · ressource créée |
204 | No Content · ressource supprimée, aucun corps retourné |
400 | Bad Request · JSON malformé ou paramètre requis manquant |
401 | Unauthenticated · clé API invalide, manquante ou révoquée |
402 | Payment Required · solde du compte insuffisant pour cette action |
403 | Forbidden · la clé n'a pas la portée requise pour cette opération |
404 | Not Found · la ressource n'existe pas ou appartient à un autre compte |
409 | Conflict · clé d'idempotence réutilisée avec des paramètres différents |
422 | Unprocessable · erreur sémantique (ex. pays non supporté) |
429 | Too Many Requests · voir Limites de débit |
500 – 503 | Problème serveur / service · sûr à retenter avec backoff |
Types d'erreurs
invalid_request_error— requête malformée, champs manquants, format invalide.authentication_error— problème de clé.authorization_error— problème de portée.rate_limit_error— ralentissez.api_error— erreur de notre côté. Réessayable.resource_error— l'état de la ressource empêche l'opération (ex. : appel depuis un numéro suspendu).upstream_error— l'opérateur ou le partenaire n'a pas répondu à temps.
Chaque réponse d'erreur inclut un request_id. Loggez-le toujours — c'est le seul moyen pour notre support de corréler votre appel avec notre trace interne.
Pagination
Les endpoints de liste utilisent une pagination par curseur en avant uniquement. Ils retournent jusqu'à limit objets (défaut 25, max 100) et un booléen has_more. Pour obtenir la page suivante, passez l'id du dernier objet en starting_after.
curl https://api.nokycnumber.com/v1/numbers?limit=10 \
-H "Authorization: Bearer sk_live_…"{
"object": "list",
"url": "/v1/numbers",
"data": [
{ "id": "num_8a4c2f1e9b3d", "object": "number", "number": "+33647189022", … },
{ "id": "num_2k7m9p3w8x4t", "object": "number", "number": "+12025550143", … }
],
"has_more": true,
"next_cursor": "num_2k7m9p3w8x4t"
}Les listes sont triées avec les objets les plus récemment créés en premier. La pagination en arrière via ending_before n'est pas supportée — utilisez le curseur à la place.
Idempotence
Les requêtes POST qui modifient l'état acceptent un en-tête Idempotency-Key. Nous dédupliquons sur la clé pendant 24 heures, retournant la réponse mise en cache pour les nouvelles tentatives. Utilisez un UUID par opération logique.
POST /v1/sms HTTP/1.1
Authorization: Bearer sk_live_…
Idempotency-Key: 9b3d4a7c-8a4c-2f1e-9b3d-4a7c8a4c2f1e
Content-Type: application/json
{ "from": "num_8a4c2f1e9b3d", "to": "+33612345678", "body": "Hello" }Rejouer la même clé avec un contenu de corps différent retourne 409 Conflict avec idempotency_key_mismatch.
Les clés d'idempotence ne sont pas obligatoires, mais fortement recommandées pour toute opération payante (appels, SMS, achats de numéros). Sans elles, une nouvelle tentative réseau peut vous facturer deux fois.
Limites de débit
Par défaut, chaque clé API est limitée à 100 requêtes par minute. Les clients à fort volume peuvent demander une augmentation via le support. Les limites s'appliquent par clé, pas par IP.
En-têtes de réponse
X-Rate-Limit-Limit: 100
X-Rate-Limit-Remaining: 73
X-Rate-Limit-Reset: 1745672460
Retry-After: 8Lorsque vous dépassez la limite, vous recevez 429 Too Many Requests avec un en-tête Retry-After en secondes. Un backoff linéaire jusqu'à 4 tentatives est recommandé ; si ça persiste, demandez une limite plus élevée.
Tolérance aux pics
Le limiteur est un token bucket — les courtes rafales au-dessus de 100 req/min sont tolérées tant que la moyenne glissante sur 60 secondes reste sous le plafond.
Versionnement
Les versions API sont datées (2026-04-01). Les changements non rétrocompatibles sont publiés dans une nouvelle version datée ; les ajouts rétrocompatibles sont intégrés à la version actuelle. Fixez une version avec l'en-tête NoKYC-Version.
Compatibilité
- Nous supportons chaque version pendant au moins 24 mois après la sortie de la suivante.
- Les avis d'obsolescence sont envoyés par email aux propriétaires de compte 90 jours à l'avance.
- Un en-tête de réponse
NoKYC-Deprecationvous avertit si vous utilisez une version obsolète.
Version actuelle : 2026-04-01.
Numéros
Un numéro représente une ligne téléphonique virtuelle que vous contrôlez. Les numéros sont liés à un pays et à un type (mobile ou landline) et portent une période de facturation.
/v1/numbers
Liste tous les numéros de votre compte. Retourne une liste paginée d'objets number.
| Field | Type | Description |
|---|---|---|
limit optionnel | integer | 1–100, défaut 25. |
starting_after optionnel | string | Curseur pour la pagination. |
country optionnel | string | Filtrez par code pays ISO-2 (ex. fr). |
type optionnel | string | Filtrez par mobile ou landline. |
status optionnel | string | Filtrez par active, paused, ou released. |
curl https://api.nokycnumber.com/v1/numbers?country=fr&type=mobile \
-H "Authorization: Bearer sk_live_…"{
"object": "list",
"data": [
{
"id": "num_8a4c2f1e9b3d",
"object": "number",
"number": "+33647189022",
"display": "+33 6 47 18 90 22",
"country": "fr",
"type": "mobile",
"tier": "standard",
"status": "active",
"billing_period": "yearly",
"renews_at": "2027-04-26T11:23:00Z",
"ai_enabled": true,
"created_at": "2026-04-26T11:23:00Z"
}
],
"has_more": false,
"next_cursor": null
}/v1/numbers/available
Recherchez dans l'inventaire les numéros disponibles pour un pays et un type donnés. Utilisez l'identifiant retourné lors de l'appel à POST /v1/numbers.
| Field | Type | Description |
|---|---|---|
country requis | string | Code pays ISO-2. |
type requis | string | mobile ou landline. |
tier optionnel | string | standard (défaut) ou premium. |
pattern optionnel | string | Filtre optionnel sur une sous-chaîne de chiffres locaux, ex. "77". |
limit optionnel | integer | 1–50, défaut 10. |
curl "https://api.nokycnumber.com/v1/numbers/available?country=fr&type=mobile&tier=premium&limit=5" \
-H "Authorization: Bearer sk_live_…"{
"object": "list",
"data": [
{ "id": "navail_2k7m9p3w8x4t", "number": "+33611112222", "display": "+33 6 11 11 22 22", "tier": "premium", "pattern": "double-repeat", "price_usd_per_month": 11.98 },
{ "id": "navail_4n2v8j1q6h7y", "number": "+33612345678", "display": "+33 6 12 34 56 78", "tier": "premium", "pattern": "sequential", "price_usd_per_month": 11.98 }
],
"expires_at": "2026-04-26T11:33:00Z"
}Les numéros disponibles sont réservés 10 minutes. Après expiration, le même identifiant peut être attribué à un autre client.
/v1/numbers
Activez un nouveau numéro à partir d'un identifiant de réservation. Débite la période configurée sur le solde de votre compte.
| Field | Type | Description |
|---|---|---|
available_id requis | string | Un identifiant navail_… issu de /v1/numbers/available. |
billing_period requis | string | monthly, quarterly, ou yearly. |
addons optionnel | array | Modules IA à activer, ex. ["ai-pickup","ai-trans"]. |
webhook_url optionnel | string | Endpoint qui recevra les événements liés au numéro. |
curl https://api.nokycnumber.com/v1/numbers \
-H "Authorization: Bearer sk_live_…" \
-H "Idempotency-Key: 9b3d4a7c-8a4c-2f1e-9b3d-4a7c8a4c2f1e" \
-d '{
"available_id": "navail_2k7m9p3w8x4t",
"billing_period": "yearly",
"addons": ["ai-pickup"]
}'{
"id": "num_8a4c2f1e9b3d",
"object": "number",
"number": "+33611112222",
"display": "+33 6 11 11 22 22",
"country": "fr",
"type": "mobile",
"tier": "premium",
"status": "active",
"billing_period": "yearly",
"renews_at": "2027-04-26T11:23:00Z",
"ai_enabled": true,
"created_at": "2026-04-26T11:23:00Z"
}/v1/numbers/{id}
Récupérez un numéro unique par identifiant.
curl https://api.nokycnumber.com/v1/numbers/num_8a4c2f1e9b3d \
-H "Authorization: Bearer sk_live_…"/v1/numbers/{id}
Mettez à jour les champs modifiables d'un numéro. Utilisez POST /v1/numbers/{id}/renew pour prolonger la période.
| Field | Type | Description |
|---|---|---|
auto_renew optionnel | boolean | Activez/désactivez le renouvellement automatique en fin de période. |
webhook_url optionnel | string | Remplacez la cible webhook liée au numéro. |
addons optionnel | array | Remplacez l'ensemble actif de modules IA. |
on_off optionnel | object | Définissez des heures silencieuses / fenêtres off. Voir configuration IA. |
/v1/numbers/{id}
Libérez un numéro. Le numéro retourne à l'inventaire en fin de période et peut être réattribué à un autre client. Retourne 204 No Content.
curl -X DELETE https://api.nokycnumber.com/v1/numbers/num_8a4c2f1e9b3d \
-H "Authorization: Bearer sk_live_…"Les numéros libérés ne peuvent pas être récupérés. Nous recommandons de suspendre d'abord via PATCH avec { "status": "paused" } si vous souhaitez peut-être le récupérer.
Appels
Un appel est une session vocale unique émise depuis l'un de vos numéros. Les appels sortants sont passés via POST /v1/calls ; les appels entrants sont mirrorés vers votre webhook et récupérables via l'API.
/v1/callsPassez un appel sortant depuis l'un de vos numéros.
| Field | Type | Description |
|---|---|---|
from requis | string | Un identifiant num_ qui vous appartient. |
to requis | string | Destination E.164, ex. +33612345678. |
recording_enabled optionnel | boolean | Défaut false. Les enregistrements sont conservés 30 jours. |
callerid_mask optionnel | string | "hide", "rotate", ou tout numéro E.164 que vous possédez. |
metadata optionnel | object | JSON arbitraire retourné dans les webhooks pour l'appel. |
curl https://api.nokycnumber.com/v1/calls \
-H "Authorization: Bearer sk_live_…" \
-d '{
"from": "num_8a4c2f1e9b3d",
"to": "+33612345678",
"callerid_mask": "rotate"
}'{
"id": "call_2k7m9p3w8x4t",
"object": "call",
"from": "num_8a4c2f1e9b3d",
"from_e164": "+33647189022",
"to": "+33612345678",
"status": "ringing",
"direction": "outbound",
"started_at": "2026-04-26T11:24:01Z",
"answered_at": null,
"ended_at": null,
"duration_sec": 0,
"recording_url": null,
"cost_usd": null
}/v1/callsListe les appels. Filtrez par number, direction, status, ou created_after / created_before.
/v1/calls/{id}Récupérez un appel unique.
/v1/calls/{id}/hangupTerminer de force un appel en cours. Idempotent.
Messages SMS
Envoyez et récupérez des SMS. Les messages longs sont auto-segmentés selon les règles GSM-03.38 / UCS-2 ; la réponse indique le nombre réel de segments pour la facturation.
/v1/smsEnvoyez un SMS depuis l'un de vos numéros.
| Field | Type | Description |
|---|---|---|
from requis | string | Un identifiant num_ qui vous appartient. |
to requis | string | Destination E.164. |
body requis | string | Corps du message. 1 600 caractères max (10 segments). |
send_at optionnel | string | Horodatage futur ISO-8601 pour planifier l'envoi. |
media_urls optionnel | array | Jusqu'à 5 URLs d'images/vidéos. MMS uniquement — fonctionne dans les pays compatibles. |
curl https://api.nokycnumber.com/v1/sms \
-H "Authorization: Bearer sk_live_…" \
-H "Idempotency-Key: 9b3d4a7c-8a4c-2f1e-9b3d-4a7c8a4c2f1e" \
-d '{
"from": "num_8a4c2f1e9b3d",
"to": "+33612345678",
"body": "Bonjour. Your code is 482917."
}'{
"id": "sms_4n2v8j1q6h7y",
"object": "sms",
"from_e164": "+33647189022",
"to": "+33612345678",
"body": "Bonjour. Your code is 482917.",
"direction": "outbound",
"segments": 1,
"status": "queued",
"created_at": "2026-04-26T11:24:50Z",
"delivered_at": null,
"cost_usd": 0.012
}/v1/smsListe les messages. Filtrez par number, direction, status.
/v1/sms/{id}Récupérez un message unique incluant le statut de livraison par segment.
Messageries vocales
Les messageries vocales sont stockées, transcrites et traduites automatiquement. Les URLs audio sont pré-signées et expirent 1 heure après leur émission.
/v1/voicemailsListe les messageries vocales. Pagination identique aux autres endpoints de liste.
/v1/voicemails/{id}Récupérez une messagerie vocale unique avec sa transcription et son URL audio.
{
"id": "vm_5p3w8x4t9k2m",
"object": "voicemail",
"number_id": "num_8a4c2f1e9b3d",
"from_e164": "+33612345678",
"received_at": "2026-04-26T11:25:42Z",
"duration_sec": 27,
"audio_url": "https://files.nokycnumber.com/vm/5p3w8x4t9k2m.mp3?expires=1745676342&sig=…",
"transcript": {
"text": "Bonjour, c'est Marc. Rappelez-moi quand vous pouvez.",
"language": "fr",
"translation_en": "Hello, this is Marc. Call me back when you can.",
"summary": "Marc asks for a callback.",
"sentiment": "neutral"
}
}translation_en et summary nécessitent tous deux le module ai-summary.
/v1/voicemails/{id}Supprimez définitivement une messagerie vocale et son fichier audio. Retourne 204 No Content.
Configuration IA
Chaque numéro peut faire tourner un agent IA qui décroche les appels à votre place, filtre les appelants inconnus, résume les messageries vocales ou traduit les conversations en direct. Configurez par numéro via la sous-ressource IA.
/v1/numbers/{id}/aiRécupérez la configuration IA actuelle d'un numéro.
{
"object": "ai_config",
"number_id": "num_8a4c2f1e9b3d",
"addons": ["ai-pickup", "ai-summary"],
"auto_pickup": {
"enabled": true,
"after_rings": 4,
"script": "I'm unavailable right now. Leave your name, the reason for the call, and a callback number.",
"language": "auto",
"voice": "neutral_fr"
},
"screening": { "enabled": false },
"translator": { "enabled": false, "target_language": "en" },
"voicemail_summary": { "enabled": true, "include_sentiment": true }
}/v1/numbers/{id}/aiMettez à jour une ou plusieurs fonctionnalités IA. Chaque bloc est optionnel ; seuls les champs présents sont mis à jour.
Voix
Voix disponibles : neutral_en, neutral_fr, neutral_es, neutral_de, neutral_jp, warm_en, warm_fr. Voix clonées sur mesure pour les entreprises sur demande.
Compte
Lire les données au niveau du compte : solde, statistiques d'utilisation, webhooks configurés.
/v1/accountRécupérez votre compte.
{
"object": "account",
"email_hash": "9b3d4a7c8a4c2f1e",
"balance_usd": 47.32,
"default_country": "fr",
"active_numbers": 3,
"monthly_call_minutes": 412,
"monthly_sms_segments": 1820,
"created_at": "2026-04-12T09:15:00Z"
}/v1/account/usageDétail de l'utilisation pour la période en cours. Passez period=last_30d ou period=last_90d.
Webhooks
Abonnez-vous aux événements de votre compte ou de numéros spécifiques. Nous envoyons un événement JSON en POST vers votre endpoint et réessayons jusqu'à 5 fois avec un backoff exponentiel sur 24 heures.
Enveloppe d'événement
{
"id": "evt_3d4a7c8a4c2f",
"object": "event",
"type": "sms.received",
"created": "2026-04-26T11:25:42Z",
"livemode": true,
"data": { "object": { "id": "sms_…", … } },
"request_id": "req_8a4c2f1e9b3d4a7c"
}Vérification de signature
Chaque requête porte un en-tête X-NoKYC-Signature sous la forme t=<ts>,v1=<hex>. La signature est un HMAC-SHA256 de <ts>.<raw_body> avec le secret de signature de l'endpoint. Rejetez toute requête de plus de 5 minutes.
# Pseudocode
ts, v1 = parse(header)
if abs(now - ts) > 300: reject
expected = hmac_sha256(secret, f"{ts}.{body}")
if not constant_time_eq(expected, v1): rejectPoints de terminaison
/v1/webhook_endpointsEnregistrez un nouvel endpoint webhook. Retourne le secret de signature une seule fois ; conservez-le.
| Field | Type | Description |
|---|---|---|
url requis | string | URL HTTPS vers laquelle nous enverrons les événements en POST. |
enabled_events requis | array | Liste d'abonnement, ex. ["sms.received","call.completed"]. Utilisez ["*"] pour tout. |
description optionnel | string | Note libre pour votre comptabilité personnelle. |
/v1/webhook_endpointsListez vos endpoints.
/v1/webhook_endpoints/{id}Supprimez un endpoint. Retourne 204.
Types d'événements
| Événement | Déclenché quand |
|---|---|
number.activated | Un nouveau numéro est provisionné et prêt. |
number.renewed | Renouvellement de période réussi. |
number.paused | Le numéro est entré en état de pause (fenêtre on/off). |
number.released | Numéro définitivement restitué à l'inventaire. |
call.initiated | Appel sortant passé. |
call.answered | Le correspondant a décroché. |
call.completed | Appel terminé (pour toute raison). |
call.recorded | L'enregistrement est terminé et disponible. |
sms.received | Un SMS entrant a atteint votre numéro. |
sms.sent | SMS sortant accepté par l'opérateur. |
sms.delivered | Accusé de réception opérateur confirmé. |
sms.failed | Rejeté par l'opérateur — vérifiez failure_code. |
voicemail.created | Nouvelle messagerie vocale enregistrée et transcrite. |
ai.pickup | Le décroché automatique IA a répondu à un appel. |
account.balance_low | Le solde est passé sous votre seuil configuré. |
Schémas d'objets
number
{
"id": "string · num_…",
"object": "string · constant \"number\"",
"number": "string · E.164",
"display": "string · pretty-printed",
"country": "string · ISO-2",
"type": "enum · mobile | landline",
"tier": "enum · standard | premium",
"tier_pattern": "string | null · double-repeat | sequential | mirror | round | …",
"status": "enum · active | paused | released",
"billing_period": "enum · monthly | quarterly | yearly",
"renews_at": "string · ISO-8601 UTC",
"auto_renew": "boolean",
"addons": "array · ai-pickup | ai-screen | ai-summary | ai-trans",
"ai_enabled": "boolean",
"metadata": "object | null",
"created_at": "string · ISO-8601 UTC"
}call
{
"id": "string · call_…",
"object": "string · constant \"call\"",
"from": "string · num_…",
"from_e164": "string · E.164",
"to": "string · E.164",
"direction": "enum · inbound | outbound",
"status": "enum · queued | ringing | in_progress | completed | failed | no_answer | busy",
"started_at": "string · ISO-8601 UTC",
"answered_at": "string | null",
"ended_at": "string | null",
"duration_sec": "integer",
"recording_url": "string | null · pre-signed, expires in 1h",
"cost_usd": "number | null"
}sms
{
"id": "string · sms_…",
"object": "string · constant \"sms\"",
"from": "string · num_…",
"from_e164": "string · E.164",
"to": "string · E.164",
"body": "string",
"media_urls": "array · up to 5",
"direction": "enum · inbound | outbound",
"segments": "integer · 1–10",
"status": "enum · queued | sent | delivered | failed | undelivered",
"failure_code": "string | null",
"created_at": "string · ISO-8601 UTC",
"delivered_at": "string | null",
"cost_usd": "number | null"
}SDK officiels
L'HTTP API est la source de vérité, mais ces SDK vous offrent des liaisons typées, des nouvelles tentatives, l'idempotence et la vérification des webhooks prêts à l'emploi.
-
node
npm install @nokycnumber/sdk -
python
pip install nokycnumber -
go
go get github.com/nokycnumber/sdk-go -
php
composer require nokycnumber/sdk -
ruby
gem install nokycnumber