---
title: "Create an identity challenge"
method: POST
path: "/api/v1/identity-challenges"
tags: ["HITL"]
---

# Create an identity challenge

`POST /api/v1/identity-challenges`

## Request

- Base URL: `https://api.proof.holdings`
- URL: `https://api.proof.holdings/api/v1/identity-challenges`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `auth_token`

Start a cross-channel Proof of Me identity challenge. The bot dispatches a CONFIRM/DENY prompt to the account owner on a channel different from the member's; the result is reported back to the member.

## Request body

- IdentityChallengeCreate: Create a cross-channel identity challenge (Proof of Me)
  - `circle_id` string, required: Circle that holds the member
  - `member_id` string, required: Enrolled member initiating the check
  - `suspicious_channel` 'telegram' | 'whatsapp': Channel the member was reached on; defaults to the member's first verified channel. The CONFIRM is routed cross-channel from it.

## Response `201`

Identity challenge created

- IdentityChallengeResponse: An identity challenge (Proof of Me)
  - `id` string, required
  - `status` 'pending' | 'confirmed' | 'denied' | 'cancelled' | 'failed' | 'expired' | 'revoked' | 'suspended', required: The one status every read reports. `pending` — waiting for the person being checked; `confirmed` — they confirmed; `denied` — they denied; `cancelled` — whoever started the check withdrew it; `failed` — the check could not be delivered; `expired` — nobody answered in time; `revoked` / `suspended` — the confirmation's proof was revoked or suspended (`POST /proofs/{proof_id}/revoke` or `/suspend`; revoking a denial's proof leaves it `denied`), or — `revoked` only — the member being checked was removed from the Circle while the check was still pending, which leaves `proof_id` null. Removing a member is not guaranteed to revoke a confirmation they already gave; revoke that one by its `proof_id`. A proof that merely reached its own expiry still reads `confirmed`; whether its token is still valid is `POST /proofs/validate`'s answer.
  - `channel` string: Channel the CONFIRM was dispatched on (GET)
  - `confirm_channel` string: Channel the CONFIRM was dispatched on (POST)
  - `single_channel_warning` boolean: True when the account holder has only one channel, so the CONFIRM ran on the same channel as the suspicious contact (degraded)
  - `circle_id` string, nullable: The Circle the check belongs to (GET)
  - `is_drill` boolean: True for a drill (scheduled, or started from the dashboard) rather than a real check (GET)
  - `proof_id` string, nullable: Public handle of the decision's proof — what `POST /proofs/{proof_id}/revoke` takes. Null until a decision minted one (GET).
  - `proof_token` string, nullable: Signed proof token, present once the person being checked decided
  - `created_at` string: ISO 8601 timestamp
  - `resolved_at` string, nullable: ISO 8601 timestamp of the decision — the CONFIRM, the DENY, the cancellation or the delivery failure — or null while the check is unanswered and after a timeout.
  - `expires_at` string: ISO 8601 timestamp

## Other responses

- `400`: No usable channel / Proof of Me disabled
- `402`: card_required. Only once billing is live: a free account with no card on file that has used its included proofs and the 50-proof grace this month is refused new proof requests until a card is added (add_card_url). Proofs already issued keep working. The error carries add_card_url, used, included and hard_limit.
- `404`: Circle or member not found
- `409`: A challenge is already in progress (`in_progress`), or the member opted out of circle checks (`member_opted_out`)
- `429`: The check's own anti-harassment limit was reached (a member may start a few checks per hour, and a person may be asked a few times per hour). `Retry-After`, `X-RateLimit-*` and the body's `retryAfter` describe that limit.

---

[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/6b8d61ee354f?raw)
