---
title: "POST verification_request.expired"
method: POST
path: "verification_request.expired"
---

# POST verification_request.expired

`POST verification_request.expired` (webhook)

Fired when a verification request passes its `expires_at` without completing. Delivered by the hourly expiry sweep (never on a request read) — at-least-once, including for requests marked expired on read before the sweep ran. A one-shot marker de-duplicates, but rare overlapping sweeps may deliver more than once: dedupe on `request_id`. The payload carries `status: "expired"` and any proofs verified before expiry (an empty array when none were).

## Payload

- WebhookPayload: Outbound webhook payload for verification request events (`verification_request.*`), and for `confirmation.approved` when it comes from a verification request created with `action_type: "confirmation"`
  - `event` 'verification_request.completed' | 'verification_request.partial' | 'verification_request.expired' | 'verification.completed' | 'confirmation.approved' | 'confirmation.denied' | 'authorization.approved' | 'authorization.denied' | 'proof.revoked' | 'proof.suspended' | 'proof.unsuspended' | 'account.deletion_scheduled' | 'account.deletion_cancelled', required: Type of webhook event. `proof.suspended`/`proof.unsuspended` fire for a delegation (`ph_dlg_*`) lifecycle act on the account's own configured webhook_url — not a channel to a separately-addressed delegate (h-fix-delegation-suspend-governance).
  - `request_id` string, required: MongoDB ObjectId
  - `reference_id` string
  - `status` 'pending' | 'partial' | 'completed' | 'expired' | 'cancelled', required: Status of a verification request
  - `action_type` 'verification' | '2fa' | 'login' | 'custom' | 'confirmation' | 'authorization', required: Type of action for verification request or authorization
  - `action_context` ActionContext: Context for custom and confirmation action types
    - `title` string: Action title (required for confirmation and custom types)
    - `description` string: Action description with details for the approver
    - `amount` number: Monetary amount for confirmation context
    - `currency` string: Currency code for confirmation context
    - `entity` string: Entity or resource being acted on
  - `client_metadata` object: Client-provided metadata passed through to webhook
  - `completed_at` string, date-time
  - `proofs` WebhookProof[], required
    - `type` 'phone' | 'email' | 'domain' | 'social' | 'wallet' | 'account' | 'telegram_bot', required: Type of asset being verified
    - `identifier` string, nullable, required: The identifier the request named for this asset; null when the recipient supplied it (an identifier-free phone asset)
    - `verified_at` string, date-time
    - `channel` 'whatsapp' | 'telegram' | 'sms' | 'email' | 'dns' | 'http' | 'auto' | 'github' | 'google' | 'facebook' | 'x' | 'linkedin' | 'instagram' | 'youtube' | 'tiktok' | 'ethereum' | 'solana' | 'bitcoin' | 'coinbase' | 'kraken' | 'telegram_bot_token', required: Channel used for verification
    - `proof_token` string: Signed JWT proof token (attestation) — ES256, verified via JWKS
    - `confidence` 'high' | 'standard' | 'degraded': Verification confidence level (present for SMS verifications)
  - `progress` object, required: Verification progress at time of webhook dispatch
    - `completed` integer, required
    - `completed_required` integer, required
    - `required` integer, required
    - `optional` integer, required
    - `total` integer, required
  - `test` boolean: Present and true for test-mode webhooks

## Acknowledgement `200`

Webhook received

---

[API](https://skmtc.dev/proof/apis/proof-holdings-api.md) · [All operations](https://skmtc.dev/proof/apis/proof-holdings-api/llms.txt) · [OpenAPI document](https://skmtc.dev/proof/apis/proof-holdings-api/revisions/b15f506de696?raw)
