Skip to content

Proveedores de SMS ​

Generado desde DialerDigital/core commit 0fc18008b3c8 — especificación openapi/dialer-v1.yaml v0.134.0. No se edita a mano; consulta Cómo se construye esta referencia. Descargar la especificación OpenAPI.

English version

Traducción en curso

Esta referencia se genera desde la especificación OpenAPI. Las cadenas que todavía no tienen traducción aparecen en inglés.

Qué es hoy el SMS

El envío de SMS a través de tu propio proveedor está disponible hoy a nivel de API; el producto completo de mensajería de cobranza está en la hoja de ruta.

Registro de enrutamiento de SMS por tenant/región.

Endpoints ​

MétodoRutaResumen
GET/v1/sms/providersRegistro de proveedores de SMS
POST/v1/sms/providersRegistrar un proveedor de SMS
GET/v1/sms/providers/{id}Obtener un proveedor
PATCH/v1/sms/providers/{id}Actualizar un proveedor (alcance inmutable)
POST/v1/sms/providers/{id}/retireRetirar un proveedor (las filas nunca se borran)

Registro de proveedores de SMS ​

http
GET /v1/sms/providers

Respuestas

200 ​

Filas propias + filas heredadas de toda la empresa.

CampoTipoObligatorioDescripción
sms_providersarreglo de SmsProvidersí
sms_providers[].idstring (uuid)no
sms_providers[].account_idstring (uuid)no
sms_providers[].tenant_idstring (uuid) | nullnonull = proveedor de toda la empresa (compartido), heredado por cada sede.
sms_providers[].scopeempresa · sedenoDerivado de tenant_id.
sms_providers[].adapterhttp · telnyx · mockno
sms_providers[].regionus · mx · euno
sms_providers[].namestringno
sms_providers[].base_urlstring | nullno
sms_providers[].default_from_e164string | nullnoLínea remitente usada cuando POST /v1/sms/messages no trae from; null = ninguna (un envío así da 422 from_required).
sms_providers[].has_secretbooleannoEl secreto del webhook NUNCA viaja por el cable: esta es la única señal de que hay una credencial almacenada.
sms_providers[].statusactive · disabled · retiredno
sms_providers[].created_atstring (date-time)no
sms_providers[].updated_atstring (date-time)no

401 — Unauthorized ​

Clave de API ausente, desconocida o revocada (o, en /v1/admin/*, un token de administración incorrecto o sin definir; en webhooks, una firma incorrecta o ausente). Una sesión del dashboard (ddu_) que un inicio de sesión más reciente de la misma persona haya cerrado responde en cambio con el código session_superseded (indicador de tenant single_session_enforced), para que la pantalla pueda explicar por qué se cerró la sesión; un cierre de sesión, un token vencido o uno desconocido siguen siendo unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

429 — ApiKeyRateLimited ​

Esta clave de API ha superado su cuota de peticiones, o las claves del tenant en conjunto han superado el techo del tenant (core#2503) (code rate_limited). La petición no se procesó. Espera Retry-After segundos y reintenta; un rechazo no cuenta contra el presupuesto, así que esa espera siempre basta. Acotado por clave de API y, por encima de las claves, por tenant (api_tenant_requests_per_minute): una clave hermana no se ve afectada hasta que las claves del tenant en conjunto alcanzan ese techo. La cuota se aplica a toda operación alcanzable con una clave dd_, así que las operaciones que nombran un 429 más específico (control de llamadas, disposiciones, SMS, …) PUEDEN responder TAMBIÉN este, con sus cabeceras X-RateLimit-*.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

Registrar un proveedor de SMS ​

http
POST /v1/sms/providers

Convenciones de los carriers: scope: "empresa" crea una fila de toda la cuenta (tenant_id null) y requiere un usuario account_admin (véase User.role): un member o una clave de máquina recibe 403; account_id/tenant_id se inyectan desde la sesión, nunca desde el cuerpo; el alcance de una fila es inmutable tras la creación. webhook_secret es SOLO DE ESCRITURA: las respuestas llevan has_secret, nunca el secreto. Para telnyx, webhook_secret contiene la clave PÚBLICA Ed25519 de la cuenta (base64) y los envíos se autentican con el bearer TELNYX_API_KEY de todo el despliegue. El adaptador mock (arnés de pruebas/e2e) se rechaza con 400 salvo que el despliegue lo permita. Solo se retira: no existe ruta DELETE.

Cuerpo de la petición (JSON, obligatorio)

CampoTipoObligatorioDescripción
adapterhttp · telnyx · mocksí
regionus · mx · eusí
namestringsí
default_from_e164string | nullnoLínea remitente usada por POST /v1/sms/messages cuando la petición no trae from. E.164; cualquier otra cosa da 422. null = ninguna declarada.
base_urlstringnoEndpoint del adaptador de contrato interno (http). DEBE ser una URL https:// en el puerto 443 cuyo host se resuelva solo a direcciones PÚBLICAS: loopback, RFC1918, CGNAT (100.64/10), enlace local (169.254/16, metadatos de la nube) y sus equivalentes IPv6 se rechazan con 422 (protección SSRF), y la misma comprobación se repite en el momento del envío con una resolución nueva. Un puerto distinto del 443 se rechaza con 422 aunque el host sea público: una dirección pública no es un servicio público, y llegar a un puerto arbitrario de ella es una alcanzabilidad que no concedemos. Llegar a un destino que legítimamente sirve en otro puerto requiere una entrada en la lista de permitidos del operador, no un campo del tenant. En blanco significa «usar el endpoint de todo el despliegue».
webhook_secretstringnoSolo de escritura. Secreto HMAC (http/mock) o clave pública Ed25519, en base64 (telnyx).
statusactive · disabled · retiredno
scopesede · empresanoCampo solo de petición; las respuestas lo derivan de tenant_id.
json
{
  "adapter": "http",
  "region": "us",
  "name": "example-sms-provider",
  "base_url": "",
  "webhook_secret": "example-hmac-secret-not-a-real-one"
}

Respuestas

201 ​

Proveedor registrado (has_secret, nunca el secreto).

CampoTipoObligatorioDescripción
sms_providerobject (SmsProvider)sí
sms_provider.idstring (uuid)no
sms_provider.account_idstring (uuid)no
sms_provider.tenant_idstring (uuid) | nullnonull = proveedor de toda la empresa (compartido), heredado por cada sede.
sms_provider.scopeempresa · sedenoDerivado de tenant_id.
sms_provider.adapterhttp · telnyx · mockno
sms_provider.regionus · mx · euno
sms_provider.namestringno
sms_provider.base_urlstring | nullno
sms_provider.default_from_e164string | nullnoLínea remitente usada cuando POST /v1/sms/messages no trae from; null = ninguna (un envío así da 422 from_required).
sms_provider.has_secretbooleannoEl secreto del webhook NUNCA viaja por el cable: esta es la única señal de que hay una credencial almacenada.
sms_provider.statusactive · disabled · retiredno
sms_provider.created_atstring (date-time)no
sms_provider.updated_atstring (date-time)no

400 — BadRequest ​

Petición mal formada (errores de forma/tipo, filtros no válidos, marcas de tiempo erróneas).

json
{
  "error": {
    "code": "bad_request",
    "message": "from must be RFC-3339"
  }
}

401 — Unauthorized ​

Clave de API ausente, desconocida o revocada (o, en /v1/admin/*, un token de administración incorrecto o sin definir; en webhooks, una firma incorrecta o ausente). Una sesión del dashboard (ddu_) que un inicio de sesión más reciente de la misma persona haya cerrado responde en cambio con el código session_superseded (indicador de tenant single_session_enforced), para que la pantalla pueda explicar por qué se cerró la sesión; un cierre de sesión, un token vencido o uno desconocido siguen siendo unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

403 — Forbidden ​

El tenant está suspendido. Una sesión del dashboard (ddu_) de un tenant cuya política de inicio de sesión (ADR 227) está en modo enforce responde 403 con el código login_policy_denied ante una solicitud desde una dirección o en una hora que la política no permite — el mismo cuerpo en ambos casos; la sesión no se revoca y una solicitud posterior dentro de la política se procesa. Un token de widget (ddw_) de un puesto queda sujeto a la misma política en cada solicitud (core#2406, indicador widget_login_honors_policy). Un tenant sintético (demo) responde 403 con el código synthetic_tenant en toda ruta que llegaría a un tercero — marcación manual, pierna de transferencia externa o de conferencia, envío de SMS (core#2251, adenda del ADR #280). Ningún pago lo cambia.

json
{
  "error": {
    "code": "forbidden",
    "message": "tenant is suspended"
  }
}

422 ​

El default_from_e164 de un proveedor con alcance de sede no es E.164 (code: sms_from_invalid) o no es un número ACTIVO del tenant (code: sms_from_not_owned; palanca por tenant sms_from_ownership_enforced, por defecto true, core#2329). Una fila de toda la empresa no se comprueba al escribir: cada envío la comprueba contra su propia sede.

429 — ApiKeyRateLimited ​

Esta clave de API ha superado su cuota de peticiones, o las claves del tenant en conjunto han superado el techo del tenant (core#2503) (code rate_limited). La petición no se procesó. Espera Retry-After segundos y reintenta; un rechazo no cuenta contra el presupuesto, así que esa espera siempre basta. Acotado por clave de API y, por encima de las claves, por tenant (api_tenant_requests_per_minute): una clave hermana no se ve afectada hasta que las claves del tenant en conjunto alcanzan ese techo. La cuota se aplica a toda operación alcanzable con una clave dd_, así que las operaciones que nombran un 429 más específico (control de llamadas, disposiciones, SMS, …) PUEDEN responder TAMBIÉN este, con sus cabeceras X-RateLimit-*.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

Obtener un proveedor ​

http
GET /v1/sms/providers/{id}

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)síUUID del recurso. Los ids mal formados o de otro tenant se leen como 404.

Respuestas

200 ​

El proveedor.

CampoTipoObligatorioDescripción
sms_providerobject (SmsProvider)sí
sms_provider.idstring (uuid)no
sms_provider.account_idstring (uuid)no
sms_provider.tenant_idstring (uuid) | nullnonull = proveedor de toda la empresa (compartido), heredado por cada sede.
sms_provider.scopeempresa · sedenoDerivado de tenant_id.
sms_provider.adapterhttp · telnyx · mockno
sms_provider.regionus · mx · euno
sms_provider.namestringno
sms_provider.base_urlstring | nullno
sms_provider.default_from_e164string | nullnoLínea remitente usada cuando POST /v1/sms/messages no trae from; null = ninguna (un envío así da 422 from_required).
sms_provider.has_secretbooleannoEl secreto del webhook NUNCA viaja por el cable: esta es la única señal de que hay una credencial almacenada.
sms_provider.statusactive · disabled · retiredno
sms_provider.created_atstring (date-time)no
sms_provider.updated_atstring (date-time)no

401 — Unauthorized ​

Clave de API ausente, desconocida o revocada (o, en /v1/admin/*, un token de administración incorrecto o sin definir; en webhooks, una firma incorrecta o ausente). Una sesión del dashboard (ddu_) que un inicio de sesión más reciente de la misma persona haya cerrado responde en cambio con el código session_superseded (indicador de tenant single_session_enforced), para que la pantalla pueda explicar por qué se cerró la sesión; un cierre de sesión, un token vencido o uno desconocido siguen siendo unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

404 — NotFound ​

Id desconocido, mal formado (no UUID) O id de otro tenant: RLS devuelve cero filas, así que los tres son indistinguibles por diseño (sin fuga de existencia, nunca un 403 para ids ajenos).

json
{
  "error": {
    "code": "not_found",
    "message": "resource not found for this tenant"
  }
}

429 — ApiKeyRateLimited ​

Esta clave de API ha superado su cuota de peticiones, o las claves del tenant en conjunto han superado el techo del tenant (core#2503) (code rate_limited). La petición no se procesó. Espera Retry-After segundos y reintenta; un rechazo no cuenta contra el presupuesto, así que esa espera siempre basta. Acotado por clave de API y, por encima de las claves, por tenant (api_tenant_requests_per_minute): una clave hermana no se ve afectada hasta que las claves del tenant en conjunto alcanzan ese techo. La cuota se aplica a toda operación alcanzable con una clave dd_, así que las operaciones que nombran un 429 más específico (control de llamadas, disposiciones, SMS, …) PUEDEN responder TAMBIÉN este, con sus cabeceras X-RateLimit-*.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

Actualizar un proveedor (alcance inmutable) ​

http
PATCH /v1/sms/providers/{id}

Editar una fila de toda la empresa (scope: "empresa", heredada por cada sede de la cuenta) requiere una sesión account_admin, igual que crearla: un member o una clave de máquina recibe 403. Cambiar al adaptador mock (arnés de pruebas/e2e) se rechaza con 400 salvo que el despliegue lo permita.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)síUUID del recurso. Los ids mal formados o de otro tenant se leen como 404.

Cuerpo de la petición (JSON, obligatorio)

CampoTipoObligatorioDescripción
adapterhttp · telnyx · mockno
regionus · mx · euno
namestringno
base_urlstringno
default_from_e164string | nullnoLínea remitente para los envíos sin from; null la borra.
webhook_secretstringnoSolo de escritura.
statusactive · disabled · retiredno
json
{
  "name": "postman-sms-renamed",
  "status": "disabled"
}

Respuestas

200 ​

Proveedor actualizado.

CampoTipoObligatorioDescripción
sms_providerobject (SmsProvider)sí
sms_provider.idstring (uuid)no
sms_provider.account_idstring (uuid)no
sms_provider.tenant_idstring (uuid) | nullnonull = proveedor de toda la empresa (compartido), heredado por cada sede.
sms_provider.scopeempresa · sedenoDerivado de tenant_id.
sms_provider.adapterhttp · telnyx · mockno
sms_provider.regionus · mx · euno
sms_provider.namestringno
sms_provider.base_urlstring | nullno
sms_provider.default_from_e164string | nullnoLínea remitente usada cuando POST /v1/sms/messages no trae from; null = ninguna (un envío así da 422 from_required).
sms_provider.has_secretbooleannoEl secreto del webhook NUNCA viaja por el cable: esta es la única señal de que hay una credencial almacenada.
sms_provider.statusactive · disabled · retiredno
sms_provider.created_atstring (date-time)no
sms_provider.updated_atstring (date-time)no

400 — BadRequest ​

Petición mal formada (errores de forma/tipo, filtros no válidos, marcas de tiempo erróneas).

json
{
  "error": {
    "code": "bad_request",
    "message": "from must be RFC-3339"
  }
}

401 — Unauthorized ​

Clave de API ausente, desconocida o revocada (o, en /v1/admin/*, un token de administración incorrecto o sin definir; en webhooks, una firma incorrecta o ausente). Una sesión del dashboard (ddu_) que un inicio de sesión más reciente de la misma persona haya cerrado responde en cambio con el código session_superseded (indicador de tenant single_session_enforced), para que la pantalla pueda explicar por qué se cerró la sesión; un cierre de sesión, un token vencido o uno desconocido siguen siendo unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

403 — Forbidden ​

El tenant está suspendido. Una sesión del dashboard (ddu_) de un tenant cuya política de inicio de sesión (ADR 227) está en modo enforce responde 403 con el código login_policy_denied ante una solicitud desde una dirección o en una hora que la política no permite — el mismo cuerpo en ambos casos; la sesión no se revoca y una solicitud posterior dentro de la política se procesa. Un token de widget (ddw_) de un puesto queda sujeto a la misma política en cada solicitud (core#2406, indicador widget_login_honors_policy). Un tenant sintético (demo) responde 403 con el código synthetic_tenant en toda ruta que llegaría a un tercero — marcación manual, pierna de transferencia externa o de conferencia, envío de SMS (core#2251, adenda del ADR #280). Ningún pago lo cambia.

json
{
  "error": {
    "code": "forbidden",
    "message": "tenant is suspended"
  }
}

404 — NotFound ​

Id desconocido, mal formado (no UUID) O id de otro tenant: RLS devuelve cero filas, así que los tres son indistinguibles por diseño (sin fuga de existencia, nunca un 403 para ids ajenos).

json
{
  "error": {
    "code": "not_found",
    "message": "resource not found for this tenant"
  }
}

422 ​

El default_from_e164 de un proveedor con alcance de sede no es E.164 (code: sms_from_invalid) o no es un número ACTIVO del tenant (code: sms_from_not_owned; palanca por tenant sms_from_ownership_enforced, por defecto true, core#2329).

429 — ApiKeyRateLimited ​

Esta clave de API ha superado su cuota de peticiones, o las claves del tenant en conjunto han superado el techo del tenant (core#2503) (code rate_limited). La petición no se procesó. Espera Retry-After segundos y reintenta; un rechazo no cuenta contra el presupuesto, así que esa espera siempre basta. Acotado por clave de API y, por encima de las claves, por tenant (api_tenant_requests_per_minute): una clave hermana no se ve afectada hasta que las claves del tenant en conjunto alcanzan ese techo. La cuota se aplica a toda operación alcanzable con una clave dd_, así que las operaciones que nombran un 429 más específico (control de llamadas, disposiciones, SMS, …) PUEDEN responder TAMBIÉN este, con sus cabeceras X-RateLimit-*.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

Retirar un proveedor (las filas nunca se borran) ​

http
POST /v1/sms/providers/{id}/retire

Retirar una fila de toda la empresa (scope: "empresa") requiere una sesión account_admin: un member o una clave de máquina recibe 403.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)síUUID del recurso. Los ids mal formados o de otro tenant se leen como 404.

Respuestas

200 ​

El proveedor retirado.

CampoTipoObligatorioDescripción
sms_providerobject (SmsProvider)sí
sms_provider.idstring (uuid)no
sms_provider.account_idstring (uuid)no
sms_provider.tenant_idstring (uuid) | nullnonull = proveedor de toda la empresa (compartido), heredado por cada sede.
sms_provider.scopeempresa · sedenoDerivado de tenant_id.
sms_provider.adapterhttp · telnyx · mockno
sms_provider.regionus · mx · euno
sms_provider.namestringno
sms_provider.base_urlstring | nullno
sms_provider.default_from_e164string | nullnoLínea remitente usada cuando POST /v1/sms/messages no trae from; null = ninguna (un envío así da 422 from_required).
sms_provider.has_secretbooleannoEl secreto del webhook NUNCA viaja por el cable: esta es la única señal de que hay una credencial almacenada.
sms_provider.statusactive · disabled · retiredno
sms_provider.created_atstring (date-time)no
sms_provider.updated_atstring (date-time)no

400 — BadRequest ​

Petición mal formada (errores de forma/tipo, filtros no válidos, marcas de tiempo erróneas).

json
{
  "error": {
    "code": "bad_request",
    "message": "from must be RFC-3339"
  }
}

401 — Unauthorized ​

Clave de API ausente, desconocida o revocada (o, en /v1/admin/*, un token de administración incorrecto o sin definir; en webhooks, una firma incorrecta o ausente). Una sesión del dashboard (ddu_) que un inicio de sesión más reciente de la misma persona haya cerrado responde en cambio con el código session_superseded (indicador de tenant single_session_enforced), para que la pantalla pueda explicar por qué se cerró la sesión; un cierre de sesión, un token vencido o uno desconocido siguen siendo unauthorized.

json
{
  "error": {
    "code": "unauthorized",
    "message": "invalid or revoked API key"
  }
}

403 — Forbidden ​

El tenant está suspendido. Una sesión del dashboard (ddu_) de un tenant cuya política de inicio de sesión (ADR 227) está en modo enforce responde 403 con el código login_policy_denied ante una solicitud desde una dirección o en una hora que la política no permite — el mismo cuerpo en ambos casos; la sesión no se revoca y una solicitud posterior dentro de la política se procesa. Un token de widget (ddw_) de un puesto queda sujeto a la misma política en cada solicitud (core#2406, indicador widget_login_honors_policy). Un tenant sintético (demo) responde 403 con el código synthetic_tenant en toda ruta que llegaría a un tercero — marcación manual, pierna de transferencia externa o de conferencia, envío de SMS (core#2251, adenda del ADR #280). Ningún pago lo cambia.

json
{
  "error": {
    "code": "forbidden",
    "message": "tenant is suspended"
  }
}

404 — NotFound ​

Id desconocido, mal formado (no UUID) O id de otro tenant: RLS devuelve cero filas, así que los tres son indistinguibles por diseño (sin fuga de existencia, nunca un 403 para ids ajenos).

json
{
  "error": {
    "code": "not_found",
    "message": "resource not found for this tenant"
  }
}

429 — ApiKeyRateLimited ​

Esta clave de API ha superado su cuota de peticiones, o las claves del tenant en conjunto han superado el techo del tenant (core#2503) (code rate_limited). La petición no se procesó. Espera Retry-After segundos y reintenta; un rechazo no cuenta contra el presupuesto, así que esa espera siempre basta. Acotado por clave de API y, por encima de las claves, por tenant (api_tenant_requests_per_minute): una clave hermana no se ve afectada hasta que las claves del tenant en conjunto alcanzan ese techo. La cuota se aplica a toda operación alcanzable con una clave dd_, así que las operaciones que nombran un 429 más específico (control de llamadas, disposiciones, SMS, …) PUEDEN responder TAMBIÉN este, con sus cabeceras X-RateLimit-*.

json
{
  "error": {
    "code": "rate_limited",
    "message": "API key request quota exceeded; retry after the interval in Retry-After"
  }
}

Nothing in these docs is legal advice — always confirm compliance posture with your own counsel.