# Get Crypto Balance
Source: https://docs.carbn.xyz/api-reference/account-management/get-crypto-balance
/api-reference/openapi.json get /payment/api/v1/offramp-audit/crypto-balance/{crypto}/{blockchain}/{user_id}
Get the crypto balance for a user in USD. Returns a decimal number representing the balance.
# Register Destination Account
Source: https://docs.carbn.xyz/api-reference/account-management/register-destination-account
/api-reference/openapi.json post /payment/api/v1/accounts/register
Register a new destination account (bank account or card) for a user
# Register Wallet
Source: https://docs.carbn.xyz/api-reference/account-management/register-wallet
/api-reference/openapi.json post /payment/api/v1/wallets/register
Register a new wallet for a user
# Get Offramp Transaction Status
Source: https://docs.carbn.xyz/api-reference/audit-&-reporting/get-offramp-transaction-status
/api-reference/openapi.json get /payment/api/v1/offramp-audit/status/{transaction_id}
Get the current status of a specific offramp transaction by its ID
# Get Onramp Audit
Source: https://docs.carbn.xyz/api-reference/audit-&-reporting/get-onramp-audit
/api-reference/openapi.json get /payment/api/v1/onramp-audit/{wallet_id}
Get audit information for onramp transactions for a specific wallet
# Get Onramp Transaction Status
Source: https://docs.carbn.xyz/api-reference/audit-&-reporting/get-onramp-transaction-status
/api-reference/openapi.json get /payment/api/v1/onramp-audit/status/{transaction_id}
Get the current status of a specific onramp transaction by its ID
# Authentication
Source: https://docs.carbn.xyz/api-reference/authentication
Learn how to authenticate with the Carbn Connect API
Carbn uses API keys to authenticate your requests. You can generate them from the [dashboard](https://dashboard.carbnconnect.com/app/keys).
API keys are shown only once at the time of creation. Be sure to copy and store them securely, they cannot be retrieved later.
### How Authentication Works
* Pass your API key in the `x-api-key` header using HTTP Basic Auth.
* No username or password is required, just the API key.
* All requests must be made over HTTPS; requests over plain HTTP are rejected.
* Invalid or missing keys will return a 401 Unauthorized.
Keep your API keys secure. They grant full access to your account and should never be shared publicly or within internal tools like Slack or Dashboards.
### Sample Request
```bash cURL theme={null}
curl --location --request GET 'https://api.carbnconnect.com/onboarding/api/v1/users/all' \
--header 'Content-Type: application/json' \
--header 'x-api-key: '
```
```javascript JavaScript theme={null}
const response = await fetch('https://api.carbnconnect.com/onboarding/api/v1/users/all', {
headers: {
'Content-Type': 'application/json',
'x-api-key': ''
}
});
```
```python Python theme={null}
import requests
headers = {
'Content-Type': 'application/json',
'x-api-key': ''
}
response = requests.get(
'https://api.carbnconnect.com/onboarding/api/v1/users/all',
headers=headers
)
```
```java Java theme={null}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.carbnconnect.com/onboarding/api/v1/users/all"))
.header("Content-Type", "application/json")
.header("x-api-key", "")
.GET()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
```
# Create Custody Wallet
Source: https://docs.carbn.xyz/api-reference/custody-wallet/create-custody-wallet
/api-reference/openapi.json post /payment/api/v1/custody-wallet
Create a Carbn custody wallet for a user on the specified chain
# Custody Wallet Transfer
Source: https://docs.carbn.xyz/api-reference/custody-wallet/custody-wallet-transfer
/api-reference/openapi.json post /payment/api/v1/custody-wallet/transfer
Initiate a transfer from a Carbn custody wallet to an external address
# Get Custody Wallet
Source: https://docs.carbn.xyz/api-reference/custody-wallet/get-custody-wallet
/api-reference/openapi.json get /payment/api/v1/custody-wallet/{custody_wallet_id}
Get details of a Carbn custody wallet by ID
# Get Custody Wallet Transactions
Source: https://docs.carbn.xyz/api-reference/custody-wallet/get-custody-wallet-transactions
/api-reference/openapi.json get /payment/api/v1/custody-wallet/{custody_wallet_id}/transactions
Get paginated list of transactions for a custody wallet
# Get Custody Wallet Transfer Status
Source: https://docs.carbn.xyz/api-reference/custody-wallet/get-custody-wallet-transfer-status
/api-reference/openapi.json get /payment/api/v1/custody-wallet/transfer/{transaction_id}
Get the status of a custody wallet transfer by transaction ID
# Get Total Custody Wallet Balances
Source: https://docs.carbn.xyz/api-reference/custody-wallet/get-total-custody-wallet-balances
/api-reference/openapi.json get /payment/api/v1/custody-wallet/total-balances
Get aggregated balances across all custody wallets for all supported cryptocurrencies
# Error Handling
Source: https://docs.carbn.xyz/api-reference/errors
Understand Carbn API error codes, responses, and handling
## Error Response Structure
All API errors follow a consistent JSON structure with detailed information to help you debug issues. Here is a sample error response:
```json Error Response Structure theme={null}
{
"code": "4300",
"httpMethod": "PATCH",
"message": "Insufficient permissions to access resource",
"path": "/onboarding/api/v1/users/all",
"requestId": "46a7ad4b-c315-441c-ad2c-473f4075e1b5",
"resourcePath": "/onboarding/api/v1/{proxy+}"
}
```
#### Response Fields
| Field | Type | Description | Example |
| :----------------- | :------- | :------------------------------------------- | :--------------------------------------- |
| **`code`** | `string` | ๐ท๏ธ Internal error code for categorization | `"4300"`, `"4030"` |
| **`httpMethod`** | `string` | ๐ HTTP method used in the request | `"GET"`, `"POST"`, `"PATCH"` |
| **`message`** | `string` | ๐ฌ Human-readable error description | `"Missing authentication token"` |
| **`path`** | `string` | ๐ฃ๏ธ Exact API endpoint path that was called | `"/onboarding/api/v1/users/all"` |
| **`requestId`** | `string` | ๐ Unique identifier for this request (UUID) | `"46a7ad4b-c315-441c-ad2c-473f4075e1b5"` |
| **`resourcePath`** | `string` | โ๏ธ AWS API Gateway resource path pattern | `"/onboarding/api/v1/{proxy+}"` |
**Pro Tip:** The `requestId` is your golden ticket for support - it's like a fingerprint for your specific API call!
Always include the `requestId` when contacting support - it helps us quickly locate your specific request in our logs.
The `code` field is our internal error classification system. Use this along with the HTTP status code to programmatically handle different error scenarios.
***
## Quick Reference
**Missing API Key (4030)**
Add `X-API-Key` header to your request
**Invalid Format (4100)**
API key must be exactly 32 alphanumeric characters
**API Key Not Found (4101)**
Double-check your API key is correct
**Insufficient Permissions (4300)**
Contact support for permission updates
***
## Complete Error Reference
### Authentication Errors
| Response Field | Details |
| :-------------- | :-------------------------------------------- |
| **HTTP Status** | `403 Forbidden` |
| **Message** | Missing authentication token |
| **Root Cause** | No `X-API-Key` header provided in the request |
| **Impact** | ๐ด High - Blocks all API access |
| **Fix Time** | โก \< 1 minute |
Add the `X-API-Key` header with your API key to all requests.
```bash cURL theme={null}
curl -H "X-API-Key: " \
-H "Content-Type: application/json" \
https://api.carbnconnect.com/onboarding/api/v1/users/all
```
```javascript JavaScript theme={null}
const response = await fetch('https://api.carbnconnect.com/onboarding/api/v1/users/all', {
headers: {
'Content-Type': 'application/json',
'X-API-Key': ''
}
});
```
```python Python theme={null}
import requests
headers = {
'Content-Type': 'application/json',
'X-API-Key': ''
}
response = requests.get(
'https://api.carbnconnect.com/onboarding/api/v1/users/all',
headers=headers
)
```
| Response Field | Details |
| :-------------- | :------------------------------------------------ |
| **HTTP Status** | `403 Forbidden` |
| **Message** | Invalid API key format |
| **Root Cause** | API key is not exactly 32 alphanumeric characters |
| **Impact** | ๐ด High - Authentication fails |
| **Fix Time** | โก \< 30 seconds |
Verify API Key format requirements - API keys are case-sensitive and must be exactly 32 characters long (A-Z, a-z, 0-9)
| Response Field | Details |
| :-------------- | :---------------------------------- |
| **HTTP Status** | `401 Unauthorized` |
| **Message** | API key not found |
| **Root Cause** | API key doesn't exist in our system |
| **Impact** | ๐ด High - Complete access denial |
| **Fix Time** | โฑ๏ธ 2-3 minutes |
Verify your API key is correct or generate a new API key from the [dashboard](https://dashboard.carbnconnect.com).
| Response Field | Details |
| :-------------- | :------------------------------------- |
| **HTTP Status** | `401 Unauthorized` |
| **Message** | API key has expired |
| **Root Cause** | API key has passed its expiration date |
| **Impact** | ๐ด High - All requests blocked |
| **Fix Time** | โฑ๏ธ 2-3 minutes |
Generate a new API key from your [dashboard](https://dashboard.carbnconnect.com).
**Pro Tip:** Set up API key rotation reminders to avoid service interruptions
| Response Field | Details |
| :-------------- | :---------------------------------------- |
| **HTTP Status** | `401 Unauthorized` |
| **Message** | API key is inactive |
| **Root Cause** | API key has been suspended or deactivated |
| **Impact** | ๐ด High - Account-level issue |
| **Fix Time** | โฐ 1-24 hours (support dependent) |
**Account Issue:** This usually indicates a billing or compliance concern. Contact [support](mailto:support@carbn.xyz) immediately.
### Authorization Errors
| Response Field | Details |
| :-------------- | :------------------------------------------------------------ |
| **HTTP Status** | `403 Forbidden` |
| **Message** | Insufficient permissions to access resource |
| **Root Cause** | Your API key lacks the required permissions for this endpoint |
| **Impact** | ๐ก Medium - Specific endpoints blocked |
| **Fix Time** | โฐ 2-24 hours (support dependent) |
**Permission Levels:** Different endpoints require different permission levels. Check the specific endpoint documentation for required permissions.
**Common Cause:** This often happens when using a read-only API key for write operations (POST, PATCH, DELETE)
***
## HTTP Status Code Reference
| Status Code | Status Name | Description | Action Required |
| :---------- | :---------- | :-------------------------------------- | :----------------- |
| **`200`** | **OK** | Your request has completed successfully | No action required |
| **`201`** | **Created** | Resource created successfully | No action required |
**2xx responses** indicate successful requests. Your API call worked as expected and you can proceed with the response data.
| Status Code | Status Name | Description | Action Required |
| :---------- | :--------------- | :------------------------------------------- | :----------------- |
| **`400`** | **Bad Request** | Request format is invalid or malformed | Fix request syntax |
| **`401`** | **Unauthorized** | Authentication failed or missing credentials | Check API key |
| **`403`** | **Forbidden** | Access forbidden due to permissions | Check permissions |
| **`404`** | **Not Found** | Resource doesn't exist or not found | Verify resource ID |
| **`429`** | **Rate Limited** | Too many requests sent recently | Wait and retry |
**4xx errors** mean there's an issue with your request. Double-check your API key, request format, and permissions.
| Status Code | Status Name | Description | Action Required |
| :---------- | :---------------------- | :------------------------------ | :----------------------- |
| **`500`** | **Internal Error** | Something went wrong on our end | Contact support |
| **`502`** | **Bad Gateway** | Gateway/proxy error | Retry or contact support |
| **`503`** | **Service Unavailable** | Temporary service issue | Wait and retry |
**5xx errors** are on us! If you see these consistently, please contact support with your `requestId`.
***
## Getting Help
When contacting support, please include:
**Request ID** from the error response**Endpoint** you were trying to access**Error** response details available**Timestamp** when the error occurred
# Get Carbn Currency Exchange Rate
Source: https://docs.carbn.xyz/api-reference/exchange/get-carbn-currency-exchange-rate
/api-reference/openapi.json get /payment/api/v1/exchange/currency-rates/carbn
Get the current exchange rate from source currency to target currency using Carbn's rates
# Get Open Banking Institutions
Source: https://docs.carbn.xyz/api-reference/open-banking/get-open-banking-institutions
/api-reference/openapi.json post /payment/api/v1/transfers/get-institutes
Fetch supported banking institutions for one or more countries. Supports two modes: browse mode (paginated list using `count` and `offset`) and search mode (filter by institution name using `query`). When `query` is provided, `count` and `offset` are not required.
# Get Open Banking Payment Status
Source: https://docs.carbn.xyz/api-reference/open-banking/get-open-banking-payment-status
/api-reference/openapi.json get /payment/api/v1/ob/{payment_id}
Get the status and details of an Open Banking payment by payment ID
# Accept Offramp Quote
Source: https://docs.carbn.xyz/api-reference/payments/accept-offramp-quote
/api-reference/openapi.json post /payment/api/v1/offramp/accept-quote
Accept a quote and initiate the offramp transfer
# Get Offramp Quote
Source: https://docs.carbn.xyz/api-reference/payments/get-offramp-quote
/api-reference/openapi.json post /payment/api/v1/offramp/get-quote
Get a quote for converting crypto to fiat and sending to a registered destination account
# Initiate Offramp
Source: https://docs.carbn.xyz/api-reference/payments/initiate-offramp
/api-reference/openapi.json post /payment/api/v1/offramp
Initiate an offramp transfer. Returns a cryptocurrency deposit address where users should send their crypto. Once crypto is deposited, it will be converted to fiat and sent to the registered destination account.
# Initiate Offramp Payout
Source: https://docs.carbn.xyz/api-reference/payments/initiate-offramp-payout
/api-reference/openapi.json post /payment/api/v1/offramp/payout
Initiate a payout after crypto has been deposited to the offramp address. This converts the deposited crypto to fiat and sends it to the registered destination account.
# Onramp Transfer
Source: https://docs.carbn.xyz/api-reference/payments/onramp-transfer
/api-reference/openapi.json post /payment/api/v1/transfers/onramp
Initiate a new onramp transfer
# Create Payout
Source: https://docs.carbn.xyz/api-reference/payouts/create-payout
/api-reference/openapi.json post /payment/api/v1/payout
Create a local currency payout to a user's bank account using their available balance.
# Get Payout Balances
Source: https://docs.carbn.xyz/api-reference/payouts/get-payout-balances
/api-reference/openapi.json get /payment/api/v1/payout/balances/{user_id}
Retrieve available payout balances for a user, grouped by currency.
# Get Payout Status
Source: https://docs.carbn.xyz/api-reference/payouts/get-payout-status
/api-reference/openapi.json get /payment/api/v1/payout/{payout_id}
Retrieve the current status and details of a payout.
# Create User Onboarding Session
Source: https://docs.carbn.xyz/api-reference/user-management/create-user-onboarding-session
/api-reference/openapi.json post /onboarding/api/v1/users/session
Create a new user onboarding session and generate a hosted KYC link. This endpoint is used for the hosted KYC flow where users complete verification through a pre-built compliance interface. The returned onboarding URL redirects users to complete their KYC verification.
# Generate User Consent
Source: https://docs.carbn.xyz/api-reference/user-management/generate-user-consent
/api-reference/openapi.json post /onboarding/api/v1/tnc
Record user acceptance of terms and conditions and generate a consent ID
# Get All Users
Source: https://docs.carbn.xyz/api-reference/user-management/get-all-users
/api-reference/openapi.json get /onboarding/api/v1/users/all
Get a list of all users in the system
# Get User Details
Source: https://docs.carbn.xyz/api-reference/user-management/get-user-details
/api-reference/openapi.json get /onboarding/api/v1/users/{user_id}
Retrieve detailed information about a user including their KYC status, verification state, and any requirements due. For comprehensive guides on handling user statuses and rejection reasons, see our [User Status Documentation](/documentation/developer-platform/users/compliance/user-status) and [Rejection Reasons Guide](/documentation/developer-platform/users/compliance/rejection-reasons).
# Update User
Source: https://docs.carbn.xyz/api-reference/user-management/update-user
/api-reference/openapi.json put /onboarding/api/v1/users/{user_id}
Update user information. All fields are optional - only include fields that need to be updated.
# User Onboarding
Source: https://docs.carbn.xyz/api-reference/user-management/user-onboarding
/api-reference/openapi.json post /onboarding/api/v1/users
Create a new user with KYC information
# Register Webhook
Source: https://docs.carbn.xyz/api-reference/webhook-management/register-webhook
/api-reference/openapi.json post /onboarding/api/v1/webhooks
Register a new webhook endpoint to receive event notifications. Webhooks are created with `status: "disabled"` by default and must be enabled using the PUT endpoint. For comprehensive webhook setup and verification guides, see [Configure Webhooks](/documentation/getting-started/configure-webhook) and [Webhook Verification](/documentation/developer-platform/monitoring/webhook-verification).
# Trigger Webhook Event
Source: https://docs.carbn.xyz/api-reference/webhook-management/trigger-webhook-event
/api-reference/openapi.json post /onboarding/api/v1/webhooks/trigger/{webhook_id}
Manually trigger a webhook event for testing purposes using the webhook event's unique ID
# Update Webhook
Source: https://docs.carbn.xyz/api-reference/webhook-management/update-webhook
/api-reference/openapi.json put /onboarding/api/v1/webhooks
Update an existing webhook's URL and status. Webhooks are created with 'disabled' status by default and must be enabled using this endpoint.
**Important:** The event category cannot be changed after webhook creation. Only the URL and status can be updated.
**Default Behavior:**
- All webhooks are created with `status: "disabled"`
- Use this endpoint to set `status: "enabled"` to start receiving events
- URL can be updated to change the webhook destination
# Changelog
Source: https://docs.carbn.xyz/changelog/overview
Stay up to date with the latest changes and improvements to Carbn Connect
# Changelog
Keep track of all changes, improvements, and new features added to the Carbn Connect API and platform.
## How to Stay Updated
* **RSS Feed**: Subscribe to our changelog RSS feed
* **Webhook Notifications**: Get notified of breaking changes via webhooks
* **Email Updates**: Subscribe to our developer newsletter
Get notified when we release new features and updates
## Version History
Our initial API release with core functionality
## Upcoming Features
We're constantly working on new features and improvements. Here's what's coming soon:
### Q1 2025
* **Multi-currency Support**: Support for additional stablecoins
* **Batch Processing**: Process multiple transactions in a single request
* **Advanced Analytics**: Enhanced reporting and analytics dashboard
### Q2 2025
* **Enhanced API endpoints**: Additional payment corridor coverage
* **Recurring Payments**: Support for subscription and recurring payment flows
* **Enhanced Webhooks**: More granular webhook events and filtering
## Breaking Changes Policy
We take backward compatibility seriously. When we do need to make breaking changes:
1. **Advance Notice**: At least 90 days notice for breaking changes
2. **Migration Guides**: Detailed guides to help you migrate
3. **Sunset Timeline**: Clear timeline for deprecated features
4. **Support**: Dedicated support during migration periods
## API Versioning
Our API uses date-based versioning in the URL path:
* Current version: `v1.0.0`
* Version format: `vMAJOR.MINOR.PATCH`
### Version Support
* **Current Version**: Full support and active development
* **Previous Version**: Bug fixes and security updates only
* **Deprecated Versions**: 12-month sunset period with advance notice
## Feedback
Have feedback on our API or suggestions for new features?
We'd love to hear from you
# Payouts
Source: https://docs.carbn.xyz/documentation/developer-platform/monitoring/payouts
Integrate fiat payouts to bank accounts using Carbn
Payouts let you send funds from your Carbn balance to a user's bank account in local currency.
Key API reference pages:
* [Create Payout](/api-reference/payouts/create-payout)
* [Get Payout](/api-reference/payouts/get-payout)
* [Get Payout Balances by User](/api-reference/payouts/get-payout-balances-by-user)
***
## Prerequisites
Before you implement payouts, make sure:
* **Users are onboarded** and KYCโverified (status `active`).
* **Funds are available** in the payout currency for the user.
* **API key** is configured with payment permissions (see [Authentication](/api-reference/authentication)).
* The destination **bank account or wallet** (for example INSTAPAY) is supported for the corridor.
***
## Payout lifecycle
API Reference: **[/payouts/get-payout-balances-by-user](/api-reference/payouts/get-payout-balances-by-user)**
```bash cURL theme={null}
curl --location 'https://api.carbnconnect.com/payment/api/v1/payout/balances/{user_id}' \
--header 'Content-Type: application/json' \
--header 'x-api-key: '
```
```javascript JavaScript theme={null}
const response = await fetch(
'https://api.carbnconnect.com/payment/api/v1/payout/balances/{user_id}',
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-api-key': '',
},
}
);
const { balances } = await response.json();
// e.g. [{ currency: 'PHP', amount: '506.54' }]
```
Typical response (trimmed):
```json theme={null}
{
"balances": [
{
"currency": "PHP",
"amount": "506.54"
}
]
}
```
API Reference: **[/payouts/create-payout](/api-reference/payouts/create-payout)**
```bash cURL theme={null}
curl --location 'https://api.carbnconnect.com/payment/api/v1/payout' \
--header 'Content-Type: application/json' \
--header 'x-api-key: ' \
--data '{
"user_id": "9973efd0-410c-4b1a-991c-5a00f1581734",
"currency": "php",
"customer_payout_id": "491595e0-2d40-4aa3-9f3d-4e8cdd79511e",
"amount": "20",
"recipient_details": {
"bank_name": "gotyme",
"account_holder_name": "Chelsea Mae Esguerra",
"recipient_account_number": "019794249552"
}
}'
```
```javascript JavaScript theme={null}
const response = await fetch(
'https://api.carbnconnect.com/payment/api/v1/payout',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': '',
},
body: JSON.stringify({
user_id: '9973efd0-410c-4b1a-991c-5a00f1581734',
currency: 'php',
customer_payout_id: '491595e0-2d40-4aa3-9f3d-4e8cdd79511e',
amount: '20',
recipient_details: {
bank_name: 'gotyme',
account_holder_name: 'Chelsea Mae Esguerra',
recipient_account_number: '019794249552',
},
}),
}
);
const payout = await response.json();
// Save payout.id and customer_payout_id for reconciliation
```
Successful response (key fields):
```json theme={null}
{
"id": "052471e2-1819-448f-ad74-03f237c1dfd6",
"currency": "php",
"rail": "INSTAPAY",
"amount": 20,
"status": "INITIATED",
"user_id": "9973efd0-410c-4b1a-991c-5a00f1581734",
"customer_payout_id": "491595e0-2d40-4aa3-9f3d-4e8cdd79511e",
"rail_fee": 10,
"account_details": {
"bank_name": "gotyme",
"account_holder_name": "Chelsea Mae Esguerra",
"recipient_account_number": "019794249552"
}
}
```
API Reference: **[/payouts/get-payout](/api-reference/payouts/get-payout)**
```bash cURL theme={null}
curl --location 'https://api.carbnconnect.com/payment/api/v1/payout/{payout_id}' \
--header 'Content-Type: application/json' \
--header 'x-api-key: '
```
```javascript JavaScript theme={null}
const response = await fetch(
'https://api.carbnconnect.com/payment/api/v1/payout/{payout_id}',
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-api-key': '',
},
}
);
const payout = await response.json();
// payout.status === 'INITIATED' | 'PAYOUT_PROCESSED' | 'FAILED' (depending on rail)
```
Example (processed):
```json theme={null}
{
"id": "052471e2-1819-448f-ad74-03f237c1dfd6",
"currency": "php",
"rail": "INSTAPAY",
"reference": "051567",
"amount": 20.0,
"status": "PAYOUT_PROCESSED",
"user_id": "9973efd0-410c-4b1a-991c-5a00f1581734",
"customer_payout_id": "491595e0-2d40-4aa3-9f3d-4e8cdd79511e",
"rail_fee": 10.0,
"account_details": {
"bank_name": "gotyme",
"account_holder_name": "Chelsea Mae Esguerra",
"recipient_account_number": "019794249552"
},
"created_at": "2026-03-13T16:32:17.604935Z",
"updated_at": "2026-03-13T16:32:46.364880Z"
}
```
For real-time updates, configure a webhook with the `PAYOUT` event category (see [Configure Webhooks](/documentation/getting-started/configure-webhook)).
When enabled, Carbn will send payout status changes (for example from `INITIATED` to `PAYOUT_PROCESSED`) to your webhook endpoint.
***
## Payout statuses
Payout has been created and queued for processing by the rail.Rail has confirmed the payout; funds are considered delivered.Payout could not be completed (for example, rail or account error); check logs and webhooks for details.
# Transfer Status
Source: https://docs.carbn.xyz/documentation/developer-platform/monitoring/transfer-status
Monitor and track transfer states throughout the complete payment lifecycle
Understanding transfer statuses is crucial for providing users with accurate information about their payments and handling edge cases appropriately. This guide covers all possible transfer states and how to monitor them effectively.
## Transfer Lifecycle
All transfers in Carbn Connect follow a predictable lifecycle with specific states that indicate the current stage of processing:
Transfer is created and awaiting funds or processing
Funds are being moved through the payment system
Transfer reaches final state (success, failure, or requires action)
***
## Transfer States
The transfer status indicates the current state of a transfer. Here are all possible states:
**Description**: Carbn is waiting to receive funds from the user before processing the transfer.
**Applies to**:
* SEPA Payments
* Wire transfers
* ACH pushes
* Virtual account transfers
**Next Steps**: Wait for user to send funds or complete payment flow.
```json Example Response theme={null}
{
"transaction_id": "d5c48677-b85d-4de5-a685-196d0e6596f7",
"status": "awaiting_funds",
"created_at": "2024-01-01T10:00:00Z",
"source_currency": "eur",
"amount": 100
}
```
**Description**: Carbn has received the funds and is preparing to move them on the user's behalf.
**Duration**: Usually seconds to a few minutes
**What's happening**: Internal processing, validation, and preparation for onward transfer.
```json Example Response theme={null}
{
"transaction_id": "d5c48677-b85d-4de5-a685-196d0e6596f7",
"status": "funds_received",
"updated_at": "2024-01-01T10:05:00Z",
"source_currency": "eur",
"amount": 100
}
```
**Description**: A temporary state triggered when transfer data needs further confirmation.
**Duration**: Typically resolves in seconds; otherwise, Carbn will reach out within 24 hours.
**Action Required**: Wait for automatic resolution or contact support if extended.
This is a rare state that usually resolves automatically. If a transfer remains in this state for more than 24 hours, contact support.
**Description**: Carbn has initiated the payment and is awaiting confirmation.
**Duration varies by payment rail**:
* **Crypto**: Minutes
* **Wires**: Hours
* **ACH**: Days
```json Example Response theme={null}
{
"transaction_id": "d5c48677-b85d-4de5-a685-196d0e6596f7",
"status": "payment_submitted",
"updated_at": "2024-01-01T10:06:00Z",
"payment_rail": "crypto",
"estimated_completion": "2024-01-01T10:15:00Z"
}
```
**Description**: The transfer is complete and funds have been successfully delivered to the destination.
**Final State**: This is a successful completion state.
```json Example Response theme={null}
{
"transaction_id": "d5c48677-b85d-4de5-a685-196d0e6596f7",
"status": "payment_processed",
"completed_at": "2024-01-01T10:12:00Z",
"final_amount": 95.50,
"destination_confirmed": true
}
```
### Exception States
**Description**: Carbn was unable to deliver funds due to an issue like an invalid account or unsupported asset at the destination.
**Common Causes**:
* Invalid destination wallet address
* Unsupported asset at destination
* Destination account closed or frozen
**Action Required**: Check destination details and retry with correct information.
**Description**: The payment was sent but failed. Funds have returned to Carbn and a refund to the sender is underway.
**What happens next**: Automatic refund process initiated to original sender.
**Description**: The transfer was refunded back to the original sender.
**Final State**: This is a completion state where funds are returned.
**Description**: The transfer was canceled. This can only happen from the `awaiting_funds` state.
**How to cancel**: Contact support to cancel a transfer in `awaiting_funds` status.
Transfers can only be canceled while in `awaiting_funds` status. Once funds are received, cancellation is no longer possible.
**Description**: A problem occurred that blocked processing. This typically requires manual review or developer action.
**Action Required**: Contact support with transfer details for investigation.
***
## Open Banking Payment Status
When using Open Banking for fund collection, the standard `awaiting_funds` status is replaced by specific Open Banking payment statuses. These statuses track the payment authorization and execution process through the banking system.
### Open Banking Flow
Open Banking payments follow this progression:
```
PAYMENT_STATUS_INPUT_NEEDED โ PAYMENT_STATUS_AUTHORISING โ PAYMENT_STATUS_INITIATED โ PAYMENT_STATUS_EXECUTED โ funds_received
```
**Description**: Awaiting user input to begin the payment authorization process.
**What's happening**: User has received the Open Banking link but hasn't started the authorization flow yet.
**Duration**: Depends on user action - no time limit
**User Action Required**: User needs to click the Open Banking link and begin authorization with their bank.
```json Example Response theme={null}
{
"transaction_id": "d5c48677-b85d-4de5-a685-196d0e6596f7",
"payment_status": "PAYMENT_STATUS_INPUT_NEEDED",
"created_at": "2024-01-01T10:00:00Z",
"payment_method": "open_banking"
}
```
**Description**: User is in the process of authorizing the payment with their bank.
**What's happening**: User has started the authorization flow and is providing credentials/consent to their bank.
**Duration**: Typically a few minutes while user completes bank authorization
**Next Steps**: Wait for user to complete authorization or abandon the process.
**Description**: Payment has been authorized and is in transit through the banking system.
**What's happening**: User successfully authorized the payment, and it's being processed by the bank.
**Duration**: Usually minutes to hours depending on the bank
**Possible Outcomes**: Can progress to `EXECUTED`, `FAILED`, `BLOCKED`, or `REJECTED`
**Description**: Funds have successfully left the payer's account.
**Final Success Status**: After this status, the transfer moves to `funds_received` and follows the standard transfer flow.
**What's Next**: Transfer continues with normal processing (`funds_received` โ `payment_submitted` โ `payment_processed`)
### Open Banking Exception States
**Description**: System error occurred during payment processing (retryable).
**Common Causes**:
* Bank system downtime
* Temporary Open Banking service issues
* Network connectivity problems
**Action Required**: Create a new Open Banking link and retry the payment process.
This is a retryable error. The payment can be attempted again with a fresh Open Banking link.
**Description**: Payment blocked by Plaid due to compliance or risk issues (rare, retryable).
**What happened**: Plaid's risk management system flagged the payment for review.
**Action Required**: Create a new Open Banking link and retry. If the issue persists, contact support.
This is rare but can happen due to risk assessment algorithms. Usually resolves with a new attempt.
**Description**: Payment was rejected by the bank (terminal status).
**What happened**: The bank declined the payment after initial authorization.
**Important**: If funds were debited, the bank will automatically return them to the source account.
**Final State**: This is a terminal status - the payment cannot be retried with the same link.
**Description**: The end user cancelled the payment during authorization (terminal status).
**What happened**: User actively cancelled the payment process while authorizing with their bank.
**User Action**: User chose to abandon the payment flow before completion.
**Final State**: This is a terminal status - the payment cannot be retried with the same link.
### Open Banking Status Transitions
**Key Points**:
* Open Banking statuses replace `awaiting_funds` in the standard flow
* Only `PAYMENT_STATUS_EXECUTED` leads to `funds_received`
* Failed, blocked, or rejected statuses require creating a new Open Banking link
* The flow can move backwards (e.g., `INITIATED` โ `FAILED`)
**Complete Flow Diagram**:
```
PAYMENT_STATUS_INPUT_NEEDED
โ
PAYMENT_STATUS_AUTHORISING
โ
PAYMENT_STATUS_INITIATED โ PAYMENT_STATUS_FAILED (retry needed)
โ โ PAYMENT_STATUS_BLOCKED (retry needed)
โ โ PAYMENT_STATUS_REJECTED (terminal)
PAYMENT_STATUS_EXECUTED
โ
funds_received โ payment_submitted โ payment_processed
```
***
## Monitoring Transfer Status
### Check Individual Transfer Status
Monitor specific transfers using the status endpoints:
```bash On-Ramp Transfer Status theme={null}
curl --location --request GET 'https://api.carbnconnect.com/payment/api/v1/onramp-audit/status/{transaction_id}' \
--header 'x-api-key: '
```
[Get Onramp Transaction Status API Reference](/api-reference/audit-reporting/get-onramp-transaction-status)
```bash Off-Ramp Transfer Status theme={null}
curl --location --request GET 'https://api.carbnconnect.com/payment/api/v1/offramp-audit/status/{transaction_id}' \
--header 'x-api-key: '
```
[Get Offramp Transaction Status API Reference](/api-reference/audit-reporting/get-offramp-transaction-status)
```bash FX Transfer Status theme={null}
curl --location --request GET 'https://api.carbnconnect.com/payment/api/v1/fx-audit/status/{transaction_id}' \
--header 'x-api-key: '
```
[Get Transfer Transaction Status API Reference](/api-reference/audit-reporting/get-transfer-transaction-status)
### Bulk Transfer Monitoring
Get status for multiple transfers by user:
```bash User On-Ramp History theme={null}
curl --location --request GET 'https://api.carbnconnect.com/payment/api/v1/onramp-audit/{wallet_id}' \
--header 'x-api-key: '
```
[Get Onramp Audit API Reference](/api-reference/audit-reporting/get-onramp-audit)
```bash User Off-Ramp History theme={null}
curl --location --request GET 'https://api.carbnconnect.com/payment/api/v1/offramp-audit/{user_id}' \
--header 'x-api-key: '
```
[Get Offramp Audit API Reference](/api-reference/audit-reporting/get-offramp-audit)
```bash User FX History theme={null}
curl --location --request GET 'https://api.carbnconnect.com/payment/api/v1/fx-audit/{user_id}' \
--header 'x-api-key: '
```
[Get Transfer Audit API Reference](/api-reference/audit-reporting/get-transfer-audit)
***
## State Progression Rules
**Important**: Transfers always progress forward through states and never go backwards:
`awaiting_funds` โ `funds_received` โ `payment_submitted` โ `payment_processed`
***
## What's Next?
Set up real-time notifications for status changes
Learn how to verify webhook authenticity
## Getting Help
When contacting support, please include:
**Transaction ID** of the payment**Wallet ID** If transfer ID not available**Transfer type** (FX, on-ramp, off-ramp)**Error messages** or **status codes** **Timestamp** when the error occurred
# Webhook Verification
Source: https://docs.carbn.xyz/documentation/developer-platform/monitoring/webhook-verification
Verify webhook authenticity using RSA signature verification
Carbn includes a `X-Webhook-Signature` header with each webhook delivery for authenticity verification. This ensures that webhook events are genuinely from Carbn and haven't been tampered with.
## Signature Format
The header value is a base64 encoded RSA signature: ``
## Verification Process
1. **Extract the signature** from the `X-Webhook-Signature` header
2. **Decode the signature** using base64 decoding to get signature bytes
3. **Verify the signature** using Carbn's public key and the raw HTTP request body
## Complete HTTP Request Example
```http HTTP Request theme={null}
POST /webhooks/carbn HTTP/1.1
Host: your-app.com
Content-Type: application/json
User-Agent: Java/17.0.14
X-Webhook-Event-Id: 1389bf11-20e2-44fe-8650-1e8ccfd9ba42
X-Webhook-Id: f79bc473-d45d-4026-86ec-864d4d047905
X-Webhook-Signature: lrmZCA323EV0oWMj9KZVcw5zEfeZzZSOmAKpcgzqPPF...
{"status": "PAYMENT_PROCESSED", "txn_id": "da4ac399-ed76-42f3-ba29-e4f4b7e2b46c", "user_id": "38758d6e-05f7-46a2-86d1-5ab45a49bc64"}
```
## Security Best Practices
1. **Always verify webhook signatures** using RSA public key verification
2. **Use HTTPS endpoints** with valid certificates
3. **Implement idempotency** using the `X-Webhook-Event-Id` header
4. **Return 200 status quickly** to avoid timeouts
5. **Store public keys securely** (use environment variables)
6. **Log webhook events** for debugging and monitoring
***
## Troubleshooting
### Common Issues
* **Webhook not receiving events**: Ensure webhook is enabled and endpoint returns 200 status
* **Signature verification fails**: Use raw request body and correct RSA public key
* **Duplicate deliveries**: Implement idempotency using `X-Webhook-Event-Id` header
### Testing Your Webhook
You can test your webhook endpoint using the trigger webhook event endpoint:
```bash cURL theme={null}
curl --request POST \
--url https://api.carbnconnect.com/onboarding/api/v1/webhooks/trigger/{webhook_id} \
--header 'Content-Type: application/json' \
--header 'x-api-key: '
```
***
## What's Next?
Learn how to set up and register webhooks
Proper webhook verification ensures the security and reliability of your integration with Carbn's payment system.
# Enhanced Due Diligence
Source: https://docs.carbn.xyz/documentation/developer-platform/users/compliance/enhanced-due-diligence
Additional verification requirements for high-risk users and increased limits
## Overview
Enhanced Due Diligence (EDD) is required for users who exceed certain transaction thresholds or present higher risk profiles. These additional verification steps ensure compliance with anti-money laundering (AML) regulations and help maintain the security of the platform.
***
## Transaction Limits
### Standard KYC Limits
Users who complete standard KYC verification can transact up to **\$10,000** without additional documentation.
### Enhanced Due Diligence Threshold
For transactions **above \$10,000**, users must complete Enhanced Due Diligence requirements.
***
## Additional Documentation Requirements
When Enhanced Due Diligence is triggered, users must provide:
Recent utility bill, bank statement, or government document showing current residential address
Documentation proving the origin of funds (employment records, business income, investment statements)
***
## AML Screening Questions
Users undergoing Enhanced Due Diligence must answer additional Anti-Money Laundering (AML) screening questions, including:
* Current occupation and employer details
* Annual income range
* Primary source of income
* Purpose of the transaction
* Expected transaction frequency
* Relationship to counterparties (if applicable)
* Politically Exposed Person (PEP) status
* High-risk jurisdiction connections
* Previous compliance issues
***
## Processing Time
**Enhanced Due Diligence Review Time**: Typically **2-5 business days** for manual review and approval.
Users will be notified via email once their EDD review is complete.
***
## What's Next?
Review standard KYC requirements and documentation
Learn about user onboarding status and verification states
# KYC Requirements
Source: https://docs.carbn.xyz/documentation/developer-platform/users/compliance/kyc-requirements
Identity verification requirements for individuals and businesses
Carbn Connect requires identity verification to ensure compliance with regional regulatory standards. Requirements vary by jurisdiction and user type - this guide provides clear, region-specific requirements.
## Overview
All users must provide **basic identity information**. Additional requirements depend on:
* **Geographic location** (country of residence)
* **User type** (individual vs. business)
* **Transaction patterns** (volume and risk assessment)
**Basic Requirements**: All users must provide the following regardless of jurisdiction:
* Full name
* Email address
* Date of birth
* Country of residence
* Residence address
**Identity Documents** (required for all users):
* Government-issued photo ID (passport or national ID)
**Tax Identification** (required only in specific countries - see regional details below)
***
## Document Requirements
Document verification is based on the individual's valid government-issued credentials from any supported jurisdiction.
Requirements vary by region due to different regulatory frameworks. Select your region for specific tax identification requirements:
| **Document Type** | **Document Name** |
| :-------------------- | :-------------------------------------------------------------------- |
| **Identity Document** | `passport`, `national_id`, `permanent_resident_id`, `driving_license` |
| **Tax Document** | `itin` |
**Additional Requirements:**
* Proof of address may be required
* New York and Alaska are currently not supported
| **Document Type** | **Document Name** |
| :-------------------- | :-------------------------------------------------------------------- |
| **Identity Document** | `passport`, `national_id`, `permanent_resident_id`, `driving_license` |
| **Tax Document** | `sin` |
| **Document Type** | **Document Name** |
| :-------------------- | :-------------------------------------------------------------------- |
| **Identity Document** | `passport`, `national_id`, `permanent_resident_id`, `driving_license` |
| **Tax Document** | `rfc`, `curp` |
### Identity Documents
* `passport`
* `national_id`
* `permanent_resident_id`
* `driving_license`
### Tax Documents for EU Countries
| **Supported Country** | **Tax Document** |
| :-------------------- | :-------------------------------------------------------------------- |
| ๐ฎ๐ช Ireland | `ppsn` - Personal Public Service Number |
| ๐ซ๐ท France | `spi` - Social Security Number |
| ๐ช๐ธ Spain | `nie` - Nรบmero de Identificaciรณn de Extranjeros |
| ๐ฉ๐ช Germany | `steuer_id` - Steueridentifikationsnummer (Tax Identification Number) |
| ๐ณ๐ฑ Netherlands | `bsn` - Burgerservicenummer (Citizen Service Number) |
| ๐ง๐ช Belgium | `nrn` - National Register Number |
| ๐ซ๐ฎ Finland | `hetu` - Finnish Personal Identity Code |
| ๐ฉ๐ฐ Denmark | `cpr` - Central Person Register Number |
| ๐ธ๐ช Sweden | `personnummer` - Personal Identity Number |
| ๐ต๐น Portugal | `nif` - Nรบmero de Identificaรงรฃo Fiscal |
| ๐ฆ๐น Austria | `si` - Social Insurance Number |
| ๐ฎ๐น Italy | `cf` - Codice Fiscale |
| ๐ฑ๐บ Luxembourg | `matricule` - Matricule Number |
| ๐ช๐ช Estonia | `isikukood` - Personal Identification Code |
| ๐ฑ๐น Lithuania | `asmens_kodas` - Personal Code |
| ๐ฑ๐ป Latvia | `personas_kods` - Person's Code |
**Proof of Address is required for following EU Countries:**
* Croatia
* Cyprus
* Czech Republic
* Estonia
* Hungary
* Latvia
* Lithuania
* Malta
* Poland
* Romania
* Slovakia
* Slovenia
| **Document Type** | **Document Name** |
| :-------------------- | :-------------------------------------------------------------------- |
| **Identity Document** | `passport`, `national_id`, `permanent_resident_id`, `driving_license` |
| **Tax Document** | `nino` |
**Additional Requirements:**
* Proof of UK address required
### Identity Documents
* `passport`
* `national_id`
* `permanent_resident_id`
* `driving_license`
### Tax Documents for Asia Pacific Countries
| **Supported Country** | **Tax Document** |
| :-------------------- | :---------------------------------------------------------------------------- |
| ๐ต๐ญ Philippines | `tin` - Tax Identification Number |
| ๐ธ๐ฌ Singapore | `nric` - National Registration Identity Card, `fin` - Foreign Identity Number |
| ๐ฆ๐บ Australia | `tfn` - Tax File Number |
| ๐ฏ๐ต Japan | `my_number` - My Number Card |
| ๐ฐ๐ท South Korea | `rrn` - Resident Registration Number |
| ๐ฎ๐ณ India | `pan` - Permanent Account Number |
| ๐ฒ๐พ Malaysia | `itr` - Income Tax Reference Number |
| ๐น๐ญ Thailand | `tin` - Tax Identification Number |
### Identity Documents
* `passport`
* `national_id`
* `permanent_resident_id`
* `driving_license`
### Tax Documents for Africa Countries
| **Supported Country** | **Tax Document** |
| :-------------------- | :------------------------------------------------------------------------------------------------------------ |
| ๐ณ๐ฌ Nigeria | `nin` - National Identification Number / `bvn` - Bank Verification Number / `tin` - Tax Identification Number |
| ๐ฟ๐ฆ South Africa | `itr` - Income Tax Reference Number |
| ๐ฌ๐ญ Ghana | `tin` - Tax Identification Number |
| ๐ฐ๐ช Kenya | *No tax document required* |
| ๐ช๐ฌ Egypt | `tin` - Tax Identification Number |
| ๐ฒ๐ฆ Morocco | `if` - Identification Fiscal |
### Identity Documents
* `passport`
* `national_id`
* `permanent_resident_id`
* `driving_license`
### Tax Documents for Latin America Countries
| **Supported Country** | **Tax Document** |
| :-------------------- | :----------------------------------------------------------------------------------------- |
| ๐ง๐ท Brazil | `cpf` - Cadastro de Pessoas Fรญsicas |
| ๐ฒ๐ฝ Mexico | `rfc` - Registro Federal de Contribuyentes / `curp` - Clave รnica de Registro de Poblaciรณn |
| ๐ฆ๐ท Argentina | `cuil` - Cรณdigo รnico de Identificaciรณn Laboral |
| ๐จ๐ด Colombia | `cc` - Cรฉdula de Ciudadanรญa |
| ๐จ๐ฑ Chile | `rut` - Registro รnico Tributario |
| ๐ต๐ช Peru | `ruc` - Registro รnico de Contribuyentes |
***
## Enhanced Due Diligence
For users requiring additional verification or to increase user limits, see [Enhanced Due Diligence](/documentation/developer-platform/users/compliance/enhanced-due-diligence).
***
## Implementation Methods
Carbn Connect offers two approaches for user identity verification:
**API-first approach** for full control over user experience:
* Build your own KYC collection interface
* Handle all document collection and validation
* Manage compliance requirements per region (detailed below)
* Custom UI/UX design and branding
* Same processing times as hosted links
* Average decision time: **under 1 minute** for automated approval
* Manual reviews: **1-2 business days**
*Best for organizations that want complete control over their user onboarding experience.*
**Pre-built compliance flow** that handles the complete verification process:
* Terms of Service acceptance
* Document collection and verification
* Automated regulatory compliance checks
* Faster implementation with minimal development required
* Same processing times as API integration
*Ideal for faster time-to-market with proven compliance workflows.*
***
## What's Next?
Implement user onboarding with proper KYC handling
Learn about user onboarding status in Carbn Connect
# Overview
Source: https://docs.carbn.xyz/documentation/developer-platform/users/compliance/overview
User management and compliance verification
## Users API Overview
The **Users API** and **KYC Links API** allow you to register your end users, enabling seamless and compliant movement of stablecoins or fiat between your users' wallets or bank accounts. Carbn handles all **KYC (Know Your Customer)** and **KYB (Know Your Business)** verification steps, so you have confidence that your users meet all applicable compliance requirements.
***
### Key Concepts
* **Users**: Represent end users of your platform who need identity verification.
* **KYC/KYB**: Mandatory identity and business verification handled by Carbn Connect.
* **User Status**: Verification states (pending, approved, rejected) that determine transaction eligibility.
* **Risk Assessment**: Automated scoring system that evaluates compliance and regulatory requirements.
* **Document Verification**: Secure processing of government-issued IDs and business documents.
* **KYC Links**: Hosted verification flow alternative to direct API integration.
***
## Key Features
Streamlined identity verification with automated document processing and verification
Support for compliance requirements across multiple jurisdictions and regulatory frameworks
Built-in risk assessment and scoring to help manage compliance and regulatory requirements
Secure storage and management of user documents with audit trails
***
## User Registration
To register a new user, use either the **Users API** or the **KYC Links API**. Upon registration:
* Users must **agree to Carbn Connect's Terms of Service**.
* You must provide **basic identity information** such as:
* Full name
* Email address
* Government-issued identifiers (e.g., SSN for individuals, EIN/TIN for businesses)
Carbn Connect will validate this information to approve the user for transactions. If additional information is needed, Carbn Connect will return precise requirements for completion of the KYC/KYB process.
***
**See Also**: KYC Requirements for a detailed list of required fields and document types.
## What's Next?
Review KYC requirements for individuals and businesses
Start the onboarding process for your region
# Rejection Reasons
Source: https://docs.carbn.xyz/documentation/developer-platform/users/compliance/rejection-reasons
Understanding user rejection reasons and how to handle them
If Users API and KYC Links return that the user's KYC status is `rejected`, there are two fields shared with rejection reasons:
* `developer_reason` is meant to be used by developers for **internal purposes only.** This field can contain sensitive information intended for only the developer and is provided to help with troubleshooting potential issues or protecting against potential abuse.
* `reason` can be shared by a developer directly with their users.
| **Develope Reason** | **Reason** |
| :-------------------------------------------------------- | :------------------------------------------------------ |
| ID cannot be verified against third-party databases | Your information could not be verified |
| Inconsistent or incomplete information. | Inconsistent or incomplete information. |
| Cannot validate user age | Your information could not be verified |
| Missing or incomplete barcode on the ID. | Cannot validate ID, upload a clear photo of the full ID |
| Inconsistent information in the barcode. | Your information could not be verified |
| Submission is blurry. | Cannot validate ID - upload photo of ID is clear |
| Inconsistent ID format | Your information could not be verified |
| Compromised ID detected | Your information could not be verified |
| ID from disallowed country. | Cannot accept provided ID |
| Incorrect ID type selected. | Incorrect ID type selected. |
| Same side submitted as both front and back. | Same side submitted as both front and back. |
| Electronic replica detected. | Your information could not be verified |
| No government ID found in submission. | No government ID found in submission. |
| ID is expired. | ID is expired. |
| Missing required ID details. | Cannot validate ID, upload a clear photo of the full ID |
| Inconsistent details in extraction. | Your information could not be verified |
| Likely fabrication detected. | Your information could not be verified |
| Glare detected in the submission. | Cannot validate ID, upload a clear photo of the full ID |
| Identity cannot be verified | Your information could not be verified |
| Inconsistent details with previous submission. | Your information could not be verified |
| Inconsistent details between submissions. | Your information could not be verified |
| Machine readable zone not detected | Cannot validate ID, upload a clear photo of the full ID |
| Inconsistent machine readable zone | Cannot validate ID, upload a clear photo of the full ID |
| ID number format inconsistency. | Your information could not be verified |
| Paper copy detected. | Your information could not be verified |
| PO box address detected. | PO box address detected. |
| Blurry face portrait. | Cannot validate ID, upload a clear photo of the full ID |
| No face portrait found in the submission. | Cannot validate ID, upload a clear photo of the full ID |
| Face portrait matches a public figure. | Your information could not be verified |
| Not a U.S. REAL ID. | Your information could not be verified |
| ID details and face match previous submission. | Your information could not be verified |
| Different faces in ID and selfie. | Your information could not be verified |
| Tampering detected. | Your information could not be verified |
| Submission cannot be processed. | Submission cannot be processed. |
| Dates on the ID are invalid. | Your information could not be verified |
| Identity cannot be verified against third-party databases | Your information could not be verified |
| Person is deceased. | Your information could not be verified |
| Document could not be verified | Your information could not be verified |
| Unsupported country | Your region is not supported |
| No government ID detected | Cannot validate ID, upload a clear photo of the full ID |
| No database check was performed | Your information could not be verified |
| Prohibited state/province | Your region is not supported |
| Prohibited country | Your information could not be verified |
| Potential elder abuse | Your information could not be verified |
| Potential PEP | Your information could not be verified |
| User information could not be verified | Your information could not be verified |
| Unsupported state/province | Your region is not supported |
| Missing or invalid proof of address | Missing or invalid proof of address |
# User Onboarding Status
Source: https://docs.carbn.xyz/documentation/developer-platform/users/compliance/user-status
User onboarding status and how to handle them
## Turnaround response time
The average decision time for KYC is typically less than one minute. If a manual review is required for KYC, the decision may take until next business day.
## User Status Transitions
All KYC flows for individual users begin with users created with basic information. If the provided information is sufficient, they can move directly to `active`, `rejected`, or `under_review`. If something is missing or more information is needed, they move to `incomplete` status.
## User Journey Scenarios
While KYC generally works quickly, there are different paths users can take through the verification process. Understanding these scenarios helps you build better user experiences and handle edge cases appropriately.
```
created โ active
```
**What happens**: User provides complete, accurate information that passes all automated verification checks immediately.
**Timeline**: Typically under 1 minute
**User experience**: Seamless onboarding with immediate access
```
created โ incomplete โ active
```
**What happens**: User's basic information is valid, but additional documents are needed (e.g., proof of address, tax documents).
**Timeline**: Depends on how quickly user provides missing documents
**User experience**: Clear guidance on what's needed, easy document upload process
```
created โ under_review โ active
created โ under_review โ rejected
```
**What happens**: Automated checks flag something that requires human review (e.g., document quality issues, name variations).
**Timeline**: Up to next business day
**User experience**: "Under review" messaging with expected timeline
```
created โ rejected
```
**What happens**: Critical information is incorrect or invalid (e.g., wrong tax ID format, prohibited jurisdiction).
**Timeline**: Immediate
**User experience**: Clear error messages with specific guidance on what went wrong
```
created โ incomplete โ under_review โ active
created โ under_review โ incomplete โ active
```
**What happens**: Multiple verification steps are needed, or additional documents are requested during manual review.
**Timeline**: Varies based on user responsiveness and review complexity
**User experience**: Step-by-step progress tracking with clear next actions
### Under Review
In this scenario, the user has provided all required information and documents, but automated verification checks have flagged something that requires human review. This could be due to document quality issues, name variations, or other factors that need manual verification. In this scenario, fetching the user via [Get User Details](/api-reference/user-management/get-user-details) would result in something like this:
```json theme={null}
{
"id": "user_john_uuid",
// ...
"status": "under_review",
"created_at": "Thu, 04 May 2023 15:40:40.832827000 UTC +00:00",
"updated_at": "Thu, 04 May 2023 15:40:40.832827000 UTC +00:00"
}
```
You can see that the user's KYC status is `under_review`. This means all required information has been submitted, but a human reviewer needs to manually verify the details. No additional action is required from the user at this point. After the manual review is complete, one of two things will happen:
* Carbn will approve your user, and the KYC status on the user will move to `active`
* Carbn will reject your user, and the KYC status on the user will move to `rejected`.
### Incomplete Status
When a user is in `incomplete` status, it means required information or documents are missing. You can check what's needed by examining the `requirements_due` field in the user object:
```json theme={null}
{
"id": "user_jane_uuid",
"status": "incomplete",
"requirements_due": [
"proof_of_address",
"tax_document"
],
"created_at": "Thu, 04 May 2023 15:40:40.832827000 UTC +00:00",
"updated_at": "Thu, 04 May 2023 15:40:40.832827000 UTC +00:00"
}
```
The `requirements_due` array tells you exactly what documents or information need to be provided. Common requirements include:
* `id_verification` - Government-issued photo ID
* `proof_of_address` - Utility bill, bank statement, or government document
* `tax_document` - Tax identification document specific to the user's country
* `source_of_funds` - Documentation proving origin of funds (for Enhanced Due Diligence)
To resolve incomplete status, submit the required documents through the appropriate API endpoints. Once all requirements are satisfied, the user will move to `active`, `rejected`, or `under_review` status.
### Immediate Rejection
Sometimes, your user could immediately move from created to `rejected` and skip `under_review` entirely. The primary reason this happens is when the tax identification number is entered incorrectly. Without a valid tax identification number, Carbn is unable to verify any of the other details you have sent up for your user (birth date, address, name). In this scenario, the user starts off created with basic information, but after attempting to verify submitted information, there was an issue detected with the submission. It is possible to move directly to `rejected` and skip `under_review` entirely. In the `rejected` scenario, fetching the user would result in something like this:
```json theme={null}
{
"id": "user_123",
"first_name": "John",
"last_name": "Doe",
"email": "johndoe@johndoe.com",
"type": "individual",
"status": "rejected",
"rejection_reasons": [
{
"developer_reason": "Missing required ID details.",
"reason": "Cannot validate ID -- upload a clear photo of the full ID",
"created_at": "2020-01-02T00:00:00.000Z"
},
{
"developer_reason": "Blurry face portrait.",
"reason": "Cannot validate ID -- upload a clear photo of the full ID",
"created_at": "2020-01-02T00:00:00.000Z"
}
],
"user_id": "user_123"
}
```
You can see that the user's KYC status is `rejected` and that there are two fields shared with rejection reasons:
* `developer_reason` is meant to be used by developers for **internal purposes only.** This field can contain sensitive information intended for only the developer and is provided to help with troubleshooting potential issues or protecting against potential abuse.
* `reason` can be shared by a developer directly with their users.
For reference, see our page on [Rejection Reasons](/documentation/developer-platform/users/compliance/rejection-reasons) for `developer_reason` and `reason` mappings for KYC rejection reasons.
# Configure Webhooks
Source: https://docs.carbn.xyz/documentation/getting-started/configure-webhook
Set up real-time notifications for payment status updates
Carbn webhooks allow you to receive real-time notifications when payment events occur in your Carbn account. This guide covers registering, implementing, and enabling webhooks using Carbn's REST API.
## Prerequisites
* A Carbn account with API access
* Carbn API credentials (API key)
* HTTPS endpoint with valid certificate
* Development environment with your preferred language
***
## Step 1: Create Your Webhook Endpoint
First, create an endpoint on your server to receive webhook notifications.
### Webhook Payload Structure
All webhook payloads follow this structure:
```json Response theme={null}
{
"status": "PAYMENT_PROCESSED",
"txn_id": "da4ac399-ed76-42f3-ba29-e4f4b7e2b46c",
"user_id": "38758d6e-05f7-46a2-86d1-5ab45a49bc64"
}
```
### HTTP Headers
When Carbn sends webhook events, your endpoint will receive these headers:
* `Content-Type: application/json`
* `User-Agent: Java/17.0.14`
* `X-Webhook-Event-Id`: Unique identifier for this delivery attempt
* `X-Webhook-Id`: Identifier of the webhook configuration
* `X-Webhook-Signature`: Base64 encoded signature for payload verification
### Example Webhook Handler
```javascript Node.js/Express theme={null}
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
app.post('/webhooks/carbn', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const eventId = req.headers['x-webhook-event-id'];
const webhookId = req.headers['x-webhook-id'];
const payload = req.body;
// Verify webhook signature (recommended)
if (!verifySignature(JSON.stringify(payload), signature)) {
return res.status(401).send('Unauthorized');
}
// Handle idempotency using event ID
if (isEventProcessed(eventId)) {
return res.status(200).send('Already processed');
}
const { status, txn_id, user_id } = payload;
switch (status) {
case 'PAYMENT_PROCESSED':
handlePaymentProcessed(txn_id, user_id);
break;
case 'PAYMENT_FAILED':
handlePaymentFailed(txn_id, user_id);
break;
default:
console.log('Unknown payment status:', status);
}
// Mark event as processed
markEventProcessed(eventId);
res.status(200).send('OK');
});
function verifySignature(payload, signature) {
// Carbn uses RSA signature verification with base64 encoded signature
// This is a simplified example - implement proper RSA verification
const publicKey = process.env.CARBN_PUBLIC_KEY;
try {
const verify = crypto.createVerify('SHA256');
verify.update(payload);
const signatureBuffer = Buffer.from(signature, 'base64');
return verify.verify(publicKey, signatureBuffer);
} catch (error) {
console.error('Signature verification failed:', error);
return false;
}
}
function handlePaymentProcessed(txnId, userId) {
console.log(`Payment ${txnId} processed for user ${userId}`);
// Update your database, notify user, etc.
}
function handlePaymentFailed(txnId, userId) {
console.log(`Payment ${txnId} failed for user ${userId}`);
// Handle payment failure, notify user, etc.
}
```
```python Python/Flask theme={null}
from flask import Flask, request, jsonify
import base64
import json
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization
app = Flask(__name__)
processed_events = set()
@app.route('/webhooks/carbn', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-Webhook-Signature')
event_id = request.headers.get('X-Webhook-Event-Id')
webhook_id = request.headers.get('X-Webhook-Id')
payload = request.get_data()
# Verify webhook signature (recommended)
if not verify_signature(payload, signature):
return jsonify({'error': 'Unauthorized'}), 401
# Handle idempotency
if event_id in processed_events:
return jsonify({'status': 'already processed'}), 200
data = request.json
status = data.get('status')
txn_id = data.get('txn_id')
user_id = data.get('user_id')
if status == 'PAYMENT_PROCESSED':
handle_payment_processed(txn_id, user_id)
elif status == 'PAYMENT_FAILED':
handle_payment_failed(txn_id, user_id)
else:
print(f'Unknown payment status: {status}')
# Mark event as processed
processed_events.add(event_id)
return jsonify({'status': 'success'}), 200
def verify_signature(payload, signature):
try:
# Load your Carbn public key
public_key_pem = os.environ['CARBN_PUBLIC_KEY']
public_key = serialization.load_pem_public_key(public_key_pem.encode())
# Decode the base64 signature
signature_bytes = base64.b64decode(signature)
# Verify the signature
public_key.verify(
signature_bytes,
payload,
padding.PKCS1v15(),
hashes.SHA256()
)
return True
except Exception as e:
print(f'Signature verification failed: {e}')
return False
def handle_payment_processed(txn_id, user_id):
print(f"Payment {txn_id} processed for user {user_id}")
# Update your database, notify user, etc.
def handle_payment_failed(txn_id, user_id):
print(f"Payment {txn_id} failed for user {user_id}")
# Handle payment failure, notify user, etc.
```
***
## Step 2: Register Your Webhook
Once your endpoint is ready, register it with Carbn. You must specify both `url` and `event_category`. **Important:** Webhooks are created with `status: "disabled"` by default and must be enabled separately.
### Webhook event categories
Choose one event category per webhook. Each webhook receives only events for its category:
| Event category | Description |
| ---------------------------- | ---------------------------------------------------------------------------------------------------- |
| `ONRAMP_TRANSACTION_STATUS` | Onramp (fiat-to-crypto) transfer status updates (e.g. initiated, funds received, payment processed). |
| `OFFRAMP_TRANSACTION_STATUS` | Offramp (crypto-to-fiat) transfer status updates. |
| `PAYOUT` | Payout status updates for local currency payouts (e.g. INITIATED, PAYOUT\_PROCESSED, FAILED). |
| `USER_STATUS_UPDATE` | User KYC and onboarding status changes (e.g. under\_review, active, rejected, incomplete). |
| `CUSTODY_WALLET_TRANSACTION` | Custody wallet transfer status updates (e.g. initiated, in\_review, completed). |
```bash cURL theme={null}
curl --request POST \
--url https://api.carbnconnect.com/onboarding/api/v1/webhooks \
--header 'Content-Type: application/json' \
--header 'x-api-key: ' \
--data '{
"url": "https://your-app.com/webhooks/carbn",
"event_category": "ONRAMP_TRANSACTION_STATUS"
}'
```
```javascript JavaScript theme={null}
const response = await fetch('https://api.carbnconnect.com/onboarding/api/v1/webhooks', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': ''
},
body: JSON.stringify({
url: "https://your-app.com/webhooks/carbn",
event_category: "ONRAMP_TRANSACTION_STATUS"
})
});
const webhook = await response.json();
console.log('Webhook registered:', webhook.id);
```
```python Python theme={null}
import requests
headers = {
'Content-Type': 'application/json',
'x-api-key': ''
}
data = {
"url": "https://your-app.com/webhooks/carbn",
"event_category": "ONRAMP_TRANSACTION_STATUS"
}
response = requests.post(
'https://api.carbnconnect.com/onboarding/api/v1/webhooks',
headers=headers,
json=data
)
webhook = response.json()
print(f"Webhook registered: {webhook['id']}")
```
**Response:**
```json Response theme={null}
{
"id": "f79bc473-d45d-4026-86ec-864d4d047905",
"url": "https://your-app.com/webhooks/carbn",
"status": "disabled",
"created_at": "2024-01-15T10:30:00Z"
}
```
Save the `webhook_id` from the response - you'll need it to enable the webhook.
***
## Step 3: Enable Your Webhook
Before your webhook can receive events, you must enable it using the PUT endpoint:
```bash cURL theme={null}
curl --request PUT \
--url https://api.carbnconnect.com/onboarding/api/v1/webhooks/{webhook_id} \
--header 'Content-Type: application/json' \
--header 'x-api-key: ' \
--data '{
"url": "https://your-app.com/webhooks/carbn",
"status": "enabled"
}'
```
```javascript JavaScript theme={null}
const response = await fetch(`https://api.carbnconnect.com/onboarding/api/v1/webhooks/${webhookId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'x-api-key': ''
},
body: JSON.stringify({
url: "https://your-app.com/webhooks/carbn",
status: "enabled"
})
});
const webhook = await response.json();
console.log('Webhook enabled:', webhook.status);
```
```python Python theme={null}
import requests
headers = {
'Content-Type': 'application/json',
'x-api-key': ''
}
data = {
"url": "https://your-app.com/webhooks/carbn",
"status": "enabled"
}
response = requests.put(
f'https://api.carbnconnect.com/onboarding/api/v1/webhooks/{webhook_id}',
headers=headers,
json=data
)
webhook = response.json()
print(f"Webhook status: {webhook['status']}")
```
***
## Payment Status Events
Carbn webhooks notify you when payment statuses change. The main status values are:
* **`PAYMENT_PROCESSED`** - Payment has been successfully processed
* **`PAYMENT_FAILED`** - Payment processing failed
**Example payload:**
```json Response theme={null}
{
"status": "PAYMENT_PROCESSED",
"txn_id": "da4ac399-ed76-42f3-ba29-e4f4b7e2b46c",
"user_id": "38758d6e-05f7-46a2-86d1-5ab45a49bc64"
}
```
***
## What's Next?
Learn how to verify webhook authenticity using RSA signatures
Your webhook is now configured to receive real-time payment notifications from Carbn. Next, implement proper signature verification to ensure webhook security.
# Create Your First Payment
Source: https://docs.carbn.xyz/documentation/getting-started/first-payment
This guide walks you through creating your first payment using Carbn's payment infrastructure. Before initiating payments, ensure your users have completed onboarding and have active status.
## Prerequisites
Before you can create payments, you need:
* **Active Users**: Users must have `active` status after successful KYC verification
* **Registered Accounts**: Users need registered bank accounts or wallets
* **API Authentication**: Valid API key with payment permissions
Users with `under_review`, `rejected`, or `incomplete` status cannot initiate payments.
***
## Steps to make your first payment:
Before initiating transfers, users need registered destination account (bank accounts or wallets).
```bash cURL theme={null}
curl --location --request POST 'https://api.carbnconnect.com/payment/api/v1/accounts/register' \
--header 'Content-Type: application/json' \
--header 'x-api-key: ' \
--data-raw '{
"user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"account_type": "bank_account",
"account_details": {
"account_number": "1234567890",
"routing_number": "021000021",
"bank_name": "Example Bank",
"account_holder_name": "John Doe"
},
"currency": "USD"
}'
```
```javascript JavaScript theme={null}
const response = await fetch('https://api.carbnconnect.com/payment/api/v1/accounts/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': ''
},
body: JSON.stringify({
user_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
account_type: "bank_account",
account_details: {
account_number: "1234567890",
routing_number: "021000021",
bank_name: "Example Bank",
account_holder_name: "John Doe"
},
currency: "USD"
})
});
```
```python Python theme={null}
import requests
headers = {
'Content-Type': 'application/json',
'x-api-key': ''
}
data = {
"user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"account_type": "bank_account",
"account_details": {
"account_number": "1234567890",
"routing_number": "021000021",
"bank_name": "Example Bank",
"account_holder_name": "John Doe"
},
"currency": "USD"
}
response = requests.post(
'https://api.carbnconnect.com/payment/api/v1/accounts/register',
headers=headers,
json=data
)
```
```bash cURL theme={null}
curl --location --request POST 'https://api.carbnconnect.com/payment/api/v1/wallets/register' \
--header 'Content-Type: application/json' \
--header 'x-api-key: ' \
--data-raw '{
"user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"crypto": "USDC",
wallet_address: "3BsSG...",
blockchain: "solana",
"source_currency": "USD"
}'
```
```javascript JavaScript theme={null}
const response = await fetch('https://api.carbnconnect.com/payment/api/v1/wallets/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': ''
},
body: JSON.stringify({
user_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
crypto: "USDC",
wallet_address: "3BsSG...",
blockchain: "solana",
source_currency: "USD"
})
});
```
```python Python theme={null}
import requests
headers = {
'Content-Type': 'application/json',
'x-api-key': ''
}
data = {
"user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"crypto": "USDC",
"wallet_address": "3BsSG...",
"blockchain": "solana",
"source_currency": "USD"
}
response = requests.post(
'https://api.carbnconnect.com/payment/api/v1/wallets/register',
headers=headers,
json=data
)
```
Now that you have registered a destination wallet, you can initiate an onramp transfer (fiat to stablecoins). Carbn Connect supports multiple methods for onramp transfers:
Open Banking provides better visibility and user experience. The deposit links guide users through the payment flow without leaving your application, giving you full control over the user journey.
**Regional Availability**: Open Banking is currently available for onramp transfers in **US**, **EU**, and **UK**.
```bash cURL theme={null}
curl --location --request POST 'https://api.carbnconnect.com/payment/api/v1/transfers/onramp' \
--header 'Content-Type: application/json' \
--header 'x-api-key: ' \
--data-raw '{
"user_id": "0abad22b-53d3-4473-b1ee-283f4b32e3ad",
"wallet_id": "34e9819d-2f1c-40a5-9404-a1be8fe34227",
"open_banking": {
"amount": 3,
"redirect_url": "https://www.yourapp.com/payment-success",
"is_mobile_app": false,
"country_codes": ["SWE"]
}
}'
```
```javascript JavaScript theme={null}
const response = await fetch('https://api.carbnconnect.com/payment/api/v1/transfers/onramp', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': ''
},
body: JSON.stringify({
user_id: "0abad22b-53d3-4473-b1ee-283f4b32e3ad",
wallet_id: "34e9819d-2f1c-40a5-9404-a1be8fe34227",
open_banking: {
amount: 3,
redirect_url: "https://www.yourapp.com/payment-success",
is_mobile_app: false,
country_codes: ["SWE"] // Optional: filter banks by country codes
}
})
});
```
```python Python theme={null}
import requests
headers = {
'Content-Type': 'application/json',
'x-api-key': ''
}
data = {
"user_id": "0abad22b-53d3-4473-b1ee-283f4b32e3ad",
"wallet_id": "34e9819d-2f1c-40a5-9404-a1be8fe34227",
"open_banking": {
"amount": 3,
"redirect_url": "https://www.yourapp.com/payment-success",
"is_mobile_app": False,
"country_codes": ["SWE"] # Optional: filter banks by country codes
}
}
response = requests.post(
'https://api.carbnconnect.com/payment/api/v1/transfers/onramp',
headers=headers,
json=data
)
```
**Country Codes Filtering**: The `country_codes` parameter is optional. When not provided, all supported bank countries for the user are available. When provided as an array of ISO 3166-1 alpha-3 country codes (e.g., `["SWE", "NOR"]`), only banks from the specified countries will be shown in the payment flow.
```json Response theme={null}
{
"transaction_id": "d5c48677-b85d-4de5-a685-196d0e6596f7",
"source_currency": "eur",
"open_banking": {
"deposit_link": "https://secure.plaid.com/hl/lpps56nr6p98sn9r89341n78s8834q672q",
"payment_id": "payment-id-production-2308307c-0d61-46d3-9225-50d48f607e36",
"link_token": "link-production-cf01ae1c-43fa-4e34-896a-23f3389d127d"
},
"v_bank": null
}
```
**Open Banking Benefits:**
* **Better Visibility**: Full payment tracking and monitoring throughout the process
* **Enhanced UX**: Users never leave your application during payment flow
* **Real-time Updates**: Immediate payment confirmation and status updates
* **Amount Control**: Exact amount validation and processing
* **Seamless Integration**: Embed payment flow directly in your app
* **Lower Fees**: Reduced processing costs compared to traditional methods
Virtual Account method serves as a fallback option or for payment methods not supported by Open Banking. It generates unique bank account details that users can transfer money to from any bank. However, it provides limited visibility - you can only monitor once funds are deposited, with no tracking of when users initiate payments or control over transfer amounts.
```bash cURL theme={null}
curl --location --request POST 'https://api.carbnconnect.com/payment/api/v1/transfers/onramp' \
--header 'Content-Type: application/json' \
--header 'x-api-key: ' \
--data-raw '{
"user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"wallet_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}'
```
```javascript JavaScript theme={null}
const response = await fetch('https://api.carbnconnect.com/payment/api/v1/transfers/onramp', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': ''
},
body: JSON.stringify({
user_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
wallet_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
})
});
const data = await response.json();
console.log('Virtual Account Details:', data.v_bank);
```
```python Python theme={null}
import requests
headers = {
'Content-Type': 'application/json',
'x-api-key': ''
}
data = {
"user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"wallet_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
response = requests.post(
'https://api.carbnconnect.com/payment/api/v1/transfers/onramp',
headers=headers,
json=data
)
result = response.json()
print('Virtual Account Details:', result['v_bank'])
```
```json Response theme={null}
{
"transaction_id": null,
"source_currency": "eur",
"open_banking": null,
"v_bank": {
"bic": "MODRIE22XXX",
"iban": "IE44MODR99035511728566",
"bank_name": "Modulr Finance, Ireland Branch",
"payment_rail": "sepa"
}
}
```
**Virtual Account Limitations:**
* **Limited Visibility**: No tracking until funds arrive - you only know when money lands
* **No Amount Control**: Users can send any amount, not necessarily what was requested
* **Payment Uncertainty**: No way to know if/when users actually make the transfer
* **Delayed Monitoring**: Can only monitor after funds are deposited, not during transfer
**When to Use Virtual Accounts:**
* As a fallback when Open Banking is not available
* For payment methods not supported by Open Banking
* When users prefer traditional bank transfers
* For regions outside US/EU/UK where Open Banking isn't available
QR Payin is available exclusively for PHP (Philippine Peso) transactions. This method generates a QR code that users can scan with their mobile banking app to complete the payment. The QR code has an expiration time and must be used before it expires.
**Regional Availability**: QR Payin is currently available only for **PHP** currency transactions.
**Minimum Amount**: The minimum transfer amount for QR Payin is **400 PHP**.
```bash cURL theme={null}
curl --location --request POST 'https://api.carbnconnect.com/payment/api/v1/transfers/onramp' \
--header 'Content-Type: application/json' \
--header 'x-api-key: ' \
--data-raw '{
"user_id": "b8aacdf0-876b-43c1-bbe1-2f2465bbed86",
"wallet_id": "9a7dc4df-c6a6-4de9-871f-83361b821c29",
"qr_payin": {
"amount": 400
}
}'
```
```json Response theme={null}
{
"transaction_id": "76e12d55-1a25-457e-9e97-0495162de555",
"source_currency": "PHP",
"qr_payin": {
"qr_code": "00020101021228600011ph.ppmi.p2m0111DCPHPHM1XXX03192147235668383093866050301152044814530360854034005802PH5904test6015MAHAGUN MORPHEU62380011ph.ppmi.p2m0519198581120859644569663048038",
"expiry_time": "2026-02-10T07:13:58.621Z"
}
}
```
**QR Payin Benefits:**
* **Convenient**: Users can pay by scanning QR code with their mobile banking app
* **Fast Processing**: Payments are processed quickly once scanned
* **Mobile-Friendly**: Ideal for mobile-first payment flows
* **Secure**: Uses standard QR payment protocols
**Important**: The QR code has an expiration time. Users must complete the payment before the `expiry_time`. After expiration, a new QR code must be generated.
***
## What's Next?
Track transfer states and understand the complete payment lifecycle
Set up real-time notifications for payment status updates
Explore supported payment methods, currencies, and assets
## Getting Help
When contacting support, please include:
**Transaction ID** of the payment**Wallet ID** If transfer ID not available**Transfer type** (FX, on-ramp, off-ramp)**Error messages** or **status codes** **Timestamp** when the error occurred
# Onboard Your First User
Source: https://docs.carbn.xyz/documentation/getting-started/onboard-first-user
Ready to onboard and verify your first user
This guide walks you through Carbn's two-step user onboarding process: first generating user consent, then creating the verified user profile.
### Understanding User Types
Carbn supports two primary user types:
* **Individual Users**: Personal accounts requiring identity verification and consent
* **Business Users**: Corporate accounts requiring business verification and beneficial ownership details
***
## Step-by-Step Onboarding
Before creating a user, you must first generate a consent record. This captures the user's acceptance of terms and conditions and generates a consent ID that's required for user creation.
### Why Consent is Required
User consent is a critical compliance requirement that:
* **Legal Protection**: Establishes clear user agreement to terms of service
* **Regulatory Compliance**: Meets KYC/AML requirements for financial services
* **Audit Trail**: Creates verifiable record of user consent with timestamps
* **Risk Management**: Ensures users understand their obligations and rights
### Requirements for Consent
* User must actively accept current terms and conditions
* Timestamp must be recorded at time of acceptance
* Consent must be obtained before any user data processing
The user must be shown a clear message where they consent to accept the terms and conditions during onborading.
```bash cURL theme={null}
curl --location --request POST 'https://api.carbnconnect.com/onboarding/api/v1/tnc' \
--header 'Content-Type: application/json' \
--header 'x-api-key: ' \
--data-raw '{
"tnc_data": {
"tnc_accepted": true,
"accepted_at": "2024-01-01T12:00:00Z"
}
}'
```
```javascript JavaScript theme={null}
const response = await fetch('https://api.carbnconnect.com/onboarding/api/v1/tnc', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': ''
},
body: JSON.stringify({
tnc_data: {
tnc_accepted: true,
accepted_at: new Date().toISOString()
}
})
});
```
```python Python theme={null}
import requests
from datetime import datetime
headers = {
'Content-Type': 'application/json',
'x-api-key': ''
}
data = {
"tnc_data": {
"tnc_accepted": True,
"accepted_at": datetime.utcnow().isoformat() + "Z"
}
}
response = requests.post(
'https://api.carbnconnect.com/onboarding/api/v1/tnc',
headers=headers,
json=data
)
```
```json Response theme={null}
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
```
The response is a unique consent ID (UUID) that you'll use in the next step. Store this securely as it's required for user creation.
### Importance of Consent
* **Required Parameter**: The consent ID is mandatory for all user creation requests
* **Compliance Link**: Connects user profiles to their consent records
* **Audit Trail**: Enables tracking of consent to user relationship
* **Legal Requirement**: Proves user agreed to terms before account creation
Now create the user profile using the consent ID from the previous step. This establishes the user's identity within the Carbn network and links them to their consent record.
### Understanding Document Types
The user creation request includes two distinct document categories:
* **Identity Documents** (`identity` object): Primary identification documents like national ID, passport, or driver's license that prove the user's identity
* **Supporting Documents** (`documents` array): Additional documents that support the user's profile, such as proof of address, tax documents, or source of funds verification
Make sure to use the `consent_id` from previous step in your request.
```bash cURL theme={null}
curl --location --request POST 'https://api.carbnconnect.com/onboarding/api/v1/users' \
--header 'Content-Type: application/json' \
--header 'x-api-key: ' \
--header 'Idempotency-Key: ' \
--data-raw '{
"first_name": "John",
"last_name": "Doe",
"email_address": "john.doe@example.com",
"phone_number": "+1234567890",
"user_type": "individual",
"date_of_birth": "1990-01-01",
"consent_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"metadata": "{}",
"sharing_consent": true,
"identity": {
"identity_country_code": "DEU",
"identity_number": "XXXXXXXXXXXX",
"identity_document_name": "permanent_residency_id",
"identity_document_front": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD...",
"identity_document_back": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
},
"documents": [
{
"name": "steuer_id",
"type": "tax_document",
"issuing_country": "DEU",
"document_number": "",
"document_front": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD...",
"document_back": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
}
],
"address": {
"line1": "123 Main Street",
"city": "City Name",
"sub_division": "ST",
"country": "DEU",
"postal_code": "12345"
}
}'
```
```javascript JavaScript theme={null}
const response = await fetch('https://api.carbnconnect.com/onboarding/api/v1/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': '',
'Idempotency-Key': ''
},
body: JSON.stringify({
first_name: "John",
last_name: "Doe",
email_address: "john.doe@example.com",
phone_number: "+1234567890",
user_type: "individual",
date_of_birth: "1990-01-01",
consent_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", // From Step 1
metadata: "{}",
sharing_consent: true,
identity: {
identity_country_code: "DEU",
identity_number: "XXXXXXXXXXXX",
identity_document_name: "permanent_residency_id",
identity_document_front: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD...",
identity_document_back: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
},
documents: [
{
name: "steuer_id",
type: "tax_document",
issuing_country: "DEU",
document_number: "",
document_front: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD...",
document_back: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
}
],
address: {
line1: "123 Main Street",
city: "City Name",
sub_division: "ST",
country: "DEU",
postal_code: "12345"
}
})
});
```
```python Python theme={null}
import requests
headers = {
'Content-Type': 'application/json',
'x-api-key': '',
'Idempotency-Key': ''
}
data = {
"first_name": "John",
"last_name": "Doe",
"email_address": "john.doe@example.com",
"phone_number": "+1234567890",
"user_type": "individual",
"date_of_birth": "1990-01-01",
"consent_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # From Step 1
"metadata": "{}",
"sharing_consent": True,
"identity": {
"identity_country_code": "DEU",
"identity_number": "XXXXXXXXXXXX",
"identity_document_name": "permanent_residency_id",
"identity_document_front": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD...",
"identity_document_back": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
},
"documents": [
{
"name": "steuer_id",
"type": "tax_document",
"issuing_country": "DEU",
"document_number": "",
"document_front": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD...",
"document_back": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
}
],
"address": {
"line1": "123 Main Street",
"city": "City Name",
"sub_division": "ST",
"country": "DEU",
"postal_code": "12345"
}
}
response = requests.post(
'https://api.carbnconnect.com/onboarding/api/v1/users',
headers=headers,
json=data
)
```
```json Response theme={null}
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "under_review",
"documents": [
{
"name": "national_id",
"type": "identity_front"
},
{
"name": "national_id",
"type": "identity_back"
},
{
"name": "steuer_id",
"type": "tax_document"
}
],
"first_name": "John",
"last_name": "Doe",
"email_address": "john.doe@example.com",
"phone_number": "+1234567890",
"date_of_birth": "1990-01-01",
"address": {
"line1": "123 Main Street",
"city": "City Name",
"sub_division": "ST",
"country": "DEU",
"postal_code": "12345"
},
"rejection_reasons": null,
"requirements": null
}
```
***
## Checking User Status
After creating a user, you can retrieve their current status and details using the GET user endpoint. This endpoint returns the exact same response format as the create and update user endpoints.
```bash Get User Details theme={null}
curl --location --request GET 'https://api.carbnconnect.com/onboarding/api/v1/users/{user_id}' \
--header 'x-api-key: '
```
```javascript JavaScript theme={null}
const response = await fetch(`https://api.carbnconnect.com/onboarding/api/v1/users/${userId}`, {
method: 'GET',
headers: {
'x-api-key': ''
}
});
```
```python Python theme={null}
import requests
headers = {
'x-api-key': ''
}
response = requests.get(
f'https://api.carbnconnect.com/onboarding/api/v1/users/{user_id}',
headers=headers
)
```
### Understanding User Status Values
The response will include a `status` field that indicates the current state of the user's verification:
```json Active User theme={null}
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "active",
"documents": [
{
"name": "national_id",
"type": "identity_front"
},
{
"name": "national_id",
"type": "identity_back"
},
{
"name": "steuer_id",
"type": "tax_document"
}
],
"first_name": "John",
"last_name": "Doe",
"email_address": "john.doe@example.com",
"phone_number": "+1234567890",
"date_of_birth": "1990-01-01",
"address": {
"line1": "123 Main Street",
"city": "City Name",
"sub_division": "ST",
"country": "DEU",
"postal_code": "12345"
},
"rejection_reasons": null,
"requirements": null
}
```
```json Under Review theme={null}
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "under_review",
"documents": [
{
"name": "national_id",
"type": "identity_front"
},
{
"name": "national_id",
"type": "identity_back"
},
{
"name": "steuer_id",
"type": "tax_document"
}
],
"first_name": "John",
"last_name": "Doe",
"email_address": "john.doe@example.com",
"phone_number": "+1234567890",
"date_of_birth": "1990-01-01",
"address": {
"line1": "123 Main Street",
"city": "City Name",
"sub_division": "ST",
"country": "DEU",
"postal_code": "12345"
},
"rejection_reasons": null,
"requirements": null
}
```
```json Rejected User theme={null}
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "rejected",
"documents": [
{
"name": "national_id",
"type": "identity_front"
},
{
"name": "national_id",
"type": "identity_back"
},
{
"name": "steuer_id",
"type": "tax_document"
}
],
"first_name": "John",
"last_name": "Doe",
"email_address": "john.doe@example.com",
"phone_number": "+1234567890",
"date_of_birth": "1990-01-01",
"address": {
"line1": "123 Main Street",
"city": "City Name",
"sub_division": "ST",
"country": "DEU",
"postal_code": "12345"
},
"rejection_reasons": [
{
"reason": "Your information could not be verified",
"created_at": "2025-09-09T11:46:22.037Z",
"developer_reason": "ID cannot be verified against third-party databases"
},
{
"reason": "Cannot validate ID, upload a clear photo of the full ID",
"created_at": "2025-09-09T11:47:15.142Z",
"developer_reason": "Missing or incomplete barcode on the ID."
}
],
"requirements": null
}
```
```json Incomplete User theme={null}
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "incomplete",
"documents": [
{
"name": "national_id",
"type": "identity_front"
},
{
"name": "national_id",
"type": "identity_back"
}
],
"first_name": "John",
"last_name": "Doe",
"email_address": "john.doe@example.com",
"phone_number": "+1234567890",
"date_of_birth": "1990-01-01",
"address": {
"line1": "123 Main Street",
"city": "City Name",
"sub_division": "ST",
"country": "DEU",
"postal_code": "12345"
},
"rejection_reasons": null,
"requirements": ["tax_identification_number"]
}
```
### Status Explanations
User has passed verification and can begin transacting. All required documents have been approved and the user is ready to use all platform features.
**Key Characteristics:**
* All KYC checks completed successfully
* User can initiate transactions
Verification is in progress. Our compliance team is reviewing the submitted documents. This typically takes 2-5 minutes for automated approval.
**Key Characteristics:**
* Initial status when user is created
* Documents are being processed
* Automated checks in progress
* User should wait for status update
Verification failed due to document or data issues. The `rejection_reasons` array contains detailed rejection objects with user-safe messages, timestamps, and internal developer reasons.
**Key Characteristics:**
* KYC verification failed
* `rejection_reasons` array populated with detailed objects
* Each rejection includes `reason`, `created_at`, and `developer_reason`
* User needs to resubmit with corrections
Only share the `reason` field with end users. The `developer_reason` may contain sensitive information.
Missing required information or documents. The `requirements` field lists what's needed to complete the user profile.
**Key Characteristics:**
* User profile is missing required data
* `requirements` array shows what's needed
* User must provide additional information
* Status will change once requirements are met
**Next Steps:**
* Use the PUT `/onboarding/api/v1/users/{user_id}` endpoint to update user details
* Provide the missing information listed in the `requirements` array
* Include any additional documents or data needed
***
## Updating User Information
If a user needs to update their information (due to rejection or incomplete status), use the PUT endpoint to modify their details:
```bash Update User theme={null}
curl --location --request PUT 'https://api.carbnconnect.com/onboarding/api/v1/users/{user_id}' \
--header 'Content-Type: application/json' \
--header 'x-api-key: ' \
--data-raw '{
"identity": {
"identity_document_front": "data:image/jpeg;base64,NEW_FRONT_IMAGE...",
"identity_document_back": "data:image/jpeg;base64,NEW_BACK_IMAGE..."
},
"documents": [
{
"name": "steuer_id",
"type": "tax_document",
"issuing_country": "DEU",
"document_number": "NEW_DOCUMENT_NUMBER",
"document_front": "data:image/jpeg;base64,NEW_DOC_FRONT...",
"document_back": "data:image/jpeg;base64,NEW_DOC_BACK..."
}
]
}'
```
```javascript JavaScript theme={null}
const response = await fetch(`https://api.carbnconnect.com/onboarding/api/v1/users/${userId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'x-api-key': ''
},
body: JSON.stringify({
identity: {
identity_document_front: "data:image/jpeg;base64,NEW_FRONT_IMAGE...",
identity_document_back: "data:image/jpeg;base64,NEW_BACK_IMAGE..."
},
documents: [
{
name: "steuer_id",
type: "tax_document",
issuing_country: "DEU",
document_number: "NEW_DOCUMENT_NUMBER",
document_front: "data:image/jpeg;base64,NEW_DOC_FRONT...",
document_back: "data:image/jpeg;base64,NEW_DOC_BACK..."
}
]
})
});
```
```python Python theme={null}
import requests
headers = {
'Content-Type': 'application/json',
'x-api-key': ''
}
data = {
"identity": {
"identity_document_front": "data:image/jpeg;base64,NEW_FRONT_IMAGE...",
"identity_document_back": "data:image/jpeg;base64,NEW_BACK_IMAGE..."
},
"documents": [
{
"name": "steuer_id",
"type": "tax_document",
"issuing_country": "DEU",
"document_number": "NEW_DOCUMENT_NUMBER",
"document_front": "data:image/jpeg;base64,NEW_DOC_FRONT...",
"document_back": "data:image/jpeg;base64,NEW_DOC_BACK..."
}
]
}
response = requests.put(
f'https://api.carbnconnect.com/onboarding/api/v1/users/{user_id}',
headers=headers,
json=data
)
```
The PUT endpoint accepts the same fields as the POST endpoint, but all fields are optional. Only include the fields you want to update. The response format is identical to the GET and POST endpoints.
***
## What's Next?
After successfully onboarding your first user, here are the essential topics to master:
Understand all possible rejection reasons and how to handle them effectively
Learn about additional verification requirements for high-risk users
Deep dive into KYC/AML requirements and regulatory compliance
Configure real-time notifications for user status changes and events
## Getting Help
When contacting support, please include:
**User ID** from the response**Endpoint** you were trying to access**Error** response details available**Timestamp** when the error occurred
# Get Setup with Carbn
Source: https://docs.carbn.xyz/documentation/getting-started/setup
Letโs get you setup and help navigate our APIs
This guide will help you make your first API call to Carbn Connect and understand the core concepts. You'll create a user, complete KYC, and process your first payment.
## Before you begin
Create your Carbn account at [dashboard.carbnconnect.com](https://dashboard.carbnconnect.com)
Navigate to **API Keys** in the dashboard and create a new sandbox API key
Safely store your API keys.
Carbn will share your **API key only once**, so make sure to **immediately copy and save the key safely and securely**. Your key is used to authenticate into our APIs and is highly sensitive. If it ever gets compromised, you can immediately revoke key access from our dashboard and generate a new key.
## Next steps
Learn about API keys, rate limits, and security best practices
Learn about error codes, troubleshooting, and best practices
## Need help?
We're excited to have you build with us! If you have questions, run into issues, or just want to say hi, you can contact us at [support@carbn.xyz](mailto:support@carbn.xyz)
# Introduction
Source: https://docs.carbn.xyz/documentation/home/introduction
# Carbn Connect API
Carbn is a global payments orchestration platform. The API is designed to provide endpoints to onboard users, create and track payment transactions, receive real-time status updates via webhooks, and retrieve invoices and logs for reconciliation.
## What you can build
Carbn Connect is used by:
* **Fintech companies** - Build cross-border payment features with ready-to-use API infrastructure
* **Payment service providers (PSPs)** - Expand corridor coverage through Carbn network
* **Remittance companies** - Process international money transfers with automated routing and compliance
* **Marketplace platforms** - Handle cross-border seller payouts and international transactions
Get started with Carbn and start building
Complete OpenAPI specification with all endpoints and methods
## Key components
User and end-user management with onboarding workflows and identity verification
Multi-currency virtual accounts with unique account and routing numbers for receiving deposits and managing user funds
Transaction routing engine that selects optimal licensed partners for each payment corridor
Built-in KYC/KYB collection, sanctions screening, and transaction monitoring for regulatory requirements
Real-time event notifications for transaction status updates, compliance approvals, and system events
## Getting Help
We're excited to have you build with us! If you have questions, run into issues, or just want to say hi, you can contact us at [support@carbn.xyz](mailto:support@carbn.xyz)
# Geographic Coverage
Source: https://docs.carbn.xyz/documentation/network/geographic-coverage
Carbn Connect facilitates payments for users across multiple jurisdictions with varying regulatory requirements. This guide outlines our geographic coverage, regional restrictions, and compliance considerations.
### Worldwide Availability
Carbn Connect facilitates payments through licensed partners in **most countries globally**, excluding jurisdictions subject to international sanctions or with restrictive regulations.
Established Coverage
United States, European Union, United Kingdom
Broad Access
Africa, Latin America, SEA, Middle East
Regulatory Standards
KYC/AML requirements enforced globally
**Exclusions**:
* OFAC sanctioned countries
* High-risk jurisdictions per FATF guidelines
* Regions with prohibitive crypto regulations
***
## Primary Markets
### United States ๐บ๐ธ
**Available in**: Most US states
**State Exclusions**:
* **New York**: Currently not supported due to BitLicense requirements
* **Alaska**: Regulatory restrictions apply
**Business Considerations**:
For business users, we evaluate based on **principal operating address**:
**Supported**: Business incorporated in NY but operating primarily from California**Supported**: California business banking with NY-based financial institution**Not Supported**: Business with primary operations in New York**Not Supported**: Business primarily operating from Alaska
**Partner Compliance Requirements**:
* Licensed partners hold money transmission licenses in applicable states
* Bank Secrecy Act (BSA) compliance through partners
* FinCEN reporting requirements handled by partners
* State-specific regulatory adherence by licensed partners
**User Types Supported**:
* Individual consumers (18+ years)
* Business entities (LLCs, Corporations, Partnerships)
* Registered financial institutions
**Enhanced Due Diligence**:
* Required for transactions above \$10,000
* Additional verification for high-risk states
* Ongoing transaction monitoring
**Individual Users**:
* Government-issued photo ID
* Social Security Number verification
* Proof of address (utility bill, bank statement)
**Business Users**:
* Certificate of incorporation
* EIN (Employer Identification Number)
* Beneficial ownership information (25%+ ownership)
* Operating agreement or bylaws
* Proof of business address
### European Union ๐ช๐บ
**Available in**: All EU member states
**Special Requirements**:
Some countries require **proof of address verification**:
* Croatia
* Cyprus
* Czech Republic
* Estonia
* Hungary
* Latvia
* Lithuania
* Malta
* Poland
* Romania
* Slovakia
* Slovenia
Proof of address must be a recent utility bill, bank statement, or government document dated within the last 3 months.
**EU Compliance Standards**:
* Markets in Crypto-Assets (MiCA) regulation
* General Data Protection Regulation (GDPR)
* Payment Services Directive 2 (PSD2)
* Anti-Money Laundering Directive (AMLD5)
**Open Banking Integration**:
* PSD2 compliant connections
* Strong Customer Authentication (SCA)
* SEPA instant payment support
* CMA9 equivalent standards
**Data Protection**:
* GDPR compliant data processing
* Right to data portability
* Right to be forgotten
* Explicit consent requirements
**Individual Users**:
* EU national ID or passport
* Proof of address (required for specific countries)
* Tax identification number where applicable
**Business Users**:
* Certificate of incorporation
* VAT registration number
* Beneficial ownership disclosure
* Articles of association
* Proof of business address
* Authorized signatory documentation
### United Kingdom ๐ฌ๐ง
**Available in**: England, Scotland, Wales, Northern Ireland
**Partner Regulatory Status**:
* Licensed partners are Financial Conduct Authority (FCA) regulated
* Open Banking CMA9 compliance through partners
* Faster Payments Scheme integration via partners
**Post-Brexit Considerations**:
* Independent regulatory framework
* Enhanced compliance requirements
* Separate from EU operations
**UK Compliance Standards**:
* Financial Services and Markets Act
* Money Laundering, Terrorist Financing and Transfer of Funds Regulations
* Open Banking Implementation Entity (OBIE) standards
* Strong Customer Authentication requirements
**Partner FCA Authorization**:
* Licensed partners hold Electronic Money Institution (EMI) permissions
* Payment Institution (PI) authorization held by partners
* Consumer credit activities where applicable through partners
**Individual Users**:
* UK driving license or passport
* Proof of UK address
* National Insurance number
**Business Users**:
* Companies House registration
* VAT registration (if applicable)
* Beneficial ownership register
* Memorandum and Articles of Association
* Proof of business address
* Director identification
***
## Coverage Map
**European Countries**
**Ireland**\
EUR
*Live*
**France**\
EUR
*Live*
**Spain**\
EUR
*Live*
**Germany**\
EUR
*Live*
**Netherlands**\
EUR
*Live*
**Belgium**\
EUR
*Live*
**Finland**\
EUR
*Live*
**Denmark**\
EUR
*Live*
**Sweden**\
EUR
*Live*
**Portugal**\
EUR
*Live*
**Austria**\
EUR
*Live*
**Italy**\
EUR
*Live*
**Luxembourg**\
EUR
*Live*
**Estonia**\
EUR
*Live*
**Lithuania**\
EUR
*Live*
**Latvia**\
EUR
*Live*
**North America**
**United States**\
USD
*Live*
**Canada**\
CAD
*Coming Soon*
**West Africa**
**Ghana**\
GHS
*Live*
**Nigeria**\
NGN
*Live*
**CFA Franc Zone**\
XOF
*Live*
**Central Africa**
**CFA Franc Zone**\
XAF
*Live*
**East Africa**
**Kenya**\
KES
*Live*
**Tanzania**\
TZS
*Live*
**Uganda**\
UGX
*Live*
**Rwanda**\
RWF
*Live*
**Southern Africa**
**South Africa**\
ZAR
*Live*
**Zambia**\
ZMW
*Live*
**Botswana**\
BWP
*Live*
**Malawi**\
MWK
*Live*
**Southeast Asia & Asia-Pacific**
**Philippines**\
PHP
*Live*
**Thailand**\
THB
*Live*
**Vietnam**\
VND
*Live*
**Hong Kong**\
HKD
*Live*
**Singapore**\
SGD
*Live*
**Indonesia**\
IDR
*Live*
**Latin America**
**Argentina**\
ARS
*Live*
**Brazil**\
BRL
*Live*
**Mexico**\
MXN
*Live*
**Expansion in Progress**: Additional countries across all regions coming soon through new licensed partnerships.
**Carbn provides technology orchestration services**. All financial services are delivered through regulated partners in their respective jurisdictions. Carbn itself does not hold financial licenses and does not operate in the flow of funds.
***
## What's Next?
Explore supported payment methods, currencies, and assets by region
Start the onboarding process for your region
# Payment Rails & Currency
Source: https://docs.carbn.xyz/documentation/network/supported-payment-methods
Complete reference for supported payment rails, currencies, and collection methods across all Carbn Connect markets. This page provides detailed technical information for each supported region.
***
## Currency and Payment Rails
### United States
*1-3 business days*
*Same business day*
*Real-time*
*Real-time*
*Real-time*
*Real-time*
***
### European Union
*1 business day*
*Real-time*
*Real-time*
***
### United Kingdom
*Real-time*
*Same business day*
*Real-time*
***
### Africa
**Mobile Wallet Network**\
*Real-time* | Africa
**Mobile Wallet Network**\
*Real-time* | West & Central Africa
**Mobile Payment System**\
*Real-time* | East Africa
**Mobile Wallet Network**\
*Real-time* | East & Southern Africa
**Traditional Banking**\
*1-2 business days* | Africa
**Mobile Banking Codes**\
*Real-time* | Nigeria, Ghana, others
**Mobile Wallet**\
*Real-time* | Ghana
**Mobile Wallet**\
*Real-time* | Malawi
**E Fund Transfer**\
*Real-time* | South Africa
***
### Asia-Pacific
**Instant Payment System**\
*Real-time* | Philippines
**Electronic Fund Transfer**\
*Next business day* | Philippines
**Mobile Wallet**\
*Real-time* | Philippines
**Mobile Wallet**\
*Real-time* | Philippines
**Traditional Banking**\
*1-2 business days* | Thailand, Vietnam, Hong Kong
**Traditional Banking**\
*1-2 business days* | Singapore, Indonesia
**Regional Systems**\
*Varies* | Coming Soon
***
### Latin America
**Instant Payment System**\
*Real-time* | Brazil
**Traditional Banking**\
*1-2 business days* | Argentina, Brazil, Mexico
***
## Stablecoins and Chains
### Stablecoins
*Most widely supported*
*High liquidity*
*Euro-denominated*
### Networks
*Fast, Cheap, Scalable*
*Global, Efficient, Interoperable*
*Secure, Developer-Friendly, Coinbase-Backed*
*Low-Cost, Ethereum-Compatible, Fast*
***
## What's Next?
Start implementing payments with your chosen method
# Welcome
Source: https://docs.carbn.xyz/welcome
Money that moves like data
Global Payments Infrastruture For Real-Time Money Movement.