Skip to main content

Prerequisites

  • You have completed onboarding and received your client_token from Proof.
  • You have a partner_user_id (your internal, stable user identifier) and the user’s email.

Step 1 — Request a session

Call POST /widget/session to get the widget parameters. This can be called from your frontend directly.
curl -X POST https://DOMAIN/widget/session \
  -H "Authorization: Bearer <client_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "partner_user_id": "user-123",
    "user_email": "user@example.com",
    "currency": "USDT",
    "fiat_currency": "EUR",
    "fiat_amount": "100",
    "type": "buy"
  }'
Response:
{
  "merchant_transaction_id": "550e8400-e29b-41d4-a716-446655440000",
  "widget_id": "fb359d09-fff6-4b1f-906c-b9062b135065",
  "address": "TRx1a2b3c4d5e6f...",
  "signature": "v2:a1b2c3d4e5f6...",
  "init_token": "eyJhbGciOi...",
  "init_token_type": "sdk_customer_token",
  "currency": "USDT",
  "fiat_currency": "EUR",
  "fiat_amount": "100",
  "type": "buy",
  "widget_url": "https://widget.proof.community/widget.2.0.js"
}
Save merchant_transaction_id — you will use it to track the transaction status in Step 3.

Step 2 — Embed the widget

Add a container element to your page, load the widget script, and call proofWidget.run() with the session parameters.
<div id="proof-widget"></div>

<script src="https://widget.proof.community/widget.2.0.js"></script>
<script>
  // Use values from the Step 1 response
  proofWidget.run({
    widgetId:              "fb359d09-fff6-4b1f-906c-b9062b135065",
    host:                  document.getElementById("proof-widget"),
    address:               "TRx1a2b3c4d5e6f...",
    signature:             "v2:a1b2c3d4e5f6...",
    initToken:             "eyJhbGciOi...",
    initTokenType:         "sdk_customer_token",
    currency:              "USDT",
    fiatCurrency:          "EUR",
    fiatAmount:            "100",
    merchantTransactionId: "550e8400-e29b-41d4-a716-446655440000",
    type:                  "buy",
    onStatusChange: function(data) {
      console.log("Widget status:", data.status);
    }
  });
</script>
The widget opens inside the #proof-widget container. The user completes KYC (first time) and payment inside the widget.

Step 3 — Track transaction status

Poll Proof Proxy API for the transaction status:
curl https://DOMAIN/widget/transactions/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer <client_token>"
Response:
{
  "merchant_transaction_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "type": "buy",
  "currency": "USDT",
  "crypto_amount": "99.50",
  "fiat_currency": "EUR",
  "fiat_amount": "100.00",
  "created_at": "2026-04-01T10:00:00Z",
  "updated_at": "2026-04-01T10:03:45Z"
}
Poll every 5–10 seconds while status is pending or processing. Stop on terminal states: completed, failed, cancelled.

JavaScript example (full flow)

async function openRampWidget(userId, userEmail) {
  // 1. Request session from Proof
  const session = await fetch("https://DOMAIN/widget/session", {
    method: "POST",
    headers: {
      "Authorization": "Bearer <client_token>",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      partner_user_id: userId,
      user_email: userEmail,
      currency: "USDT",
      fiat_currency: "EUR",
      type: "buy"
    })
  }).then(r => r.json());

  // 2. Launch widget with session params
  proofWidget.run({
    widgetId:              session.widget_id,
    host:                  document.getElementById("proof-widget"),
    address:               session.address,
    signature:             session.signature,
    initToken:             session.init_token,
    initTokenType:         session.init_token_type,
    currency:              session.currency,
    fiatCurrency:          session.fiat_currency,
    fiatAmount:            session.fiat_amount,
    merchantTransactionId: session.merchant_transaction_id,
    type:                  session.type,
    onStatusChange:        (data) => console.log(data.status)
  });

  // 3. Poll for status
  const txId = session.merchant_transaction_id;
  const interval = setInterval(async () => {
    const tx = await fetch(
      `https://DOMAIN/widget/transactions/${txId}`,
      { headers: { "Authorization": "Bearer <client_token>" } }
    ).then(r => r.json());

    console.log("Status:", tx.status);

    if (["completed", "failed", "cancelled"].includes(tx.status)) {
      clearInterval(interval);
    }
  }, 5000);
}

Next steps

KYC Verification

How KYC works and how to check user verification status

Off-Ramp (Sell)

Enable sell (USDT → EUR/USD) for your users

Mobile Integration

iOS and Android setup for KYC camera and payment methods

Error Handling

Error codes and how to handle them