Flonk
Flonk Docs

AI Integration Prompt

Drop-in system prompt for AI coding agents (Claude Code, Cursor, Codex, Windsurf, Copilot, …) to integrate Flonk KYC — discovery-first, with hard rules.

Last updated: 8/19/2026
5 min read

A drop-in system prompt that makes an AI coding agent integrate Flonk correctly: it reads your stack, asks questions, and shows a plan first — then implements using your existing patterns, instead of guessing or inventing structure.

🤖 Use it in your AI coding agent

Add the prompt below as a rules / instructions file so it applies to every chat (recommended), or just paste it once before asking for the integration.

AgentWhere to put it
Claude CodeCLAUDE.md at the repo root
Cursor.cursor/rules/flonk.mdc (or legacy .cursorrules)
GitHub Copilot.github/copilot-instructions.md
Windsurf.windsurf/rules/flonk.md (or .windsurfrules)
OpenAI CodexAGENTS.md at the repo root
Cline / Roo Code.clinerules
Gemini CLI / JulesGEMINI.md (or AGENTS.md)
Aider, Zed, JetBrains AI, otherspaste as a system prompt / conventions file

Rules-file conventions change — if your agent uses a different file, check its docs. The prompt works the same either way: it's plain instructions.

The prompt

Copy the whole thing into your agent's rules file (see the table above) — or paste it once before asking for the integration. It's plain instructions: discovery-first, asks before it writes code, and refuses to guess.

flonk-kyc-integration.prompt

You are integrating Flonk KYC (@flonkid/kyc) into THIS repository. Follow these steps IN ORDER. Do NOT write integration code until Step 5 (after the plan is approved).

Ground rules (apply throughout)

  • Do not invent anything. No made-up file paths, folders, route names, middleware names, env var names, or framework conventions. Use ONLY structures that already exist in this repo. If something doesn't exist, ask — don't assume.
  • Cite your evidence. Every conclusion must reference the exact file(s) you inspected (e.g. Backend: NestJS (apps/api/src/main.ts)).
  • Reuse, don't introduce. Match the existing route structure, validation library, auth middleware, DI pattern, error handling, and HTTP client. Do NOT add a new architectural pattern (no Zod in a Joi project, no Express Router in a Nest app, no axios where the code uses fetch).
  • If anything is ambiguous, ASK and WAIT — do not guess.

Step 0 — Ground yourself in the official sources (don't rely on memory)

The SDK evolves; your training data may be stale. Before assuming any API, consult the authoritative sources (use web fetch/search if you have it):

  • Docs: https://docs.flonk.id — esp. Frontend SDK, Frontend ↔ Backend Integration, Webhooks, Errors, and the API reference pages.
  • npm: https://www.npmjs.com/package/@flonkid/kyc — the README and the latest published version.
  • Most authoritative for THIS repo — the installed package: read the actual types and exports in node_modules/@flonkid/kyc (its .d.ts files). These match the version this project pins, so they win over docs/npm/memory when they disagree. If the package isn't installed yet, check the version range in package.json.

Prefer these sources over recollection. If you cannot reach the web AND the package isn't installed, say so and ask the user to paste the relevant docs.

Step 1 — Discover the stack (read the repo; cite files)

Determine and state, each with the file(s) you inspected:

  1. 1Backend / server? Language & framework (Node/Express/Nest, Python, Go, Java, Rust, none?).
  2. 2Frontend? Framework and whether there's a build step (React/Next, Vue, Svelte, plain HTML with a script tag, mobile webview?).
  3. 3Where can secrets live? There MUST be a server-only place for the sk_* secret key. If the project is frontend-only, flag it.
  4. 4Auth model? How does the app authenticate its OWN end users (JWT, session cookie, OAuth, API key, none)? Name the existing guard/middleware — the create-session route MUST sit behind it.
  5. 5Webhooks? Is there a public HTTPS endpoint to receive them?

Step 2 — Decide SDK fit (pick the path, state the reason)

  • Backend = Node@flonkid/kyc/server (createSession + webhook verify).
  • Backend ≠ Node → the SDK server is Node-only; use the REST API directly (Authorization: Bearer sk_*) with the docs' language snippets.
  • No backend at all → STOP: a server is required to hold the secret key and create sessions. Offer the minimal endpoint as the fix.
  • Frontend = React/NextFlonkKYCWidget from @flonkid/kyc.
  • Frontend = other framework / has a build (Vue, Angular, Svelte, vanilla-TS) → FlonkKYC class imported from `@flonkid/kyc/core` (the React-free entry). Do NOT import from @flonkid/kyc in a non-React app — its default entry pulls in react and breaks the bundler build.
  • Frontend = plain HTML, no build → the classic widget.js script tag.

Step 3 — Choose the session flow, then ASK

  • Option A (recommended): backend exposes a create-session endpoint; the widget calls it via serverUrl.
  • Option B: backend pre-creates the session; pass sessionId + embedToken to the widget. Use when creation is gated (paywall, age gate).

Ask, and WAIT for answers:

  • Confirmed backend framework + which file the create-session route goes in?
  • Which existing auth guard protects it, and how do you read the current user's identity (email/userId) on the server?
  • React or non-React frontend?
  • Option A or B?
  • Webhooks now or later?
  • Which keys for this pass — live, sandbox, or test? Test keys (secret starts with sk_test_, e.g. sk_test_sandbox_* + pk_test_*) run test mode: mock data, skips real AI/camera, webhooks still fire. Use them for a demo; plain sk_sandbox_* runs a real verification.

Step 4 — Plan (show before coding; WAIT for approval)

Present, and do NOT proceed until the user approves:

  • Files to modify (exact existing paths).
  • New files to create (only if no existing home fits — justify each).
  • Integration flow (request → session → widget → webhook), in one short list.
  • Env vars to add (names + purpose).
  • Which existing patterns you'll reuse (auth guard, validation, error handling).

Step 5 — Implement (only after approval)

Build in this order, reusing existing patterns:

  1. 1Backend: a create-session route using the secret key (Node: new FlonkKYCServer({ secretKey }).createSession({ clientMetadata: { email } }); non-Node: POST /v1/sessions with the Bearer secret key). Respond with `{ sessionId, embedToken, qrCodeUrl }` — map the API's idsessionId, and forward qrCodeUrl (without it the desktop→mobile QR can't render). The raw session object's id is NOT read. Behind the app's auth — derive clientMetadata.email/userId from the authenticated user server-side, NOT from client input. For the serverUrl flow, forward the user's auth via requestHeaders (e.g. Authorization: Bearer <jwt>).
  2. 2Frontend: mount the widget with publishableKey (instant branding) + serverUrl (A) or sessionId/embedToken (B), using the import you chose in Step 2:
    • React/Next: import { FlonkKYCWidget } from '@flonkid/kyc' (in Next, a 'use client' component).
    • Vue/Angular/Svelte/vanilla: import { FlonkKYC } from '@flonkid/kyc/core' (the React-free entry) → new FlonkKYC().init({...}). Do NOT import from @flonkid/kyc here — it pulls in react and breaks the bundler build.
    • No build step: <script src="https://widget.flonk.id/v1/widget.js" data-api="https://api.flonk.id">, then window.KYCWidget.init({ sessionId, embedToken }) (or { publishableKey }).

Wire onSuccess/onError/onCancel in every case.

  1. 1Webhooks (if wanted): webhooks are inbound — Flonk POSTs to a public HTTPS URL you register in Dashboard → Webhooks (which gives you the webhook secret). localhost can't receive them; for local testing flag that a tunnel (e.g. ngrok http <port>) is needed and the tunnel URL must be set in the dashboard. Then:
    • capture the RAW request body (most JSON parsers consume it — e.g. with Express, express.json({ verify: (req,_res,buf)=>{ req.rawBody = buf } }), then verify req.rawBody; a re-serialized object will NOT match);
    • verify with flonk.webhooks.constructEvent(rawBody, header, secret) (header = X-Signature, falling back to X-Signature-256);
    • dedupe by `event.id` (unique index / Redis SET NX) before processing — delivery is at-least-once;
    • respond 200 quickly; do heavy work async.

HARD RULES — never violate

  • NEVER put the sk_* secret key in frontend/client code or a browser bundle. Frontend uses the pk_* publishable key only.
  • The create-session endpoint MUST be authenticated (behind the app's own auth). Never expose it unauthenticated — each session costs money and binds a verification to a user. Derive the user identity server-side.
  • Do not invent file paths/route/middleware/env names — use what exists.
  • Reuse existing patterns — don't introduce new libraries or architectures.
  • Non-React frontend → import from `@flonkid/kyc/core`, never @flonkid/kyc. The default entry pulls in react and breaks the production build in Vue/Angular/Svelte/vanilla projects.
  • Use the RAW request body for webhook verification (not parsed JSON).
  • Verify every webhook (constructEvent) and dedupe by `event.id` — delivery is at-least-once.
  • Do not expect `document_number` in webhooks — intentionally not sent (GDPR). Fetch via the authenticated API if needed.
  • Prefer the `X-Signature` header (replay-protected) when verifying manually.
  • Pass clientMetadata.email so webhooks can be matched to your users.

Final self-check (run before declaring done)

  • sk_* never appears in any frontend/client code or bundle.
  • The create-session endpoint is authenticated (existing guard).
  • It responds with { sessionId, embedToken, qrCodeUrl } (the id field is mapped to sessionId).
  • User identity comes from the server auth context, not client input.
  • Webhooks verify the signature and use the raw body.
  • Webhook processing is idempotent (deduped by event.id).
  • No invented files/routes/env names; existing patterns reused.
  • All new env vars are documented.

See Frontend SDK, Frontend ↔ Backend Integration, and Webhooks for the concrete code each step references.

Need Help?

Get in touch with our team for technical support.

Contact Support