Quickstart
Get a key, send your first verification code, and verify it.
This page walks through the shortest path: issuing and verifying a code from your server with an sk_ secret key.
To call the API directly from a browser, also read about pk_ keys in Authentication.
Create an app and keys in the console
In the console, create an app and issue a server-side sk_ key. This example needs the otp:issue and otp:verify scopes.
The app's wallet must hold credits before anything is sent (Credits & billing).
Keep the key in an environment variable, never in source code or a client bundle.
export KOTP_SECRET_KEY="sk_..."Issue a code
Call POST /v1/issue. Every issue request needs an idempotency key. Create a new key (for example a UUID) per request, and send the same key again when you retry that request.
curl -X POST "https://api.k-otp.dev/v1/issue" \
-H "Authorization: Bearer $KOTP_SECRET_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 5b0f8f2e-3c1d-4d7a-9a2b-6f1e0c9d8a71" \
-d '{"phoneNumber":"01012345678","purpose":"login"}'The success response (200) never contains the code. Store the issueId, for example in the user's session.
{
"issueId": "0192f3c4-8b7a-7c3e-9a51-2f4d6e8b1a90",
"expiresAt": "2026-09-28T03:03:00.000Z",
"attemptsRemaining": 5,
"queuedAt": "2026-09-28T03:00:00.000Z"
}Optional fields (channel, template, lifetime, max attempts, …) are listed in the Issue OTP reference. Defaults: SMS, the default template (otp_default_kr), 180-second lifetime, 5 attempts.
Verify the code
Send the 6-digit code the user entered together with the issueId.
curl -X POST "https://api.k-otp.dev/v1/verify" \
-H "Authorization: Bearer $KOTP_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"issueId":"0192f3c4-8b7a-7c3e-9a51-2f4d6e8b1a90","code":"123456"}'A failed verification is still HTTP 200. Always check verified.
{
"issueId": "0192f3c4-8b7a-7c3e-9a51-2f4d6e8b1a90",
"verified": false,
"reasonCode": "MISMATCH",
"attemptsRemaining": 4,
"expiresAt": "2026-09-28T03:03:00.000Z"
}verified: true means the user is verified. A verified issue cannot be verified again (one-time). See Issue lifecycle for how to handle each failure reason.
Next steps
- Read Idempotency & retries before handling timeouts and
503s. - Track delivery with the Issue lifecycle guide.
- All error codes are listed in Errors.