NOKYCNUMBER

HTTP API v1

Acceso programático a números de teléfono, llamadas, SMS, buzones de voz y funciones de IA. JSON sobre HTTPS. Idempotente cuando importa. No se requiere SDK, pero enviamos 5.

Introducción

La API de NoKYCNumber está organizada en torno a REST. Usamos URLs orientadas a recursos predecibles, aceptamos y devolvemos cuerpos codificados en JSON, y usamos códigos de respuesta HTTP estándar, autenticación y verbos.

URL base

http
https://api.nokycnumber.com/v1/

Todas las peticiones deben realizarse mediante HTTPS. Las llamadas por HTTP simple fallarán con 301 Moved Permanently. Las peticiones sin autenticación fallarán con 401 Unauthenticated.

Convención JSON

  • Todas las peticiones con cuerpo usan Content-Type: application/json. Los cuerpos codificados como formulario se rechazan con 415.
  • Las marcas de tiempo se devuelven como cadenas ISO-8601 UTC (2026-04-26T14:23:00Z) y se aceptan en el mismo formato.
  • Los números de teléfono se devuelven en formato E.164 con un + inicial (+33647189022) y formateados en display cuando sea relevante.
  • Los IDs de objeto llevan el prefijo de su recurso: num_, call_, sms_, vm_, whk_, evt_.

Autenticación

Autentícate con una clave bearer emitida desde tu panel en Ajustes → Claves API. Existen dos tipos de clave:

  • sk_live_… — secreto del lado del servidor. Lectura/escritura completa. Nunca expongas en código del cliente.
  • pk_live_… — clave publicable. Actualmente reservada; aún no utilizada por ningún endpoint.

Formato de cabecera

http
Authorization: Bearer sk_live_5f3a8b2c4d1e9f6a7b8c2d1e9f6a7b8c
Content-Type: application/json
NoKYC-Version: 2026-04-01

Usa la cabecera NoKYC-Version para fijar una versión específica de la API (ver Versiones). Si se omite, se usa el predeterminado fijado de tu cuenta.

Alcances

Las claves se emiten con uno de tres alcances:

AlcanceMétodos permitidosCaso de uso
readGETInformes, paneles de monitorización.
read_writeGET · POST · PATCHLa mayoría de las integraciones del lado del servidor.
adminTodo incluyendo DELETEAutomatización de aprovisionamiento, gestión de cuentas.

Las claves se pueden rotar en cualquier momento. Las claves antiguas siguen siendo válidas durante 5 minutos tras la rotación para permitir despliegues sin tiempo de inactividad.

Errores

La API usa códigos de estado HTTP convencionales. 2xx significa éxito, 4xx significa un problema con tu solicitud, 5xx significa que cometimos un error y nos gustaría saberlo.

Sobre de error

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "Required parameter `country` is missing.",
    "param": "country",
    "request_id": "req_8a4c2f1e9b3d4a7c"
  }
}

Códigos de estado

CódigoSignificado
200OK · solicitud exitosa
201Creado · recurso creado
204Sin contenido · recurso eliminado, sin cuerpo devuelto
400Solicitud incorrecta · JSON malformado o parámetro requerido faltante
401Sin autenticar · clave API inválida, faltante o revocada
402Pago requerido · saldo de cuenta insuficiente para la acción
403Prohibido · la clave no tiene el alcance necesario para esta operación
404No encontrado · el recurso no existe o pertenece a otra cuenta
409Conflicto · clave de idempotencia reutilizada con parámetros diferentes
422No procesable · error semántico (p.ej. país no soportado)
429Demasiadas solicitudes · ver Límites de velocidad
500503Problema de servidor / servicio · seguro reintentar con retroceso exponencial

Tipos de error

  • invalid_request_error — entrada malformada, campos faltantes, formato inválido.
  • authentication_error — problema con la clave.
  • authorization_error — problema de alcance.
  • rate_limit_error — reduce la velocidad.
  • api_error — error nuestro. Reintentable.
  • resource_error — el estado del recurso impide la operación (p.ej., intentar realizar una llamada desde un número pausado).
  • upstream_error — el operador o socio superó el tiempo de espera.

Cada respuesta de error incluye un request_id. Regístralo siempre — es la única forma de que nuestro soporte pueda correlacionar tu llamada con nuestra traza interna.

Paginación

Los endpoints de lista usan paginación de cursor solo hacia adelante. Devuelven hasta limit objetos (por defecto 25, máx. 100) y un booleano has_more. Para obtener la página siguiente, pasa el id del último objeto como starting_after.

curl
curl https://api.nokycnumber.com/v1/numbers?limit=10 \
  -H "Authorization: Bearer sk_live_…"
json
{
  "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"
}

Las listas están ordenadas con los objetos más recientes primero. La paginación hacia atrás mediante ending_before no está soportada — navega mediante el cursor.

Idempotencia

Las peticiones POST que modifican estado aceptan una cabecera Idempotency-Key. Deduplicamos por la clave durante 24 horas, devolviendo la respuesta en caché para reintentos. Usa un UUID por operación lógica.

http
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" }

Reutilizar la misma clave con contenido de cuerpo diferente devuelve 409 Conflict con idempotency_key_mismatch.

Las claves de idempotencia no son obligatorias, pero se recomiendan encarecidamente para cualquier operación que tenga coste (llamadas, SMS, compras de números). Sin una, un reintento de red puede cobrarte dos veces.

Límites de velocidad

Por defecto, cada clave API está limitada a 100 solicitudes por minuto. Los clientes de alto volumen pueden solicitar un aumento al soporte. Los límites se aplican por clave, no por IP.

Cabeceras de respuesta

http
X-Rate-Limit-Limit: 100
X-Rate-Limit-Remaining: 73
X-Rate-Limit-Reset: 1745672460
Retry-After: 8

Cuando superas el límite, recibes 429 Too Many Requests con una cabecera Retry-After en segundos. Se recomienda un retroceso lineal de hasta 4 reintentos; si persiste, solicita un límite más alto.

Margen de ráfaga

El limitador es un cubo de tokens — se toleran ráfagas cortas por encima de 100 rpm siempre que el promedio móvil de 60 segundos se mantenga por debajo del límite.

Versiones

Las versiones de la API tienen fecha (2026-04-01). Los cambios incompatibles se publican como una nueva versión con fecha; las adiciones compatibles se incluyen en la actual. Fija una versión con la cabecera NoKYC-Version.

Compatibilidad

  • Damos soporte a cada versión durante al menos 24 meses después del siguiente lanzamiento.
  • Los avisos de obsolescencia se envían por email a los propietarios de cuentas con 90 días de antelación.
  • Una cabecera de respuesta NoKYC-Deprecation avisa cuando estás en una versión obsoleta.

Versión actual: 2026-04-01.

Números

Un número representa una línea telefónica virtual que controlas. Los números están vinculados a un país y un tipo (mobile o landline) y tienen un período de facturación.

GET /v1/numbers

Lista todos los números de tu cuenta. Devuelve una lista paginada de objetos number.

FieldTipoDescription
limit opcionalinteger1–100, por defecto 25.
starting_after opcionalstringCursor para paginación.
country opcionalstringFiltra por código de país ISO-2 (p.ej. fr).
type opcionalstringFiltra por mobile o landline.
status opcionalstringFiltra por active, paused o released.
curl
curl https://api.nokycnumber.com/v1/numbers?country=fr&type=mobile \
  -H "Authorization: Bearer sk_live_…"
json
{
  "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
}
POST /v1/numbers

Activa un número nuevo a partir de un id de reserva. Carga el período configurado en el saldo de tu cuenta.

FieldTipoDescription
available_id requeridostringUn id navail_… de /v1/numbers/available.
billing_period requeridostringmonthly, quarterly, o yearly.
addons opcionalarrayComplementos de IA a activar, p.ej. ["ai-pickup","ai-trans"].
webhook_url opcionalstringEndpoint que recibirá los eventos del número.
curl
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"]
  }'
json
{
  "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"
}
GET /v1/numbers/{id}

Recupera un número individual por id.

curl
curl https://api.nokycnumber.com/v1/numbers/num_8a4c2f1e9b3d \
  -H "Authorization: Bearer sk_live_…"
PATCH /v1/numbers/{id}

Actualiza campos modificables de un número. Usa POST /v1/numbers/{id}/renew para extender el período.

FieldTipoDescription
auto_renew opcionalbooleanActiva/desactiva la renovación automática al final del período.
webhook_url opcionalstringReemplaza el destino del webhook del número.
addons opcionalarrayReemplaza el conjunto activo de complementos de IA.
on_off opcionalobjectEstablece horas silenciosas / ventanas desactivadas. Consulta Configuración de IA.
DELETE /v1/numbers/{id}

Libera un número. El número vuelve al inventario al final del período y puede ser reasignado a otro cliente. Devuelve 204 No Content.

curl
curl -X DELETE https://api.nokycnumber.com/v1/numbers/num_8a4c2f1e9b3d \
  -H "Authorization: Bearer sk_live_…"

Los números liberados no pueden recuperarse. Recomendamos pausar primero mediante PATCH con { "status": "paused" } si podrías querer recuperarlo.

Llamadas

Una llamada es una sesión de voz iniciada desde uno de tus números. Las llamadas salientes se realizan mediante POST /v1/calls; las entrantes se replican a tu webhook y también son recuperables a través de la API.

POST/v1/calls

Realiza una llamada saliente desde uno de tus números.

FieldTipoDescription
from requeridostringUn id num_ que posees.
to requeridostringDestino E.164, p.ej. +33612345678.
recording_enabled opcionalbooleanPor defecto false. Las grabaciones se almacenan 30 días.
callerid_mask opcionalstring"hide", "rotate", o cualquier número E.164 que poseas.
metadata opcionalobjectJSON arbitrario devuelto en los webhooks para la llamada.
curl
curl https://api.nokycnumber.com/v1/calls \
  -H "Authorization: Bearer sk_live_…" \
  -d '{
    "from": "num_8a4c2f1e9b3d",
    "to":   "+33612345678",
    "callerid_mask": "rotate"
  }'
json
{
  "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
}
GET/v1/calls

Lista llamadas. Filtra por number, direction, status, o created_after / created_before.

GET/v1/calls/{id}

Recupera una llamada individual.

POST/v1/calls/{id}/hangup

Finaliza forzosamente una llamada en curso. Idempotente.

Mensajes SMS

Envía y recupera SMS. Los mensajes largos se segmentan automáticamente según las reglas GSM-03.38 / UCS-2; la respuesta muestra el número real de segmentos para la facturación.

POST/v1/sms

Envía un SMS desde uno de tus números.

FieldTipoDescription
from requeridostringUn id num_ que posees.
to requeridostringDestino E.164.
body requeridostringCuerpo del mensaje. Máx. 1.600 caracteres (10 segmentos).
send_at opcionalstringMarca de tiempo futura en ISO-8601 para programar la entrega.
media_urls opcionalarrayHasta 5 URLs de imagen/vídeo. Solo MMS — funciona en países compatibles.
curl
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."
  }'
json
{
  "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
}
GET/v1/sms

Lista mensajes. Filtra por number, direction, status.

GET/v1/sms/{id}

Recupera un mensaje individual incluyendo el estado de entrega a nivel de segmento.

Buzones de voz

Los buzones de voz se almacenan, transcriben y traducen automáticamente. Las URLs de audio están prefirmadas y caducan 1 hora después de su emisión.

GET/v1/voicemails

Lista buzones de voz. Paginación idéntica a otros endpoints de lista.

GET/v1/voicemails/{id}

Recupera un buzón de voz individual con transcripción y URL de audio.

json
{
  "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"
  }
}

Tanto translation_en como summary requieren el complemento ai-summary.

DELETE/v1/voicemails/{id}

Elimina permanentemente un buzón de voz y su archivo de audio. Devuelve 204 No Content.

Configuración de IA

Cada número puede ejecutar un agente de IA que contesta llamadas cuando no puedes, filtra llamantes desconocidos, resume buzones de voz o traduce conversaciones en tiempo real. Configúralo por número mediante el subrecurso de IA.

GET/v1/numbers/{id}/ai

Recupera la configuración de IA actual de un número.

json
{
  "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 }
}
PATCH/v1/numbers/{id}/ai

Actualiza una o más funciones de IA. Cada bloque es opcional; solo se actualizan los campos presentes.

Voces

Voces disponibles: neutral_en, neutral_fr, neutral_es, neutral_de, neutral_jp, warm_en, warm_fr. Voces clonadas personalizadas para empresas bajo solicitud.

Cuenta

Lee datos a nivel de cuenta: saldo, estadísticas de uso, webhooks configurados.

GET/v1/account

Recupera tu cuenta.

json
{
  "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"
}
GET/v1/account/usage

Desglose detallado de uso para el período actual. Pasa period=last_30d o period=last_90d.

Webhooks

Suscríbete a eventos de tu cuenta o números específicos. Enviamos un evento JSON por POST a tu endpoint y reintentamos hasta 5 veces con retroceso exponencial en 24 horas.

Sobre de evento

json
{
  "id": "evt_3d4a7c8a4c2f",
  "object": "event",
  "type": "sms.received",
  "created": "2026-04-26T11:25:42Z",
  "livemode": true,
  "data": { "object": { "id": "sms_…", … } },
  "request_id": "req_8a4c2f1e9b3d4a7c"
}

Verificación de firma

Cada solicitud lleva una cabecera X-NoKYC-Signature en la forma t=<ts>,v1=<hex>. La firma es HMAC-SHA256 de <ts>.<raw_body> usando el secreto de firma del endpoint. Rechaza cualquier solicitud con más de 5 minutos de antigüedad.

shell
# 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): reject

Endpoints

POST/v1/webhook_endpoints

Registra un nuevo endpoint de webhook. Devuelve el secreto de firma una sola vez; guárdalo.

FieldTipoDescription
url requeridostringURL HTTPS a la que enviaremos eventos por POST.
enabled_events requeridoarrayLista de suscripción, p.ej. ["sms.received","call.completed"]. Usa ["*"] para todos.
description opcionalstringNota libre para tu propio registro.
GET/v1/webhook_endpoints

Lista tus endpoints.

DELETE/v1/webhook_endpoints/{id}

Elimina un endpoint. Devuelve 204.

Tipos de evento

EventoSe activa cuando
number.activatedSe ha aprovisionado un número nuevo y está listo.
number.renewedRenovación del período exitosa.
number.pausedEl número entró en estado pausado por ventana activa/inactiva.
number.releasedNúmero liberado permanentemente al inventario.
call.initiatedLlamada saliente realizada.
call.answeredEl interlocutor remoto contestó.
call.completedLlamada finalizada (cualquier motivo).
call.recordedGrabación finalizada y disponible.
sms.receivedSMS entrante recibido en tu número.
sms.sentSMS saliente aceptado por el operador.
sms.deliveredAcuse de entrega del operador confirmado.
sms.failedOperador rechazó — verifica failure_code.
voicemail.createdNuevo buzón de voz grabado y transcrito.
ai.pickupLa respuesta automática de IA contestó una llamada.
account.balance_lowEl saldo cayó por debajo del umbral configurado.

Esquemas de objetos

number

json
{
  "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

json
{
  "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

json
{
  "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"
}

SDKs oficiales

La HTTP API es la fuente de verdad, pero estos SDKs te proporcionan bindings tipados, reintentos, idempotencia y verificación de webhooks de fábrica.

  • 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