Channels
Discover payment channels and run validate → quote → execute. Prefer POST /channels/execute for execution.
Auth labels match the endpoint index. Envelopes follow Responses and errors.
Endpoints#
| Method | Path | Auth |
|---|---|---|
GET | /channels | API key |
GET | /channels/categories | API key |
GET | /channels/discovery | API key |
GET | /channels/discovery/capability/{capabilityId} | API key |
GET | /channels/discovery/{gateId} | API key |
POST | /channels/execute | Session |
GET | /channels/methods/{channelSlug} | API key |
POST | /channels/onboarding/complete | Session |
POST | /channels/quote | Header context |
GET | /channels/{channelSlug} | Public |
POST | /channels/{channelSlug}/action/{actionName}/{actionId} | API key |
GET | /channels/{channelSlug}/method/{methodName} | API key |
POST | /channels/{channelSlug}/validate | Optional context |
GET | /channels/{channelSlug}/{txId} | API key |
GET | /v1/apps/channels | API key |
GET | /v1/channels/fees | Header context |
Details#
GET /channels#
GET: channel discovery (with optional filters). Execute is at POST /channels/execute.
| Auth | API key |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key. No session required.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Path parameters#
None.
Query parameters#
| Field | Type | Required |
|---|---|---|
country | string | No |
fiat_asset | string | No |
crypto_asset | string | No |
service_type | enum | No |
category | string | No |
Body#
Not applicable.
Success response#
{
"success": true,
"data": [
{
"name": "Vudy Payment Channel",
"slug": "vudy",
"methods": ["createRequest", "processRequest", "createSend"]
}
]
}Errors and statuses#
HTTP statuses used by this route: 400, 500, 200.
| Code | Meaning |
|---|---|
CH-01 | Invalid API key |
GET /channels/categories#
Lists provider categories for discovery filters. Excludes “unknown” by default.
| Auth | API key |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key. No session required.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Path parameters#
None.
Query parameters#
| Field | Type | Required |
|---|---|---|
includeUnknown | string | No |
Body#
Not applicable.
Success response#
{
"success": true,
"data": {
"categories": [
{
"id": "8b756d4b-7e4a-4b3a-bc68-b2bc6b25b506",
"name": "Bank transfer",
"slug": "bank-transfer",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
]
}
}Errors and statuses#
HTTP statuses used by this route: 400, 500, 200.
Typical failures: 403 (API key/permissions), 401 (session/context), 400 (validation), 429 (rate limit).
GET /channels/discovery#
Returns the app’s channel discovery tree (gates, categories, and capabilities available to the API key’s app). May return 503 if discovery is temporarily unavailable.
| Auth | API key |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key. No session required.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Path parameters#
None.
Query parameters#
None.
Body#
Not applicable.
Success response#
{
"success": true,
"data": {
"filters": {
"countries": [{ "id": "...", "code": "US", "name": "United States", "flag": null }],
"tokens": [{ "id": "...", "symbol": "USDC", "name": "USD Coin" }],
"currencies": [{ "id": "...", "symbol": "USD", "name": "US Dollar" }],
"categories": [{ "id": "...", "slug": "bank", "name": "Bank" }],
"chains": [{ "id": "...", "slug": "base", "name": "Base", "chainId": 8453, "image": null }],
"serviceTypes": ["onramp", "offramp"]
},
"gates": [
{
"id": "gate-uuid",
"name": "Bank card",
"imgUrl": null,
"onboardingUrl": null,
"filters": {},
"matrix": {}
}
],
"updatedAt": "2026-03-17T00:00:00.000Z"
}
}filters and each gate’s filters / matrix follow the discovery snapshot shape (nested service → country → category → currency → token → chain). Gate entries also include id, name, imgUrl, and onboardingUrl.
Errors and statuses#
HTTP statuses used by this route: 400, 500, 200, 503.
Typical failures: 403 (API key/permissions), 401 (session/context), 400 (validation), 429 (rate limit).
GET /channels/discovery/capability/{capabilityId}#
Returns discovery details for a single capability id within the app’s discovery tree.
| Auth | API key |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key. No session required.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Path parameters#
| Param | Description |
|---|---|
capabilityId | Path parameter. |
Query parameters#
None.
Body#
Not applicable.
Success response#
{
"success": true,
"data": {
"capability": {
"capabilityId": "9f57d1d4-693f-4878-96e5-c8490d10a2c4",
"channelId": "channel-uuid",
"channelSlug": "unlimit",
"channelName": "Unlimit",
"category": "bank",
"serviceType": "onramp",
"fiatSymbol": "USD",
"cryptoSymbol": "USDC",
"cryptoChainId": "chain-uuid",
"chain": {
"id": "chain-uuid",
"name": "Base",
"slug": "base",
"chainId": 8453,
"image": null
},
"countryCode": "US",
"channelMethodId": "create_tx",
"gate": {
"id": "gate-uuid",
"name": "Bank card",
"imgUrl": null,
"onboardingUrl": null
},
"params": [
{
"key": "email",
"type": "string",
"description": "Customer email",
"required": true
}
],
"limits": null
},
"updatedAt": "2026-03-17T00:00:00.000Z"
}
}Errors and statuses#
HTTP statuses used by this route: 400, 500, 404, 200, 503.
Typical failures: 403 (API key/permissions), 401 (session/context), 400 (validation), 429 (rate limit).
GET /channels/discovery/{gateId}#
Returns discovery details for a single gate id within the app’s discovery tree.
| Auth | API key |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key. No session required.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Path parameters#
| Param | Description |
|---|---|
gateId | Path parameter. |
Query parameters#
None.
Body#
Not applicable.
Success response#
{
"success": true,
"data": {
"gate": {
"id": "gate-uuid",
"name": "Bank card",
"imgUrl": null,
"onboardingUrl": null,
"filters": {},
"providers": [
{
"channelId": "channel-uuid",
"slug": "unlimit",
"name": "Unlimit",
"rating": 0
}
],
"capabilities": [],
"matrix": {}
},
"updatedAt": "2026-03-17T00:00:00.000Z"
}
}gate.capabilities entries use the same capability fields as GET /channels/discovery/capability/{capabilityId}. filters and matrix follow the discovery snapshot nesting.
Errors and statuses#
HTTP statuses used by this route: 400, 500, 404, 200, 503.
Typical failures: 403 (API key/permissions), 401 (session/context), 400 (validation), 429 (rate limit).
POST /channels/execute#
Executes a channel capability for the session profile. Wallet is resolved from targetAddress, or the team default wallet when targetAddress is omitted and configured. When Vudy can sign for the wallet, the transfer may complete server-side; otherwise the response includes transaction data for the user to sign.
| Auth | Session |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key and Authorization: Bearer <session>.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Authorization | Yes — Bearer <session> |
Path parameters#
None.
Query parameters#
None.
Body#
| Field | Type | Required |
|---|---|---|
capabilityId | string | Yes |
targetAddress | string | No |
amount | number | Yes |
params | object | Yes |
Success response#
Adapter createTx result (HTTP 201):
{
"success": true,
"data": {
"txId": "tx-uuid",
"channelTableType": "ch_unlimit_onramp",
"recordId": "record-uuid",
"walletFlow": "external",
"providerPayload": {
"url": "https://...",
"orderCustomId": "order-custom-id",
"expiresAt": "2026-07-28T12:00:00.000Z",
"refreshUrlEndpoint": "/channel/unlimit/tx-uuid/refresh-url"
}
}
}providerPayload is channel-specific and omitted for some internal flows. walletFlow is "internal" or "external".
Errors and statuses#
HTTP statuses used by this route: 400, 201, 403, 500, 501.
Typical failures: 403 (API key/permissions), 401 (session/context), 400 (validation), 429 (rate limit).
GET /channels/methods/{channelSlug}#
Returns channel method definitions and required inputs.
| Auth | API key |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key. No session required.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Path parameters#
| Param | Description |
|---|---|
channelSlug | Path parameter. |
Query parameters#
| Field | Type | Required |
|---|---|---|
method | string | No |
Body#
Not applicable.
Success response#
{
"success": true,
"data": {
"channelId": "channel-uuid",
"slug": "vudy",
"methods": {
"createRequest": {
"httpMethod": "POST",
"params": {
"customId": { "type": "string", "required": false },
"note": { "type": "string", "required": false }
}
}
}
}
}Method keys and params vary by channel. When ?method= is set, methods contains only that method.
Errors and statuses#
HTTP statuses used by this route: 400, 403, 500, 404, 200.
Typical failures: 403 (API key/permissions), 401 (session/context), 400 (validation), 429 (rate limit).
POST /channels/onboarding/complete#
Mark channel onboarding complete (green-lit) for team or user.
| Auth | Session |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key and Authorization: Bearer <session>.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Authorization | Yes — Bearer <session> |
Path parameters#
None.
Query parameters#
None.
Body#
| Field | Type | Required |
|---|---|---|
channelId | string | Yes |
Success response#
{
"success": true,
"data": {
"scope": "team",
"channelId": "channel-uuid"
}
}scope is "team" or "user" depending on which onboarding record was completed.
Errors and statuses#
HTTP statuses used by this route: 400, 403, 500, 404, 200.
Typical failures: 403 (API key/permissions), 401 (session/context), 400 (validation), 429 (rate limit).
POST /channels/quote#
Quotes a channel capability without creating a transaction. A profile context is mandatory and may come from a valid session, valid x-profile-id + x-team-id, or an API key already scoped to both a profile and team.
| Auth | Header context |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key plus one profile-context mode: Authorization: Bearer <session>, both x-profile-id and x-team-id, or a profile/team-scoped API key.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Authorization | Optional (preferred) |
x-profile-id | Required without session or a profile/team-scoped key |
x-team-id | Required without session or a profile/team-scoped key |
Path parameters#
None.
Query parameters#
None.
Body#
| Field | Type | Required |
|---|---|---|
capabilityId | string | Yes |
targetAddress | string | No |
amount | number | Yes |
params | object | Yes |
Success response#
{
"success": true,
"data": {
"capabilityId": "9f57d1d4-693f-4878-96e5-c8490d10a2c4",
"channelSlug": "unlimit",
"serviceType": "onramp",
"selection": {
"amount": "100",
"fiat": "USD",
"payment": "card",
"crypto": "USDC",
"chainId": 8453,
"country": "US"
},
"quote": {
"amountIn": { "value": "100", "currency": "USD" },
"amountOut": { "value": "99.5", "currency": "USDC" },
"exchangeRate": { "value": "0.995", "pair": "USD/USDC" },
"fees": {
"total": { "value": "0.5", "currency": "USD" },
"breakdown": [{ "type": "provider", "value": "0.5", "currency": "USD" }]
},
"raw": {}
}
}
}context is included only when the adapter supplies it. Client input errors return 400; a missing/disabled capability returns 403; unsupported channel adapters or quote implementations return 501; unexpected failures return 500.
Errors and statuses#
HTTP statuses used by this route: 200, 400, 401, 403, 429, 500, 501.
GET /channels/{channelSlug}#
Returns public channel information and available methods for a channel slug. No API key required.
| Auth | Public |
| Permissions | None (public). |
| Guide | Channel payments |
No API key required.
Headers#
No auth headers.
Path parameters#
| Param | Description |
|---|---|
channelSlug | Path parameter. |
Query parameters#
None.
Body#
Not applicable.
Success response#
{
"success": true,
"data": {
"channelSlug": "vudy",
"methods": {
"createRequest": {
"httpMethod": "POST",
"description": "Create a payment request",
"parameters": {
"tokenAddress": "string",
"description": "string",
"expiresAt": "string"
}
},
"processRequest": {
"httpMethod": "POST",
"description": "Process a payment request",
"parameters": {
"requestId": "string",
"signature": "string"
}
}
}
}
}Errors and statuses#
HTTP statuses used by this route: 404, 200.
| Code | Meaning |
|---|---|
CH-01 | Channel not found |
POST /channels/{channelSlug}/action/{actionName}/{actionId}#
Runs a named channel action on an existing channel record (follow-up step after execute/poll).
| Auth | API key |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key. No session required.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Path parameters#
| Param | Description |
|---|---|
channelSlug | Path parameter. |
actionName | Path parameter. |
actionId | Path parameter. |
Query parameters#
None.
Body#
Body schema is action-specific — resolved from the channel action registry for {actionName}. Discover fields via GET /channels/{channelSlug} or the channel guide.
Success response#
{
"success": true,
"data": {
"transactionHash": "0x456...",
"status": "completed",
"processedAt": "2024-01-01T00:00:00Z"
}
}Errors and statuses#
HTTP statuses used by this route: 400, 418, 500, 404, 200.
| Code | Meaning |
|---|---|
CH-01 | Invalid API key |
CH-02 | Action not found |
CH-05 | Invalid HTTP method |
CH-06 | Invalid request body |
CH-07 | Action function execution failed |
GET /channels/{channelSlug}/method/{methodName}#
Returns definition and required inputs for one channel method.
| Auth | API key |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key. No session required.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Path parameters#
| Param | Description |
|---|---|
channelSlug | Path parameter. |
methodName | Path parameter. |
Query parameters#
None.
Body#
Not applicable.
Success response#
{
"success": true,
"data": {
"createRequest": {
"httpMethod": "POST",
"params": {
"customId": { "type": "string", "required": false },
"note": { "type": "string", "required": false }
}
}
}
}data is the parsed method map for the requested {methodName} (same structure as entries under GET /channels/methods/{channelSlug}).
Errors and statuses#
HTTP statuses used by this route: 400, 403, 500, 404, 200.
| Code | Meaning |
|---|---|
CH-01 | Invalid API key |
CH-02 | Method not found |
CH-03 | Channel not available for app |
POST /channels/{channelSlug}/validate#
Validates a channel input before execute. Body: paramKey, value, and required capabilityId. On success, the response may include a signature to send with the value (for example as [value, signature]) in POST /channels/execute.
| Auth | Optional context |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key. Profile context is optional: a valid session, valid x-profile-id + x-team-id, or a profile/team-scoped key is used when present. An app-level key with no profile context is also accepted; the adapter then receives the API key’s team id when available.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Authorization | Optional — Bearer <session> |
x-profile-id | Optional; pair with x-team-id |
x-team-id | Optional; pair with x-profile-id |
Path parameters#
| Param | Description |
|---|---|
channelSlug | Path parameter. |
Query parameters#
None.
Body#
| Field | Type | Required |
|---|---|---|
paramKey | string | Yes |
value | any | Yes |
capabilityId | string | Yes |
Success response#
The adapter-defined result is returned in the standard envelope. For a signed-input validator, a stable shape is:
{
"success": true,
"data": {
"ok": true,
"signature": "base64url-signature"
}
}Errors and statuses#
HTTP statuses used by this route: 400, 500, 200.
Typical failures: 403 (API key/permissions), 401 (session/context), 400 (validation), 429 (rate limit).
GET /channels/{channelSlug}/{txId}#
Returns channel-scoped transaction details for a txId, including status and any actionNeeded / steps.
| Auth | API key |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key. No session required.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Path parameters#
| Param | Description |
|---|---|
channelSlug | Path parameter. |
txId | Path parameter. |
Query parameters#
None.
Body#
Not applicable.
Success response#
Envelope wraps channel-scoped transaction detail. Nested tx / detail fields vary by channel; reliably known top-level keys:
{
"success": true,
"data": {
"tx": {
"id": "tx-uuid",
"status": "pending",
"txs": {},
"channel": {},
"token": {},
"chain": {}
},
"detail": {},
"actionNeeded": false,
"steps": []
}
}Optional top-level keys: team (id, name, image), offers (OTC flows). detail and steps are channel-specific.
Errors and statuses#
HTTP statuses used by this route: 400, 500, 404, 200.
| Code | Meaning |
|---|---|
CHID#GET-01 | Invalid API key |
CHID#GET-03 | Transaction not found |
GET /v1/apps/channels#
Lists payment channels enabled for the API key’s app.
| Auth | API key |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key. No session required.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Path parameters#
None.
Query parameters#
None.
Body#
Not applicable.
Success response#
Envelope wraps an array of enabled app-channel join rows. Nested appChannels / channel objects follow the stored resource shape; reliably known top-level keys per item:
{
"success": true,
"data": [
{
"appChannels": {},
"channel": {}
}
]
}Errors and statuses#
HTTP statuses used by this route: 500, 200.
Typical failures: 403 (API key/permissions), 401 (session/context), 400 (validation), 429 (rate limit).
GET /v1/channels/fees#
Returns channel fee configuration for the active profile/team context (session, x-profile-id + x-team-id, or a profile/team-scoped key). channelSlug is required.
| Auth | Header context |
| Permissions | Standard API-key access (no extra permission flags). |
| Guide | Channel payments |
Requires x-api-key plus one profile-context mode: session, both profile/team headers, or a profile/team-scoped key.
Headers#
| Header | Required |
|---|---|
x-api-key | Yes |
Authorization | Optional (preferred) |
x-profile-id | Required without session or a profile/team-scoped key |
x-team-id | Required without session or a profile/team-scoped key |
Path parameters#
None.
Query parameters#
| Field | Type | Required |
|---|---|---|
channelSlug | string | Yes |
Body#
Not applicable.
Success response#
{
"success": true,
"data": {
"send": {
"type": "fixed",
"style": "surcharge",
"value": 0.03
},
"request": {
"type": "percentage",
"style": "commission",
"value": 50
},
"minSurchargeBps": 50,
"minCommissionBps": 50
}
}Errors and statuses#
HTTP statuses used by this route: 400, 500, 200.
Typical failures: 403 (API key/permissions), 401 (session/context), 400 (validation), 429 (rate limit).