> ## 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.

# API para enviar OTP por email: código de verificación

> POST /v3/email/send/ de Didit envía un código de un solo uso. Reintento si no se entrega, validez de 5 min, pago por uso, sin mínimos mensuales.



## OpenAPI

````yaml es/openapi-25.json POST /v3/email/send/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API de verificación de identidad. Autentícate con el encabezado x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/email/send/:
    post:
      tags:
        - Standalone APIs
      summary: Enviar código por correo electrónico
      description: >-
        Envía un código de un solo uso (OTP) a una dirección de correo
        electrónico y luego verifícalo con [`POST
        /v3/email/check/`](/es/standalone-apis/email-check).


        **Cómo se relacionan el envío y la comprobación.** El estado de la
        verificación se identifica por tu aplicación y la dirección `email`: la
        llamada de comprobación no recibe `request_id`. Cada nuevo envío crea
        una verificación pendiente que dura **5 minutos**: llama a la
        comprobación con la misma dirección y el código que recibió el usuario
        antes de que se cierre ese plazo. Si vuelves a llamar al envío para la
        misma dirección mientras hay una verificación pendiente, se genera un
        código nuevo para esa misma verificación (`status: "Retry"`, mismo
        `request_id`) y el código anterior deja de funcionar. Así se asocia como
        máximo un reintento (dos envíos en total); un envío adicional inicia una
        verificación nueva con un nuevo `request_id`. El plazo de 5 minutos se
        cuenta desde el primer envío y los reintentos no lo amplían.


        **Comprobación previa de entregabilidad.** Antes de enviar nada, la
        dirección pasa por una validación de sintaxis y de DNS/MX. Las
        direcciones que no pueden recibir correo devuelven `200` con `status:
        "Undeliverable"` y `reason: "email_can_not_be_delivered"`: no se envía
        ningún correo, no se factura nada y la verificación se finaliza de
        inmediato como `Declined` (una comprobación posterior devuelve `Expired
        or Not Found`). Un fallo de envío posterior se notifica de la misma
        forma.


        **Formato del código y marca.** Los códigos tienen de 4 a 8 caracteres
        (`options.code_size`, 6 por defecto) y son numéricos por defecto;
        establece `options.alphanumeric_code: true` para usar letras mayúsculas
        y dígitos (la comparación en la comprobación no distingue mayúsculas de
        minúsculas). La plantilla del correo se localiza mediante
        `options.locale` (54 idiomas compatibles) y puede usar la
        personalización de marca blanca de tu aplicación mediante
        `options.use_white_label_customization`.


        **Facturación.** Un crédito de la API de Verificación de correo
        electrónico por cada envío correcto (`status: "Success"`), que se cobra
        en el momento del envío. Los envíos `Retry` y `Undeliverable` son
        gratuitos, y las comprobaciones también.


        **Persistencia de la sesión.** Cada nueva verificación se guarda como
        una sesión de tipo API: `request_id` es un id de sesión real que puedes
        pasar a `GET /v3/session/{sessionId}/decision/`, la verificación aparece
        en la Business Console y se disparan webhooks `status.updated` a medida
        que avanza.


        **Sandbox.** Las claves de API de sandbox omiten la entrega y la
        facturación: tras validar la solicitud (una entrada mal formada sigue
        devolviendo `400`), el endpoint devuelve un payload estático `Success`
        con un `request_id` aleatorio; no se envía ningún correo y no se guarda
        nada. Usa el código `123456` en la comprobación de sandbox.


        **Autenticación.** Envía la clave de API de tu aplicación en el
        encabezado `x-api-key`. Si faltan las credenciales o no son válidas, se
        devuelve `403` (`{"detail": "You do not have permission to perform this
        action."}`): esta API nunca devuelve `401`.


        **Límite de solicitudes.** Presupuesto de escritura compartido de 300
        solicitudes por minuto por clave de API entre todos los endpoints
        POST/PATCH/DELETE; si se supera, se devuelve `429`.
      operationId: post_v3email_send
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  format: email
                  description: >-
                    Dirección de correo electrónico del destinatario. Las
                    direcciones mal formadas devuelven `400`; las direcciones
                    sintácticamente válidas que no pueden recibir correo
                    (validación DNS/MX fallida) devuelven `200` con `status:
                    "Undeliverable"`.
                  example: alice@example.com
                options:
                  type: object
                  description: >-
                    Opciones de formato, localización y marca del OTP. Todos los
                    campos son opcionales.
                  properties:
                    code_size:
                      type: integer
                      minimum: 4
                      maximum: 8
                      default: 6
                      description: >-
                        Número de caracteres del OTP (dígitos de forma
                        predeterminada; letras mayúsculas y dígitos cuando
                        `alphanumeric_code` es `true`).
                    alphanumeric_code:
                      type: boolean
                      default: false
                      description: >-
                        Si es `true`, el OTP se compone de letras mayúsculas
                        `A–Z` y dígitos `0–9` en lugar de solo dígitos. La
                        comparación de `/v3/email/check/` no distingue entre
                        mayúsculas y minúsculas.
                    locale:
                      type: string
                      maxLength: 5
                      enum:
                        - en
                        - ar
                        - bn
                        - bg
                        - bs
                        - ca
                        - cs
                        - da
                        - de
                        - el
                        - es
                        - et
                        - fa
                        - fi
                        - fr
                        - he
                        - hi
                        - hr
                        - hu
                        - hy
                        - id
                        - it
                        - ja
                        - ka
                        - kk
                        - ko
                        - ky
                        - lt
                        - lv
                        - cnr
                        - mk
                        - mn
                        - ms
                        - nl
                        - 'no'
                        - pl
                        - pt-BR
                        - pt
                        - ro
                        - ru
                        - sk
                        - sl
                        - so
                        - sq
                        - sr
                        - sv
                        - th
                        - tr
                        - uk
                        - uz
                        - vi
                        - zh-CN
                        - zh-TW
                        - zh
                      description: >-
                        Idioma de la plantilla de correo electrónico del OTP. El
                        valor predeterminado es `en`. Los valores no admitidos
                        devuelven `400` con la lista de todas las
                        configuraciones regionales admitidas.
                      example: en
                    use_white_label_customization:
                      type: boolean
                      default: false
                      description: >-
                        Si es `true`, el correo electrónico del OTP usa la
                        personalización de marca blanca de tu aplicación
                        (logotipo, colores, marca del remitente) en lugar de la
                        plantilla predeterminada de Didit.
                signals:
                  type: object
                  description: >-
                    Señales opcionales de dispositivo y red sobre el usuario
                    final, que se envían a la capa antifraude para mejorar la
                    detección de tráfico abusivo o automatizado. Todos los
                    campos son opcionales.
                  properties:
                    ip:
                      type: string
                      description: >-
                        Dirección IP del dispositivo del usuario final. IPv4 o
                        IPv6.
                      example: 192.0.2.1
                    device_id:
                      type: string
                      maxLength: 255
                      description: >-
                        Identificador único del dispositivo del usuario final.
                        Android: `ANDROID_ID`; iOS: `identifierForVendor`.
                      example: 8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2
                    device_platform:
                      type: string
                      enum:
                        - android
                        - ios
                        - ipados
                        - tvos
                        - web
                      description: Plataforma del dispositivo del usuario final.
                    device_model:
                      type: string
                      maxLength: 255
                      description: Modelo del dispositivo del usuario final.
                      example: iPhone17,2
                    os_version:
                      type: string
                      maxLength: 64
                      description: >-
                        Versión del sistema operativo del dispositivo del
                        usuario final.
                      example: 18.0.1
                    app_version:
                      type: string
                      maxLength: 64
                      description: Versión de tu aplicación.
                      example: 1.2.34
                    user_agent:
                      type: string
                      maxLength: 512
                      description: >-
                        User agent del navegador o la aplicación del usuario
                        final.
                      example: >-
                        Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X)
                        AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3
                        Mobile/15E148 Safari/604.1
                vendor_data:
                  type: string
                  description: >-
                    Identificador opcional controlado por quien llama (tu id
                    interno de usuario, un correo electrónico, un UUID, etc.)
                    que se guarda en la sesión y se devuelve en la respuesta del
                    envío, en la respuesta de la comprobación correspondiente,
                    en los webhooks y en la Business Console. Úsalo para
                    relacionar el `request_id` de Didit con tu registro de
                    usuario.
                metadata:
                  type: object
                  nullable: true
                  description: >-
                    Objeto JSON opcional de formato libre que se guarda en la
                    sesión y se devuelve en la respuesta del envío, en la
                    respuesta de la comprobación correspondiente, en los
                    webhooks y en la Business Console.
              required:
                - email
            examples:
              Numeric 6-digit code:
                summary: 'Predeterminado: código numérico de 6 dígitos en inglés'
                value:
                  email: alice@example.com
                  options:
                    locale: en
                  vendor_data: user-1234
              Alphanumeric 8-character code:
                summary: Letras mayúsculas + dígitos, plantilla española
                value:
                  email: bob@example.com
                  options:
                    code_size: 8
                    alphanumeric_code: true
                    locale: es
              White-label branding:
                summary: >-
                  Envía el correo de OTP con la personalización de marca blanca
                  de tu aplicación
                value:
                  email: carol@example.com
                  options:
                    locale: en
                    use_white_label_customization: true
                  vendor_data: user-5678
      responses:
        '200':
          description: >-
            Envío confirmado. Revisa `status`: `Success` y `Retry` significan
            que hay un código en camino; `Undeliverable` significa que la
            dirección no puede recibir correo y la verificación ya se ha
            finalizado como `Declined`. `request_id` es el id de sesión
            persistido (el mismo id en un `Retry`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmailVerificationSendResponse'
              examples:
                Success:
                  summary: >-
                    OTP enviado por correo electrónico para una nueva
                    verificación (facturado)
                  value:
                    request_id: e39cb057-92fc-4b59-b84e-02fec29a0f24
                    status: Success
                    reason: null
                    vendor_data: user-1234
                    metadata: null
                Retry:
                  summary: >-
                    Segundo envío dentro de la ventana de 5 minutos: código
                    nuevo, mismo request_id, gratis
                  value:
                    request_id: e39cb057-92fc-4b59-b84e-02fec29a0f24
                    status: Retry
                    reason: null
                    vendor_data: user-1234
                    metadata: null
                Undeliverable:
                  summary: >-
                    La dirección no superó la validación DNS/MX: la verificación
                    finalizó como Rechazada y no se facturó nada
                  value:
                    request_id: cb1a5011-344d-444d-bdce-218904745d7f
                    status: Undeliverable
                    reason: email_can_not_be_delivered
                    vendor_data: user-1234
                    metadata: null
        '400':
          description: >-
            Error de validación: formato de errores de campo de DRF, con un
            array de mensajes por cada campo incorrecto, anidado bajo `options`
            para los errores de opciones.
          content:
            application/json:
              examples:
                Invalid email:
                  summary: Dirección de correo electrónico con formato incorrecto
                  value:
                    email:
                      - Enter a valid email address.
                Unsupported locale:
                  summary: '`options.locale` fuera del conjunto admitido'
                  value:
                    options:
                      locale:
                        - >-
                          Invalid locale. Supported locales are en, ar, bn, bg,
                          bs, ca, cs, da, de, el, es, et, fa, fi, fr, he, hi,
                          hr, hu, hy, id, it, ja, ka, kk, ko, ky, lt, lv, cnr,
                          mk, mn, ms, nl, no, pl, pt-BR, pt, ro, ru, sk, sl, so,
                          sq, sr, sv, th, tr, uk, uz, vi, zh-CN, zh-TW, zh.
                Code size out of range:
                  summary: '`options.code_size` fuera del rango 4–8'
                  value:
                    options:
                      code_size:
                        - Ensure this value is less than or equal to 8.
        '403':
          description: >-
            Permiso denegado. Se devuelve cuando falta el encabezado `x-api-key`
            (`{"detail": ...}`); una clave incorrecta, revocada o expirada
            devuelve `401`. También se devuelve antes de cualquier envío cuando
            el saldo de la organización no cubre un crédito de la API de
            Verificación de correo electrónico (`{"error": ...}`).
          content:
            application/json:
              examples:
                Missing or invalid API key:
                  summary: >-
                    Falta el encabezado `x-api-key`, o la clave no es válida o
                    está revocada
                  value:
                    detail: You do not have permission to perform this action.
                Not enough credits:
                  summary: El saldo de la organización no cubre el precio del envío
                  value:
                    error: You don't have enough credits to perform this request.
        '429':
          description: >-
            Límite de solicitudes superado. Todos los endpoints
            POST/PATCH/DELETE comparten un presupuesto de 300 solicitudes de
            escritura por minuto por clave de API. La respuesta incluye los
            encabezados `X-RateLimit-Limit`, `X-RateLimit-Remaining`,
            `X-RateLimit-Reset` y `Retry-After`.
          content:
            application/json:
              examples:
                Write rate limit exceeded:
                  summary: Más de 300 solicitudes de escritura en el minuto actual
                  value:
                    detail: >-
                      Write request rate limit exceeded. You can make up to 300
                      requests per minute.
              schema:
                type: object
                properties:
                  detail:
                    type: string
        '503':
          description: >-
            No se pudo contactar con el proveedor de correo electrónico (por una
            interrupción o un tiempo de espera agotado), por lo que no se envió
            ningún código y no se facturó nada ni se contó como intento de
            envío. Repite la misma solicitud.
          content:
            application/json:
              examples:
                Email delivery unavailable:
                  summary: >-
                    El proveedor de correo electrónico falló tras un reintento
                    automático
                  value:
                    detail: >-
                      Email delivery is temporarily unavailable. Please try
                      again.
              schema:
                type: object
                properties:
                  detail:
                    type: string
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST https://verification.didit.me/v3/email/send/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "email": "alice@example.com",
                "options": { "code_size": 6, "locale": "en" },
                "vendor_data": "user-1234"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.email.send_code(
                email="alice@example.com",
                options={
                    "locale": "en",
                },
                vendor_data="user-1234",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.email.sendCode({
              email: "alice@example.com",
              options: {
                locale: "en",
              },
              vendor_data: "user-1234",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Email.SendCode(ctx, didit.EmailSendCodeParams{\n\tEmail: \"alice@example.com\",\n\tOptions: didit.Some(didit.EmailSendCodeParamsOptions{\n\t\tLocale: didit.Some(didit.EmailSendCodeParamsOptionsLocale(\"en\")),\n\t}),\n\tVendorData: didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: |-
            import me.didit.Didit;
            import me.didit.types.EmailSendCodeParams;

            // Reads DIDIT_API_KEY.
            Didit client = new Didit();

            var result = client.email().sendCode(EmailSendCodeParams.builder()
                    .email("alice@example.com")
                    .options(EmailSendCodeParams.Options.builder()
                            .locale(EmailSendCodeParams.Options.Locale.of("en"))
                            .build())
                    .vendorData("user-1234")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $result = $didit->email->sendCode([
                'email' => 'alice@example.com',
                'options' => [
                    'locale' => 'en',
                ],
                'vendor_data' => 'user-1234',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.email.send_code(
              email: "alice@example.com",
              options: {
                locale: "en",
              },
              vendor_data: "user-1234"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.Email.SendCodeAsync(new
            EmailSendCodeParams

            {
                Email = "alice@example.com",
                Options = new EmailSendCodeParamsOptions
                {
                    Locale = new EmailSendCodeParamsOptionsLocale("en"),
                },
                VendorData = "user-1234",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    EmailVerificationSendResponse:
      type: object
      properties:
        request_id:
          type: string
          format: uuid
          description: >-
            ID de sesión de la verificación. Un envío `Retry` devuelve el mismo
            `request_id` que el envío original. Este ID aparece en la Business
            Console, lo vuelve a devolver un `POST /v3/email/check/` finalizado
            y se puede pasar a `GET /v3/session/{sessionId}/decision/`.
        status:
          type: string
          enum:
            - Success
            - Retry
            - Undeliverable
          description: >-
            `Success`: OTP enviado por correo electrónico a una nueva
            verificación (se factura). `Retry`: nuevo OTP enviado por correo
            electrónico para la verificación pendiente creada por un envío
            anterior (gratis). `Undeliverable`: la dirección no superó la
            validación de entregabilidad o no se pudo enviar el mensaje; la
            verificación se finaliza de inmediato como `Declined` y no se
            factura nada.
        reason:
          type: string
          nullable: true
          enum:
            - email_can_not_be_delivered
            - null
          description: >-
            `email_can_not_be_delivered` cuando `status` es `Undeliverable`;
            `null` en caso contrario.
        vendor_data:
          type: string
          nullable: true
          description: >-
            Devuelve el `vendor_data` almacenado en la sesión (del primer
            envío).
        metadata:
          type: object
          nullable: true
          description: Devuelve el `metadata` almacenado en la sesión (del primer envío).
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        La clave de API de tu aplicación, que encontrarás en Developers -> API
        keys en la Business Console. La clave principal tiene acceso completo.
        Una clave con nombre puede tener un alcance limitado: ninguno, lectura o
        escritura por recurso, limitada a algunos flujos o a sesiones aprobadas,
        a una lista de direcciones IP y a una fecha de caducidad. 401 significa
        que la clave es incorrecta, se revocó o expiró; 403 significa que no se
        envió ninguna clave, que la clave no tiene acceso a este recurso o
        acción, o que la solicitud provino de una dirección fuera de su lista de
        IP; 404 en una ruta de sesión significa que la sesión está fuera de los
        flujos o estados de la clave. Una clave sin acceso a contenido
        multimedia recibe las URL de imágenes, videos y PDF como null, y una
        clave sin permiso de escritura en sesiones recibe los enlaces y tokens
        de sesión como null. Consulta https://docs.didit.me/console/api-keys.

````

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