Skip to main content

Overview

Didit is the most agent-friendly identity verification platform. AI coding agents (Cursor, Claude Code, GitHub Copilot, Devin, OpenHands, Codex) can register, configure workflows, and start verifying identities — all programmatically, without ever opening a browser. Why agents love Didit:
  • 2 API calls from zero to credentials (register + verify-email).
  • No browser required — fully headless, perfect for CI/CD and agent workflows.
  • No 2FA friction for API accounts — tokens are returned immediately after email verification.
  • Auto-provisioned organization and application with api_key in the verify response.
  • Full management API — configure workflows, questionnaires, lists, billing, all via API.
  • MCP server available — agents can discover and use Didit tools natively.
The full contract is published as openapi-auth.json; the endpoints below are audited against it.

Base URL

All endpoints in this guide live on the auth host:
This is a different host from the verification API (https://verification.didit.me/v3). The auth host issues JWT access tokens and manages applications. The verification host runs sessions, AML, workflows, etc., authenticated with the long-lived api_key you get from this flow.

Quick start

Use a real, deliverable email address. The endpoint sends the verification code synchronously, so reserved test domains (@example.com, @example.org, @*.test, @*.example, @*.invalid) get rejected by mail delivery and the call returns a 500. Substitute the you@yourdomain.com placeholder below with an inbox you can read.

Step 1: Register

Response (201 Created):
A 6-character alphanumeric verification code (e.g. A3K9F2) is emailed to the address. The code expires 10 minutes after it is sent — if it lapses, call this endpoint again with the same email and password: for a still-unverified account it returns 200 with "A new verification code has been sent to your email." and a fresh code. A dedicated POST /programmatic/resend-otp/ endpoint (body: {"email", "password"}) also re-sends the code, with a 60-second cooldown between sends; both routes share the registration rate limit below.

Step 2: Verify the code and get credentials

Response (200 OK):
You now have everything you need. Persist application.api_key securely and send it as the x-api-key header on every verification API call.
Tokens are RS256-signed JWTs. expires_in defaults to 86400 seconds (24 hours). The access token is only needed for the management endpoints on apx.didit.me/auth/v2 — verification API traffic on verification.didit.me/v3 is authenticated with the long-lived api_key, not the JWT.

Step 3: Use the API

Subsequent logins

From any future machine, exchange your email and password for a fresh JWT:
Returns access_token + refresh_token directly — no browser. From there, hit GET /organizations/me/ to discover your org_id (the organization’s uuid), then GET /organizations/me/{org_id}/applications/ to list the organization’s applications (each entry’s uuid is an app_id), and finally GET /organizations/me/{org_id}/applications/{app_id}/ to recover the api_key.
Console-created email/password accounts can also use POST /programmatic/login/ after the email is verified. OAuth-only console accounts need to set a password before using this headless login endpoint.

Password requirements

Enforced server-side, one rule at a time — the first failure short-circuits with a bare-array error like ["Password must contain at least one uppercase letter."]. (Other validation errors on this endpoint use the field-keyed {"password": [...]} envelope. The bare-array shape on password-strength rules is a known server-side inconsistency; treat it as {"password": [...]} in client code.)
RuleDetail
Minimum length8 characters
Uppercase letterAt least one A–Z
Lowercase letterAt least one a–z
DigitAt least one 0–9
Special characterAt least one of !@#$%^&*()_+-=[]{}|;:,.<>?

Rate limits and lockouts

Three independent controls protect the auth host. Any of them can trigger a 429 response; the Retry-After response header tells you how long to back off.
SurfaceLimit
Registration5 attempts per IP per hour (shared with POST /programmatic/resend-otp/).
Verify-email10 code attempts per email per hour, plus exponential backoff between attempts (30 s, doubling per failure, capped at 1 hour).
Login (IP)20 attempts per IP per minute, and 100 per IP per hour.
Login (email)Progressive lockout on the account: 5 consecutive failures → 15 min lockout; 10 → 1 hour; 20 → 24 hours.
A 429 body looks like this:
Verification API rate limits (e.g. 600 sessions/min) are independent and documented in Rate limiting.

Managing applications

Once authenticated, you can retrieve, create, or update applications inside your organization. This is a perfect fit for resellers that want one application per customer. Each application has its own client_id, api_key, metadata, and settings. It is also useful when your organization has different products, brands, regions, environments, or use cases you want to keep separate.
Listing, creating, or updating applications requires the user to be an owner or admin of the target organization; otherwise the response is 403.

What can agents do after registration?

With the api_key, agents have full access to the verification API. Audited paths on https://verification.didit.me/v3:
APIWhat it does
POST /v3/session/Create a verification session.
GET /v3/sessions/List sessions.
GET /v3/session/{id}/decision/Get the V3 decision (plural arrays — see Data models).
GET /v3/workflows/List verification workflows.
GET /v3/questionnaires/List custom questionnaires.
GET /v3/users/List end users (indexed by vendor_data).
GET /v3/billing/balance/Check credit balance.
POST /v3/billing/top-up/Top up credits.
GET /v3/webhook/destinations/Manage webhook destinations (list / create / update / delete).
See the Management API reference for the full surface.

MCP server integration

For the best agent experience, use the Didit MCP server. Most coding agents (Cursor, Claude Code, Windsurf, etc.) accept this MCP server entry:
See the AI agent integration guide for details.

Error envelope reference

All apx.didit.me/auth/v2 endpoints share the same three response shapes (see openapi-auth.json):
  • Field-level validation{"field": ["message", ...]} with HTTP 400.
  • Form-level validation (notably password strength and verification-code errors) — bare array ["Invalid or expired verification code."] with HTTP 400.
  • Authentication / business rule{"detail": "..."} with 400, 401, 403, 404, or 429. 429 responses carry a Retry-After response header telling you how long to back off (the body has only detail).
The verification host returns errors as {"detail": "..."} and 429s include X-RateLimit-* and Retry-After — see Rate limiting.