Verify Push API
Verify Push endpoints exposed by the Devotel CPaaS API Base path:/api/v1/verify/push
Endpoint count: 4
title: “Errors worth branching on” description: “Per-endpoint failure templates matching the envelope — what actually fires, what to retry, what to surface to the operator.”
Errors worth branching on
These five failures cover the verification issue (POST /api/v1/verify-push), triggered on every factor prompt from auth flows. Each block below is a full{ error, meta } envelope as the API returns it, and the matrix at the bottom answers retry vs surface for the same five classes. For the platform-wide decision table these branches plug into, see the error handling guide.
401 — Unauthorized
401 on this page is the bearer key failing before the route ran — it never means the resource is wrong. Rotate the key or re-mint the scoped token; retrying the same request changes nothing.
403 — Forbidden
403 means the key authenticated but the operation is gated by scope — check the key’s scopes on the developer page; a 403 is never a data-not-found shape.
422 — Schema
422 means the payload did not match the request schema — branch on error.details.field and resend with the full device token instead of blind-retrying the same body.
429 — Rate
Retry-After header and error.details.retry_after are both set on every 429 — resend the SAME request after the lower of the two.
402 — Feature gate
60-second retry matrix
Verify a push challenge signature
POST /api/v1/verify/push/challenges/{challengeId}/verifyapproved, factor flips to verified. On mismatch: attempts increment; auto-denied at maxAttempts.
string
required
—
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the
Idempotency-Replay: true response header.string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to
true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.string
required
The device’s base64-encoded signature over the challenge signing string factorId.challengeId.nonce (1–4096 characters).
Register a push factor
POST /api/v1/verify/push/factorsstring
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the
Idempotency-Replay: true response header.string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to
true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.string
required
Stable identifier for the end user this device belongs to — your user id, email, or username (1–255 characters).
string
required
Human-readable label for the paired device, shown when the user reviews their registered factors (1–120 characters).
string (enum: ed25519|ecdsa-p256)
required
Signature algorithm of the device key pair —
ed25519 or ecdsa-p256.string
required
The device’s base64-encoded public key. The matching private key never leaves the device; it signs each challenge (1–4096 characters).
string (enum: raw|spki)
required
Encoding of
publicKey — raw for a bare key or spki for a SubjectPublicKeyInfo-wrapped key.string
Optional push-token id (FCM, APNs, or Web Push) the service uses to deliver challenge notifications to this device (1–120 characters).
object
Optional free-form key/value bag — device model, OS version, attestation chain. The caller defines the contract.
Issue a push challenge
POST /api/v1/verify/push/factors/{factorId}/challenges<factorId>.<challengeId>.<nonce> and submits the signature via /verify/push/challenges/:challengeId/verify.
string
required
—
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the
Idempotency-Replay: true response header.string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to
true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.string
Human-readable prompt shown in the push notification so the user knows what they are approving, e.g. the action or device (1–280 characters).
integer
Lifetime of the issued challenge, in seconds, before it expires. Defaults to 120; range 30–600.
Revoke a push factor
POST /api/v1/verify/push/factors/{factorId}/revokestring
required
—
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the
Idempotency-Replay: true response header.string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to
true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.