Prompt Your LLM
Copy a ready-made prompt into ChatGPT, Claude, Cursor, or any AI coding assistant to get a working Akedly Shield V1.2 integration. Each prompt explains the full API flow and SDK usage for a specific platform.
How to Use
- Select your platform in the tabs below.
- Copy the prompt and paste it into your AI assistant.
- Optionally add context about your specific project (framework, state management, etc.).
- The LLM will generate a complete, working integration.
Adding passkeys?
These prompts cover the OTP integration only. For passkey enrollment and sign-in — a full greenfield build or a delta on top of an existing V1.2 integration — use the passkey prompts.
Every prompt assumes a backend proxy
The prompts below instruct LLMs to generate frontend code that calls your own backend — never Akedly directly. Your backend holds APIKey + pipelineID and exposes three thin routes (/auth/akedly/challenge, /auth/akedly/send, /auth/akedly/verify). If you don't already have a backend for this, each of the five OTP platform prompts includes a ready-to-copy Node.js/Express snippet you can drop in. The passkey prompts instead instruct the LLM to generate the larger backend route set and proof verifier. This matches the pattern shown on every SDK page.
The prompts opt you in to per-end-user-IP rate limiting
The five OTP platform prompts include app.set('trust proxy', 1) and x-end-user-ip: req.ip to enable Akedly's optional per-end-user-IP rate-limit dimension. The passkey prompts forward x-end-user-ip only after deployment-appropriate trusted-proxy configuration. If you don't need that dimension, you can omit the header — phone and pipeline limits always apply. For a non-Node backend, mirror the IP-extraction patterns on the V1.2 API reference so the value is the user's IP and not your server's.
Choose Your Platform
- Name
V1.2 Passkeys- Type
- all supported platforms
- Description
Greenfield and delta prompts for passkey-first authentication, OTP fallback, enrollment, and backend proof verification. View prompts
- Name
Web / JavaScript- Type
- @akedly/shield
- Description
npm or CDN integration with Web Worker PoW and Turnstile helpers.
- Name
Flutter / Dart- Type
- akedly_shield (GitHub)
- Description
Dart Isolate-based PoW and AkedlyTurnstile widget. Installed via a
git:pubspec dependency.
- Name
iOS / Swift- Type
- AkedlyShield (GitHub via SPM)
- Description
Async/await PoW with CryptoKit and WKWebView Turnstile.
- Name
Android / Kotlin- Type
- akedly-shield-kotlin (GitHub via JitPack)
- Description
Coroutine-based PoW and invisible WebView Turnstile.
- Name
React Native- Type
- @akedly/shield
- Description
Same npm package as web with RN-specific Turnstile WebView pattern.
Copy This Prompt
I need to integrate Akedly Shield V1.2 OTP authentication into my web application.
## Architecture: keep APIKey on the backend
APIKey and pipelineID are credentials and MUST NOT appear in browser code.
My backend exposes three thin proxy routes that the frontend will call:
GET /auth/akedly/challenge
POST /auth/akedly/send body: { phoneNumber, powSolution, turnstileToken? }
POST /auth/akedly/verify body: { transactionReqID, otp }
The FRONTEND code you generate must ONLY call these three routes.
Never reference APIKey or pipelineID in the frontend. Never call api.akedly.io from the browser.
## Reference backend (Node.js / Express) — drop in if I don't have one yet
import express from 'express';
const app = express();
app.use(express.json());
// Optional: only needed if you want per-end-user-IP rate limiting (drop
// this line and the x-end-user-ip header below if you don't). Makes req.ip
// the real client IP behind Cloudflare / Vercel / AWS ALB / Nginx.
app.set('trust proxy', 1);
app.get('/auth/akedly/challenge', async (_req, res) => {
const r = await fetch(
`https://api.akedly.io/api/v1.2/transactions/challenge` +
`?APIKey=${process.env.AKEDLY_API_KEY}` +
`&pipelineID=${process.env.AKEDLY_PIPELINE_ID}`
);
res.status(r.status).json(await r.json());
});
app.post('/auth/akedly/send', async (req, res) => {
const { phoneNumber, powSolution, turnstileToken } = req.body;
const r = await fetch('https://api.akedly.io/api/v1.2/transactions/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-end-user-ip': req.ip },
body: JSON.stringify({
APIKey: process.env.AKEDLY_API_KEY,
pipelineID: process.env.AKEDLY_PIPELINE_ID,
verificationAddress: { phoneNumber },
powSolution,
turnstileToken,
}),
});
res.status(r.status).json(await r.json());
});
app.post('/auth/akedly/verify', async (req, res) => {
const { transactionReqID, otp } = req.body;
const r = await fetch('https://api.akedly.io/api/v1.2/transactions/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ transactionReqID, otp }),
});
res.status(r.status).json(await r.json());
});
## Challenge response shape (what the frontend receives from /auth/akedly/challenge)
{ status, data: { challenge, difficulty, challengeToken, challengeRequired, turnstile: { required, siteKey } } }
## Frontend flow
1. GET /auth/akedly/challenge
2. Solve PoW with @akedly/shield: `const { nonce } = await solvePow(challenge, difficulty)`
Algorithm: SHA256(challenge + ":" + nonce) must start with `difficulty` leading hex zeros.
3. If turnstile.required: `const token = await getTurnstileToken(siteKey)`
4. POST /auth/akedly/send body: { phoneNumber, powSolution: { challengeToken, nonce }, turnstileToken }
Response: { status, data: { transactionReqID } }
5. POST /auth/akedly/verify body: { transactionReqID, otp: "123456" }
## SDK: @akedly/shield (v1.1.0)
Install: npm install @akedly/shield
CDN: <script src="https://unpkg.com/@akedly/shield/dist/akedly-shield.min.js"></script>
Key functions:
- solvePow(challenge, difficulty, options?) -> Promise<{ nonce: number }>
options: { onProgress: (hashesChecked) => void, useWorker: 'auto'|true|false }
- getTurnstileToken(siteKey, options?) -> Promise<string>
- renderTurnstile(siteKey, container, options?) -> Promise<string>
- new AkedlyShield(options?) with .solve() and .terminate()
Web Worker is used automatically in browsers. Falls back to batched main-thread where Workers aren't available.
## Requirements
Please generate a complete integration with:
- A reusable function/hook for the full OTP flow (challenge -> solve -> send -> verify) that talks ONLY to my backend
- Error handling for all backend responses
- Loading states
- Phone number input, OTP input, verification UI
- No APIKey and no pipelineID anywhere in the frontend code
Customizing the Prompt
Add any of these to the end of the prompt to tailor the output:
- Framework: "I'm using Next.js App Router with TypeScript" or "I'm using Expo with React Navigation"
- State management: "Use Zustand for state" or "Use Redux Toolkit"
- Styling: "Use Tailwind CSS" or "Use styled-components" or "Use NativeWind"
- Auth flow: "After OTP verification, create a JWT session" or "Store the session in SecureStore"
- Error handling: "Show toast notifications for errors" or "Use react-hot-toast"
