# auditing-implementing-didit > Audits and implements Didit.me API v3 verifications, decisions, and webhooks. Handles orchestration and standalone flows. - Author: Damir Sagi - Repository: Damir-VistaBlox/VistaBlox - Version: 20260203124151 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/Damir-VistaBlox/VistaBlox - Web: https://mule.run/skillshub/@@Damir-VistaBlox/VistaBlox~auditing-implementing-didit:20260203124151 --- --- name: auditing-implementing-didit description: Audits and implements Didit.me API v3 verifications, decisions, and webhooks. Handles orchestration and standalone flows. tags: ["didit", "kyc", "identity", "verification", "api", "security"] risk_level: medium version: 1.1.0 --- # Didit.me API v3 Audit & Implementation ## Environment & Config - `DIDIT_API_KEY`: Secret key for authentication (Header: `x-api-key`). **NEVER** expose to client. - `DIDIT_WEBHOOK_SECRET`: Secret for verifying `X-Signature-V2` on webhooks. - Base URL: `https://verification.didit.me/v3/` - Documentation: [Didit API v3 Reference](https://docs.didit.me/reference/introduction) ## When to use this skill - When user wants to implement KYC/Identity verification. - When auditing existing Didit integrations for security/version compliance. - When debugging session creation, decision retrieval, or webhooks. ## Pre-Implementation Questions (Ask User) Before starting implementation, verify: 1. **Workflow Type**: "Are we using the standard Orchestrated Workflow (Didit handles UI) or Standalone (Custom UI)?" -> *Recommend Orchestrated.* 2. **Environment**: "Is this for Production or Sandbox?" 3. **Compliance**: "Do we need AML/PEP screening enabled on sessions?" 4. **Webhooks**: "Do you have a public endpoint for webhooks, or should we set up a polling fallback?" ## Workflow ### 1. Verification & Sanity Check * **Fail Fast**: Run the connection verification script to validate `DIDIT_API_KEY`. * Command: `node .agent/skills/didit/scripts/verify-connection.js` * **Audit**: Check codebase for exposed keys (grep for `x-api-key` in `src/app/(www)` or client components). ### 2. Implementation Strategy (Orchestrated) 1. **Create Session (Server-Side)**: * POST `/session/` with `workflow_id`. * Store `session_id` linked to internal User ID. 2. **Redirect User**: * Send user to `response.url`. 3. **Handle Result**: * **Primary**: Implementation Webhook endpoint validating `X-Signature-V2`. * **Secondary**: Polling on success page (GET `/session/{id}/decision/`). ## Instructions ### Authentication - **Header**: `x-api-key: ` - **Error Handling**: - `401 Unauthorized`: Key is invalid/missing. - `403 Forbidden`: IP not whitelisted or key lacks permissions. - `422 Unprocessable`: Invalid body/parameters (check `workflow_id`). ### Do's and Don'ts (Best Practices) #### ✅ What to DO - **DO** use `vendor_data` to pass your internal `userId` -> easier reconciliation. - **DO** implement `X-Signature-V2` validation for webhooks using `DIDIT_WEBHOOK_SECRET`. - **DO** whitelist Didit IP `18.203.201.92` if behind Cloudflare/Firewall. - **DO** use the provided TypeScript definitions in `resources/types.ts`. #### ❌ What NOT to DO - **NOT TO DO** Expose `x-api-key` in the browser (React/Next.js Client Components). - **NOT TO DO** Hardcode API keys. Use `process.env`. - **NOT TO DO** Rely solely on the client-side redirect for "Success" state (user can fake this). Always verify the decision server-side. ## Troubleshooting & Common Pitfalls | Symptom | Probable Cause | Fix | | :--- | :--- | :--- | | `401 Unauthorized` | Invalid API Key | Check `.env` and run `verify-connection.js`. | | `403 Forbidden` | IP Restriction | Whitelist `18.203.201.92` or check console settings. | | Webhook Failure | Signature Mismatch | Ensure you are using the **raw body** string for HMAC, not parsed JSON. | | Callbacks failing | Public Reachability | Ensure dev machine is exposed via Ngrok/Tunnel if testing webhooks locally. | ## Usage Examples ### 1. Create Verification Session *Using TypeScript types from `resources/types.ts`* ```typescript import { DiditSessionResponse } from '../.agent/skills/didit/resources/types'; // POST https://verification.didit.me/v3/session/ export const createSession = async (internalUserId: string): Promise => { const response = await fetch("https://verification.didit.me/v3/session/", { method: "POST", headers: { "x-api-key": process.env.DIDIT_API_KEY!, "Content-Type": "application/json" }, body: JSON.stringify({ workflow_id: process.env.DIDIT_WORKFLOW_ID, vendor_data: internalUserId, }) }); if (!response.ok) { const err = await response.text(); throw new Error(\`Didit Session Creation Failed: \${err}\`); } return response.json(); }; ``` ### 2. Secure Webhook Handler (Next.js) ```typescript import crypto from 'crypto'; import { DiditWebhookPayload } from '../.agent/skills/didit/resources/types'; export async function POST(req: Request) { const bodyText = await req.text(); // Get RAW body for signature const signature = req.headers.get("x-signature-v2"); const expectedSignature = crypto .createHmac('sha256', process.env.DIDIT_WEBHOOK_SECRET!) .update(bodyText) .digest('hex'); if (signature !== expectedSignature) { return new Response("Invalid Signature", { status: 401 }); } const payload = JSON.parse(bodyText) as DiditWebhookPayload; if (payload.event === 'session.approved') { // Update user status in DB } return new Response("OK", { status: 200 }); } ``` ## Resources - [Types Definitions](resources/types.ts) - [Verification Script](scripts/verify-connection.js)