When you create an intent for a new customer who needs to complete compliance steps, the response includes a frontendUrl. You can embed this URL in an iframe to keep users within your application during the onboarding/KYC process.
When to Show the Iframe
After creating an intent, check the response:
const response = await createIntent(payload);
if (response.transaction) {
// Returning customer — auto-completed, show deposit instructions directly
showDepositInstructions(response.transaction.context);
} else if (response.frontendUrl) {
// New customer — show the iframe for onboarding/compliance
showIframe(response.frontendUrl);
}
frontendUrl is populated — the customer has compliance steps to complete. Show the iframe.
frontendUrl is null — the customer was auto-completed (returning user). The transaction field contains deposit instructions.
Embedding the Iframe
<iframe
id="gnosisramp-onboarding"
src="https://app.gnosisramp.io/intent/int_123"
style="width: 100%; height: 600px; border: none;"
allow="camera; microphone"
></iframe>
The allow="camera; microphone" attributes may be needed for KYC verification steps that require photo ID or liveness checks.
Listening for postMessage Events
The iframe communicates completion and dismissal via postMessage. Listen for these events to transition your UI:
window.addEventListener('message', (event) => {
// Verify the origin matches your GnosisRamp frontend URL
if (event.origin !== 'https://app.gnosisramp.io') return;
const { type, data } = event.data;
switch (type) {
case 'INTENT_COMPLETED':
// Compliance is done — remove the iframe and poll for transaction/deposit instructions
removeIframe();
pollForTransaction(data.intentId);
break;
case 'INTENT_DISMISSED':
// User closed or cancelled the onboarding flow
removeIframe();
showCancelledState();
break;
}
});
Event Types
| Event | Description |
|---|
INTENT_COMPLETED | The customer has completed all compliance steps. You can now poll for the transaction or call POST /intent/{intentId}/transaction to execute it. |
INTENT_DISMISSED | The customer dismissed or cancelled the onboarding flow. |
Full Integration Example
async function startRampFlow(payload) {
// 1. Create the intent
const response = await fetch('https://api.gnosisramp.io/v1/intent', {
method: 'POST',
headers: {
'Authorization': `Bearer ${customerToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
}).then(r => r.json());
// 2. Check if auto-completed
if (response.transaction) {
showDepositInstructions(response.transaction.context);
return;
}
// 3. Show iframe for onboarding
const iframe = document.createElement('iframe');
iframe.src = response.frontendUrl;
iframe.style.cssText = 'width:100%;height:600px;border:none;';
iframe.allow = 'camera; microphone';
document.getElementById('ramp-container').appendChild(iframe);
// 4. Listen for completion
window.addEventListener('message', async (event) => {
if (event.origin !== 'https://app.gnosisramp.io') return;
if (event.data.type === 'INTENT_COMPLETED') {
iframe.remove();
// 5. Poll for transaction
const poll = setInterval(async () => {
const txn = await fetch(
`https://api.gnosisramp.io/v1/intent/${response.intent.id}/transaction`,
{ headers: { 'Authorization': `Bearer ${customerToken}` } }
).then(r => r.json());
if (txn.status !== 'PENDING') {
clearInterval(poll);
showDepositInstructions(txn.context);
}
}, 5000);
}
});
}