Get Ramp Intent
Retrieve the full details of a ramp intent, including the generated widget URL for embedding. This endpoint also manages automatic status transitions — the intent moves from created to active on the first GET request, and auto-expires if past its expiresAt timestamp.
https://api.zenpayz.com/payment/api/v1/ramp-intents/:intentIdRequest
Headers
| Header | Description |
|---|---|
x-request-id OPTIONAL | Custom request ID for tracing |
This endpoint does not require authentication headers. It is designed to be called from your frontend or checkout page.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
intentId REQUIRED | string | The ramp intent ID (e.g. ri_1710345678000_a1b2c3d4e5f6g7h8) |
Response
Success (200 OK)
{
"success": true,
"data": {
"intent": {
"intentId": "ri_1710345678000_a1b2c3d4e5f6g7h8",
"type": "buy",
"fiatCurrency": "USD",
"cryptoCurrency": "eth_ethereum",
"amount": 100,
"status": "active",
"kycStatus": "approved",
"cancelReason": null,
"wallets": [
{ "network": "ethereum", "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD28" }
],
"userId": "usr_abc123",
"kycVerified": true,
"successUrl": "https://yourapp.com/success",
"cancelUrl": "https://yourapp.com/cancel",
"expiresAt": "2026-03-15T10:00:00.000Z",
"metadata": {}
},
"widgetUrl": "https://widget.onramper.com/...signed_url..."
},
"message": "Ramp intent retrieved"
}
Response Fields
Intent Object
| Parameter | Type | Description |
|---|---|---|
intentId OPTIONAL | string | Unique intent identifier |
type OPTIONAL | string | buy or sell |
fiatCurrency OPTIONAL | string | Fiat currency code |
cryptoCurrency OPTIONAL | string| null | Crypto identifier |
amount OPTIONAL | number| null | Default amount |
status OPTIONAL | string | Lifecycle state: created, active, completed, expired, or cancelled |
kycStatus OPTIONAL | string | KYC sub-state: pending, in_review, approved, declined, or expired. When KYC is declined, status flips to cancelled and cancelReason='kyc_rejected'. |
cancelReason OPTIONAL | string| null | Reason the intent was cancelled. kyc_rejected when KYC was declined; kyc_expired for KYC session expiry. null otherwise. |
successUrl OPTIONAL | string| null | Merchant success redirect URL |
cancelUrl OPTIONAL | string| null | Merchant cancel redirect URL |
expiresAt OPTIONAL | string | Expiry timestamp |
metadata OPTIONAL | object | Custom metadata |
wallets OPTIONAL | array | Array of { network, address } wallet objects |
userId OPTIONAL | string | Merchant's user identifier (KYC record key) |
kycVerified OPTIONAL | boolean | Whether KYC was pre-verified by merchant. Convenience flag — equivalent to kycStatus === 'approved'. |
customerEmail OPTIONAL | string| null | Customer email if provided |
Root Fields
| Parameter | Type | Description |
|---|---|---|
widgetUrl OPTIONAL | string| null | Signed widget URL for iframe embedding. null if expired. |
kycRequired OPTIONAL | boolean| undefined | Whether ZenPays KYC verification is required. Present when kycVerified is false and the user has not yet been verified. |
kycVerificationUrl OPTIONAL | string| null | URL to redirect user for identity verification. null if no verification session has been initiated yet. |
KYC Gating
The response shape depends on the user's KYC status:
Scenario 1: KYC pre-verified by merchant (kycVerified: true on the intent)
Widget URL is returned immediately. No KYC prompts.
Scenario 2: KYC verified via ZenPays (kycVerified: false, user already verified)
Widget URL is returned. kycRequired is absent or false.
Scenario 3: KYC required (kycVerified: false, user not verified)
widgetUrl is null, kycRequired is true. If a verification session exists, kycVerificationUrl contains the URL. If not, call initiateKyc (or the equivalent REST endpoint) to create a session.
{
"success": true,
"data": {
"intent": {
"intentId": "ri_1710345678000_a1b2c3d4e5f6g7h8",
"type": "sell",
"fiatCurrency": "INR",
"status": "active",
"wallets": [{ "network": "ethereum", "address": "0x742d..." }],
"userId": "usr_abc123",
"kycVerified": false,
"expiresAt": "2026-03-15T10:00:00.000Z"
},
"widgetUrl": null,
"kycRequired": true,
"kycVerificationUrl": "https://verify.zenpayz.com/session/abc123"
},
"message": "Ramp intent retrieved"
}
Automatic Behaviors
| Condition | Action |
|---|---|
Intent status is created | Auto-transitions to active on first GET |
expiresAt has passed | Auto-transitions to expired, returns widgetUrl: null |
| Widget URL not yet cached | Generates and caches the widget URL |
Intent in awaiting_payout phase | Skips widget URL generation (sell flow Phase 2) |
Error Responses
| Code | HTTP | Message |
|---|---|---|
| NOT_FOUND | 404 | Intent with the given ID does not exist |
Examples
- cURL
- JavaScript
- Python
curl https://api.zenpayz.com/payment/api/v1/ramp-intents/ri_1710345678000_a1b2c3d4e5f6g7h8
const intentId = 'ri_1710345678000_a1b2c3d4e5f6g7h8';
const response = await fetch(
`https://api.zenpayz.com/payment/api/v1/ramp-intents/${intentId}`
);
const { data } = await response.json();
const { intent, widgetUrl } = data;
if (intent.status === 'expired') {
console.log('Intent has expired — create a new one');
} else if (widgetUrl) {
// Embed in an iframe
const iframe = document.createElement('iframe');
iframe.src = widgetUrl;
iframe.style.width = '100%';
iframe.style.height = '600px';
iframe.style.border = 'none';
document.getElementById('widget-container').appendChild(iframe);
}
import requests
intent_id = "ri_1710345678000_a1b2c3d4e5f6g7h8"
response = requests.get(
f"https://api.zenpayz.com/payment/api/v1/ramp-intents/{intent_id}"
)
data = response.json()["data"]
intent = data["intent"]
widget_url = data["widgetUrl"]
print(f"Status: {intent['status']}")
print(f"Type: {intent['type']}")
if intent["status"] == "expired":
print("Intent has expired — create a new one")
elif widget_url:
print(f"Widget URL: {widget_url}")
Next Steps
- Create Ramp Intent — Create a new ramp intent
- Update Ramp Intent Status — Manually transition status
- Widget URL — Alternative widget URL generation
- On-Ramp Flow — Complete buy integration guide