K-OTP

Verify OTP code

POST /v1/verify

POST https://api.k-otp.dev/v1/verify

Overview

Checks a 6-digit code against issueId with one-time semantics. On success the issue transitions to verified and cannot be verified again. A wrong code consumes one attempt. Verification failures are returned as 200 with verified: false and a reasonCode (MISMATCH, MAX_ATTEMPTS, EXPIRED, ALREADY_VERIFIED, REPLACED, NOT_FOUND), not as HTTP errors.

Accepts pk_ public keys (browser, Origin must exactly match an allowed origin) or sk_ secret keys.

Authentication

Accepted keysRequired scopeAlso accepted
pk_ / sk_otp:verifyotp:read, *

Request body

FieldTypeRequiredDescription
issueIdstringyesissueId returned by POST /v1/issue.
codestringyesThe 6-digit numeric code the end user received.

Response (200)

Verification result. Check verified; failures carry reasonCode.

FieldTypeRequiredDescription
issueIdstringyes
verifiedbooleanyestrue only when the code matched an active, unexpired issue.
reasonCode"ALREADY_VERIFIED" | "EXPIRED" | "MAX_ATTEMPTS" | "MISMATCH" | "NOT_FOUND" | "REPLACED"Present when verified is false.
attemptsRemainingnumberyesVerification attempts left after this call.
expiresAtstringyesExpiry of the issue (RFC 3339).
verifiedAtstringWhen the issue was verified (RFC 3339), if it has been.

Error responses

Every error uses the { defined, code, status, message, data? } envelope. See Errors.

StatuscodeDescription
400BAD_REQUESTinvalid payload, blank issueId, or code is not a 6-digit numeric string.
401UNAUTHORIZEDthe Authorization: Bearer credential is missing, malformed, inactive, or rejected by introspection.
403FORBIDDENthe credential lacks otp:verify (or an accepted alias), or a pk_ public key was sent without an Origin header / with an Origin that is not an exact match for one of the key's allowedOrigins.
409CONFLICTthe request conflicts with the current state of the resource.
500INTERNAL_SERVER_ERRORunexpected server failure. Undefined errors (defined: false) use the same envelope.
503SERVICE_UNAVAILABLEcredential introspection or a downstream dependency is temporarily unavailable. Retry with backoff.

Example request

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"}'

On this page