Skip to content

Error Codes

Coinepay OpenAPI error responses contain:

  • code: same as HTTP status (200/400/401/404/409/429/500)
  • message: localized via Accept-Language
  • message_key: stable English key, use this for programmatic checks
json
{
  "code": 400,
  "message": "Idempotency-Key conflict",
  "message_key": "openapi_idempotency_key_conflict",
  "data": null
}

HTTP Status Semantics

HTTPMeaning
200Success (incl. "idempotent replay" and "queued")
400Validation / business-rule failure (use message_key to differentiate)
401Auth failure (always openapi_invalid_credentials, no further detail)
403Authenticated but feature-gated (e.g. second-factor verification missing/failed for sensitive card info, or card not active)
404Resource not found / not owned by current account
409Idempotency-Key conflict (same key, different body)
429Rate limited
500Internal server error

Full message_key Dictionary

Auth & Credentials

message_keyen-USzh-CNHTTP
openapi_invalid_credentialsInvalid OpenAPI credentials无效的 OpenAPI 凭证401

ID Validation

message_keyen-USzh-CNHTTP
openapi_invalid_header_idInvalid header_idheader_id 不合法400
openapi_invalid_package_idInvalid package_idpackage_id 不合法400
openapi_invalid_card_idInvalid card_idcard_id 不合法400

Idempotency

message_keyen-USzh-CNHTTP
openapi_idempotency_key_requiredMissing Idempotency-Key header缺少 Idempotency-Key 请求头400
openapi_idempotency_key_too_longIdempotency-Key too longIdempotency-Key 超长400
openapi_idempotency_key_invalid_charsInvalid characters含非法字符400
openapi_idempotency_key_conflictIdempotency-Key conflictIdempotency-Key 冲突409

Business Rules

message_keyen-USzh-CNHTTP
openapi_card_type_not_supportedNot supported (virtual cards only)暂不支持该卡类型400
account_manager_bind_requiredAccount-manager-controlled header; bind an account manager first该卡头需绑定客户经理后才能开通400
account_manager_unavailableYour account manager is no longer active; contact support绑定的客户经理已失效,请联系客服400
account_manager_open_disabledHeader / package not opened for your account by your account manager您的客户经理尚未对该账号开放此卡头 / 套餐400
amount_requiredamount is requiredamount 为必填400
card_not_foundCard not found卡片不存在404
insufficient_balanceInsufficient balance余额不足400
kyc_requiredPlease complete identity verification first请先完成实名认证400
kyc_not_approvedKYC not approvedKYC 未通过400
virtual_g_name_invalid(G card) cardholder name fails the ASCII-letters / single-space / ≤40 chars rule(G 卡)持卡人姓名不满足规则400
virtual_g_required_fields_missing(G card) server could not assemble a complete apply payload(G 卡)开卡资料不完整400
virtual_a_required_fields_missing(A card) first_name / last_name missing or blank, or apply payload incomplete(A 卡)持卡人姓名缺失或开卡资料不完整400

First Deposit (Custom Amount)

Returned by /card/apply (as message_key, HTTP 400) and by /card/first_deposit/preview (as invalid_reason inside a 200 body) when a custom first_deposit_amount cannot be honored.

message_keyen-USzh-CNHTTP
invalid_first_deposit_amountfirst_deposit_amount must be a non-negative integerfirst_deposit_amount 必须是非负整数400
first_recharge_below_baseFirst deposit below the config base首充低于配置底额400
first_recharge_exceeds_maxExcess exceeds max recharge超额超过最大充值400
first_recharge_limit_exceededExcess exceeds the recharge limit超额超过充值限额400
first_recharge_asset_mismatchOpen-fee asset differs from recharge asset开卡费资产与充值资产不一致400
first_recharge_excess_too_smallExcess too small after fee + rounding超额扣费取整后过小400

Sensitive Card Information

These codes are returned by /openapi/card/info when with_sensitive=true cannot be honored, and by /openapi/card/sensitive/send_code. Sensitive fields require the card to be status=2 (active) plus either valid user second-factor codes or a verification-exempt credential.

message_keyen-USzh-CNHTTP
email_code_requiredPlease enter email verification code请输入邮箱验证码403
sms_code_requiredPlease enter SMS verification code请输入短信验证码403
pin_requiredPlease enter PIN请输入 PIN 码403
2fa_code_requiredPlease enter 2FA code请输入 2FA 验证码403
invalid_email_codeInvalid email verification code邮箱验证码错误403
invalid_sms_codeInvalid SMS verification code短信验证码错误403
invalid_pinInvalid PINPIN 码错误403
invalid_2fa_codeInvalid 2FA code2FA 验证码错误403
email_not_verifiedEmail not verified邮箱未验证403
phone_not_verifiedPhone not verified手机号未验证403
no_usable_auth_methodNo usable authentication method无可用的认证方式403
card_sensitive_access_bannedSensitive card info access via API has been disabled by the administrator通过 API 获取敏感卡片信息的权限已被管理员关闭403
openapi_sensitive_card_only_activeSensitive card info is only available for active cards.仅激活状态的卡片可获取敏感信息403
too_many_requestsToo many requests (verification locked / send cooldown; honor Retry-After)请求过于频繁(验证锁定 / 发码冷却,遵循 Retry-After429
send_code_failedFailed to send verification code (cooldown released, retry allowed)验证码发送失败(冷却已释放,可立即重试)500

openapi_sensitive_card_info_disabled (403) is no longer returned: credentials without the verification exemption now fall back to the user second-factor path instead of being rejected outright.

Card List Filters

message_keyen-USzh-CNHTTP
openapi_conflicting_card_filtersusable_only and statuses cannot be used togetherusable_only 与 statuses 不能同时传400
openapi_invalid_status_valuestatuses contains an invalid value (only 1-6 allowed)statuses 含非法状态值(仅允许 1-6)400
invalid_min_balancemin_balance must be a valid non-negative number最小余额必须是合法非负数字400
invalid_max_balancemax_balance must be a valid non-negative number最大余额必须是合法非负数字400
min_balance_exceeds_max_balancemin_balance must not exceed max_balance最小余额不能大于最大余额400
invalid_date_formatdate must be in the expected format日期格式不正确400

Transaction Filters

Returned by /transactions/list and /card/transactions/list.

message_keyen-USzh-CNHTTP
invalid_date_formattransaction_time_from/to must be YYYY-MM-DD HH:MM:SS交易时间格式必须为 YYYY-MM-DD HH:MM:SS400
invalid_paramsInvalid parameters (e.g. bad amount format)参数无效(如金额格式错误)400

Freeze / Unfreeze

Returned by /card/freeze and /card/unfreeze.

message_keyen-USzh-CNHTTP
card_already_frozenCard is already frozen卡片已被冻结400
card_status_cannot_freezeCurrent card status does not allow freezing当前卡状态不可冻结400
card_not_frozenCard is not frozen卡片未被冻结400
card_type_mismatchCard type does not match卡类型与配置不匹配400
operation_not_supportedOperation not supported for this card type该操作不支持400
recharge_unfreeze_disabledRecharge-based unfreeze is not available for this card该卡不允许通过充值自动解冻400
unauthorized_unfreeze_adminFrozen by admin — cannot self-unfreeze该卡片被管理员冻结,用户无法自行解冻403
unauthorized_unfreeze_riskFrozen by risk control — cannot self-unfreeze该卡片被风控冻结403
unauthorized_unfreeze_systemFrozen by system — cannot self-unfreeze该卡片被系统冻结403

Close Card

Returned by /card/close (v1.3 — the endpoint has been live since v1.2 but undocumented).

message_keyen-USzh-CNHTTP
card_is_closingCard is being closed卡片正在注销中400
card_already_closedCard is already closed卡片已注销400
card_frozen_cannot_closeCard is frozen and cannot be cancelled卡片已冻结,无法注销400
card_status_cannot_closeCurrent card status does not allow cancellation当前卡状态不可注销400
close_not_accepted_by_upstreamClosure not accepted by the provider; the card has been restored to active — retry later销卡未被上游受理,卡片已恢复为可用状态,请稍后重试400
card_upstream_closed_pending_reconcileCard was already closed by the provider and awaits manual refund reconciliation该卡已被上游直接注销,正在等待人工对账退款400
card_config_not_foundCard configuration not found卡配置不存在400
openapi_close_card_failedFailed to close card销卡失败500

Server Errors

message_keyen-USzh-CNHTTP
openapi_internal_errorOpenAPI internal errorOpenAPI 内部错误500
openapi_list_card_headers_failedFailed to list card headers查询卡头列表失败500
openapi_list_card_configs_failedFailed to list card configs查询卡配置列表失败500
openapi_apply_card_failedFailed to apply virtual card申请虚拟卡失败500
openapi_first_deposit_preview_failedFailed to preview first deposit首充预览失败500
openapi_recharge_failedFailed to recharge充值失败500
openapi_get_card_info_failedFailed to get card info获取卡片信息失败500
openapi_list_cards_failedFailed to list cards查询卡列表失败500
openapi_list_webhook_events_failedFailed to list webhook events查询 Webhook 事件历史失败500
openapi_list_transactions_failedFailed to list transactions查询交易明细失败500
openapi_freeze_card_failedFailed to freeze card冻结卡片失败500
openapi_unfreeze_card_failedFailed to unfreeze card解冻卡片失败500
python
def handle_response(resp):
    code = resp.get('code', 500)
    key = resp.get('message_key', '')

    if code == 200:
        return resp['data']
    if code == 401:
        # Always openapi_invalid_credentials
        raise AuthError("invalid credentials — check AppID/Secret/clock")
    if code == 403:
        # Feature-gated: caller is authenticated but lacks permission for this specific request
        if key.endswith('_required'):
            raise PermissionError(f"Second factor missing ({key}) — "
                                  "call /openapi/card/sensitive/send_code, then resubmit")
        if key.startswith('invalid_'):
            raise PermissionError(f"Second factor rejected: {key}")
        if key == 'openapi_sensitive_card_only_active':
            raise RuntimeError("Card must be active before requesting sensitive fields")
        raise PermissionError(f"Forbidden: {key}")
    if key == 'insufficient_balance':
        raise BalanceError()
    if key == 'kyc_not_approved' or key == 'kyc_required':
        raise KYCError()
    if key.startswith('openapi_invalid_') and key.endswith('_id'):
        raise ValueError(f"bad ID: {key}")
    if key == 'openapi_idempotency_key_conflict':
        # Don't auto-retry — caller must check the body
        raise IdempotencyConflict()
    if code == 429:
        raise RateLimited()
    if code >= 500:
        raise ServerError(resp.get('message', 'internal error'))

    raise ApiError(code, key, resp.get('message'))

Localization

Set the Accept-Language header to control the message language:

http
Accept-Language: en-US
ValueBehavior
Not sentDefault Chinese
zh-CN / zhChinese
en-US / enEnglish
OtherFallback to default

message_key is independent of Accept-Language and always stable.

Released under MIT-equivalent terms.