Unfreeze Card
Restores a frozen virtual card to active, making it usable again.
- Only cards frozen as a user-initiated freeze (i.e. via Freeze Card) can be unfrozen through this endpoint.
- Cards frozen by risk-control, admin, or the system cannot be unfrozen here and return
403— contact your account manager. - No money moves — unfreezing has no fee.
Endpoint
| Item | Value |
|---|---|
| Method | POST |
| Path | /api/v1/openapi/card/unfreeze |
| Auth | HMAC |
| Idempotency | Not required |
No Idempotency-Key needed
Retrying on a card that is not frozen returns 400 card_not_frozen rather than double-applying. No monetary effect, so no Idempotency-Key header is required.
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
card_id | string | ✅ | card_<id> — must belong to your account and be a virtual card |
Example Request
json
{ "card_id": "card_12345" }Response Fields
| Field | Type | Description |
|---|---|---|
card_id | string | Echo of the card ID |
status | int | Card status after the operation — always 2 (active) on success |
status_desc | string | English status description — active |
success | bool | true on success |
Example Response
json
{
"code": 200,
"message": "OK",
"data": {
"card_id": "card_12345",
"status": 2,
"status_desc": "active",
"success": true
}
}Preconditions & Rules
- Ownership —
card_idmust belong to the authenticated account, else404 card_not_found. - Card type — virtual cards only.
- State — only
status=6 (frozen)cards may be unfrozen. - Freeze origin — only user-initiated freezes are reversible here. If the card was frozen by risk-control / admin / system, the request is rejected with the corresponding
403.
Common Errors
| HTTP | message_key | Description |
|---|---|---|
| 400 | openapi_invalid_card_id | Missing/invalid card_id |
| 400 | openapi_card_type_not_supported | Card is not a virtual card type |
| 400 | card_not_frozen | Card is not currently frozen |
| 400 | recharge_unfreeze_disabled | This card can only be unfrozen by recharging (risk freeze), and that path is disabled |
| 400 | operation_not_supported | This provider/card type does not support unfreeze |
| 401 | openapi_invalid_credentials | Auth failure |
| 403 | unauthorized_unfreeze_admin | Frozen by an administrator — cannot self-unfreeze |
| 403 | unauthorized_unfreeze_risk | Frozen by risk-control — cannot self-unfreeze |
| 403 | unauthorized_unfreeze_system | Frozen by the system — cannot self-unfreeze |
| 404 | card_not_found | Card not found / not owned |
| 500 | openapi_unfreeze_card_failed | Server error |
Notes
- After a successful unfreeze,
/card/inforeportsstatus=2. - A
403here means the freeze was applied by a party other than you; the card stays frozen and you must contact support to lift it.
Integration pitfalls & best practices
- Synchronous, provider-bound call — allow up to ~60 s. Unfreeze calls the upstream provider inline (same latency profile as freeze — commonly a few seconds, up to ~60 s server-side). Set your HTTP client timeout to ≥ 60 s for this endpoint.
- A client-side timeout does NOT mean the unfreeze failed. On any timeout / network error, reconcile via
/card/info:status=2→ unfreeze succeeded (proceed);status=6→ not applied (safe to retry). - No webhook for freeze/unfreeze. The synchronous response is the only signal; no asynchronous
card.*callback is emitted. Use the response (or/card/info) as the source of truth. - No
Idempotency-Key, but safe to retry. Retries are not deduplicated, but the state machine protects you: re-unfreezing an already-active card returns400 card_not_frozen. Treatcard_not_frozenas "already in the desired state", not a hard error. 403is terminal — do not retry-loop. Only user-initiated freezes (freezes made via Freeze Card) are reversible here. If risk-control / admin / system froze — or later re-froze — the card, unfreeze returns403 unauthorized_unfreeze_*and retrying will keep returning403. The card can only be lifted by that party / support. Surface it to the user instead of looping.