bolt.com is getting a new home → boltapp.com. Click here to transition smoothly to boltapp.com.

Skip to content

Frontend events

Look up the callbacks, events, and window messages Bolt sends to your storefront page from Bolt Checkout, the SSO sign-in modal, and the Embedded API.

View As MarkdownMCP

Each Bolt script reports what the shopper does in its own way. Find the script your page loads:

Your page loadsBolt reports throughSection
connect.js, for Bolt CheckoutCallbacks you pass to BoltCheckout.configure, including onNotify eventsBolt Checkout
account.js, for SSO CommerceWindow messages from the sign-in modalSSO sign-in modal
embed.js, for the Embedded APIEvents on the Bolt objectEmbedded API

These run in the shopper's browser. Use them to update your page and to send analytics, not as a record of payment: confirm orders on your server with Merchant Callbacks and webhooks.

Bolt Checkout

Pass callbacks in the third argument of BoltCheckout.configure. Every callback is optional. This example sends checkout start and every notification to a Google Tag Manager data layer:

JavaScript
const callbacks = {
  onCheckoutStart() {
    window.dataLayer?.push({ event: "bolt_checkout_start" });
  },
  onNotify({ eventName, eventSeverity }) {
    window.dataLayer?.push({ event: "bolt_notify", bolt_event: eventName, bolt_severity: eventSeverity });
  },
  success(transaction, callback) {
    // Update your page, then let checkout finish.
    callback();
  },
};

// token is the order token from your backend, as in Web checkout.
BoltCheckout.configure({ orderToken: token }, {}, callbacks);

Where you register callbacks depends on your storefront. The plugin settings cover some callbacks, not all of them.

StorefrontWhere callbacks go
Your own storefront codeThe third argument of BoltCheckout.configure. See Web checkout.
BigCommerceBoltCheckout.setClientCustomCallbacks(callbacks). See BigCommerce callbacks.
Adobe CommerceThe Bolt plugin's Advanced options, in fields such as Tracking: onCheckoutStart
WooCommerceThe Bolt plugin's settings, in fields such as Javascript event: onCheckoutStart

Callbacks

CallbackArgumentsWhen Bolt calls it
check()NoneThe shopper tries to open checkout. Return true, or a promise of true, to open it. Return false to keep it closed. Checkout also stays closed if a returned promise takes longer than 10 seconds.
onCheckoutStart()NoneCheckout opened and shows its first step.
onEmailEnter(email)email: the addressThe shopper entered a valid email address or changed it, or logged in to their Bolt account.
onCredentialsCheck({ email, recognized })email, and recognized: true when the shopper can log in to a Bolt account with that emailBolt checked the email the shopper entered. Also called with recognized: true when the shopper opens checkout already logged in.
onShippingDetailsComplete(address)address: the shipping address, with fields such as first_name, last_name, street_address1, locality, region, postal_code, country_code, phone, and email. Missing for Apple Pay.The shopper completed the shipping address. Multi-step checkout only.
onShippingOptionsComplete()NoneThe shopper chose how the order ships. Multi-step checkout only.
onPaymentSubmit(customFields)customFields: the shopper's custom field responses, keyed by custom field public IDThe shopper selected the pay button.
onUpsellPageShown(cart)cart: the order's cartA post-purchase offer appeared. Only when your checkout shows post-purchase offers.
onUpsellDecision({ cart, decision })cart, and decision: accepted, declined, timed_out, or abandonedThe shopper responded to a post-purchase offer, or the offer timed out or was abandoned.
success(transaction, callback)transaction: the completed transaction. callback: call it when your code finishes.Payment succeeded. Checkout waits up to 10 seconds for callback(), then continues without it.
close()NoneThe checkout modal closed. Not called when Bolt redirects the shopper to your order_received_url.
onNotify(notifyEvent)notifyEvent: see onNotify eventsCheckout reported one of the events below.

onNotify events

notifyEvent has an eventName, an eventSeverity of info or error, and, for some events, an eventMetadata object. Bolt adds events over time, so ignore names you don't recognize.

Example notifyEvent
{
  "eventName": "error_invalid_payment",
  "eventSeverity": "error",
  "eventMetadata": { "reasonCode": "payment_declined" }
}

Info events

EventeventMetadataWhen it fires
info_account_creation_checkedNoneThe shopper checked the box to create a Bolt account.
info_account_creation_uncheckedNoneThe shopper cleared the box to create a Bolt account.
info_address_addedNoneA logged-in shopper submitted a new or edited address. Also sent when the save fails.
info_address_editedNoneCheckout finished updating the order's address, including after it loads a logged-in shopper's saved addresses.
info_apm_selectedapm: the payment method, such as paypal, applepay, or klarnaThe shopper selected an alternative payment method, or a saved one became the selected payment.
info_checkbox_checkedcheckbox_public_id: the custom field's public IDReports a checked custom field. Sent for each custom field whenever checkout changes step, and again when payment details are complete.
info_checkbox_uncheckedcheckbox_public_idReports an unchecked custom field. Sent for each custom field whenever checkout changes step.
info_checkout_transitionnextStep: the step checkout moves to, such as shipping_method, payment, or logged_in_summaryCheckout moved to another step.
info_custom_field_submittedcustomFieldId: the custom field's external ID. value: the response.A guest continued from the shipping address step to the delivery step, or a logged-in shopper started payment. Sent once for each custom field. Guests in a checkout without a separate delivery step don't send it.
info_delivery_option_selectedcart, and shippingTier: the delivery option's nameThe shopper selected a delivery option.
info_delivery_option_submittedcart, shippingTierThe shopper continued from the delivery step to payment.
info_discount_removeddiscountCode, and discountAmount when checkout knows itThe shopper removed a coupon or other discount. Not sent for gift cards.
info_discount_successfuldiscountCode, and discountAmount when checkout knows itA coupon or other discount applied.
info_giftcard_successfulNoneA gift card applied.
info_payment_processingNoneCheckout started authorizing the payment.
info_payment_type_addedNoneThe shopper chose to add a new card.
info_payment_type_editedNoneThe shopper deleted a saved card.
info_payment_type_selectedNoneA card became the selected payment, whether the shopper chose it or checkout selected it by default.
webview_link_clickedurlThe shopper selected a link in checkout running inside a WebView. Checkout doesn't open the link; open url from your app.

discountAmount has amount, currency, and currency_symbol, with amount in the currency's minor unit, such as cents. cart is the cart as checkout shows it.

Bolt can turn off info_checkout_transition, info_address_edited, info_checkbox_checked, and info_checkbox_unchecked for a division. If you don't receive them, contact Bolt support.

Error events

EventeventMetadataWhen it fires
error_discount_unsuccessfulNoneA coupon or other discount didn't apply.
error_giftcard_unsuccessfulNoneA gift card didn't apply, or couldn't be removed.
error_invalid_addressNoneCheckout showed an error on a shipping address field, or the shipping address is incomplete.
error_invalid_emailNoneCheckout showed an error on the email field.
error_invalid_nameNoneCheckout showed an error on the shipping first or last name field.
error_invalid_paymentreasonCode: payment_declined, duplicate_transaction, payment_method_not_supported, or bot_check_failed. Missing when saved payment methods fail to load.A payment attempt failed, or the shopper's saved payment methods didn't load. Every card or issuer decline reports payment_declined.
error_login_unsuccessfulNoneA login code couldn't be sent or verified, the shopper's email or phone failed validation, or the shopper reached a rate limit.
error_remove_discount_unsuccessfulNoneA discount couldn't be removed.
error_shippingNoneA logged-in shopper's saved addresses, or the delivery options, didn't load.
error_taxNoneTax couldn't be calculated.

SSO sign-in modal

account.js opens Bolt's sign-in modal for SSO Commerce. When a shopper logs in with a verification code, the modal posts window messages to your page as JSON strings. It doesn't call onNotify or any other callback, so listen for message events on window.

These window messages are not a stable interface. Bolt can change or remove them at any time, including in ways that break code listening for them. Ignore fields you don't expect, and don't make sign-in or checkout depend on them.

Accept messages only from Bolt's sign-in frame: https://connect.boltapp.com in production and https://connect-sandbox.boltapp.com in sandbox. That is not the host that serves account.js, which redirects to account.boltapp.com. If your page loads account.js from a bolt.com host, the frame and its messages use https://connect.bolt.com or https://connect-sandbox.bolt.com instead.

Bolt sends these messages only to pages on your division's Trusted Domains, set in the Merchant Dashboard. A page on any other origin, such as www.example.com when only example.com is listed, receives none.

JavaScript
const BOLT_ORIGIN = "https://connect.boltapp.com";

window.addEventListener("message", (event) => {
  if (event.origin !== BOLT_ORIGIN || typeof event.data !== "string") return;

  let message;
  try {
    message = JSON.parse(event.data);
  } catch {
    return;
  }
  if (message.type !== "onNotify") return;

  const { eventName, eventMetadata } = message.notifyEvent;
  if (eventName === "login_outcome") {
    window.dataLayer?.push({ event: "bolt_sso_login", outcome: eventMetadata.outcome });
  }
});

Each message has this shape:

Message
{
  "type": "onNotify",
  "notifyEvent": {
    "eventName": "login_outcome",
    "eventSeverity": "info",
    "eventMetadata": { "outcome": "SUCCESS" }
  }
}
EventeventSeverityeventMetadataWhen it fires
login_attemptedinfoemail: the email the shopper entered to sign inThe shopper continued to the verification-code screen. Retrying a code on that screen sends no new event. Going back and continuing again, with the same or a different email, sends a new one.
login_outcomeinfo, or error for FAILEDoutcome: SUCCESS, FAILED, or ABANDONEDSUCCESS: Bolt accepted the code, before any platform login or redirect. FAILED: Bolt rejected a code; each rejected retry sends one. ABANDONED: the shopper closed the modal without logging in, including after a rejected code or after going back.
  • One login can send several login_attempted and FAILED events, then at most one SUCCESS or ABANDONED. Nothing follows either of those.
  • No outcome is sent when the shopper goes back from the code screen or leaves the page with the modal open, or for a login response that arrives after the modal closed.
  • These events cover verification-code login only, not registration, social login, or dashboard login.
  • login_attempted carries the shopper's email, and any script on your page can read window messages, so treat it as shopper data. No message carries a verification code or token.

Embedded API

embed.js emits events on the Bolt object when shoppers log in and when Bolt checks their accounts. Call Bolt.initialize first: Bolt.on and Bolt.once throw an error before it.

Signature
Bolt.on(eventName: string, callback: (payload: any) => void, options?: { replayLast?: boolean }): () => void;
Bolt.once(eventName: string, callback: (payload: any) => void): () => void;
  • Bolt.on calls callback every time the event fires. Bolt.once calls it the next time only.
  • Both return a function that removes the listener.
  • With replayLast: true, Bolt.on also runs the callback right away with the event's latest payload, if the event already fired on this page. Don't pass replayLast to Bolt.once: when the event already fired, it throws an error instead of running the callback.
JavaScript
Bolt.initialize("YOUR_PUBLISHABLE_KEY");

// Runs on every successful login.
const stopListening = Bolt.on("login_succeeded", ({ result }) => {
  sendAuthorizationCodeToServer(result.authorizationCode); // your function
});

// Runs once, the next time the shopper logs out.
Bolt.once("logout", () => {
  showSignedOutHeader(); // your function
});

// Later, stop listening for logins.
stopListening();
EventPayloadWhen it fires
account_check_complete{ email, result }: result is true when the email has a Bolt accountBolt finished checking an email the shopper entered.
auto_authorize_complete{ email, result }: result is the login result or an ErrorA login that email detection started has ended.
forgot_password_continue{ email, error }The shopper selected the element you attached with context: "forgot_password", and Bolt didn't log them in. Continue with your own password reset. email is empty when no valid email was entered. When the login fails, the event fires twice, first with the email and then with an empty email, so start only one reset.
loginThe shopper's email, as a stringThe shopper logged in, or Bolt.helpers.checkShopper() found an active Bolt session.
login_complete{ email, result, loginContext }: result is the login result or an ErrorA login attempt ended, whether it succeeded or failed.
login_failed{ email, result, loginContext }: result is an ErrorA login attempt failed.
login_modal_closed{ context }The login modal closed after a login attempt, for any reason.
login_modal_dismissed{ context }The shopper closed the login modal without logging in.
login_succeeded{ email, result, loginContext }: result has authorizationCode and scopeA login attempt succeeded. Exchange authorizationCode on your server with Bolt OAuth.
logout{}Bolt.helpers.logout() logged the shopper out.
mount_failed{ component, email, context, reason }mountPasswordlessLoginButton() couldn't show the login button. component is login_button. reason is Invalid email, No account found in the checkout context, or an error message.

context and loginContext are the context you gave the login modal: checkout, sign_in, register, pre_checkout, or forgot_password.

Events kept for older integrations

These still fire. Use the newer event in new code.

EventPayloadUse instead
authorize_complete{ email, result }login_complete. Fires with every login_complete, and when the older authorization component finishes.
auto_account_check_complete{ email, result }: result is a boolean or an Erroraccount_check_complete. This event is deprecated.
authorize_modal_closed{ context: "checkout" }login_modal_closed. Sent only by the older authorization component.

Components report their own events through the component's on method, such as the payment fields' error event and the account checkbox's change event. See Payment fields and Account checkbox.

On this page