Skip to main content
A Connect widget is an iframe. You mint a short-lived access token on your backend, put it in the URL, style the widget with query parameters, and listen for the messages it posts back to your page. Try the parameters interactively on the playground, which generates the snippet for you.

Embedding

Swap payout for payin to embed the pay-in widget, and give it more room while you are there; pay-in is the taller of the two and 600 is a comfortable height. The allow attribute matters. Identity verification uses the camera, and card flows need payment permissions. Without it, those steps fail inside the frame rather than falling back.
Mint the token on your backend, never in the browser. Tokens default to a one-hour lifetime and cannot exceed 24 hours, so treat them as short-lived credentials rather than configuration.
The widgetUrls returned by POST /auth/token are complete URLs. If you saved a widget theme in the Connect console, they already carry it as query parameters, so append your own with &. A saved theme with per-colour, typography or label settings is serialised as a single config parameter, and config takes precedence over individual parameters (see below).

Height

A fixed height="500" is the simplest thing that works. The widget also posts its height to the parent whenever its content changes, so you can size the frame to fit:
One caveat: the widget’s own container defaults to min-height: 100vh so that short content still covers the frame, which means it never reports a height smaller than the frame you gave it. If you want the frame to shrink to its content, set minHeight explicitly, for example ?minHeight=0.

Overlays

Identity verification and withdrawal confirmation in the payout widget open as modals. Inside a short iframe they are cramped, so the widget announces them and lets you expand the frame over the full viewport. The expanded frame is transparent behind the modal, so your page stays visible under the dimmed backdrop.
Without a listener the modal still works; it just fills whatever space the iframe has.

What the user sees

Payout widget

The widget reads the account’s withdrawal-ready balance, gates the first withdrawal behind identity verification, then collects a payout method and an amount.
  • Balance. Available, pending and reserved amounts from the payment provider. Only Available is withdrawable. A passedInBalance you set on the account renders as a separate display-only “Pending Balance from your platform” tile and is never spendable.
  • Identity verification. Required before the first withdrawal and enforced in the widget. The button reads “Complete verification” until the account is verified, “Pending approval” while a submission is under review, and “Withdraw” once cleared.
  • Payout method. Added inline. Which rails appear (instant bank transfer, next-day bank, wire, digital wallets, crypto) depends on the account’s country and currency.
  • Amount and confirmation. Fees, estimated delivery and estimated amount received are quoted per method before the user confirms.
An account that is only linked to your integration, rather than created by it, sees a prompt to withdraw in the SideShift app instead of a withdraw button. For creators under 18, your company can enable parent or legal guardian verification in Connect settings. This adds a relationship choice to new individual KYC sessions. The adult’s identity details remain separate from the creator’s details. The option is off by default and cannot be enabled with a widget URL parameter. See Guardian verification settings for setup and access to the saved record. In sandbox the widget renders account, verification and balance status, but the withdraw, bank-link and payout-submission controls are unavailable because the payment provider does not support payouts there. See Testing.

Pay-in widget

The pay-in widget lists the account’s saved payment methods, takes an amount, and charges the selected method. No identity verification is involved. Three query parameters control the amount field, and they are pay-in only: The processing fee is fetched per payment method and added on top of the amount: the wallet is credited what the user typed, and the card or bank is charged amount plus fee. The server recalculates the fee when it charges, so treat the figure in the breakdown as a quote. Connect accounts use a 1minimumdepositunlessanoverridehasbeensetontheaccount,anda1 minimum deposit unless an override has been set on the account, and a 200,000 maximum.
payin:deposit_completed is not settlement. It fires as soon as the charge is accepted, including when the provider status is still processing. Credit the user’s balance on the deposit.confirmed webhook, not on this event.

Customization

Every option below is a query parameter on the widget URL.

Theme and colour

theme accepts light or dark. Any other value, including auto, renders the light palette. To follow the reader’s system theme, detect it yourself and set the value on the iframe URL:
Reassigning src reloads the frame, so change the theme before the reader starts a withdrawal rather than during one.

Individual colours

For finer control, override any of these directly. Each takes a hex value (3, 6 or 8 digits): background, cardBackground, inputBackground, textPrimary, textSecondary, textMuted, textInverted, border, borderFocus, borderSelected, primary, primaryHover, primaryLight, success, successBackground, error, errorBackground, warning, warningBackground, iconColor, iconMuted, divider, skeleton. primary wins over primaryColor when both are present.

Typography, spacing, buttons and cards

buttonTextTransform accepts none, uppercase or capitalize. cardBorderStyle accepts solid, dashed or none. fontFamily is capped at 160 characters and may not contain braces, semicolons or angle brackets. The rest take CSS values and are passed through.

Sections

Send false to hide a section. showWithdrawHeader, showKycHeader and showKycSteps act on screens you only reach by clicking (the withdraw panel and the verification wizard). To use flat verification controls, set kycLiquidMetal=false in the widget URL, or layout.kycLiquidMetal: false in the theme configuration. The default is true. This changes only the verification style. Your custom colors still apply. The Connect theme editor also includes a Liquid-metal verification style toggle.

Labels

Payout: payoutTitle, balanceLabel, withdrawButton, historyTitle, historyDescription, settingsTitle, settingsDescription, kycButton, kycTitle, kycVerifiedTitle, kycVerifiedDescription. Pay-in: payinTitle, paymentMethodsTitle, addMethodButton, depositButton, amountLabel, feeLabel, totalLabel, walletLabel, successTitle, successMessage. In depositButton, $X is replaced with the formatted amount. Labels should be URL-encoded.
Label values (and buttonGradient) are decoded a second time after URL parsing, so a value that already round-tripped through an encoder comes back intact. A literal % in a hand-written URL is passed through as typed rather than decoded again. If you want a label to contain %20 as visible text rather than a space, encode it as %2520.

Three behaviours worth knowing

These surprise people, and each one is easy to mistake for a bug in your own code. Only the literal string false hides a section. showBalance=0 and showBalance=no both read as true. An out-of-range borderRadius is discarded, not clamped. borderRadius=99 falls back to the 12px default rather than rendering at 50. The same applies to borderRadiusSmall and borderRadiusLarge. Inside config, radii are clamped instead. The config parameter replaces everything else. You can pass a whole theme as URL-encoded JSON in config. If it parses, every individual parameter on the URL is ignored, so pick one approach rather than mixing them. If it fails to parse, the widget falls back to the individual parameters rather than erroring.

Events

The widget posts messages to the parent window with window.postMessage. Every message has source: 'sideshift-connect', a type, and sometimes data. Messages are posted to any origin, so check event.origin and event.source yourself before acting on one. session:expired is the one to handle. Tokens are short-lived, so mint a fresh one and reload the frame when it arrives.
Three more names exist in the widget’s event type but are never sent: payout:withdraw_completed, payout:balance_updated and payout:kyc_started. Do not build on them. payout:withdraw_completed is the trap, because it is the natural place to mark a payout finished and a handler for it will never run. Confirm completed withdrawals from the withdrawal.completed webhook instead, which is server-to-server and survives the reader closing the tab.

When the widget will not load

The widget renders failures as a full-panel state whose message is the exact reason. The messages, their causes and the fixes are listed under Widget error messages.