---
updatedAt: 2026-10-14T19:00:18.000Z
agentTools:
  projectIndex: https://docs.cybrid.xyz/llms.txt
---

# FAQ

What are the most common questions about the Cybrid platform?

## Authentication

<Accordion title="What is the difference between Bank and Organization credentials?" icon="fa-shield" iconColor="blue">

Bank credentials (`client_id` / `client_secret`) call Bank-level APIs (customers, transfers, trades, accounts, etc.). Organization credentials call the Organization service, which handles webhook subscriptions. Using Bank keys for subscription endpoints returns an error because Bank keys cannot have subscription scopes. For more information, see the [API keys](https://docs.cybrid.xyz/docs/api-keys) and [token scopes](https://docs.cybrid.xyz/docs/token-scopes) guides.

</Accordion>

<Accordion title="What is the TTL for access tokens?" icon="fa-shield" iconColor="blue">

Access tokens are valid for 30 minutes in the production environment and 8 hours in the sandbox environment. For details on generating tokens, see the [API keys](https://docs.cybrid.xyz/docs/api-keys) guide.

</Accordion>

<Accordion title="What are the rate limits on the OAuth token endpoint?" icon="fa-shield" iconColor="blue">

`/oauth/token` is limited to 20 requests per IP per 5 minutes. `/api/customer_tokens` is limited to 200 requests per IP per 5 minutes. These limits are enforced at the infrastructure level and may change.

</Accordion>

<Accordion title="Can I restrict which IP addresses can use an API key?" icon="fa-shield" iconColor="blue">

Yes. Each Bank or Organization Application supports an optional IP allowlist of up to 3 public IPv4 addresses or CIDR ranges. Set it during key generation or from the **Edit Application** form on the **Developers** tab. Requests from a source IP that is not in the allowlist are rejected with `403 Forbidden` and `message_code: ip_not_allowed`. The allowlist is embedded in the access token at issuance, so edits apply on the next token request. For the full walkthrough, see the [API keys](https://docs.cybrid.xyz/docs/api-keys#restrict-access-with-an-ip-allowlist) guide.

</Accordion>

<Accordion title="What scopes should I use when authenticating against the Bank Swagger UI?" icon="fa-shield" iconColor="blue">

Use only Bank-level scopes. Do not include subscription or organization scopes for Bank authentication. Recommended scopes:

```text
banks:read banks:write
accounts:read accounts:execute
customers:read customers:write customers:execute
prices:read
quotes:execute quotes:read
trades:execute trades:read
transfers:execute transfers:read transfers:write
external_bank_accounts:read external_bank_accounts:write external_bank_accounts:execute
external_wallets:read external_wallets:execute
workflows:read workflows:execute
deposit_addresses:read deposit_addresses:execute
deposit_bank_accounts:read deposit_bank_accounts:execute
identity_verifications:read identity_verifications:write identity_verifications:execute
```

For a complete list of available scopes, see the [token scopes](https://docs.cybrid.xyz/docs/token-scopes) guide.

</Accordion>

<Accordion title="Are Cybrid POST API calls synchronous or asynchronous?" icon="fa-shield" iconColor="blue">

All POST API calls are asynchronous. The API returns a response with the resource in a `storing` state, but creation may still be processing. Poll the resource or use webhooks to confirm the resource reaches a terminal state. For webhook setup, see the [webhooks](https://docs.cybrid.xyz/docs/webhooks) guide.

</Accordion>

## Identity Verifications

<Accordion title="Is permanent residence in the US or Canada required for KYC?" icon="fa-scale-balanced" iconColor="blue">

Yes, permanent residence in the US or Canada is required for Cybrid KYC.

</Accordion>

<Accordion title="What are the allowable countries for government ID?" icon="fa-scale-balanced" iconColor="blue">

The allowable countries for government ID are the US and Canada.

</Accordion>

<Accordion title="Which forms of government ID are accepted?" icon="fa-scale-balanced" iconColor="blue">

The following government IDs are accepted:

- Passport
- Passport card
- Driver's license
- State ID
- Permanent resident card
- Visa
- Work permit

> ℹ️ Government ID country requirement
>
> Only government-issued IDs from the US and Canada are accepted. Foreign passports (such as Indian passports) are not accepted, even if the customer has a US address or account. Ensure that the ID provided is issued by the US or Canadian government.

</Accordion>

<Accordion title="What is the minimum age for identity verification?" icon="fa-scale-balanced" iconColor="blue">

The minimum age for partner end-users is 18 years old.

</Accordion>

<Accordion title="How long does KYC take in production?" icon="fa-scale-balanced" iconColor="blue">

KYC using `id_and_selfie` typically completes within a few minutes if automated checks pass. If the verification enters `reviewing`, it may take up to 2 business days due to manual compliance review. The SLA targets are documented in the [compliance review targets](https://docs.cybrid.xyz/docs/review-targets) guide.

</Accordion>

<Accordion title="What are the main states an identity verification goes through?" icon="fa-scale-balanced" iconColor="blue">

`storing` → `waiting` (customer has not started) → `pending` (customer has started but not finished) → `reviewing` (requires manual compliance review) or `completed` (with `outcome: passed` or `outcome: failed`). A verification that has not started moves to `expired` after a timeout period controlled by the identity verification provider. For the full verification workflow, see the [verifying a customer](https://docs.cybrid.xyz/docs/verifying-a-customer) guide.

</Accordion>

<Accordion title="What happens if a customer's KYC is rejected?" icon="fa-scale-balanced" iconColor="blue">

The customer state becomes `rejected` and new identity verifications cannot be created. The failure may be due to various reasons, including a 'Country Comparison Check Failure' (when identity verification is attempted from a country different than the customer's registered country, which is not permitted). To allow a retry, open a [Zendesk ticket](https://cybridhelp.zendesk.com) and ask the Compliance team to reset the customer state to `unverified`. Creating a new customer account for the same individual will not bypass this restriction, as duplicate checks will also result in rejection. For more details, see the [verifying a customer](https://docs.cybrid.xyz/docs/verifying-a-customer) guide.

</Accordion>

<Accordion title="How many KYC attempts can a customer make before requiring Compliance intervention?" icon="fa-scale-balanced" iconColor="blue">

A customer can retry as many times as needed while their state is not `rejected`. Once they reach `rejected`, a Zendesk ticket is required to reset their state to `unverified`.

</Accordion>

<Accordion title="Does the platform allow repeat identity verifications?" icon="fa-scale-balanced" iconColor="blue">

Yes, repeat identity verifications are allowed as long as the same customer account is used. If a new customer account is created for the same individual and a new identity verification is performed, the identity verification is flagged as a repeat and auto-denied.

</Accordion>

<Accordion title="What are the expirations of the various identity verification types?" icon="fa-scale-balanced" iconColor="blue">

The following are the identity verification expirations:

- Individual customer KYC (`type: kyc`, `method: id_and_selfie`): 60 minutes
- Business customer KYB (`type: kyc`, `method: business_registration`): 14 days

For details on handling expired inquiries, see the [Persona inquiry expiry](https://docs.cybrid.xyz/docs/persona-inquiry-expiry) guide.

</Accordion>

<Accordion title="How do I simulate a KYC failure in sandbox?" icon="fa-scale-balanced" iconColor="blue">

Pass `"expected_behaviours": ["failed_immediately"]` in the `POST /api/identity_verifications` body to produce a `rejected` customer state with `outcome: failed`. Use `"passed_immediately"` to pass instantly. For other sandbox-specific behaviors, see the [sandbox environment differences](https://docs.cybrid.xyz/docs/how-does-the-sandbox-environment-differ) guide.

</Accordion>

<Accordion title="What causes a KYC to enter the `reviewing` state?" icon="fa-scale-balanced" iconColor="blue">

Common reasons include `selfie_quality_check_failure`, `selfie_pose_check_failure`, `id_quality_check_failure`, `id_expiration_check_failure`, `name_check_failure`, `address_check_failure`, and `id_country_allowed_check_failure`. Other possible reasons include `id_check_failure`, `id_mrz_check_failure`, `id_barcode_check_failure`, `database_check_failure`, `pep_check_failure`, `watchlist_check_failure`, `duplicate_person_check_failure`, `dob_check_failure`, `phone_number_check_failure`, `email_address_check_failure`, `banned_ip_address_check_failure`, and others. Customers aged over 70 also go to `reviewing` for additional fraud checks.

</Accordion>

<Accordion title="What do `address_check_failure` and `database_check_failure` mean when KYC fails?" icon="fa-scale-balanced" iconColor="blue">

The customer failed the database check on the address after they were prompted to submit a supporting document. The address on the provided document does not match the address the customer entered.

</Accordion>

<Accordion title="What does it mean if a bank IDV has `name_check_failure` or `address_check_failure` but is in the `reviewing` state?" icon="fa-scale-balanced" iconColor="blue">

The bank account remains in `reviewing` because it is undergoing manual compliance review. Typically, the bank verification moves to `completed` with `outcome: failed`, unless the customer is prompted to provide additional documents. Once all information is provided, it moves to `completed` with `outcome: failed`, or `expired` if the customer does not complete the process in 60 minutes.

</Accordion>

<Accordion title="How long does a customer's `verified` status remain valid?" icon="fa-scale-balanced" iconColor="blue">

It remains valid as long as the underlying compliance decisions are not expired or invalidated, and the government-issued ID used for KYC is not expired. When the ID expires, the customer state automatically moves to `unverified`, requiring re-verification.

</Accordion>

<Accordion title="Can a verified customer go to `frozen`?" icon="fa-scale-balanced" iconColor="blue">

Yes. A customer can go to `frozen` due to security concerns (such as suspicious activity) or a negative balance caused by an ACH return. A negative balance persists until the customer repays, so a customer frozen this way stays frozen until the debt is settled and the Cybrid team unfreezes them. There is no webhook for customer state changes yet (planned for a future release); use polling via `GET /api/customers/{customer_guid}`. See the [creating a customer](https://docs.cybrid.xyz/docs/creating-a-customer) and [negative customer balances](https://docs.cybrid.xyz/docs/negative-balances) guides for details.

</Accordion>

<Accordion title="How do I integrate Persona for Flutter or Android apps?" icon="fa-scale-balanced" iconColor="blue">

Most partners run the Persona JS SDK inside a WebView, binding the `inquiryId` (not a `templateId`). For Android OAuth redirect flows using `plaid_flutter`, register your Android package name (such as `com.yourapp.app`) via Cybrid support and pass it in the Plaid workflow request instead of a redirect URI. See the [Persona theming](https://docs.cybrid.xyz/docs/persona-theming) and [resume Persona inquiry session](https://docs.cybrid.xyz/docs/resume-persona-inquiry-session) guides.

</Accordion>

<Accordion title="Can I create a `tax_id_and_selfie` identity verification before the customer completes `id_and_selfie`?" icon="fa-scale-balanced" iconColor="blue">

No. The customer must first complete `id_and_selfie` and reach `verified` state. Attempting to create an identity verification with `"method": "tax_id_and_selfie"` for an unverified customer returns a 422 error with message code `unverified_customer`. For the SSN/SIN capture workflow, see the [capturing SSN/SIN](https://docs.cybrid.xyz/docs/capturing-ssn-sin) guide.

</Accordion>

<Accordion title="How do I generate a document submission link for a customer?" icon="fa-scale-balanced" iconColor="blue">

Create an identity verification with `"method": "document_submission"`: `POST /api/identity_verifications` with `{"type": "kyc", "method": "document_submission", "customer_guid": "customer_guid"}`. This generates a Persona link for the customer to upload documents. For the full workflow, see the [document submission](https://docs.cybrid.xyz/docs/document-submission) guide.

</Accordion>

<Accordion title="How do I access customer KYC documents and PII via the API?" icon="fa-scale-balanced" iconColor="blue">

Add the `identity_verifications:pii:read` scope to your API credentials. Call `GET /api/identity_verifications/{identity_verification_guid}?include_pii=true` to retrieve PII data. Associated document files are accessible through the API or the Partner Portal Documents tab. For more details, see the [PII and IDV documents](https://docs.cybrid.xyz/docs/pii-and-idv-documents) guide.

</Accordion>

<Accordion title="Why doesn't `include_pii=true` return PII data in production?" icon="fa-shield" iconColor="blue">

Your access token must include the `identity_verifications:pii:read` scope. Without this scope, the API returns the identity verification record but omits PII fields such as name, address, date of birth, phone number, and email. Add this scope when generating your bank token via `POST /oauth/token`. See the [token scopes](https://docs.cybrid.xyz/docs/token-scopes) and [PII and IDV documents](https://docs.cybrid.xyz/docs/pii-and-idv-documents) guides.

</Accordion>

<Accordion title="How do I initiate Enhanced Due Diligence (EDD) via the API?" icon="fa-scale-balanced" iconColor="blue">

Create an identity verification with `"method": "enhanced_due_diligence"`: `POST /api/identity_verifications` with `{"type": "kyc", "method": "enhanced_due_diligence", "customer_guid": "customer_guid"}`. Use the returned `persona_inquiry_id` to launch the Persona EDD questionnaire. Monitor the `identity_verification.completed` webhook, then poll `GET /api/customers/{customer_guid}` to confirm updated `activity_limits`. For the full EDD workflow, see the [enhanced due diligence](https://docs.cybrid.xyz/docs/enhanced-due-diligence) guide.

</Accordion>

<Accordion title="How long is an EDD Persona link valid?" icon="fa-scale-balanced" iconColor="blue">

The EDD link is valid for 14 days. If a customer starts the Persona flow and abandons it, they cannot resume and see an "expired" screen on return. Create a new EDD identity verification in this case. See the [enhanced due diligence](https://docs.cybrid.xyz/docs/enhanced-due-diligence) and [Persona inquiry expiry](https://docs.cybrid.xyz/docs/persona-inquiry-expiry) guides.

</Accordion>

<Accordion title="Is EDD per transaction or per account?" icon="fa-scale-balanced" iconColor="blue">

EDD is per account. When approved, all of the customer's activity limits increase across trades, book transfers, crypto transfers, and funding. EDD limits are valid for 7 days from approval. After expiration, limits revert to the customer's defaults. A new EDD overwrites any previous EDD limits and resets the 7-day window.

</Accordion>

<Accordion title="Can I change a customer's type from `business` to `individual` or vice versa?" icon="fa-scale-balanced" iconColor="blue">

No. The customer type is set at creation via `POST /api/customers` and cannot be changed. Create a new customer and complete a new KYC/KYB process to switch types. See the [creating a customer](https://docs.cybrid.xyz/docs/creating-a-customer) guide.

</Accordion>

<Accordion title="How long does KYB verification take?" icon="fa-scale-balanced" iconColor="blue">

The standard SLA is 5 business days from when the KYB reaches `reviewing` state. Raise a Zendesk ticket if the SLA is exceeded. For the full KYB workflow, see the [KYB](https://docs.cybrid.xyz/docs/kyb) guide.

</Accordion>

<Accordion title="What triggers the 5-business-day KYB review clock?" icon="fa-scale-balanced" iconColor="blue">

The clock starts when the identity verification state updates to `reviewing`, meaning all business information and associated UBO information has been collected and UBOs have completed their KYC.

</Accordion>

<Accordion title="Do UBO (Ultimate Beneficial Owner) individuals receive their KYC link automatically?" icon="fa-scale-balanced" iconColor="blue">

Yes. Once a KYB is submitted, UBOs are automatically sent an email with a Persona inquiry link. You can also retrieve the inquiry IDs via the API and share them manually.

</Accordion>

<Accordion title="Can a partner add themselves (their own business entity) as a business customer?" icon="fa-scale-balanced" iconColor="blue">

No. Cybrid's Compliance team declines identity verifications where a partner attempts to onboard itself as a business customer.

</Accordion>

<Accordion title="What documents are accepted for KYB proof of address?" icon="fa-scale-balanced" iconColor="blue">

A bank statement, utility bill, or EIN letter. Business formation documents alone are not sufficient for proof of address.

</Accordion>

<Accordion title="Does bank account verification (`type: bank_account`) apply to business customers?" icon="fa-scale-balanced" iconColor="blue">

No. Bank account verifications are only required for individual customers, not business customers. See the [verifying external bank accounts](https://docs.cybrid.xyz/docs/verifying-external-bank-accounts) guide.

</Accordion>

## External Bank Accounts

<Accordion title="How do I connect an external bank account via Plaid?" icon="fa-building-columns" iconColor="blue">

Create a workflow with `"type": "plaid"` and `"kind": "link_token_create"`, launch the Plaid Link SDK with the returned `plaid_link_token`, then call `POST /api/external_bank_accounts` with `"account_kind": "plaid"` passing the `plaid_public_token` and `plaid_account_id`. For step-by-step instructions, see the [Plaid integration](https://docs.cybrid.xyz/docs/plaid-integration) and [add customer external bank accounts](https://docs.cybrid.xyz/docs/add-customer-external-bank-accounts) guides.

</Accordion>

<Accordion title="What `account_kind` values are available for external bank accounts?" icon="fa-building-columns" iconColor="blue">

`plaid` (using Cybrid's Plaid integration), `plaid_processor_token` (using your own Plaid account with a processor token), and `raw_routing_details` (manual routing and account number). For counterparty-owned accounts, use `raw_routing_details` and pass a `counterparty_guid` parameter. See the [external bank accounts](https://docs.cybrid.xyz/docs/external-bank-accounts) guide for details on each account kind.

</Accordion>

<Accordion title="Why is the available balance null for a Plaid Processor Token connection?" icon="fa-building-columns" iconColor="blue">

When connecting an external bank account using a Plaid Processor Token (your own Plaid account), Cybrid cannot retrieve the available balance for the account. As a result, the available balance is returned as `null`. This is expected behavior for processor token connections. The current balance is typically returned, but available balance is optional and may not be reported by some banks. If you require available balance or refresh status, use your own Plaid API integration directly.

</Accordion>

<Accordion title="What happens when the available balance is null but the current balance is present?" icon="fa-building-columns" iconColor="blue">

The Cybrid platform evaluates current and available balances independently. Some banks may not report available balance (it may be `null` or zero), while current balance is typically always returned. The platform only raises an error if both balances are `null`. Having just the current balance is valid and by design.

</Accordion>

<Accordion title="How do I verify an external bank account after linking?" icon="fa-building-columns" iconColor="blue">

Call `POST /api/identity_verifications` with `"type": "bank_account"`. Use `"method": "account_ownership"` for `plaid` accounts, or `"method": "attested_ownership"` for `plaid_processor_token` accounts. For the full verification workflow, see the [verifying external bank accounts](https://docs.cybrid.xyz/docs/verifying-external-bank-accounts) guide.

</Accordion>

<Accordion title="Why is my Plaid-connected external bank account returning `null` for balance?" icon="fa-building-columns" iconColor="blue">

For accounts connected via Plaid Processor Token, Cybrid cannot query the balance. Use your own Plaid API integration to retrieve balance and account refresh status for processor token accounts.

</Accordion>

<Accordion title="What is `refresh_required` state and how do I handle it?" icon="fa-building-columns" iconColor="blue">

`refresh_required` means the customer's Plaid connection has expired or been revoked. Create a new workflow with `"kind": "link_token_update"`, launch Plaid Link in update mode, and PATCH the external bank account state to `completed` after the customer re-authenticates. See the [Plaid integration](https://docs.cybrid.xyz/docs/plaid-integration) guide for the update flow.

</Accordion>

<Accordion title="What does the transfer failure code `refresh_required` indicate?" icon="fa-building-columns" iconColor="blue">

The transfer failure code `refresh_required` means the Plaid-connected bank account must be reconnected by the customer by creating a new workflow with `kind` set to `link_token_update`.

</Accordion>

<Accordion title="What does the transfer API error `invalid_external_bank_account` mean during the creation of an ACH funding transaction?" icon="fa-building-columns" iconColor="blue">

This error can occur if the external bank account is in `refresh_required` state. To resolve, the customer needs to reconnect their external bank account by creating a new workflow with `kind` set to `link_token_update`.

</Accordion>

<Accordion title="What does the transfer failure code `plaid_institution_not_responding` indicate?" icon="fa-building-columns" iconColor="blue">

The failure code `plaid_institution_not_responding` means [Plaid](https://plaid.com/docs/errors/institution/) is unable to communicate with the customer's bank. This can happen if the bank is temporarily offline or if there are performance issues on Plaid's side. Retry later. If the issue persists, try a different institution or bank.

</Accordion>

<Accordion title="What should I do for `plaid_no_accounts`, `plaid_multiple_accounts`, or `plaid_item_not_supported`?" icon="fa-building-columns" iconColor="blue">

These errors are from Plaid, and in most cases retrying the same account does not help. Delete the account and re-add it (or add a different account).

</Accordion>

<Accordion title="How do I register a Plaid redirect URI for my application?" icon="fa-building-columns" iconColor="blue">

Contact Cybrid support with your redirect URI. Sandbox only supports HTTPS URIs. Separate registrations are needed for sandbox and production environments. For Android apps, register your package name (such as `com.yourapp`) instead of a redirect URI.

</Accordion>

<Accordion title="Can I connect a bank-level (partner) external bank account via Plaid?" icon="fa-building-columns" iconColor="blue">

No. Bank-level external bank accounts cannot be connected via Plaid. Provide the raw routing and account number details to Cybrid support, who will add it manually on your behalf.

</Accordion>

<Accordion title="What action is required when `no_account` or `invalid_account` is returned from `GET /api/external_bank_accounts`?" icon="fa-building-columns" iconColor="blue">

When either `no_account` or `invalid_account` is returned as the `message_code` on a 422 response, the external bank account must be deleted and re-added, as Cybrid no longer has access to the account.

</Accordion>

<Accordion title="Can customers add external bank accounts using raw routing details instead of Plaid?" icon="fa-building-columns" iconColor="blue">

Yes, but with limitations. Raw routing details accounts are disabled by default in production and must be enabled per bank by contacting Cybrid support. You cannot initiate a funding deposit (ACH pull) via API on these accounts — deposits must be initiated externally by the customer. Funding withdrawals (ACH push) work on all rails with no difference. Contact Cybrid support.

</Accordion>

<Accordion title="When does a bank account identity verification go to the `waiting` state?" icon="fa-building-columns" iconColor="blue">

A bank account identity verification transitions to `waiting` only when the system cannot make an automated decision and the case requires analyst review (such as a `name_check_failure` requiring a bank statement upload via Persona). If the verification passes automatically, it goes directly from `storing` to `completed`.

</Accordion>

<Accordion title="Does deleting an external bank account affect existing transfers?" icon="fa-building-columns" iconColor="blue">

No. Deleting an external bank account does not affect transfers that have already been initiated. You cannot create new transfers to the deleted account.

</Accordion>

<Accordion title="What does the `invalid_routing_number` error mean when linking a bank account via Plaid?" icon="fa-building-columns" iconColor="blue">

This error occurs when Plaid does not have access to the most recent routing details for the customer's bank. The account creation always fails in this case. The customer can try a different bank account or financial institution.

</Accordion>

## Transfers

<Accordion title="What is the difference between EFT and Interac E-Transfer?" icon="fa-money-bill-transfer" iconColor="blue">

EFT and Interac E-Transfer are separate Canadian (CAD) rails. EFT moves funds bank-to-bank using a deposit bank account's routing and account numbers — use it to receive deposits into a [deposit bank account](https://docs.cybrid.xyz/docs/customer-deposit-bank-accounts). Interac E-Transfer is an email- or phone-routed instant rail initiated with `payment_rail: etransfer` — see the [Interac E-Transfer](https://docs.cybrid.xyz/docs/interac-e-transfer) guide.

</Accordion>

<Accordion title="What is the difference between `funding` and `instant_funding` transfer types?" icon="fa-money-bill-transfer" iconColor="blue">

A standard `funding` transfer initiates an ACH pull that settles in a few hours on the same business day. An `instant_funding` transfer immediately credits the customer's fiat account using a pre-funded bank-level float account; the ACH pull settles later. Instant funding requires passing `"bank_fiat_account_guid"` in the `POST /api/transfers` call. For setup details, see the [instant funding](https://docs.cybrid.xyz/docs/instant-funding) and [transfer process](https://docs.cybrid.xyz/docs/transfer-process) guides.

</Accordion>

<Accordion title="How are API amounts specified (dollars or cents)?" icon="fa-money-bill-transfer" iconColor="blue">

All amounts are in base units: cents for USD (100 = $1.00), 1/1,000,000 of a USDC for USDC (1,000,000 = 1 USDC), wei for ETH, etc.

</Accordion>

<Accordion title="What is the minimum transfer amount?" icon="fa-money-bill-transfer" iconColor="blue">

$0.50 USD (50 cents). Transfers or quotes below this threshold are rejected. See the [limits and minimums](https://docs.cybrid.xyz/docs/limits-and-minimums) guide for all platform limits.

</Accordion>

<Accordion title="What payment rails are supported?" icon="fa-money-bill-transfer" iconColor="blue">

ACH (same-day ACH for Plaid pulls; standard ACH for push), Wire, RTP/FedNow, EFT, and Interac e-Transfer. In the API `payment_rail` field, valid values are `ach`, `wire`, `rtp`, `eft`, and `etransfer`. The `rtp` rail represents real-time payment rails (RTP and FedNow) at the payment processor level. EFT and e-Transfer are available for Canadian banking operations in both directions (deposit and withdrawal). See the [platform rails](https://docs.cybrid.xyz/docs/platform-rails) guide.

</Accordion>

<Accordion title="What rails are supported for CAD withdrawals?" icon="fa-money-bill-transfer" iconColor="blue">

CAD funding withdrawals are supported on two rails: EFT (`eft`) and Interac E-Transfer (`etransfer`). EFT withdrawals require `destination_account_guid` on the quote; e-Transfer withdrawals instead require `payment_rail: etransfer` on the quote and route to the recipient using the customer's email or phone. See the [Interac E-Transfer](https://docs.cybrid.xyz/docs/interac-e-transfer) guide.

</Accordion>

<Accordion title="Which payment rail is used for Plaid pull transfers?" icon="fa-money-bill-transfer" iconColor="blue">

Only ACH (same-day). There is no option to specify the rail for Plaid pull deposits.

</Accordion>

<Accordion title="What does the `reviewing` transfer state indicate?" icon="fa-money-bill-transfer" iconColor="blue">

The `reviewing` state may occur after `pending`, indicating the transfer requires compliance review. After `reviewing`, the transfer progresses to either `completed` or `failed`.

</Accordion>

<Accordion title="Is there an API to cancel ACH transactions in a pending state?" icon="fa-money-bill-transfer" iconColor="blue">

Yes. Request cancellation of an eligible `funding` transfer with `DELETE /api/transfers/{transfer_guid}`, sending `Accept-Version: 2026-04-01` or later; earlier API versions return `404`. Cancellation is best-effort: the transfer moves to `cancelling` and then ends in `failed` with `failure_code: cancelled`, or in `completed` if it settled before the cancellation took effect. See the [Cancel a Transfer](https://docs.cybrid.xyz/docs/cancel-a-transfer) guide.

</Accordion>

<Accordion title="How do I apply fees to book transfers?" icon="fa-money-bill-transfer" iconColor="blue">

There is no built-in fee mechanism for book transfers. Perform two transfers: (1) a book transfer of the fee amount from the customer's account to your partner fiat account, then (2) the customer's actual book transfer. See the [book transfers](https://docs.cybrid.xyz/docs/book-transfers) guide.

</Accordion>

<Accordion title="How do I withdraw fees collected in my bank-level *Fee* account?" icon="fa-money-bill-transfer" iconColor="blue">

Book transfer the fees to your bank-level fiat account (if not already there), connect a bank-level external bank account via raw routing details, then perform a `funding` withdrawal transfer from the bank-level fiat account to that external bank account. See the [platform accounts](https://docs.cybrid.xyz/docs/platform-accounts) guide for account types and fee collection.

</Accordion>

<Accordion title="Why do I get `invalid_external_bank_account` when sending a funding withdrawal from a customer's fiat account to a bank-level external bank account?" icon="fa-money-bill-transfer" iconColor="blue">

You cannot use a bank-level external bank account as the target for a transfer originating from a customer's fiat account. Either (a) add the external bank account at the customer level, or (b) book transfer the funds to the bank-level fiat account first, then perform the withdrawal from there.

</Accordion>

<Accordion title="How does the ACH hold work after a funding deposit?" icon="fa-money-bill-transfer" iconColor="blue">

Cybrid can apply an internal 48-hour hold on ACH-pulled funds even after same-day settlement. The `platform_balance` field on `GET /api/accounts` shows total funds including held amounts; `platform_available` shows funds immediately available for transactions. Contact support to configure the hold period for your production bank. See the [Transfer Process](https://docs.cybrid.xyz/docs/transfer-process) guide.

</Accordion>

<Accordion title="What is the difference between account `platform_balance` and `platform_available`?" icon="fa-money-bill-transfer" iconColor="blue">

`platform_available` is the balance that has already settled, whereas `platform_balance` includes pending transfers that have not yet settled.

</Accordion>

<Accordion title="How can I make account reads faster?" icon="fa-money-bill-transfer" iconColor="blue">

`GET /api/accounts` and `GET /api/accounts/{account_guid}` accept `include_balances`, which defaults to `true` and returns `platform_balance` and `platform_available`. Keep the default when you are reading balances. When you are not, pass `include_balances=false`: the platform skips the balance lookup and returns a lighter response, with every other field unchanged. Typical cases are polling a new account until `created`, resolving an account GUID before a trade or transfer, and rendering account lists or pickers. See [Read Accounts Efficiently](https://docs.cybrid.xyz/docs/platform-accounts#read-accounts-efficiently).

</Accordion>

<Accordion title="Why is my account Balance different from the Available amount?" icon="fa-money-bill-transfer" iconColor="blue">

A difference between an account's Balance and Available amounts can occur for several reasons:

- **Administrative Holds:** After certain deposit types (such as ACH), funds may be subject to a required holding period (typically 2 days). During this time, the full amount appears in the Balance, but only becomes Available once the hold expires. This is a risk management measure for potential returns or reversals.
- **Transfers Under Review:** If a transfer is under review or subject to compliance checks, the associated funds may not be available for withdrawal or use, even if the transfer is not marked as `pending`.

You can track when funds become available by monitoring the `platform_available` field on `GET /api/accounts`. Once a transfer is canceled or the hold is released, the Available amount should update accordingly.

</Accordion>

<Accordion title="What happens to a funding transfer if it is returned?" icon="fa-money-bill-transfer" iconColor="blue">

If you have a two-day ACH hold configured: (1) If the ACH return occurs *within* the two-day hold window, the funding transfer goes into `failed` state with the error in the `failure_code` field and the NACHA return code in the `return_code` field. (2) If the ACH return occurs *outside* the two-day hold window, the original funding transfer remains `completed` but has the `return_code` set. Additionally, a new transfer of type `funding_return` is created with a reference to the original transfer in `reference_transfer_guid`.

</Accordion>

<Accordion title="What do R03 and R04 return codes mean?" icon="fa-money-bill-transfer" iconColor="blue">

Plaid verifies the bank account during online banking sign-in, but this does not guarantee the ability to send or receive money. If Cybrid receives an R03 or R04 return code, the external bank account must be removed. Notify the customer that their account details caused an ACH return. They should contact their bank to confirm the account information is accurate before attempting another transaction.

</Accordion>

<Accordion title="Why did my e-Transfer withdrawal fail with `customer_contact_info_missing`?" icon="fa-money-bill-transfer" iconColor="blue">

The Interac E-Transfer rail routes funds to the recipient using the customer's email or phone on their identity record. If both fields are empty when the transfer is executed, the transfer terminates in `failed` with `failure_code: customer_contact_info_missing`. Populate an email or phone on the customer's identity, then create a new transfer to retry — this failure is non-retryable on the original transfer.

</Accordion>

<Accordion title="How long before an Interac E-Transfer expires?" icon="fa-money-bill-transfer" iconColor="blue">

E-Transfer deposits and withdrawals have different validity windows. A deposit request expires **1 day** after it is created if the customer does not authorize it. A withdrawal expires **7 days** after it is sent if the recipient does not claim it. In both cases the transfer terminates in `failed` with `failure_code: payment_request_expired`.

</Accordion>

<Accordion title="Is there a fee for Interac E-Transfer withdrawals?" icon="fa-money-bill-transfer" iconColor="blue">

Yes. Interac E-Transfer withdrawals include a **$1.25 CAD** network fee in the funding quote. The platform charges this fee on every withdrawal, including withdrawals that do not complete — it is not refunded if the e-transfer expires unclaimed or the recipient declines it.

</Accordion>

<Accordion title="What does the `invalid_payment_rail_for_direction` error indicate?" icon="fa-money-bill-transfer" iconColor="blue">

This 422 error means the RTP payment rail is not supported for the direction of the transfer you are attempting. For withdrawals (`side: withdrawal`), RTP withdrawal transfers from bank-level external bank accounts are not yet supported. For deposits (`side: deposit`), RTP transfers cannot be initiated on the Cybrid platform — they must be initiated externally by customers (for customer-level accounts) or by partners (for bank-level accounts).

</Accordion>

<Accordion title="Can Cybrid accounts receive or send international wires?" icon="fa-money-bill-transfer" iconColor="blue">

International wires are not currently supported. ACH, domestic Wire, and RTP/FedNow are supported for US customers. EFT and Interac E-Transfer are supported for Canadian customers.

</Accordion>

<Accordion title="Is the Cybrid platform affected by bank holidays?" icon="fa-money-bill-transfer" iconColor="blue">

Yes, all US and Canadian bank holidays affect the platform. Every holiday adds an additional business day for all fiat transfer and trade settlements. Crypto transfers are unaffected.

</Accordion>

<Accordion title="What is the difference between `fiat_account_guid`, `customer_fiat_account_guid`, and `bank_fiat_account_guid` in the transfer API?" icon="fa-money-bill-transfer" iconColor="blue">

`fiat_account_guid` is for `funding` transfers where only one fiat account is involved. `customer_fiat_account_guid` and `bank_fiat_account_guid` are for `instant_funding` and `lightning` transfers where multiple fiat accounts are involved (both customer and bank level).

</Accordion>

<Accordion title="How do I prevent duplicate transfers?" icon="fa-money-bill-transfer" iconColor="blue">

The quote GUID acts as an idempotency key when you create a transfer or trade. Each quote can be executed only once: a second `POST /api/transfers` or `POST /api/trades` with the same `quote_guid` returns a 409 error with message code `quote_already_exists`, even if both requests arrive at the same time. Creating a quote does not move funds or reserve a balance, so duplicate quotes are harmless; quotes that are never executed expire.

To avoid duplicates, store the `quote_guid` against your internal order or payment ID. If a create request times out or returns a network error, retry with the same `quote_guid` instead of creating a new quote. A `409` with `quote_already_exists` on retry means the original request already created the transfer or trade. Create a new quote only if the original expired before it was executed. See the [Transfer Process](https://docs.cybrid.xyz/docs/transfer-process) guide.

</Accordion>

<Accordion title="How long can a customer file an ACH return after a deposit?" icon="fa-money-bill-transfer" iconColor="blue">

A customer can file an ACH return up to 60 days after the settlement date. If you issue a refund via a funding withdrawal, it is not connected to the original deposit in the banking system, so the customer could still file a return on the original transaction.

</Accordion>

<Accordion title="Why did my transfer fail with `limit_exceeded`?" icon="fa-money-bill-transfer" iconColor="blue">

The `limit_exceeded` failure code means the customer has exceeded their activity limits. View a customer's `activity_limits` by calling `GET /api/customers/{customer_guid}` or checking the Customer Details in the Partner Portal. Limits are based on calendar days. See the [limits and minimums](https://docs.cybrid.xyz/docs/limits-and-minimums) guide for default limits and how to request increases. ACH pull deposits for recently created customers can also fail with `limit_exceeded` when they exceed the additional new-customer limits described in "Do new customer accounts have additional deposit restrictions?"

</Accordion>

<Accordion title="What is the ACH pulls processing cutoff time?" icon="fa-money-bill-transfer" iconColor="blue">

ACH transfers are processed on business days only (Monday through Friday, excluding US bank holidays) in three same-day batches with cutoffs at 9:50 AM, 12:50 PM, and 3:50 PM ET. Transfers initiated after 3:50 PM ET or on weekends and holidays are processed on the next business day. See [Fiat Transfer Settlement](https://docs.cybrid.xyz/docs/settlement-process-fiat-transfer-settlement) for batch settlement times.

</Accordion>

<Accordion title="What are the per-transaction limits for each payment rail?" icon="fa-money-bill-transfer" iconColor="blue">

ACH has a per-transaction limit of $6,000 (can be increased up to $25,000 but requires a higher reserve amount). RTP has a per-transaction limit of $25,000 (can be increased up to $500,000). Wire has a per-transaction limit of $750,000. These are rail-level limits and apply regardless of the customer's activity limits. For amounts exceeding the ACH limit, use `"payment_rail": "wire"` or split the transfer into multiple ACH transactions. See the [limits and minimums](https://docs.cybrid.xyz/docs/limits-and-minimums) guide for the complete limits reference.

</Accordion>

<Accordion title="Are there deposit limits when customers push funds to their deposit bank account?" icon="fa-money-bill-transfer" iconColor="blue">

No. There is no limit on receiving funds when customers push funds to their deposit bank account via wire, ACH push, or RTP. Activity limits for deposit transfers only apply to ACH pull (debit) transfers.

</Accordion>

<Accordion title="Do new customer accounts have additional deposit restrictions?" icon="fa-money-bill-transfer" iconColor="blue">

Customer accounts created within the previous 60 days may be subject to additional ACH pull deposit limits to protect against excessive ACH returns:

- $1,000 per week
- $2,000 cumulative in the first 30 days
- $5,000 cumulative in the first 60 days

After 60 days, the customer moves to their standard activity limits automatically. These limits apply only to ACH pull deposits. An ACH pull that would exceed one of these limits fails with `limit_exceeded`. A transfer that risk screening flags as likely to be returned fails with `return_risk_exceeded`. For customers who need to transact above these limits within their first 60 days, wire transfers to deposit bank accounts are an option.

</Accordion>

<Accordion title="Why did my transfer return `no_deposit_bank_account`?" icon="fa-money-bill-transfer" iconColor="blue">

`POST /api/transfers` returns HTTP 422 with `message_code: no_deposit_bank_account` when the customer `fiat` account used by a `funding` transfer has no `main` deposit bank account in `state: created`. Create one with `POST /api/deposit_bank_accounts` for that `fiat` account, poll until `state: created`, then retry the transfer. If the customer has more than one `fiat` account for the asset, each needs its own deposit bank account. See [Customer Deposit Bank Accounts](https://docs.cybrid.xyz/docs/customer-deposit-bank-accounts#handling-no_deposit_bank_account-errors).

</Accordion>

<Accordion title="Why did my transfer fail with `return_risk_exceeded`?" icon="fa-money-bill-transfer" iconColor="blue">

The `return_risk_exceeded` failure code means the transfer was declined because Cybrid's risk screening (primarily using the Plaid Signal score and other factors) determined there is a high likelihood the transfer would be returned by the originating bank. This protection prevents transfers that are likely to fail (for example, due to insufficient funds, unauthorized return, or account-related issues) from being submitted. This can be more common for new or recently linked accounts, or accounts with limited transaction history.

If you receive this failure, you cannot override the risk decision. You may try the following:

- Retry the transfer with a lower amount (e.g., $10 USD)
- Wait a few days and try again
- Use a different bank account if available

If the customer continues to experience issues and believes their account is in good standing, they may need to contact their bank or use an alternative funding method (such as wire transfer).

</Accordion>

<Accordion title="Why are my ACH transfers stuck in `reviewing` state?" icon="fa-money-bill-transfer" iconColor="blue">

Multiple ACH transfers with the same dollar amount can be flagged as potential duplicate transfers by the partner bank's compliance system. The transfers are held for review before being released. Consider varying transfer amounts when splitting larger transactions.

</Accordion>

<Accordion title="Can I confirm that an outgoing wire or ACH transfer has been received by the counterparty's bank?" icon="fa-money-bill-transfer" iconColor="blue">

No. There is no way to confirm that an outgoing transfer has landed in the recipient's bank account, except providing the trace number to the customer to follow up with their bank. For incoming deposits via deposit bank accounts, you receive a `transfer` webhook when funds arrive on the platform. See the [settlement process](https://docs.cybrid.xyz/docs/settlement-process-fiat-transfer-settlement) guide for fiat transfer settlement timelines.

</Accordion>

<Accordion title="How do I get the IMAD and OMAD for wire transfers?" icon="fa-money-bill-transfer" iconColor="blue">

Wire transfer identifiers (IMAD and OMAD) are available in the `identifiers` array on the transfer resource. Retrieve them via `GET /api/transfers/{transfer_guid}` or view them in the Partner Portal under the Identifiers tab on a transfer's detail page.

</Accordion>

<Accordion title="How do I detect incoming deposits to a customer's deposit bank account?" icon="fa-money-bill-transfer" iconColor="blue">

Monitor your webhook subscription for `transfer.completed` events. Call `GET /api/transfers/{transfer_guid}` and check if `transfer_type` is `funding` and `side` is `deposit`. The `transfer_details` field contains additional information such as `beneficiary_name` (sender name), `transaction_type`, and routing details. Use `destination_account.guid` to match the transfer to a customer. See the [deposit bank accounts](https://docs.cybrid.xyz/docs/customer-deposit-bank-accounts) and [webhooks](https://docs.cybrid.xyz/docs/webhooks) guides.

</Accordion>

<Accordion title="What types of external wallets can I create?" icon="fa-coins" iconColor="blue">

External wallets can be owned by a customer (pass `customer_guid`), a counterparty (pass `counterparty_guid`), or the bank (omit both). The `address` field is the on-chain blockchain address and is required. See the [add external wallets](https://docs.cybrid.xyz/docs/add-external-wallets) guide.

</Accordion>

<Accordion title="Why don't I provide a network when creating an external wallet?" icon="fa-coins" iconColor="blue">

The network is inherent in the asset specified when creating an external wallet, so the network is predetermined when specifying the asset for quotes and external withdrawals.

</Accordion>

<Accordion title="Can a customer send crypto directly to a bank-level external wallet?" icon="fa-coins" iconColor="blue">

Yes. Use `POST /api/quotes` with `product_type: crypto_transfer` and `customer_guid`, then `POST /api/transfers` with `transfer_type: crypto`, `external_wallet_guid` pointing to the bank-level wallet, and `source_participants` / `destination_participants` set to the customer. See the [withdraw crypto](https://docs.cybrid.xyz/docs/withdraw-crypto) and [transfer participants](https://docs.cybrid.xyz/docs/transfer-participants) guides.

</Accordion>

<Accordion title="How long does it take to move crypto assets between `trading` and `storage` accounts?" icon="fa-coins" iconColor="blue">

Transfers from `trading` to `storage` go on-chain immediately and are subject to the normal blockchain confirmation period. On the platform, a transaction is considered settled after 4 confirmations. Transfers from `storage` to `trading` can take up to 24 hours to process, followed by the normal blockchain confirmation time.

</Accordion>

<Accordion title="Do Lightning Network transfers count toward the crypto transfer limit?" icon="fa-coins" iconColor="blue">

No. Lightning transfers do not currently contribute to the crypto transfer limit. Independent limits for Lightning may be introduced in the future. See the [send Lightning payment](https://docs.cybrid.xyz/docs/send-lightning-payment) and [receive Lightning payment](https://docs.cybrid.xyz/docs/receive-lightning-payment) guides.

</Accordion>

<Accordion title="What does the `prohibited_address` failure code mean when adding an external wallet?" icon="fa-coins" iconColor="blue">

The `prohibited_address` failure code means the wallet address did not pass Cybrid's on-chain wallet screening. The wallet's `state` is `failed`, and a `failed` wallet cannot be used as a withdrawal destination, including to return funds to the original sender. To return funds, ask the sender for a different wallet address. Open a Zendesk compliance ticket if you believe this is an error. Wallet addresses with no transaction history may occasionally trigger false positives.

</Accordion>

<Accordion title="How do I collect on a customer's negative balance?" icon="fa-coins" iconColor="blue">

Credit the customer's `fiat` account — the negative balance rises toward zero and your reserve is repaid automatically with a `loss_reclaim` transfer. Partial repayments are fine. Both of these work while the customer is frozen: the customer pushes funds to their deposit bank account (ACH push, wire, RTP, or FedNow for USD; EFT for CAD), or you book funds from your bank's `fiat` account. See the [negative customer balances](https://docs.cybrid.xyz/docs/negative-balances) guide.

</Accordion>

## Trades

<Accordion title="Can I trade USDC_SOL, USDT_TRX, or CADD for CAD?" icon="fa-coins" iconColor="blue">

Yes. Canadian banks trade against CAD, including the `USDC_SOL-CAD`, `USDT_TRX-CAD`, and `CADD-CAD` pairs. Generate a quote with the pair you want, such as `symbol: CADD-CAD`, then execute the trade the same way as any other pair. Note that `CADD` has 18 decimals, unlike the 6 decimals used by `USDC_SOL` and `USDT_TRX`. See [Create and execute a trade](https://docs.cybrid.xyz/docs/execute-trades) and [Assets and Symbols](https://docs.cybrid.xyz/docs/assets-and-symbols).

</Accordion>

<Accordion title="Why do trades stay in `executed` state in sandbox?" icon="fa-coins" iconColor="blue">

In sandbox, trades always remain in `executed` state and never move to `settling`. This is by design. See the [sandbox environment differences](https://docs.cybrid.xyz/docs/how-does-the-sandbox-environment-differ) guide.

</Accordion>

<Accordion title="What is the `symbol` field for quotes, and when is it required?" icon="fa-coins" iconColor="blue">

The `symbol` field (such as `USDC-USD`) is only required for `trading` product type quotes. For crypto transfers, omit `symbol` and use `asset` instead. Use `"product_type": "crypto_transfer"` (not `"crypto"`) for withdrawal quotes. See the [Withdraw crypto](https://docs.cybrid.xyz/docs/withdraw-crypto) guide.

</Accordion>

<Accordion title="How does trade fee billing work?" icon="fa-coins" iconColor="blue">

Cybrid applies a trading fee per your contract in BPS. For example, at 50 BPS on a $9.95 trade: fee = 9.95 x 0.005 = ~$0.05. This fee appears as a `fee` field in the quote response. Trade fees are collected on every quote and appear on your monthly invoice. See the [trade fees](https://docs.cybrid.xyz/docs/trade-fees) guide.

</Accordion>

<Accordion title="Why are trade fees zero when I use a customer token instead of a bank token?" icon="fa-coins" iconColor="blue">

Only bank tokens (generated via `POST /oauth/token`) can set fees on trades and transfers. Customer tokens (generated via `POST /api/customer_tokens`) cannot set fees for security reasons. Always use a bank token when initiating trades or transfers on behalf of customers if you need to apply spread or fixed fees. See the [trade fees](https://docs.cybrid.xyz/docs/trade-fees) and [token scopes](https://docs.cybrid.xyz/docs/token-scopes) guides.

</Accordion>

<Accordion title="What is the correct trading symbol format for USDT on Tron?" icon="fa-coins" iconColor="blue">

The trading symbol for USDT on Tron pairs the asset with a fiat currency: `USDT_TRX-USD` at US banks and `USDT_TRX-CAD` at Canadian banks. When adding trading symbols to your bank configuration via `PATCH /api/banks/{bank_guid}`, use the full symbol format that includes the fiat pair (such as `USDT_TRX-USD` or `USDT_TRX-CAD`). Using only the asset code returns a `"Trading symbol not supported"` error. See the [assets and symbols](https://docs.cybrid.xyz/docs/assets-and-symbols) guide for all supported symbols.

</Accordion>

<Accordion title="Should I use the `/api/prices` endpoint or create a quote to get an accurate trading rate?" icon="fa-coins" iconColor="blue">

Use quotes (`POST /api/quotes`) for accurate trading rates. Quotes query multiple liquidity providers and lock the best rate for that trade. The `/api/prices` endpoint values may be temporarily cached and are not always the most up to date. Unused quotes are periodically cleaned up by the platform. See the [Create and execute a trade](https://docs.cybrid.xyz/docs/execute-trades) guide.

</Accordion>

## Webhooks

<Accordion title="Why am I not receiving webhook events?" icon="fa-cube" iconColor="blue">

Check the subscription's state on the **Developers → Subscriptions** tab in the Partner Portal, where subscriptions are created and managed. Ensure your endpoint is publicly accessible over HTTPS and returns a 2xx status quickly. Use `GET /api/subscription_deliveries` to inspect recent delivery attempts. See the [webhooks](https://docs.cybrid.xyz/docs/webhooks) guide for complete setup instructions.

</Accordion>

<Accordion title="What information is included in a webhook event payload?" icon="fa-cube" iconColor="blue">

For security, webhook events only contain the `object_guid` of the changed resource and the event type. Always perform a `GET /api/{resource}/{object_guid}` after receiving a webhook to retrieve the full details.

</Accordion>

<Accordion title="Which events does Cybrid send webhooks for?" icon="fa-cube" iconColor="blue">

`trade`, `transfer`, `identity_verification`, `plan`, and `execution` state changes. Customer state changes do not currently trigger webhooks (planned for a future release).

</Accordion>

<Accordion title="What happens if my webhook endpoint is down and events fail to deliver?" icon="fa-cube" iconColor="blue">

Cybrid retries delivery according to the [webhook retry schedule](https://docs.cybrid.xyz/docs/webhooks#retry-strategy). After a configurable number of failures, the subscription is marked `failed`. Delete old or dead subscriptions (such as expired ngrok sessions) promptly to avoid impacting platform performance.

</Accordion>

<Accordion title="How do I get an Organization Bearer token for subscription events?" icon="fa-cube" iconColor="blue">

Call `POST /oauth/token` with your Organization `client_id`, `client_secret`, and appropriate scopes (such as `subscription_events:read`). This is the same endpoint used for Bank tokens, with Organization credentials. API-key tokens cannot hold the `subscriptions:*` scopes; create, view and delete subscriptions in the Partner Portal. See the [API keys](https://docs.cybrid.xyz/docs/api-keys) guide.

</Accordion>

<Accordion title="What is the limit on active subscriptions?" icon="fa-cube" iconColor="blue">

The limit is 5 active subscriptions (webhook endpoints).

</Accordion>

<Accordion title="How can webhooks detect if a transfer has been returned?" icon="fa-cube" iconColor="blue">

Set up webhooks to monitor for `transfer.completed` events, then retrieve the transfer details using `GET /api/transfers/{transfer_guid}`. Check whether (1) the `return_code` field has a value other than `null`, indicating the underlying transfer has been returned, or (2) the `transfer_type` field is set to `funding_return`, indicating a return transfer associated with the original transfer GUID in `reference_transfer_guid`.

</Accordion>

<Accordion title="Are there webhook events for external bank account state changes?" icon="fa-cube" iconColor="blue">

No. Webhook events currently only cover `trade`, `transfer`, `identity_verification`, `plan`, and `execution` resources. As a workaround, monitor `bank_account` type identity verifications, since external bank accounts transition to `completed` only after a successful bank IDV.

</Accordion>

<Accordion title="Why am I receiving duplicate or repeated webhook events?" icon="fa-cube" iconColor="blue">

Your endpoint must respond with a 2xx status code within 2 seconds. If the response takes longer, the system treats it as a timeout and retries delivery. Move any processing logic (such as API calls to retrieve the full resource) to a background job so your endpoint can return 200 immediately. Verify delivery status by calling `GET /api/subscription_deliveries?subscription_event_guid={subscription_event_guid}` and checking the `response` field.

</Accordion>

## Deposit Bank Accounts

<Accordion title="What is a deposit bank account and when do I need one?" icon="fa-building-columns" iconColor="blue">

A deposit bank account generates routing and account numbers that allow partners or their customers to receive ACH, Wire, and RTP/FedNow push deposits (US accounts) or EFT deposits (CAD accounts). Every customer fiat account requires a `main` deposit bank account before it can deposit or withdraw, so create one with `POST /api/deposit_bank_accounts` immediately after creating the fiat account. See the [deposit bank accounts](https://docs.cybrid.xyz/docs/customer-deposit-bank-accounts) guide.

</Accordion>

<Accordion title="How do I retrieve wire deposit instructions for my bank-level deposit account?" icon="fa-building-columns" iconColor="blue">

Call `GET /api/deposit_bank_accounts/{deposit_bank_account_guid}`. The response includes `account_details` (account number) and `routing_details` (routing number). Beneficiary details on bank-level accounts require a manual update — provide your legal business name, registered address, contact email, and phone number to Cybrid support. See the [partner deposit bank account](https://docs.cybrid.xyz/docs/deposit-bank-accounts-partner-deposit-bank-account) guide.

</Accordion>

<Accordion title="Can individual and business customers receive deposits from third parties?" icon="fa-building-columns" iconColor="blue">

Yes. Both individual and business customers can receive ACH, Wire, and RTP deposits to their deposit bank account from third parties (such as payroll, receivables, or other financial institutions). As long as the sender uses the customer's assigned deposit account details (routing number and account number), the funds post automatically.

</Accordion>

<Accordion title="Can I open a deposit bank account for a Canadian (CAD) customer?" icon="fa-building-columns" iconColor="blue">

Yes. Create a `CAD` `fiat` account, then call `POST /api/deposit_bank_accounts` linked to it — the request is identical to a US account. The response returns `asset: CAD` and `CPA` routing details (an 8-digit Canadian institution and transit number). Canadian deposit accounts receive funds via EFT. See the [deposit bank accounts](https://docs.cybrid.xyz/docs/customer-deposit-bank-accounts) guide.

</Accordion>

## Counterparties

<Accordion title="What is a counterparty and how does it differ from a customer?" icon="fa-cube" iconColor="blue">

Counterparties are third-party participants (businesses or individuals) that can receive payments from your platform. They undergo sanctions screening but do not go through the full Persona KYC/KYB flow. Use `POST /api/counterparties` then `POST /api/external_bank_accounts` (with `account_kind: raw_routing_details` and `counterparty_guid`) to add their bank details. See the [counterparties](https://docs.cybrid.xyz/docs/counterparties) and [creating a counterparty](https://docs.cybrid.xyz/docs/creating-a-counterparty) guides.

</Accordion>

<Accordion title="What address format does the Counterparty API require for subdivision?" icon="fa-cube" iconColor="blue">

The `subdivision` field must be an ISO 3166-2 subdivision code without the country prefix (such as `CA` for California, not `US-CA`, or `30` for Kenya's Nairobi County, not `KE-30`). The same format applies to other address fields in the API, including customer, identity verification, and external bank account addresses. Country-specific requirements apply — for some countries the field is nullable, but for others (such as US and Kenya) it is required.

</Accordion>

<Accordion title="How do I add counterparties in countries outside the US?" icon="fa-cube" iconColor="blue">

Your bank configuration must explicitly allow the destination country for counterparties. Update your Compliance board (Jurisdiction of Customers / counterparties) and contact support to have it added to your bank configuration. See the [sending cross-border payments](https://docs.cybrid.xyz/docs/sending-cross-border-payments) and [supported corridors](https://docs.cybrid.xyz/docs/supported-corridors) guides.

</Accordion>

<Accordion title="What is the maximum length for a counterparty business name?" icon="fa-cube" iconColor="blue">

The counterparty name must not exceed 15 words. Names longer than 15 words fail AML screening. Shorten the name before submitting the counterparty creation request.

</Accordion>

<Accordion title="How do I create a counterparty in a country that does not use postal codes (such as Hong Kong)?" icon="fa-cube" iconColor="blue">

Omit the `postal_code` field entirely from the `address` object. Do not send empty strings or placeholder values. For example, a Hong Kong address should include only `street`, `city`, and `country_code`.

</Accordion>

<Accordion title="Is the counterparty `name` field mandatory, and does counterparty verification expire?" icon="fa-cube" iconColor="blue">

Yes, the `name` field (with `first` and `last`) is mandatory for AML/Sanctions screening. Counterparty verification does not expire, but the system periodically re-runs AML checks in the background. After creating a counterparty, create an identity verification with `"type": "counterparty"` and `"method": "watchlists"` to verify them. See the [verifying a counterparty](https://docs.cybrid.xyz/docs/verifying-a-counterparty) guide.

</Accordion>

## Implementation, Production Testing, and Going Live

<Accordion title="What are the requirements to go live on Cybrid?" icon="fa-cube" iconColor="blue">

You must: (1) complete a compliance review via the Compliance board, (2) pass an implementation review call demonstrating your full flow of funds, (3) implement MFA on account creation, and either on each transaction or at login with a 30-minute session timeout, (4) have customers acknowledge the [Cybrid User Agreement](https://cybrid.xyz/legal/user-agreement) during account creation, and keep it and the [Cybrid Privacy Policy](https://cybrid.xyz/legal/privacy-policy-usa) accessible in your application after onboarding (see the [User Agreement & Privacy Policy update](https://docs.cybrid.xyz/docs/notice-ua-and-pp-update)), and (5) test the complete on-ramp and off-ramp flow in production with the $100/day testing limits. See the [securely implementing Cybrid](https://docs.cybrid.xyz/docs/securely-implementing-cybrid) guide.

</Accordion>

<Accordion title="What is the production testing bank and its limits?" icon="fa-cube" iconColor="blue">

When approved for production testing, a production bank is created with a $100 USD daily transaction limit. This limit applies to all transactions during the production testing phase and is enforced until you receive approval to go live. Once your flow of funds has been reviewed and approved by Cybrid, this limit will be lifted.

You can test real KYC and money movement against this bank. Limits are removed after Cybrid reviews your full-flow test results.

> ⚠️ KYB restriction for partners
>
> You cannot add your own company as a business customer for KYB testing. Any KYB attempts for your own organization will be declined by Cybrid's compliance team.

</Accordion>

<Accordion title="What does Cybrid check during the implementation review?" icon="fa-cube" iconColor="blue">

Cybrid verifies: (1) MFA is enforced on account creation, and either on each financial transaction or at login with a 30-minute session timeout, (2) the Cybrid User Agreement is accessible and acknowledged by customers, (3) the demonstrated flow matches the approved flow of funds, and (4) security requirements (credentials stored server-side, encrypted at rest). See the [securely implementing Cybrid](https://docs.cybrid.xyz/docs/securely-implementing-cybrid) guide for full security requirements.

</Accordion>

<Accordion title="How do I get production testing limits removed to go fully live?" icon="fa-cube" iconColor="blue">

Once you have tested the complete flow (deposit, trade, and crypto withdrawal if applicable) within the $100/day production testing limits, notify your Cybrid contact or submit a request to inform us that you are ready to go live. Cybrid will conduct an internal review of your end-to-end flow of funds. After successful review and approval, Cybrid will remove the production testing limits and you may begin live operations.

</Accordion>

<Accordion title="How can I access the Cybrid User Agreement or share it with customers?" icon="fa-cube" iconColor="blue">

The [Cybrid User Agreement](https://cybrid.xyz/hubfs/Legal/Cybrid_User_Agreement.pdf) is available at the link above. This agreement covers all flows, including fiat-only (Nostro) use cases. While an updated agreement is planned, the current version applies to both crypto and fiat-only transactions. For compliance, it is preferable to provide a direct link to the Cybrid User Agreement in your application, rather than embedding its content within your own terms of service.

</Accordion>

## Fees & Billing

<Accordion title="How are KYC fees charged?" icon="fa-chart-pie" iconColor="blue">

KYC fees are charged per successful verification as a line item on your monthly invoice. At the Starter Tier, the fee is $1.50 per successful KYC (Cybrid subsidizes the actual cost).

</Accordion>

<Accordion title="What are the typical per-transaction fees for fiat rails?" icon="fa-chart-pie" iconColor="blue">

Typical costs (vary by contract): ACH $0.25-$1.00/transaction, RTP/FedNow $1.00/transaction, Wire $20.00-$25.00/transaction. Exact rates are specified in your contract fee schedule.

</Accordion>

<Accordion title="Where do trading fees land and how do I collect them?" icon="fa-chart-pie" iconColor="blue">

Cybrid collects its platform trading fee automatically. To charge your own spread, pass a `fees` array in the `POST /api/quotes` request. Your fee lands in the quote `fee` field and is collected from the customer at trade execution. To withdraw collected fees, book transfer from your bank-level fee account to your bank-level fiat account, then perform a funding withdrawal to your external bank. See the [trade fees](https://docs.cybrid.xyz/docs/trade-fees) and [platform accounts](https://docs.cybrid.xyz/docs/platform-accounts) guides.

</Accordion>

<Accordion title="What is the gas account and how do crypto network fees work?" icon="fa-chart-pie" iconColor="blue">

The `gas` account accumulates crypto network fees for on-chain transactions. ACH and wire fees are invoiced monthly based on volume per your contract schedule. Before withdrawing funds from your `fee` account, you must first clear any outstanding balance on the `gas` account by transferring funds from your `fee` or `fiat` account to the `gas` account. Alternatively, the gas account balance is billed and zeroed out at the end of each month. See the [platform accounts](https://docs.cybrid.xyz/docs/platform-accounts) and [finance](https://docs.cybrid.xyz/docs/finance) guides.

</Accordion>

## Compliance

<Accordion title="How long does Cybrid retain KYC information?" icon="fa-scale-balanced" iconColor="blue">

Cybrid retains all KYC information used to identify customers for a minimum of 5 years after the account is closed, as required by the Bank Secrecy Act.

</Accordion>

<Accordion title="Is there a customer delete API?" icon="fa-scale-balanced" iconColor="blue">

No. Customers cannot be deleted. You can delete external bank accounts and external wallets. Deposit bank accounts can be closed by contacting support.

</Accordion>

<Accordion title="How do I handle a compliance issue for a live customer?" icon="fa-scale-balanced" iconColor="blue">

Create a [Zendesk ticket](https://cybridhelp.zendesk.com) for all compliance-related inquiries, such as KYC/KYB status, transaction monitoring, or bank account verifications. See the [support ticketing system](https://docs.cybrid.xyz/docs/ticketing-system) guide for instructions. Do not use Slack for compliance requests after going live; all such requests must be submitted through Zendesk.

</Accordion>

<Accordion title="Is there a way to bulk export customer data from the platform?" icon="fa-scale-balanced" iconColor="blue">

There is no built-in data export feature. Write a script that uses the API to retrieve data — for example, use `GET /api/accounts` to list accounts and check `platform_available` balances, and `GET /api/identity_verifications/{identity_verification_guid}?include_pii=true` to retrieve customer PII.

</Accordion>

<Accordion title="Can records be deleted in the production environment?" icon="fa-scale-balanced" iconColor="blue">

No. Cybrid cannot delete any records in the production environment. If you created a resource in error, you must work around it (such as abandoning the incorrect customer GUID and creating a new one).

</Accordion>

<Accordion title="How can I detect when a customer account is frozen?" icon="fa-scale-balanced" iconColor="blue">

There is no webhook event for customer state changes. As a workaround, listen for the `transfer.completed` webhook, check if `transfer_type` is `funding_return` or `instant_funding_return`, extract the `customer_guid`, and call `GET /api/customers/{customer_guid}` to check if the customer `state` is `frozen`.

</Accordion>

## Bank and Organization configuration

<Accordion title="Can I update my bank name and CORS values after creation?" icon="fa-building-columns" iconColor="blue">

Yes. Bank name and CORS values can be modified after creation. Organization name changes are not exposed in the Partner Portal and require a manual update by Cybrid support.

</Accordion>

<Accordion title="Can I have multiple bank-level fiat accounts?" icon="fa-building-columns" iconColor="blue">

Yes, but it requires Cybrid to update your bank configuration. Multiple bank-level fiat accounts are generally discouraged as they complicate the flow of funds audit trail. Clearly justify the business reason when requesting this.

</Accordion>

<Accordion title="How do I add a new trading asset to my bank?" icon="fa-building-columns" iconColor="blue">

Some assets can be added via Partner Portal under Bank Details. For assets that cannot be added via the UI (such as USDC-SOL), provide your Bank GUID to Cybrid support and they will configure it. See the [assets and symbols](https://docs.cybrid.xyz/docs/assets-and-symbols) guide.

</Accordion>

<Accordion title="How do I enable business customers on my bank?" icon="fa-building-columns" iconColor="blue">

Business customers must be explicitly enabled on each bank. Contact Cybrid support to enable the `business_customers` feature. Verify the configuration in the Partner Portal under your bank's Configuration tab, where "Business Customers" should be listed if enabled.

</Accordion>

<Accordion title="Can a customer belong to multiple banks?" icon="fa-building-columns" iconColor="blue">

No. Customers can only belong to one bank. To use a customer in a second bank, create a new customer resource in that bank and complete KYC/KYB verification again. Identity verifications do not transfer between banks.

</Accordion>

## Attested KYC / KYB

<Accordion title="What is Attested KYC and when is it available?" icon="fa-scale-balanced" iconColor="blue">

Attested KYC allows you to pass customer PII and ID images directly to Cybrid without requiring your customers to go through the
Persona SDK flow. Availability depends on your bank configuration, and Cybrid support must enable the attested verification method
for your bank before you can use it. See the [verifying a customer](https://docs.cybrid.xyz/docs/verifying-a-customer) guide for
current verification methods.

</Accordion>

## Sandbox vs production

<Accordion title="How does sandbox differ from production?" icon="fa-cube" iconColor="blue">

Key differences: (1) Sandbox trades never fully settle (stay in `executed`); (2) ACH transfers do not trigger real bank transactions; (3) the Persona `expected_behaviours` parameter works in sandbox but not in production; (4) Plaid uses test credentials. See the [sandbox environment differences](https://docs.cybrid.xyz/docs/how-does-the-sandbox-environment-differ) guide for full details.

</Accordion>

<Accordion title="How do I simulate a funding deposit in sandbox to test my webhook flow?" icon="fa-cube" iconColor="blue">

You cannot simulate an externally-initiated deposit to a deposit bank account in sandbox. Alternatives: (1) execute a Plaid ACH pull via API using a connected Plaid test account, or (2) book transfer funds from your bank-level fiat account (book transfers process even with a $0 balance in sandbox).

</Accordion>