---
title: "Verify the account"
method: POST
path: "/api/verification"
tags: ["account"]
---

# Verify the account

`POST /api/verification`

## Request

- Base URL: `https://api.depixapp.com`
- URL: `https://api.depixapp.com/api/verification`
- Auth: none required

Evaluates the proof and, when everything is satisfied, unlocks the merchant tools. No request body. Send a Bearer JWT or an sk_ API key; NO scope is required. Idempotent: an already-verified account answers 200. On 409 the reason is in `error.code` and the detail in `error.details.missing` / `error.details.remaining` — the same values GET returns. A CPF/CNPJ verifies exactly one account: once bound it can never verify another (`verification_tax_number_in_use`).

## Response `200`

The account is verified (just now, or already was).

- VerificationStatusResponse: Whether this account can use the merchant tools, and what is still missing if it cannot. Verification is independent of how much the account may receive — it never changes a limit.
  - `verified` boolean, required: True when the merchant tools are unlocked on this account.
  - `verified_at` string, nullable, required: When verification completed (RFC 3339 UTC, "YYYY-MM-DDTHH:MM:SS.sssZ"). Null while unverified.
  - `whatsapp_verified` 0 | 1, required: 1 once the account has verified its WhatsApp number, 0 otherwise (raw SQLite boolean). It gates the first deposit — a human account must clear it in the app before verifying. Always 0 for an agent account, which is exempt (it proves a domain instead).
  - `method` 'round_trip' | 'domain', required: Which proof applies to this account. `round_trip`: send money from a CPF/CNPJ to the account and withdraw it back to the SAME document. `domain`: prove control of a registrable domain by DNS TXT (agent accounts — POST /api/agents/verify-domain).
  - `enabled` boolean, required: False when automatic verification is switched off platform-wide; contact support instead of retrying.
  - `eligible` boolean, required: True when every requirement is satisfied and POST /api/verification would promote the account. A promotion still has to land: a suspended account never verifies.
  - `requirements` object, required: What this account's proof requires. Null members do not apply to the account's method.
    - `deposit_cents` integer, nullable, required: Minimum to receive from one document, in cents. Null on the domain method.
    - `withdraw_cents` integer, nullable, required: Minimum to withdraw back to that SAME document, in cents. Lower than deposit_cents because fees are deducted along the way. Null on the domain method.
    - `min_account_age_days` integer, nullable, required: Minimum account age in days. Null on the domain method. **0 means there is no age requirement at all** — the `account_age` step is then omitted from `steps` and never appears in `missing`. 0 is the value in force.
    - `max_days_between_legs` integer, nullable, required: Maximum days between the two movements — they must sit inside one window of this length. Null on the domain method.
    - `domain_proof` boolean, required: True when a proven domain is what verifies this account.
  - `progress` object, required: What has been done so far. Amounts count only movements made after this feature went live.
    - `account_age_days` integer, required: Age of the account in whole days.
    - `account_age_ok` boolean, required: True when the age requirement is satisfied.
    - `deposited_cents` integer, required: Received from the best-matching document, in cents.
    - `withdrawn_cents` integer, required: Withdrawn back to that same document, in cents.
    - `deposit_leg_ok` boolean, required: True when the received side reaches its minimum.
    - `withdraw_leg_ok` boolean, required: True when the withdrawn side reaches its minimum.
    - `tax_number` string, nullable, required: The document being matched, MASKED (only the last digits are shown). Null when no document has been seen yet.
    - `tax_number_locked` boolean, required: True once a document is permanently bound to this account. A document verifies exactly one account, so a bound one can never verify another.
    - `domain` string, nullable, required: The proven domain, on the domain method. Null otherwise.
  - `remaining` object, required: How much is left on each requirement — zero when satisfied, null when it does not apply.
    - `deposit_cents` integer, nullable, required: Still to receive from one document, in cents.
    - `withdraw_cents` integer, nullable, required: Still to withdraw back to it, in cents.
    - `account_age_days` integer, nullable, required: Days the account still has to wait.
  - `missing` string[], required: Machine-readable list of what is blocking verification — empty when eligible. Branch on these instead of parsing prose.
  - `unlocks` string[], required: What verification unlocks on this account.
  - `lbtc_fuel` object, nullable, required: How much DePix to convert to L-BTC before withdrawing, and null when it does not apply (agent accounts). The Liquid network charges its transaction fee in L-BTC, so a wallet holding only DePix cannot move its own money — the most common reason a first withdrawal never leaves. This is GUIDANCE, not a requirement: it is absent from `requirements` and never affects `eligible`, because a non-custodial wallet's balance is not visible server-side.
    - `min_depix_cents` integer, required: Minimum DePix to convert to L-BTC, in cents. Convert about this much — converting a lot more can leave too little DePix to complete the withdrawal step.
    - `balance_known` boolean, required: Whether the server knows this account's L-BTC balance. Always false: the wallet is non-custodial and no balance is reported to the server. Determine it in the wallet.
    - `sufficient` boolean, nullable, required: Whether the account already holds enough L-BTC. Always null, for the reason in balance_known — treat null as "unknown", never as "no".
  - `steps` object[], required: The checklist IN THE ORDER THE ACCOUNT MUST ACT — render it as given and do not reorder or recompute it. `convert_lbtc` comes before `withdraw` because the withdrawal cannot be broadcast without network fuel. Amounts and days are pre-computed per step so the client never restates the rule.
    - `id` 'deposit' | 'convert_lbtc' | 'withdraw' | 'account_age' | 'domain_proof', required: `deposit`: receive from your own CPF/CNPJ. `convert_lbtc`: convert a little DePix to L-BTC for the network fee. `withdraw`: send DePix back to the same document. `account_age`: the account also has to be old enough — PRESENT ONLY when `requirements.min_account_age_days` > 0, which it is not today. `domain_proof`: agent accounts — replaces all of the above. Render the list as given; a step that is absent is not a requirement.
    - `state` 'done' | 'pending' | 'unknown', required: `done`, `pending`, or `unknown` — `unknown` means the server genuinely cannot tell (the L-BTC step, since no wallet balance reaches it) and the client must resolve it locally. Never render `unknown` as a failure.
    - `target_cents` integer, nullable, required: What this step asks for, in cents. Null when the step is not about an amount.
    - `remaining_cents` integer, nullable, required: How much of that is left, in cents. Null when the step is not about an amount, or when the server cannot know.
    - `target_days` integer, nullable, required: What this step asks for, in days. Null when the step is not about time.
    - `remaining_days` integer, nullable, required: How many days are left. Null when the step is not about time.

## Other responses

- `401`: Missing/invalid credentials. `invalid_api_key` for a failed sk_* lookup (revoked/expired/unknown); `invalid_token` for a bad or missing JWT/Authorization header.
- `403`: The account is suspended.
- `409`: Not verified. `verification_requirements_not_met`: something is still missing (see details). `verification_tax_number_in_use`: that document already verified another account.
- `429`: Rate limited. Beyond the endpoint's own limit when set (`rate_limited`), API-key calls are also bounded by the shared per-merchant budget (`merchant_rate_limited`, default 30 req/min across all endpoints) and by the key's own rate limit when configured (`rate_limited`). Retry after `retry_after` seconds (also in the Retry-After header).
- `503`: Automatic verification is switched off platform-wide.

---

[API](https://skmtc.dev/depixapp/apis/depix-api.md) · [All operations](https://skmtc.dev/depixapp/apis/depix-api/llms.txt) · [OpenAPI document](https://skmtc.dev/depixapp/apis/depix-api/revisions/04094536dd0f?raw)
