Skip to content

Embedded Web Integration ​

Overview ​

The Falcon SDK supports embedded mode, which renders promotional content directly within a container on your webpage, rather than as a fullscreen overlay. This allows for seamless integration of offers within your existing page layout (e.g., order confirmation pages, account dashboards, checkout flows).

Quick Integration Guide ​

Step 1: Get Your SDK Key ​

Contact your Falcon Labs account manager to obtain your unique SDK key and placement ID.

Step 2: Add the SDK Script ​

Add the Falcon embedded SDK script to your HTML page:

html
<head>
  <title>Your Website</title>
  <script src="https://d6y5cd3imay52.cloudfront.net/sdk/v1/embedded-sdk.js"></script>
</head>

Staging: Use https://d6y5cd3imay52.cloudfront.net/sdk/staging/embedded-sdk.js and your staging API key while testing. See Staging Environment for the full URL reference across the Web SDKs.

Step 3: Create HTML Container ​

Add a container element where the promotional content will render:

html
<div id="falcon-ads-container" style="width: 580px; height: 260px;"></div>

Recommended dimensions:

  • Desktop: 580px × 260px (minimum)
  • Mobile: 479px × 400px (minimum)

Note: These dimensions are a starting size to reserve space before the offer loads, not a size the offer will stretch to fill. The offer's height automatically adjusts to match its own content. See Container Sizing in Best Practices to avoid empty space below the offer.

Step 4: Initialize with Single API Call ​

Use FalconAds.init() method to initialize and display perks in one call:

javascript
FalconAds.init({
  apiKey: "YOUR_API_KEY",
  containerId: "falcon-ads-container",
  placementId: "YOUR_PLACEMENT_ID",
});

That's it! The SDK will automatically:

  • Initialize with your API key
  • Find the container element
  • Load available perks
  • Display them if available

Complete Integration Example ​

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Falcon Ads - Embedded Integration</title>
    <script src="https://d6y5cd3imay52.cloudfront.net/sdk/v1/embedded-sdk.js"></script>
    <style>
      .perks-container {
        border: 1px solid #e0e0e0;
        border-radius: 8px;
        padding: 2px;
        margin: 20px auto;
        height: 260px;
        width: 580px;
        background: #f9f9f9;
      }

      @media (max-width: 768px) {
        .perks-container {
          width: 100%;
          max-width: 479px;
          height: 400px;
        }
      }
    </style>
  </head>
  <body>
    <h1>Order Confirmation</h1>
    <p>
      Thank you for your order! Here are some exclusive offers just for you:
    </p>

    <!-- Promotional content container -->
    <div id="falcon-ads-container" class="perks-container"></div>

    <p>Continue shopping or explore more products below...</p>

    <script>
      // Initialize Falcon Ads with a single call
      FalconAds.init({
        apiKey: "YOUR_API_KEY",
        containerId: "falcon-ads-container",
        placementId: "YOUR_PLACEMENT_ID",
      });
    </script>
  </body>
</html>

API Reference ​

FalconAds.init(config: FalconAdsConfig): Promise<void> ​

Initializes and displays embedded promotional content with a single method call.

Parameters:

javascript
FalconAds.init({
  apiKey: "YOUR_API_KEY", // Required: Your Falcon API key
  containerId: "falcon-ads-container", // Required: ID of container element
  placementId: "YOUR_PLACEMENT_ID", // Required: Your placement ID
});

What it does:

  1. Initializes the Falcon SDK with your API key
  2. Finds the container element by ID
  3. Loads available promotional offers
  4. Automatically displays offers if available
  5. Handles errors gracefully (won't break your page)

Error Handling:

The SDK handles errors internally and logs them to console:

  • [FalconAds] Container not found: "{id}" - Container element doesn't exist
  • [FalconAds] Authentication failed - Invalid API key or placement ID
  • [FalconAds] Connection failed - Network connectivity issues
  • [FalconAds] Init failed - General initialization error

Important Notes:

  • Container must exist in the DOM before calling init()
  • If no offers are available, the container remains empty (no error)
  • The method returns a Promise<void> but is fire-and-forget — all errors are handled internally, so await is not required
  • Multiple calls with different placements will work, but avoid duplicate placement IDs

Need to reload the unit on the same page? init() creates the ad unit internally and hands nothing back, so there is no way to tear it down and start over. If your page can be opened more than once in a single session (a single-page app route, a drawer, a tab), use Embedded SDK Manual Control instead. It exposes the instance along with show(), hide(), and destroy().

Configuration ​

FalconAdsConfig ​

The configuration object passed to FalconAds.init():

typescript
interface FalconAdsConfig {
  apiKey: string; // Your Falcon API key (required)
  containerId: string; // HTML element ID for the container (required)
  placementId: string; // Your placement ID from Falcon (required)
  attributes?: object; // Order/customer data (optional)
}

Example:

javascript
FalconAds.init({
  apiKey: "abc123xyz",
  containerId: "falcon-ads-container",
  placementId: "placement_xyz789",
});

TypeScript ​

Types for the SDK (add once, e.g. in falcon-ads.d.ts):

typescript
// Any JSON value. Objects and arrays are serialized by the SDK before sending.
type JsonValue =
  | string
  | number
  | boolean
  | null
  | JsonValue[]
  | { [key: string]: JsonValue };

declare const FalconAds: {
  init(config: FalconAdsConfig): Promise<void>;
};

interface FalconAdsConfig {
  /** Your Falcon API key */
  apiKey: string;
  /** HTML element ID of the container where ads will render */
  containerId: string;
  /** Your placement ID from Falcon */
  placementId: string;
  /** Optional order/customer data for offer targeting */
  attributes?: FalconAdsAttributes;
}

interface FalconAdsAttributes {
  /** Unique order identifier (no special characters: #, @, ., spaces) */
  orderId?: string;
  /** Customer email, hashed (SHA-256, lowercase) on your end. Pass this or `email`, not both */
  hashedEmail?: string;
  /** Customer email address, plain text. The SDK hashes it in the browser before sending. Pass this or `hashedEmail`, not both */
  email?: string;
  /** Order or product category */
  category?: string;
  /** Order or product subcategory */
  subcategory?: string;
  /** Colour scheme of your page. "dark" renders the widget's dark palette */
  theme?: "dark" | "light";
  /** Background for the dark palette, hex only. Too light a colour is ignored */
  darkBgColor?: string;
  /** Order total as a string (e.g. "99.99") */
  amount?: string;
  /** Customer first name */
  firstname?: string;
  /** Customer last name */
  lastname?: string;
  /** ISO 4217 currency code (e.g. "USD", "EUR") */
  currency?: string;
  /** ISO 3166-1 alpha-2 country code (e.g. "US", "GB") */
  country?: string;
  /** ISO 639-1 language code (e.g. "en", "fr") */
  language?: string;
  /** Billing ZIP or postal code */
  billingzipcode?: string;
  /** Merchant/seller name — displayed in offer headline */
  confirmationref?: string;
  /** Payment method (e.g. "credit_card", "paypal") */
  paymenttype?: string;
  /** First 6 digits of credit card (BIN) */
  ccbin?: string;
  /** Customer phone, hashed (SHA-256, lowercase) on your end. Pass this or `mobile`, not both */
  hashedPhone?: string;
  /** Customer mobile phone number, plain text. Hashed in the browser the same way as `email` */
  mobile?: string;
  /** Billing address line 1 */
  billingaddress1?: string;
  /** Billing address line 2 */
  billingaddress2?: string;
  /** Customer age */
  age?: string;
  /** Customer gender */
  gender?: string;
  /** Cart or order line items as JSON, an array or object in your own shape */
  lineItems?: JsonValue;
}

Passing Order Attributes ​

You can pass order and customer data via the attributes field. These attributes are used for personalization, analytics, and offer targeting.

javascript
FalconAds.init({
  apiKey: "YOUR_API_KEY",
  containerId: "falcon-ads-container",
  placementId: "YOUR_PLACEMENT_ID",
  attributes: {
    orderId: "ORD-123456",
    hashedEmail: "SHA256_HEX_OF_EMAIL_LOWERCASE",
    category: "Electronics",
    subcategory: "Headphones",
    amount: "99.99",
    currency: "USD",
    firstname: "John",
    lastname: "Doe",
    country: "US",
    language: "en",
    billingzipcode: "10001",
  },
});

Attribute Reference ​

Pass user and order data via attributes for revenue attribution, offer targeting, personalization, and rendering hints. All values are strings, except lineItems, which is JSON.

Keys are case-sensitive. Spell each one exactly as the table shows. Most are lowercase, but orderId, lineItems, hashedEmail and hashedPhone are camelCase. A key with the wrong casing is ignored rather than corrected, so orderid or order_id silently sends nothing. The SDK logs a console warning naming the correct spelling when it recognises the mistake.

AttributePriorityDescriptionFormat
orderIdRequiredUnique order/transaction identifier. Links the offer impression back to a specific purchase for revenue attributionString, no special characters (#, @, ., spaces)
hashedEmailRequired*Customer email, hashed on your end before it's passed inSHA-256 hex, lowercase, 64 characters
emailRequired*Customer email, plain text. The SDK hashes it in the browser (same SHA-256 algorithm) before anything is sent — nothing leaves the page in the clearValid email string
categoryOptionalOrder or product categoryString
subcategoryOptionalOrder or product subcategoryString
amountRecommendedOrder totalNumeric string (e.g. "99.99")
currencyOptionalCurrency codeISO 4217 (e.g. "USD", "EUR")
countryOptionalCustomer countryISO 3166-1 alpha-2 (e.g. "US", "GB")
languageOptionalCustomer languageISO 639-1 (e.g. "en", "fr")
firstnameRecommendedCustomer first nameString
lastnameRecommendedCustomer last nameString
hashedPhoneOptionalCustomer phone, hashed on your end before it's passed inSHA-256 hex, lowercase, 64 characters
mobileOptionalCustomer phone, plain text. Hashed in the browser the same way as emailString
ageOptionalCustomer ageNumeric string
genderOptionalCustomer genderString
billingzipcodeOptionalBilling ZIP or postal codeString
billingaddress1OptionalBilling address line 1String
billingaddress2OptionalBilling address line 2String
lineItemsOptionalContents of the shopper's cart or order, one entry per line item, in your own shape (for example sku, title, quantity, price). Used for product-aware offer targeting and rankingJSON array or object. Pass the value itself, the SDK serialises it; a pre-serialised JSON string is accepted too
paymenttypeOptionalPayment method (e.g. "credit_card", "paypal")String
ccbinOptionalFirst 6 digits of the credit card number (BIN)String
confirmationrefOptionalMerchant/seller name, or your own internal confirmation reference if separate from orderId. Displayed in the offer headline on some templatesString
themeOptionalColour scheme of the page the widget sits on. Pass "dark" when your page uses a dark background so the widget renders its dark palette. Any other value, or omitting it, renders the default light widget"dark" or "light"
darkBgColorOptionalBackground colour for the widget's dark palette, so the card matches your page. Hex only, three or six digits, with or without the leading hash. Ignored with theme: "light", and ignored when the colour is too light for the widget's white text, in which case the default dark background is used"#1B2A4A" or "1b2a4a"

* Pass either hashedEmail or email, not both. If both are present, hashedEmail takes priority. Without one of them (or orderId), the SDK still loads and displays offers, but there's nothing to match the impression back to the order, so attribution won't work — this isn't enforced as a hard error, so it's easy to miss during testing.

Hashed fields: hashedEmail and hashedPhone use trim → lowercase → SHA-256. Uppercase hex or un-trimmed input will not validate and gets silently dropped rather than erroring, so double check the format before sending.

Not attributes: IP address and User-Agent are read automatically from the browser request. State and city are resolved server-side from the visitor's IP, there's no attribute for either. country above is only needed if you want to override what's detected (for example, billing country differs from shipping country).

Error Handling ​

The FalconAds.init() method handles errors internally and will not break your page. Errors are logged to the browser console for debugging.

No try-catch needed - the SDK fails gracefully:

javascript
// This is safe - won't throw errors or break your page
FalconAds.init({
  apiKey: "YOUR_API_KEY",
  containerId: "falcon-ads-container",
  placementId: "YOUR_PLACEMENT_ID",
});

Error messages in console:

text
[FalconAds] Container not found: "falcon-ads-container"
→ The container element with this ID doesn't exist in the DOM

[FalconAds] Authentication failed: Invalid API key or placement ID
→ Check your credentials with Falcon Labs

[FalconAds] Connection failed: Unable to establish connection
→ Network connectivity issue or server unavailable

[FalconAds] Init failed: [error details]
→ General initialization error (check console for details)

Best Practices ​

Container Sizing ​

The SDK automatically adjusts the offer's height to match its own content. It does not stretch to fill whatever height you give the container. Treat the dimensions below as a minimum starting size to reserve space before the offer loads, not a fixed size the offer will grow or shrink to fill. If the container is taller than the offer needs, the extra space stays empty underneath it.

css
/* Desktop */
#falcon-ads-container {
  width: 580px;
  height: 260px;
}

/* Mobile */
@media (max-width: 768px) {
  #falcon-ads-container {
    width: 100%;
    max-width: 479px;
    height: 400px;
  }
}

Recommended minimum sizes:

  • Desktop: 580px × 260px
  • Mobile: 479px × 400px

To avoid empty space below the offer: use min-height instead of a fixed height so the container can shrink to whatever size the offer actually renders at:

css
#falcon-ads-container {
  width: 580px;
  min-height: 260px;
}

Width behaves differently from height: the offer fills 100% of the container's width, so a fixed width is safe to use.

Container Must Exist Before Initialization ​

Ensure the container element is in the DOM before calling FalconAds.init():

html
<!-- ✅ Good: Container exists before script -->
<div id="falcon-ads-container"></div>
<script src="https://d6y5cd3imay52.cloudfront.net/sdk/v1/embedded-sdk.js"></script>
<script>
  FalconAds.init({
    apiKey: "YOUR_API_KEY",
    containerId: "falcon-ads-container",
    placementId: "YOUR_PLACEMENT_ID",
  });
</script>

<!-- ❌ Bad: Script runs before container exists -->
<script>
  FalconAds.init({
    /* ... */
  });
</script>
<div id="falcon-ads-container"></div>

Place Script Near Closing </body> Tag ​

For best performance, place the SDK script and initialization at the bottom of your page:

html
<body>
  <!-- Your page content -->
  <div id="falcon-ads-container"></div>

  <!-- SDK at the end -->
  <script src="https://d6y5cd3imay52.cloudfront.net/sdk/v1/embedded-sdk.js"></script>
  <script>
    FalconAds.init({
      /* ... */
    });
  </script>
</body>

Use Unique Container IDs ​

Each placement should have its own unique container:

html
<!-- ✅ Good: Unique IDs -->
<div id="falcon-checkout-offers"></div>
<div id="falcon-thankyou-offers"></div>

<script>
  FalconAds.init({
    apiKey: "YOUR_API_KEY",
    containerId: "falcon-checkout-offers",
    placementId: "PLACEMENT_1",
  });

  FalconAds.init({
    apiKey: "YOUR_API_KEY",
    containerId: "falcon-thankyou-offers",
    placementId: "PLACEMENT_2",
  });
</script>

Troubleshooting ​

Perks don't display ​

Check the following:

  1. Container element exists:

    javascript
    // Open browser console and run:
    document.getElementById("falcon-ads-container");
    // Should return the HTML element, not null
  2. Container has dimensions:

    javascript
    // Check container size:
    const container = document.getElementById("falcon-ads-container");
    console.log(container.offsetWidth, container.offsetHeight);
    // Should be greater than 0
  3. Check console for errors:

    Open your browser's developer console (F12) and look for messages starting with [FalconAds]

  4. Verify SDK script loaded:

    javascript
    // In browser console:
    typeof FalconAds;
    // Should return "object", not "undefined"

Common Issues and Solutions ​

"Placement already in use" error ​

Problem: [FalconAds] Init failed: Error: Placement "YOUR_PLACEMENT_ID" already in use

The unit renders the first time, then fails when the page is opened again.

Solution:

  • One placement ID can have one live ad unit at a time
  • FalconAds.init() creates that unit internally and gives you no way to remove it
  • Switch to Embedded SDK Manual Control, which hands you the instance and a destroy() method to call before rendering again

"Container not found" error ​

Problem: [FalconAds] Container not found: "falcon-ads-container"

Solution:

  • Verify the container ID matches exactly (case-sensitive)
  • Ensure container exists before calling FalconAds.init()
  • Check for typos in the ID
html
<!-- Make sure these match -->
<div id="falcon-ads-container"></div>
<script>
  FalconAds.init({
    containerId: "falcon-ads-container", // Must match exactly
  });
</script>

"Authentication failed" error ​

Problem: [FalconAds] Authentication failed: Invalid API key or placement ID

Solution:

  • Verify your API key with Falcon Labs
  • Confirm placement ID is correct
  • Check for extra spaces or typos in credentials

SDK script doesn't load ​

Problem: Uncaught ReferenceError: FalconAds is not defined

Solution:

  • Verify the script URL is correct
  • Check browser network tab for 404 or network errors
  • Ensure script loads before calling FalconAds.init()
html
<!-- ✅ Correct order -->
<script src="https://d6y5cd3imay52.cloudfront.net/sdk/v1/embedded-sdk.js"></script>
<script>
  FalconAds.init({
    /* ... */
  });
</script>

Empty space below the offer ​

Problem: The container has blank space underneath the rendered offer.

Cause: The offer's height is sized to its own content, not to the container. If the container has a fixed height set higher than what the offer needs (for example, higher than the recommended minimum), the leftover space is that gap.

Solution: Use min-height instead of a fixed height on the container so it can shrink to match the offer's rendered size. See Container Sizing.

No offers display (no error) ​

This is normal behavior - it means:

  • The SDK initialized successfully
  • No promotional offers are available for this user/placement at this time
  • The container remains empty (not an error)

What to do:

  • Verify with Falcon Labs that offers are configured for your placement
  • Check if offers have geographic or other targeting restrictions
  • Test with different user scenarios

Integration Checklist ​

Before going live, verify:

  • [ ] Embedded SDK script tag added to HTML (embedded-sdk.js)
  • [ ] Container element exists with unique ID
  • [ ] Container has explicit width and height dimensions
  • [ ] FalconAds.init() called with correct API key
  • [ ] Placement ID is correct
  • [ ] Container exists in DOM before calling FalconAds.init()
  • [ ] No console errors in browser developer tools
  • [ ] Container displays correctly on desktop (580px × 260px minimum)
  • [ ] Container displays correctly on mobile (479px × 400px minimum)
  • [ ] Tested on major browsers (Chrome, Firefox, Safari, Edge)
  • [ ] Page loads without errors when no offers are available

Additional Features ​

Need more control over the integration? Two advanced options are documented:

  • Embedded SDK Callbacks — hook show, view, click, close, and ready events into your own analytics, without leaving FalconAds.init()
  • Embedded SDK Manual Control — hold the ad-unit instance yourself for show(), hide(), and destroy(), which is what a page the visitor can reopen needs

For anything not covered there, contact your Falcon Labs account manager.

Support ​

For technical support or questions about the embedded SDK integration:

  • Contact: Your Falcon Labs account manager
  • Documentation: This guide

Need your API key or placement ID? Contact your Falcon Labs account manager.