> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Registro programático: API de KYC para agentes de IA

> Regístrate y obtén credenciales de la API de Didit en 2 llamadas, sin navegador. KYC nativo para agentes de IA como Cursor, Claude y Devin.

## Descripción general

Didit es la **plataforma de verificación de identidad más adecuada para agentes**. Los agentes de programación con IA (Cursor, Claude Code, GitHub Copilot, Devin, OpenHands, Codex) pueden registrarse, configurar flujos de verificación (workflows) y empezar a verificar identidades, todo de forma programática y sin abrir nunca un navegador.

**Por qué a los agentes les encanta Didit:**

* **2 llamadas a la API** para pasar de cero a credenciales (registro + verificación del correo).
* **Sin navegador**: totalmente headless, ideal para CI/CD y flujos de agentes.
* **Sin segundo factor en una cuenta de API nueva:** los tokens se devuelven inmediatamente después de verificar el correo electrónico.
* **Organización y aplicación aprovisionadas automáticamente**, con `api_key` en la respuesta de verificación.
* **API de gestión completa**: configura flujos, cuestionarios, listas y facturación, todo mediante la API.
* **Servidor MCP** disponible: los agentes pueden descubrir y usar las herramientas de Didit de forma nativa.

El contrato completo está publicado como [openapi-auth.json](https://docs.didit.me/openapi-auth.json); los endpoints que se describen a continuación se han auditado con respecto a él.

## URL base

Todos los endpoints de esta guía se encuentran en el **host de autenticación**:

```
https://apx.didit.me/auth/v2
```

Es un host distinto al de la API de verificación (`https://verification.didit.me/v3`). El host de autenticación emite tokens de acceso JWT y gestiona las aplicaciones. El host de verificación ejecuta sesiones, AML, flujos, etc., y se autentica con la `api_key` de larga duración que obtienes en este proceso.

## Inicio rápido

> [!WARNING]
>
> **Usa una dirección de correo electrónico real y que pueda recibir mensajes.** El endpoint envía el código de verificación de forma síncrona, por lo que los dominios de prueba reservados (`@example.com`, `@example.org`, `@*.test`, `@*.example`, `@*.invalid`) son rechazados por el servicio de entrega de correo y la llamada devuelve un `500`. Sustituye el marcador `you@yourdomain.com` de abajo por una bandeja de entrada a la que tengas acceso.

### Paso 1: Registro

```bash theme={null}
curl -X POST https://apx.didit.me/auth/v2/programmatic/register/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@yourdomain.com", "password": "MyStr0ng!Pass"}'
```

**Respuesta** (`201 Created`):

```json theme={null}
{
  "message": "Registration successful. Check your email for the verification code.",
  "email": "you@yourdomain.com"
}
```

Se envía a la dirección un código de verificación alfanumérico de 6 caracteres (por ejemplo, `A3K9F2`). **El código expira 10 minutos después de enviarse**: si caduca, vuelve a invocar este endpoint con el mismo correo y la misma contraseña; para una cuenta aún no verificada, devuelve `200` con `"A new verification code has been sent to your email."` y un código nuevo. Un endpoint específico, `POST /programmatic/resend-otp/` (cuerpo: `{"email", "password"}`), también reenvía el código, con un tiempo de espera de 60 segundos entre envíos; ambas rutas comparten el límite de solicitudes de registro que se indica más abajo.

### Paso 2: Verifica el código y obtén las credenciales

```bash theme={null}
curl -X POST https://apx.didit.me/auth/v2/programmatic/verify-email/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@yourdomain.com", "code": "A3K9F2"}'
```

**Respuesta** (`200 OK`):

```json theme={null}
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_in": 86400,
  "organization": {
    "uuid": "a1b2c3d4-5678-90ab-cdef-111111111111",
    "name": "developer"
  },
  "application": {
    "uuid": "b2c3d4e5-6789-01bc-defg-222222222222",
    "name": "developer",
    "client_id": "S9LIYGSoWNuGMLHsvEt9dQ",
    "api_key": "sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  }
}
```

Ya tienes todo lo que necesitas. Guarda `application.api_key` de forma segura y envíala como encabezado `x-api-key` en cada llamada a la API de verificación.

> [!NOTE]
>
> Los tokens son **JWT firmados con RS256**. `expires_in` tiene un valor predeterminado de **86400 segundos (24 horas)**. El token de acceso solo se necesita para los endpoints de gestión en `apx.didit.me/auth/v2`; el tráfico de la API de verificación en `verification.didit.me/v3` se autentica con la `api_key` de larga duración, no con el JWT.

### Paso 3: Usa la API

```bash theme={null}
curl https://verification.didit.me/v3/sessions/ \
  -H "x-api-key: sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

## Inicios de sesión posteriores

Desde cualquier otra máquina, intercambia tu correo electrónico y tu contraseña por un JWT nuevo:

```bash theme={null}
curl -X POST https://apx.didit.me/auth/v2/programmatic/login/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@yourdomain.com", "password": "MyStr0ng!Pass"}'
```

Devuelve `access_token` + `refresh_token` directamente, sin navegador. A partir de ahí, invoca `GET /organizations/me/` para descubrir tu `org_id` (el `uuid` de la organización), luego `GET /organizations/me/{org_id}/applications/` para listar las aplicaciones de la organización (el `uuid` de cada entrada es un `app_id`) y, por último, `GET /organizations/me/{org_id}/applications/{app_id}/` para recuperar la `api_key`.

> [!NOTE]
>
> Las cuentas con correo electrónico y contraseña creadas en la consola también pueden usar `POST /programmatic/login/` una vez verificado el correo. Las cuentas de la consola que solo usan OAuth deben establecer una contraseña antes de usar este endpoint de inicio de sesión headless.

### Cuando el inicio de sesión pide algo más

`POST /programmatic/login/` devuelve tokens solo cuando la cuenta no tiene un segundo factor.
Hay otras tres respuestas posibles, y un agente que automatice el inicio de sesión debe gestionarlas:

| Cuenta | Respuesta |
| - | - |
| Tiene una app de autenticación o una passkey | `200` con `{"2fa_required": true, "temp_token": "...", "has_passkeys": true, "has_authenticator": false}` y sin tokens |
| Su organización exige SSO | `403` con `{"error": "sso_required", "message": "...", "organization_name": "...", "organization_slug": "...", "sso_url": "/sso/<slug>"}` |
| Se recuperó y todavía no tiene ningún método de inicio de sesión | `403` con `"code": "recovery_setup_required"`, y se envía a la dirección de la cuenta un enlace para configurar uno |

Una clave de API no necesita inicio de sesión, así que úsala para cualquier proceso automatizado: una cuenta con segundo factor no puede completar el inicio de sesión a través de este endpoint.

## Requisitos de la contraseña

Se aplican en el servidor, **una regla cada vez**: el primer fallo interrumpe la validación con un error en forma de array simple, como `["Password must contain at least one uppercase letter."]`. (Los demás errores de validación de este endpoint usan el formato con clave de campo `{"password": [...]}`. La forma de array simple en las reglas de seguridad de la contraseña es una inconsistencia conocida del servidor; trátala como `{"password": [...]}` en el código del cliente).

| Regla | Detalle |
| - | - |
| Longitud mínima | 8 caracteres |
| Letra mayúscula | Al menos una `A–Z` |
| Letra minúscula | Al menos una `a–z` |
| Dígito | Al menos un `0–9` |
| Carácter especial | Al menos uno de `!@#$%^&*()_+-=[]{}\|;:,.<>?` |

## Límites de solicitudes y bloqueos

Tres controles independientes protegen el host de autenticación. Cualquiera de ellos puede producir una respuesta `429`; el encabezado de respuesta `Retry-After` te indica cuánto tiempo debes esperar antes de reintentar.

| Superficie | Límite |
| - | - |
| Registro | **5** intentos por **IP** por **hora** (compartido con `POST /programmatic/resend-otp/`). |
| Verificación de correo | **10** intentos de código por **correo electrónico** por **hora** y **50** por **IP** de origen por **hora**, además de una espera exponencial entre intentos (30 s, que se duplica con cada fallo, con un máximo de 1 hora). |
| Inicio de sesión (IP) | **20** intentos por **IP** por **minuto** y **100** por **IP** por **hora**. |
| Inicio de sesión (correo) | Bloqueo progresivo de la cuenta: **5** fallos consecutivos → bloqueo de 15 min; **10** → 1 hora; **20** → 24 horas. |

El cuerpo de una respuesta `429` tiene este aspecto:

```json theme={null}
{ "detail": "Too many login attempts from this IP address. Please wait before trying again." }
```

Los límites de solicitudes de la API de verificación (p. ej., 600 sesiones/min) son independientes y se documentan en [Límites de solicitudes](https://docs.didit.me/es/integration/rate-limiting.md).

## Gestionar aplicaciones

Una vez autenticado, puedes obtener, crear o actualizar aplicaciones dentro de tu organización.

Esto encaja perfectamente con los **revendedores** que quieren una aplicación por cliente. Cada aplicación tiene sus propios `client_id`, `api_key`, metadatos y configuración. También resulta útil cuando tu organización tiene distintos productos, marcas, regiones, entornos o casos de uso que quieres mantener separados.

```bash theme={null}
# 1. Discover your org_id
curl https://apx.didit.me/auth/v2/organizations/me/ \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 2. List the organization's applications (each entry's uuid is an app_id)
curl "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 3. Create an application for a customer, product, or environment
curl -X POST "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Customer App",
    "website_url": "https://acme.example",
    "redirect_uris": ["https://acme.example/callback"],
    "terms_url": "https://acme.example/terms",
    "privacy_url": "https://acme.example/privacy"
  }'

# 4. Recover credentials (client_id + api_key) for an existing application
curl "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/$APP_ID/" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 5. Update application metadata (PATCH — uuid, client_id, api_key never change)
curl -X PATCH "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/$APP_ID/" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Production App",
    "website_url": "https://app.acme.example"
  }'
```

Para listar, crear o actualizar aplicaciones, el usuario debe ser **owner** o **admin** de la organización de destino; de lo contrario, la respuesta es `403`.

## Qué pueden hacer los agentes tras el registro

Con la `api_key`, los agentes tienen acceso completo a la API de verificación. Rutas auditadas en `https://verification.didit.me/v3`:

| API | Qué hace |
| - | - |
| `POST /v3/session/` | Crea una sesión de verificación. |
| `GET /v3/sessions/` | Lista las sesiones. |
| `GET /v3/session/{id}/decision/` | Obtiene la decisión V3 (arrays en plural; consulta Modelos de datos). |
| `GET /v3/workflows/` | Lista los flujos de verificación. |
| `GET /v3/questionnaires/` | Lista los cuestionarios personalizados. |
| `GET /v3/users/` | Lista los usuarios finales (indexados por `vendor_data`). |
| `GET /v3/billing/balance/` | Consulta el saldo de créditos. |
| `POST /v3/billing/top-up/` | Recarga créditos. |
| `GET /v3/webhook/destinations/` | Gestiona los destinos de webhook (listar / crear / actualizar / eliminar). |

Consulta la [referencia de la API de administración](https://docs.didit.me/es/sessions-api/management-api.md) para ver todas las operaciones disponibles.

## Integración con el servidor MCP

Para obtener la mejor experiencia con agentes, usa el servidor MCP alojado de Didit en `https://mcp.didit.me/mcp`. No necesita clave de API: en la primera conexión, tu cliente abre un navegador, eliges **Log in with Didit** (OAuth 2.1 con PKCE) y el servidor actúa en tu nombre, con los permisos de tu rol en la consola. Los clientes con soporte nativo para MCP remoto (Cursor, VS Code) usan esta entrada; Claude web y Desktop lo añaden como conector personalizado:

```json theme={null}
{
  "mcpServers": {
    "didit": {
      "url": "https://mcp.didit.me/mcp"
    }
  }
}
```

Claude Code: `claude mcp add --transport http didit https://mcp.didit.me/mcp`. Los clientes que solo admiten stdio (Windsurf, Zed) pasan por el puente `mcp-remote`, que ejecuta el flujo OAuth por ti.

La clave de API que recibes del flujo de registro anterior sirve para llamar a la API REST desde tu propio backend; el MCP nunca la usa. Consulta la [visión general del MCP](https://docs.didit.me/es/integration/mcp/overview.md) y la [instalación por cliente](https://docs.didit.me/es/integration/mcp/installation.md) para más detalles.

## Referencia del formato de errores

Todos los endpoints de `apx.didit.me/auth/v2` comparten las mismas tres formas de respuesta (consulta `openapi-auth.json`):

* **Validación a nivel de campo**: `{"field": ["message", ...]}` con HTTP `400`.
* **Validación a nivel de formulario** (en particular, errores de robustez de la contraseña y del código de verificación): array simple `["Invalid or expired verification code."]` con HTTP `400`.
* **Autenticación / regla de negocio**: `{"detail": "..."}` con `400`, `401`, `403`, `404` o `429`. Las respuestas `429` incluyen un encabezado de respuesta `Retry-After` que te indica cuánto tiempo debes esperar antes de reintentar (el cuerpo solo contiene `detail`).

El host de verificación devuelve los errores como `{"detail": "..."}` y las respuestas 429 incluyen `X-RateLimit-*` y `Retry-After`; consulta [Límites de solicitudes](https://docs.didit.me/es/integration/rate-limiting.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.