> ## 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：获取 Didit API 凭证

> Didit 提供 POST /programmatic/verify-email/ 接口，用于确认邮箱并返回访问令牌、client_id 和 api_key。支持智能体原生入驻，按量付费定价。



验证邮箱并获取凭证提示词
        将提示词复制到剪贴板



      
      

\<pre>

\`Exchange the email verification code for usable Didit credentials — step 2 of programmatic onboarding.

Endpoint:
POST https://apx.didit.me/auth/v2/programmatic/verify-email/

Authentication:
None. The email + code pair is the credential.

Request body:
\- email (string, required) — Same email used in /programmatic/register/.
\- code (string, required) — 6-character alphanumeric code from the registration email (e.g. "A3K9F2"). Valid for 15 minutes.

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

Response (200 OK):
\{
"access_token": "eyJ...RS256 JWT",
"refresh_token": "eyJ...RS256 JWT",
"expires_in": 86400,
"organization": {
"uuid": "a1b2c3d4-5678-...",
"name": "you"
},
"application": {
"uuid": "b2c3d4e5-6789-...",
"name": "you",
"client_id": "S9LIYGSoWNuGMLHsvEt9dQ",
"api_key": "sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"data_location": "eu"
}
}

What happens server-side:
1\. The pending account is marked email-verified.
2\. A default organization is created (named after the local part of the email, e.g. "you" from "you@yourdomain.com").
3\. A default application is created inside the organization with a fresh client_id and api_key, in the European Union (data_location "eu"). Its location can be chosen once with PATCH /organizations/me/{org_id}/applications/{app_id}/ before the application is used; see /auth-api/update-application.
4\. JWTs are issued (RS256, default 24h / 86400 seconds lifetime).

How to use the response:
\- application.api_key → set as the x-api-key header on EVERY call to https://verification.didit.me/v3/... (sessions, workflows, questionnaires, billing, etc.). PERSIST IT SECURELY. You can read it again later with GET /organizations/me/{org_id}/applications/{app_id}/.
\- access_token → use as "Authorization: Bearer <access_token>" against Account Management endpoints on https://apx.didit.me/auth/v2 (e.g. to create more applications).
\- refresh_token → exchange for a new access_token after expiry.

Save the api_key, the organization.uuid (org_id), and the application.uuid (app_id) — you will need all three to manage applications later.

Failure modes (400 unless noted):
\- Field-level: { "email": ["Enter a valid email address."] } or { "code": ["Ensure this field has at least 6 characters."] }.
\- Wrong or expired code CURRENTLY returns a BARE ARRAY ["Invalid or expired verification code."] — known server-side inconsistency; treat as { "code": [...] } client-side.
\- Unknown email: { "detail": "User not found." }

Recovery if you lose the api_key later:
Call POST /programmatic/login/ with email + password to get a fresh access_token, then GET /organizations/me/{org_id}/applications/{app_id}/ to read the api_key back. See /auth-api/login and /auth-api/get-credentials.

For end-to-end Didit integration, paste in the full prompt at /integration/integration-prompt.`

\</pre>



      
      

粘贴到



## OpenAPI

````yaml zh/openapi-auth.json POST /programmatic/verify-email/
openapi: 3.0.0
info:
  version: 1.0.0
  title: Didit Auth API
  description: >-
    面向开发者和 AI 代理的程序化注册与认证 API。仅需 2 次 API 调用即可完成注册，无需浏览器。对代理最友好的身份证件验证平台。


    ## Base URL


    本规范中的所有 endpoint 均托管在 `https://apx.didit.me/auth/v2`。该主机与验证
    API（`https://verification.didit.me/v3`）不同。请务必区分它们：此认证主机负责签发您的 **JWT 访问
    token**，并允许您列出和管理您的**组织**与**应用**。验证主机则是您调用会话、工作流、AML 等服务的地方，使用此 API 返回的
    **`api_key`** 进行身份验证。


    ## 认证流程运作方式


    1. `POST /programmatic/register/`：提交邮箱 + 密码。

    2. 通过电子邮件接收 6 位字母数字验证码。

    3. `POST /programmatic/verify-email/`：提交验证码。您将获得 JWT
    `access_token`、`refresh_token`、一个组织以及带有 `client_id` + `api_key` 的默认应用。

    4. 保存 `api_key`。在对 `https://verification.didit.me/v3/...` 的每次调用中将其作为
    `x-api-key` 使用。

    5. 在将来的任何机器上，`POST /programmatic/login/` 都可以用您的邮箱 + 密码换取全新的 JWT，然后调用 `GET
    /organizations/me/` 和应用 endpoint 来恢复或轮换凭据。


    JWT 仅在用于本规范中的**账户管理** endpoint 时需要；验证 API 的流量使用的是长期有效的 `api_key`，而非 JWT。


    ## 约定


    - 所有请求体和响应体均为 JSON（`Content-Type: application/json`）。

    - **在测试 `POST /programmatic/register/` 时，请使用真实、可投递的电子邮件地址。** 该 endpoint
    会同步发送验证码，因此保留测试域名（`@example.com`、`@example.org`、`@*.test`、`@*.example`、`@*.invalid`）的地址将被邮件发送系统拒绝，且请求将返回
    `500`。请将示例中的占位符 `you@yourdomain.com` 替换为您实际可以查收的收件箱。

    - 验证错误返回 HTTP `400`，具有以下两种外层结构之一：针对字段级问题的 `{"field": ["message",
    ...]}`，或针对业务规则错误的 `{"detail":
    "message"}`。少数验证器（注册时的密码强度、验证邮箱时的验证码过期）目前会响应纯数组 `["message"]`
    而不是以字段为键的形式，这是已知的服务端不一致性，因此客户端代码应同时支持这两种结构。

    - 身份验证错误将作为 `{"detail": "..."}` 返回，状态码为 HTTP `401`（无效的 bearer token）或
    `403`（缺少 bearer token / 权限不足）。

    - 速率限制响应包含一个以秒为单位的冷却时间字段 `wait`。
servers:
  - url: https://apx.didit.me/auth/v2
    description: 生产环境认证服务器
security: []
tags:
  - name: Programmatic Auth
    description: >-
      邮箱和密码账户生命周期：注册、验证、登录。返回用于访问账户管理 endpoint 的 JWT
      `access_token`，并在验证通过时一并返回您首个应用的 `client_id` 和 `api_key`。
  - name: Account Management
    description: >-
      用于列出组织以及创建、获取或更新应用的经认证 endpoint（JWT bearer）。使用这些 endpoint 可以恢复或轮换用于验证 API
      调用身份的 `api_key`。
paths:
  /programmatic/verify-email/:
    post:
      tags:
        - Programmatic Auth
      summary: 验证邮箱并签发凭证
      description: 入驻的第 2 步。使用 6 位字符验证码换取已验证账户、默认组织+应用以及一对 JWT。请妥善保存返回的 `api_key`。
      operationId: programmatic_verify_email
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyEmailRequest'
            examples:
              Default:
                summary: 提交注册邮件中的验证码
                value:
                  email: you@yourdomain.com
                  code: A3K9F2
      responses:
        '200':
          description: >-
            邮箱已验证。响应包含此认证 API 的 token，以及全新应用的 `client_id` 和 `api_key`。请妥善保存
            `api_key`，它是每次调用验证 API 时所使用的长期凭据。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerifyEmailResponse'
              examples:
                Success:
                  value:
                    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
                      data_location: eu
        '400':
          description: >-
            验证错误。预期的封装格式为：字段级问题使用 `{"field": ["..."]}`，业务规则错误使用 `{"detail":
            "..."}`（例如未找到用户）。验证码错误或已过期目前会返回裸数组 `["Invalid or expired
            verification code."]`，这是已知的服务端不一致性；在修复前请将其视为 `{"code": ["..."]}` 处理。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
              examples:
                MissingFields:
                  summary: 空请求体
                  value:
                    email:
                      - This field is required.
                    code:
                      - This field is required.
                CodeTooShort:
                  summary: 验证码少于 6 个字符
                  value:
                    code:
                      - Ensure this field has at least 6 characters.
                InvalidEmail:
                  summary: 邮箱格式错误
                  value:
                    email:
                      - Enter a valid email address.
                InvalidCode:
                  summary: 验证码错误或已过期
                  value:
                    - Invalid or expired verification code.
                UserNotFound:
                  summary: 该邮箱没有待处理的账户
                  value:
                    detail: User not found.
        '429':
          description: '服务当前正在同时核验尽可能多的密码或验证码。随 `Retry-After: 5` 请求头一同发送；请在指定的秒数后重试。'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitError'
              examples:
                PasswordChecksBusy:
                  summary: 正在进行的密码检查过多
                  value:
                    detail: >-
                      Too many sign-in attempts are being processed right now.
                      Please try again in a few seconds.
      security:
        - {}
      x-codeSamples:
        - lang: curl
          label: cURL
          source: >-
            curl -X POST https://apx.didit.me/auth/v2/programmatic/verify-email/
            \
              -H "Content-Type: application/json" \
              -d '{
                "email": "you@yourdomain.com",
                "code": "A3K9F2"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # This call needs no API key.
            client = Didit()

            result = client.account.verify_email(
                email="you@yourdomain.com",
                code="A3K9F2",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // This call needs no API key.
            const didit = new Didit();

            const result = await didit.account.verifyEmail({
              email: "you@yourdomain.com",
              code: "A3K9F2",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// This call needs no API key.\nclient := didit.NewClient()\n\nresult, err := client.Account.VerifyEmail(ctx, didit.VerifyEmailRequest{\n\tEmail: \"you@yourdomain.com\",\n\tCode:  \"A3K9F2\",\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.VerifyEmailRequest;


            // This call needs no API key.

            Didit client = new Didit();


            var result =
            client.account().verifyEmail(VerifyEmailRequest.builder()
                    .email("you@yourdomain.com")
                    .code("A3K9F2")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // This call needs no API key.
            $didit = new DiditClient();

            $result = $didit->account->verifyEmail([
                'email' => 'you@yourdomain.com',
                'code' => 'A3K9F2',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # This call needs no API key.
            didit = Didit::Client.new

            result = didit.account.verify_email(
              email: "you@yourdomain.com",
              code: "A3K9F2"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // This call needs no API key.

            using var client = new DiditClient();


            var result = await client.Account.VerifyEmailAsync(new
            VerifyEmailRequest

            {
                Email = "you@yourdomain.com",
                Code = "A3K9F2",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    VerifyEmailRequest:
      type: object
      required:
        - email
        - code
      properties:
        email:
          type: string
          format: email
          description: 在 `POST /programmatic/register/` 期间使用的邮箱。
          example: you@yourdomain.com
        code:
          type: string
          minLength: 6
          maxLength: 6
          description: 验证邮件中的 6 位字母数字代码。验证码在最新一次发送后的 10 分钟过期。
          example: A3K9F2
    VerifyEmailResponse:
      type: object
      properties:
        access_token:
          type: string
          description: >-
            RS256 签名的 JWT。用作 `apx.didit.me/auth/v2` 上账户管理 endpoint 的
            `Authorization: Bearer <token>`。
        refresh_token:
          type: string
          description: 与访问 token 配对的刷新 token。
        expires_in:
          type: integer
          description: 访问 token 的生命周期（秒），默认 86400。
          example: 86400
        organization:
          $ref: '#/components/schemas/OrganizationSummary'
        application:
          $ref: '#/components/schemas/ApplicationCredentialsSummary'
    ValidationError:
      description: >-
        验证错误主体。预期的包装格式为针对字段级错误的 `{field: ["message", ...]}` 映射，或针对业务规则错误的
        `{detail: "..."}` 单键包装格式。少数验证器（注册时的密码强度、邮箱验证时的验证码有效性）当前会返回单纯的数组
        `["message"]`（已知的服务端不一致情况）。以下架构保留了该单纯数组分支，以便根据本规范生成的客户端代码可以反序列化当前的响应，但新的客户端代码应将其视为以相关字段为键的形式（`{password:
        [...]}` 或 `{code: [...]}`），服务端契约也将逐步统一为该结构。
      oneOf:
        - type: object
          additionalProperties:
            type: array
            items:
              type: string
          example:
            email:
              - Enter a valid email address.
        - type: object
          properties:
            detail:
              type: string
          example:
            detail: An account with this email already exists.
        - type: array
          items:
            type: string
          example:
            - Invalid or expired verification code.
    RateLimitError:
      type: object
      description: 速率限制或递进式锁定响应。`wait` 为冷却时间（秒）。
      properties:
        detail:
          type: string
          example: >-
            Too many login attempts from this IP address. Please wait before
            trying again.
    OrganizationSummary:
      type: object
      description: '`POST /programmatic/verify-email/` 内联返回的最小组织结构。'
      properties:
        uuid:
          type: string
          format: uuid
          example: a1b2c3d4-5678-90ab-cdef-111111111111
        name:
          type: string
          example: developer
    ApplicationCredentialsSummary:
      type: object
      description: '`POST /programmatic/verify-email/` 内联返回的最小应用结构。请立即持久化保存该 `api_key`。'
      properties:
        uuid:
          type: string
          format: uuid
          example: b2c3d4e5-6789-01bc-defg-222222222222
        name:
          type: string
          example: developer
        client_id:
          type: string
          example: S9LIYGSoWNuGMLHsvEt9dQ
        api_key:
          type: string
          description: >-
            在每次调用验证 API 时将其用作 `x-api-key`。新密钥以 `sk_live_`（生产环境应用）或
            `sk_test_`（沙盒应用）开头，后跟 43 个 URL 安全字符（字母、数字、`-` 和
            `_`）。在此格式之前创建的密钥没有前缀，可继续正常使用。
          example: sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        data_location:
          $ref: '#/components/schemas/ApplicationDataLocation'
    ApplicationDataLocation:
      type: string
      enum:
        - eu
        - au
        - mx
      description: >-
        应用验证数据的存储和处理位置，在创建应用时选择。`eu` 为欧盟（爱尔兰），即默认值。`au`（澳大利亚，悉尼）和
        `mx`（墨西哥）即将推出：指定这些位置的请求将返回 400 `This data location is not available
        yet.`。组织的沙盒应用始终位于欧盟。
      example: eu

````

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