Saltar al contenido

Claves de API ​

Generado desde DialerDigital/core commit bbb8e373d900 — especificación openapi/dialer-v1.yaml v0.151.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.

Claves de API por tenant (sha256 en reposo; texto plano mostrado una vez).

Endpoints ​

MétodoRutaResumen
GET/v1/api_keysListar las claves de API
POST/v1/api_keysEmitir una clave de API
PATCH/v1/api_keys/{id}Establecer la lista de permitidos de red de una clave de API
DELETE/v1/api_keys/{id}Revocar una clave de API
POST/v1/api_keys/{id}/rotateRotar una clave de API en un paso, con solape
GET/v1/api_keys/{id}/requestsPeticiones hechas con una clave de API
GET/v1/api_keys/{id}/requests/summaryPeticiones por minuto de una clave de API, con sus 429

Listar las claves de API ​

http
GET /v1/api_keys

Solo ids, etiquetas y marcas de tiempo de revocación — los hashes nunca se exponen.

Respuestas

200 ​

Las claves del tenant.

CampoTipoObligatorioDescripción
api_keysarreglo de ApiKeysí
api_keys[].idstring (uuid)no
api_keys[].labelstringno
api_keys[].environmentlive · testnolive (toda clave anterior al campo) o test: una clave de prueba no alcanza ninguna ruta de salida. Fijo en la creación.
api_keys[].revoked_atstring (date-time) | nullno
api_keys[].last_used_atstring (date-time) | nullnoReloj de higiene de rotación: la última vez que esta clave se autenticó CON ÉXITO. Se escribe como mucho una vez por minuto por clave, de modo que una lectura reciente puede ir retrasada hasta ese tiempo. null significa que no se ha autenticado con éxito desde que la columna adquirió un escritor — no que la clave nunca se haya presentado.
api_keys[].allowed_cidrsarreglo de stringnoLista de permitidos de red. [] = sin restricción. Fuera de ella, una petición se sirve y se cuenta, o se rechaza con 401, según el interruptor de tenant api_key_network_enforced (desactivado por defecto).
api_keys[].stalebooleannotrue para una clave live sin uso durante 90 días (una clave que nunca se autenticó cuenta desde su creación). Es un consejo para que la consola la rote o la revoque; una clave solo caduca por sí sola cuando tiene expires_at.
api_keys[].permissionsarreglo de ApiKeyPermission | nullnoGrupos de rutas a los que puede entrar la clave. null = todos (toda clave anterior al campo).
api_keys[].expires_atstring (date-time) | nullnoInstante a partir del cual la clave deja de autenticarse; null = nunca. Una rotación lo fija en la clave antigua al final del solape.
api_keys[].created_by_user_idstring (uuid) | nullnoEl usuario del dashboard cuya sesión emitió la clave. null cuando la emitió otra clave dd_, el operador o las semillas, y en toda clave anterior al campo.
api_keys[].created_atstring (date-time)no
json
{
  "api_keys": [
    {
      "id": "7a3f0f7e-52a1-4f3d-9f9d-27e5a1b9c001",
      "label": "onboarding",
      "revoked_at": null,
      "created_at": "2026-06-01T12:00:00Z"
    }
  ]
}

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

Emitir una clave de API ​

http
POST /v1/api_keys

El token en claro (dd_...) se devuelve UNA SOLA VEZ y solo se almacena su sha256. Rota en un paso con POST /v1/api_keys/{id}/rotate.

environment es live (por defecto; el prefijo histórico dd_) o test (prefijo de token dd_test_). Una clave de prueba se autentica y lee por los mismos carriles y RLS que una live, pero no alcanza ninguna ruta de salida: las rutas que marcan, envían SMS, compran números o aprovisionan operadores responden 403 test_environment, y no se mide ni se cobra nada. La misma respuesta cubre las rutas que emiten, fijan o restablecen una credencial o identidad live: POST|DELETE /agents/{id}/credential, POST /api_keys/{id}/rotate, POST /users y su enable, mfa/reset-failures y mfa/remove, POST|PATCH /click-to-call/sites, POST /widget_tokens (y /sip_credential) y PUT|PATCH /sso/idp-config. El entorno queda fijado en la creación.

Reglas de rol: emitir exige un login account_admin (403 role_forbidden para un member Y, una vez que el tenant tiene un account_admin activo, para una clave dd_; ajuste por tenant api_key_admin_only, activado por defecto; ajuste del fundador api_key_manages_people, desactivado por defecto). Un tenant sin account_admin activo mantiene la emisión con la clave dd_. Una clave emitida desde un login del dashboard registra a esa persona en created_by_user_id; toda emisión se escribe en el rastro de auditoría de claves.

allowed_cidrs es la lista de redes permitidas de la clave; omitido o [] significa sin restricción. Lo que ocurre con una petición desde fuera de la lista lo decide el ajuste del tenant api_key_network_enforced: desactivado (por defecto) la sirve y la cuenta, activado responde 401.

permissions restringe la clave a GRUPOS de rutas; ausente o null es la clave de siempre (todas las rutas). Una clave con lista recibe 403 permission_denied en las rutas de cualquier otro grupo (p. ej. /v1/billing/* sin billing); el grupo de una ruta es su primer segmento de path, y un segmento que ningún grupo reclama pertenece a general. Una clave que a su vez tiene una lista no puede emitir una con más permisos (403 permission_escalation). expires_at (ISO 8601, en el futuro; ausente = nunca) es el instante a partir del cual la clave deja de autenticarse (401, como una revocada); las demás claves no se ven afectadas.

Límites: un tenant tiene como máximo api_keys_max_live claves LIVE (50 por defecto; 409 api_key_limit por encima, revocar una clave libera un hueco), y la emisión tiene límite de tasa por tenant (429 rate_limited con Retry-After). La cuota de peticiones es por clave, así que las claves de un tenant juntas también están acotadas por api_tenant_requests_per_minute (por defecto 5 veces la de una clave).

Cuerpo de la petición (JSON)

CampoTipoObligatorioDescripción
labelstringnoEtiqueta de formato libre (por defecto "").
environmentlive · testnotest emite una clave que nunca alcanza llamadas, SMS ni correo (prefijo dd_test_). Inmutable. Cualquier otro valor es 422.
allowed_cidrsarreglo de stringnoCIDR (o direcciones simples) desde los que se puede usar la clave. Una lista con una entrada que no se puede interpretar se rechaza entera (400); un valor que no es una lista de cadenas da 422.
permissionsarreglo de ApiKeyPermission | nullnoGrupos de rutas a los que puede entrar la clave. Ausente o null = todos. [] = ninguno. Un grupo desconocido es 422.
expires_atstring (date-time) | nullnoInstante a partir del cual la clave deja de autenticarse. Debe estar en el futuro (si no, 422).
json
{
  "label": "postman-smoke-1751600000"
}

Respuestas

201 ​

Clave emitida; token es la única vez que el texto plano es visible.

CampoTipoObligatorioDescripción
api_keyobject (ApiKey)síMetadatos de la clave — el hash del token nunca se expone.
api_key.idstring (uuid)no
api_key.labelstringno
api_key.environmentlive · testnolive (toda clave anterior al campo) o test: una clave de prueba no alcanza ninguna ruta de salida. Fijo en la creación.
api_key.revoked_atstring (date-time) | nullno
api_key.last_used_atstring (date-time) | nullnoReloj de higiene de rotación: la última vez que esta clave se autenticó CON ÉXITO. Se escribe como mucho una vez por minuto por clave, de modo que una lectura reciente puede ir retrasada hasta ese tiempo. null significa que no se ha autenticado con éxito desde que la columna adquirió un escritor — no que la clave nunca se haya presentado.
api_key.allowed_cidrsarreglo de stringnoLista de permitidos de red. [] = sin restricción. Fuera de ella, una petición se sirve y se cuenta, o se rechaza con 401, según el interruptor de tenant api_key_network_enforced (desactivado por defecto).
api_key.stalebooleannotrue para una clave live sin uso durante 90 días (una clave que nunca se autenticó cuenta desde su creación). Es un consejo para que la consola la rote o la revoque; una clave solo caduca por sí sola cuando tiene expires_at.
api_key.permissionsarreglo de ApiKeyPermission | nullnoGrupos de rutas a los que puede entrar la clave. null = todos (toda clave anterior al campo).
api_key.expires_atstring (date-time) | nullnoInstante a partir del cual la clave deja de autenticarse; null = nunca. Una rotación lo fija en la clave antigua al final del solape.
api_key.created_by_user_idstring (uuid) | nullnoEl usuario del dashboard cuya sesión emitió la clave. null cuando la emitió otra clave dd_, el operador o las semillas, y en toda clave anterior al campo.
api_key.created_atstring (date-time)no
tokenstringsíToken bearer en texto plano, mostrado exactamente una vez.
json
{
  "api_key": {
    "id": "9a1c2b3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d",
    "label": "postman-smoke-1751600000",
    "revoked_at": null,
    "created_at": "2026-07-05T10:00:00Z"
  },
  "token": "dd_example_plaintext_shown_once"
}

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 — ApiKeyAdminForbidden ​

Se rechazó emitir o revocar una clave de API. code role_forbidden: quien llama es un inicio de sesión de dashboard sin el rol account_admin, o una clave dd_ en un tenant que ya tiene un account_admin activo (interruptor del founder api_key_manages_people, desactivado por defecto); el interruptor por tenant api_key_admin_only (activado por defecto) desactiva esto.

json
{
  "error": {
    "code": "role_forbidden",
    "message": "minting or revoking an API key takes a dashboard login with the account_admin role; a dd_ key may do it only while the tenant has no account_admin"
  }
}

409 — ApiKeyLimit ​

El tenant ya tiene el número máximo de claves de API VIVAS (interruptor por tenant api_keys_max_live, 50 por defecto). code api_key_limit. No se emitió nada; revoca una clave (DELETE /v1/api_keys/{id}) y reintenta.

json
{
  "error": {
    "code": "api_key_limit",
    "message": "this tenant already holds the maximum number of live API keys; revoke one first"
  }
}

422 — Unprocessable ​

La forma es correcta, la semántica no (regla de dominio incumplida).

json
{
  "error": {
    "code": "unprocessable",
    "message": "scheduled_at is closer than the minimum notice for a callback (10 minutes unless the tenant's callback_min_notice_seconds says otherwise)"
  }
}

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

Establecer la lista de permitidos de red de una clave de API ​

http
PATCH /v1/api_keys/{id}

Sustituye allowed_cidrs de una clave LIVE; [] levanta la restricción. Admite los mismos roles que la emisión (403 role_forbidden para un member mientras el knob api_key_admin_only esté activado). El cambio se escribe en la pista de auditoría de la clave como network_changed y rige desde la siguiente petición: la clave se olvida de la caché de autenticación. Una clave revocada o desconocida es 404. Una clave que tiene una lista de permisos solo puede modificarse a sí misma y a las claves cuyos permisos cubre: en otro caso 403 permission_escalation.

Una clave de API test solo puede actuar sobre claves test: contra una clave live se rechaza con 403 test_environment y la clave queda intacta.

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
allowed_cidrsarreglo de stringsí
json
{
  "allowed_cidrs": [
    "203.0.113.0/24",
    "2001:db8::/32"
  ]
}

Respuestas

200 ​

La clave con su nueva lista.

CampoTipoObligatorioDescripción
api_keyobject (ApiKey)síMetadatos de la clave — el hash del token nunca se expone.
api_key.idstring (uuid)no
api_key.labelstringno
api_key.environmentlive · testnolive (toda clave anterior al campo) o test: una clave de prueba no alcanza ninguna ruta de salida. Fijo en la creación.
api_key.revoked_atstring (date-time) | nullno
api_key.last_used_atstring (date-time) | nullnoReloj de higiene de rotación: la última vez que esta clave se autenticó CON ÉXITO. Se escribe como mucho una vez por minuto por clave, de modo que una lectura reciente puede ir retrasada hasta ese tiempo. null significa que no se ha autenticado con éxito desde que la columna adquirió un escritor — no que la clave nunca se haya presentado.
api_key.allowed_cidrsarreglo de stringnoLista de permitidos de red. [] = sin restricción. Fuera de ella, una petición se sirve y se cuenta, o se rechaza con 401, según el interruptor de tenant api_key_network_enforced (desactivado por defecto).
api_key.stalebooleannotrue para una clave live sin uso durante 90 días (una clave que nunca se autenticó cuenta desde su creación). Es un consejo para que la consola la rote o la revoque; una clave solo caduca por sí sola cuando tiene expires_at.
api_key.permissionsarreglo de ApiKeyPermission | nullnoGrupos de rutas a los que puede entrar la clave. null = todos (toda clave anterior al campo).
api_key.expires_atstring (date-time) | nullnoInstante a partir del cual la clave deja de autenticarse; null = nunca. Una rotación lo fija en la clave antigua al final del solape.
api_key.created_by_user_idstring (uuid) | nullnoEl usuario del dashboard cuya sesión emitió la clave. null cuando la emitió otra clave dd_, el operador o las semillas, y en toda clave anterior al campo.
api_key.created_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 — ApiKeyAdminForbidden ​

Se rechazó emitir o revocar una clave de API. code role_forbidden: quien llama es un inicio de sesión de dashboard sin el rol account_admin, o una clave dd_ en un tenant que ya tiene un account_admin activo (interruptor del founder api_key_manages_people, desactivado por defecto); el interruptor por tenant api_key_admin_only (activado por defecto) desactiva esto.

json
{
  "error": {
    "code": "role_forbidden",
    "message": "minting or revoking an API key takes a dashboard login with the account_admin role; a dd_ key may do it only while the tenant has no account_admin"
  }
}

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 — Unprocessable ​

La forma es correcta, la semántica no (regla de dominio incumplida).

json
{
  "error": {
    "code": "unprocessable",
    "message": "scheduled_at is closer than the minimum notice for a callback (10 minutes unless the tenant's callback_min_notice_seconds says otherwise)"
  }
}

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

Revocar una clave de API ​

http
DELETE /v1/api_keys/{id}

Fija revoked_at; las claves nunca se borran. Semántica de revocación idempotente.

Reglas de rol: revocar requiere un login account_admin (403 role_forbidden para un member Y, una vez que el tenant tiene un account_admin activo, para una clave dd_; knob por tenant api_key_admin_only, activado por defecto; knob del founder api_key_manages_people, desactivado por defecto). Un tenant sin ningún account_admin activo mantiene la revocación con la clave dd_. Toda revocación se escribe en la pista de auditoría de la clave. Una clave que tiene una lista de permisos solo puede revocarse a sí misma y a las claves cuyos permisos cubre: en otro caso 403 permission_escalation.

Una clave de API test solo puede actuar sobre claves test: contra una clave live se rechaza con 403 test_environment y la clave queda intacta.

Parámetros

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

Respuestas

200 ​

La clave revocada.

CampoTipoObligatorioDescripción
api_keyobject (ApiKey)síMetadatos de la clave — el hash del token nunca se expone.
api_key.idstring (uuid)no
api_key.labelstringno
api_key.environmentlive · testnolive (toda clave anterior al campo) o test: una clave de prueba no alcanza ninguna ruta de salida. Fijo en la creación.
api_key.revoked_atstring (date-time) | nullno
api_key.last_used_atstring (date-time) | nullnoReloj de higiene de rotación: la última vez que esta clave se autenticó CON ÉXITO. Se escribe como mucho una vez por minuto por clave, de modo que una lectura reciente puede ir retrasada hasta ese tiempo. null significa que no se ha autenticado con éxito desde que la columna adquirió un escritor — no que la clave nunca se haya presentado.
api_key.allowed_cidrsarreglo de stringnoLista de permitidos de red. [] = sin restricción. Fuera de ella, una petición se sirve y se cuenta, o se rechaza con 401, según el interruptor de tenant api_key_network_enforced (desactivado por defecto).
api_key.stalebooleannotrue para una clave live sin uso durante 90 días (una clave que nunca se autenticó cuenta desde su creación). Es un consejo para que la consola la rote o la revoque; una clave solo caduca por sí sola cuando tiene expires_at.
api_key.permissionsarreglo de ApiKeyPermission | nullnoGrupos de rutas a los que puede entrar la clave. null = todos (toda clave anterior al campo).
api_key.expires_atstring (date-time) | nullnoInstante a partir del cual la clave deja de autenticarse; null = nunca. Una rotación lo fija en la clave antigua al final del solape.
api_key.created_by_user_idstring (uuid) | nullnoEl usuario del dashboard cuya sesión emitió la clave. null cuando la emitió otra clave dd_, el operador o las semillas, y en toda clave anterior al campo.
api_key.created_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"
  }
}

403 — ApiKeyAdminForbidden ​

Se rechazó emitir o revocar una clave de API. code role_forbidden: quien llama es un inicio de sesión de dashboard sin el rol account_admin, o una clave dd_ en un tenant que ya tiene un account_admin activo (interruptor del founder api_key_manages_people, desactivado por defecto); el interruptor por tenant api_key_admin_only (activado por defecto) desactiva esto.

json
{
  "error": {
    "code": "role_forbidden",
    "message": "minting or revoking an API key takes a dashboard login with the account_admin role; a dd_ key may do it only while the tenant has no account_admin"
  }
}

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

Rotar una clave de API en un paso, con solape ​

http
POST /v1/api_keys/{id}/rotate

Emite una clave nueva con la misma etiqueta, entorno, lista de redes y permisos y deja que la antigua siga autenticándose durante overlap_seconds (3600 por defecto, máximo 86400; 0 la corta de inmediato); pasado ese tiempo solo lo hace la nueva. El expires_at de la clave antigua pasa a ser el final del solape (nunca posterior al que ya tuviera) y se devuelve como rotated. El token nuevo se muestra UNA SOLA VEZ. El rastro de auditoría de claves recibe issued (nueva) y rotated (antigua). Mismos roles, límite de tasa de emisión y límite de claves live que la emisión; durante el solape ambas claves cuentan para el límite. Una clave que tiene una lista de permisos solo rota claves cuyos permisos cubre (403 permission_escalation). Una clave revocada, caducada o desconocida es 404.

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)

CampoTipoObligatorioDescripción
overlap_secondsintegerno
expires_atstring (date-time) | nullnoCaducidad opcional de la clave NUEVA (la caducidad de la antigua no se hereda).
json
{
  "overlap_seconds": 1800
}

Respuestas

201 ​

La clave nueva (con su token, una sola vez) y la antigua con el final de su solape.

CampoTipoObligatorioDescripción
api_keyobject (ApiKey)síMetadatos de la clave — el hash del token nunca se expone.
api_key.idstring (uuid)no
api_key.labelstringno
api_key.environmentlive · testnolive (toda clave anterior al campo) o test: una clave de prueba no alcanza ninguna ruta de salida. Fijo en la creación.
api_key.revoked_atstring (date-time) | nullno
api_key.last_used_atstring (date-time) | nullnoReloj de higiene de rotación: la última vez que esta clave se autenticó CON ÉXITO. Se escribe como mucho una vez por minuto por clave, de modo que una lectura reciente puede ir retrasada hasta ese tiempo. null significa que no se ha autenticado con éxito desde que la columna adquirió un escritor — no que la clave nunca se haya presentado.
api_key.allowed_cidrsarreglo de stringnoLista de permitidos de red. [] = sin restricción. Fuera de ella, una petición se sirve y se cuenta, o se rechaza con 401, según el interruptor de tenant api_key_network_enforced (desactivado por defecto).
api_key.stalebooleannotrue para una clave live sin uso durante 90 días (una clave que nunca se autenticó cuenta desde su creación). Es un consejo para que la consola la rote o la revoque; una clave solo caduca por sí sola cuando tiene expires_at.
api_key.permissionsarreglo de ApiKeyPermission | nullnoGrupos de rutas a los que puede entrar la clave. null = todos (toda clave anterior al campo).
api_key.expires_atstring (date-time) | nullnoInstante a partir del cual la clave deja de autenticarse; null = nunca. Una rotación lo fija en la clave antigua al final del solape.
api_key.created_by_user_idstring (uuid) | nullnoEl usuario del dashboard cuya sesión emitió la clave. null cuando la emitió otra clave dd_, el operador o las semillas, y en toda clave anterior al campo.
api_key.created_atstring (date-time)no
tokenstringsíToken bearer en texto plano, mostrado exactamente una vez.
rotatedobject (ApiKey)síMetadatos de la clave — el hash del token nunca se expone.
rotated.idstring (uuid)no
rotated.labelstringno
rotated.environmentlive · testnolive (toda clave anterior al campo) o test: una clave de prueba no alcanza ninguna ruta de salida. Fijo en la creación.
rotated.revoked_atstring (date-time) | nullno
rotated.last_used_atstring (date-time) | nullnoReloj de higiene de rotación: la última vez que esta clave se autenticó CON ÉXITO. Se escribe como mucho una vez por minuto por clave, de modo que una lectura reciente puede ir retrasada hasta ese tiempo. null significa que no se ha autenticado con éxito desde que la columna adquirió un escritor — no que la clave nunca se haya presentado.
rotated.allowed_cidrsarreglo de stringnoLista de permitidos de red. [] = sin restricción. Fuera de ella, una petición se sirve y se cuenta, o se rechaza con 401, según el interruptor de tenant api_key_network_enforced (desactivado por defecto).
rotated.stalebooleannotrue para una clave live sin uso durante 90 días (una clave que nunca se autenticó cuenta desde su creación). Es un consejo para que la consola la rote o la revoque; una clave solo caduca por sí sola cuando tiene expires_at.
rotated.permissionsarreglo de ApiKeyPermission | nullnoGrupos de rutas a los que puede entrar la clave. null = todos (toda clave anterior al campo).
rotated.expires_atstring (date-time) | nullnoInstante a partir del cual la clave deja de autenticarse; null = nunca. Una rotación lo fija en la clave antigua al final del solape.
rotated.created_by_user_idstring (uuid) | nullnoEl usuario del dashboard cuya sesión emitió la clave. null cuando la emitió otra clave dd_, el operador o las semillas, y en toda clave anterior al campo.
rotated.created_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 — ApiKeyAdminForbidden ​

Se rechazó emitir o revocar una clave de API. code role_forbidden: quien llama es un inicio de sesión de dashboard sin el rol account_admin, o una clave dd_ en un tenant que ya tiene un account_admin activo (interruptor del founder api_key_manages_people, desactivado por defecto); el interruptor por tenant api_key_admin_only (activado por defecto) desactiva esto.

json
{
  "error": {
    "code": "role_forbidden",
    "message": "minting or revoking an API key takes a dashboard login with the account_admin role; a dd_ key may do it only while the tenant has no account_admin"
  }
}

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

409 — ApiKeyLimit ​

El tenant ya tiene el número máximo de claves de API VIVAS (interruptor por tenant api_keys_max_live, 50 por defecto). code api_key_limit. No se emitió nada; revoca una clave (DELETE /v1/api_keys/{id}) y reintenta.

json
{
  "error": {
    "code": "api_key_limit",
    "message": "this tenant already holds the maximum number of live API keys; revoke one first"
  }
}

422 — Unprocessable ​

La forma es correcta, la semántica no (regla de dominio incumplida).

json
{
  "error": {
    "code": "unprocessable",
    "message": "scheduled_at is closer than the minimum notice for a callback (10 minutes unless the tenant's callback_min_notice_seconds says otherwise)"
  }
}

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

Peticiones hechas con una clave de API ​

http
GET /v1/api_keys/{id}/requests

El rastro de peticiones de UNA clave dd_, la más reciente primero, paginado por keyset: método, PLANTILLA de ruta (/v1/calls/:call_id, nunca la URL con ids), estado HTTP, duración y el request_id que quien llama también vio en x-request-id. Una petición aparece en cuestión de segundos (el escritor es asíncrono, fuera de la ruta de la petición).

Nunca se almacena: cuerpos de petición o respuesta, cabeceras (incluida Authorization), la query string, la IP ni el hash de la clave. Las filas se conservan API_REQUEST_LOG_RETENTION_DAYS días (30 por defecto, mínimo 1). Un 429 de la cuota de la clave es una fila como cualquier otra; lleva la plantilla de ruta que el router había casado (/v1 cuando aún ninguna).

Filtros: since (inclusivo) y until (exclusivo), RFC-3339; status, un estado HTTP exacto. Un filtro mal formado es 400, nunca una página vacía en silencio. Ámbito de tenant (clave dd_ o login del dashboard); una clave de otro tenant es 404.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)síUUID del recurso. Los ids mal formados o de otro tenant se leen como 404.
sincequerystring (date-time)no
untilquerystring (date-time)no
statusqueryintegerno
limitqueryintegerno
cursorquerystringnoCursor keyset opaco: el next_cursor de la página anterior.

Respuestas

200 ​

Una página de peticiones, la más reciente primero.

CampoTipoObligatorioDescripción
requestsarreglo de ApiRequestsí
requests[].idstring (uuid)sí
requests[].request_idstringsíEl x-request-id de la petición.
requests[].methodstringsí
requests[].routestringsíPlantilla de ruta, nunca la URL con ids.
requests[].statusintegersí
requests[].duration_usintegersíMicrosegundos desde que se aceptó la clave hasta que salió la respuesta.
requests[].requested_atstring (date-time)sí
next_cursorstring | nullsíCursor de la página siguiente; null en la última.

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 (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. 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 (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"
  }
}

Peticiones por minuto de una clave de API, con sus 429 ​

http
GET /v1/api_keys/{id}/requests/summary

Recuentos por minuto de las peticiones de UNA clave: requests, rate_limited (estado 429, la cuota de la clave o del tenant) y server_errors (estado >= 500). Solo aparecen los minutos con tráfico, el más reciente primero. Ventana [since, until): por defecto la última hora, como máximo 1440 minutos (400 por encima). Mismo ámbito, retención y regla 404 que el listado.

Parámetros

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

Respuestas

200 ​

Los recuentos por minuto.

CampoTipoObligatorioDescripción
minutesarreglo de ApiRequestMinutesí
minutes[].minutestring (date-time)sí
minutes[].requestsintegersí
minutes[].rate_limitedintegersíRespuestas con estado 429.
minutes[].server_errorsintegersíRespuestas con estado >= 500.

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 (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. 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 (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"
  }
}

Nada de esta documentación es asesoría legal: confirma siempre tu postura de cumplimiento con tu propio abogado.