Appearance
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.jsand your staging API key while testing. See Staging Environment for the full URL reference across all three 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:
- Initializes the Falcon SDK with your API key
- Finds the container element by ID
- Loads available promotional offers
- Automatically displays offers if available
- 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, soawaitis not required - Multiple calls with different placements will work, but avoid duplicate placement IDs
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
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;
/** 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 items as a JSON string */
cartItems?: string;
}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, and personalization. All values are strings.
| Attribute | Priority | Description | Format |
|---|---|---|---|
orderId | Required | Unique order/transaction identifier. Links the offer impression back to a specific purchase for revenue attribution | String, no special characters (#, @, ., spaces) |
hashedEmail | Required* | Customer email, hashed on your end before it's passed in | SHA-256 hex, lowercase, 64 characters |
email | Required* | 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 clear | Valid email string |
category | Optional | Order or product category | String |
subcategory | Optional | Order or product subcategory | String |
amount | Recommended | Order total | Numeric string (e.g. "99.99") |
currency | Optional | Currency code | ISO 4217 (e.g. "USD", "EUR") |
country | Optional | Customer country | ISO 3166-1 alpha-2 (e.g. "US", "GB") |
language | Optional | Customer language | ISO 639-1 (e.g. "en", "fr") |
firstname | Recommended | Customer first name | String |
lastname | Recommended | Customer last name | String |
hashedPhone | Optional | Customer phone, hashed on your end before it's passed in | SHA-256 hex, lowercase, 64 characters |
mobile | Optional | Customer phone, plain text. Hashed in the browser the same way as email | String |
age | Optional | Customer age | Numeric string |
gender | Optional | Customer gender | String |
billingzipcode | Optional | Billing ZIP or postal code | String |
billingaddress1 | Optional | Billing address line 1 | String |
billingaddress2 | Optional | Billing address line 2 | String |
cartItems | Optional | Cart contents | JSON string |
paymenttype | Optional | Payment method (e.g. "credit_card", "paypal") | String |
ccbin | Optional | First 6 digits of the credit card number (BIN) | String |
confirmationref | Optional | Merchant/seller name, or your own internal confirmation reference if separate from orderId. Displayed in the offer headline on some templates | String |
* 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
1. 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.
2. 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>3. 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>4. 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:
Container element exists:
javascript// Open browser console and run: document.getElementById("falcon-ads-container"); // Should return the HTML element, not nullContainer has dimensions:
javascript// Check container size: const container = document.getElementById("falcon-ads-container"); console.log(container.offsetWidth, container.offsetHeight); // Should be greater than 0Check console for errors:
Open your browser's developer console (F12) and look for messages starting with
[FalconAds]Verify SDK script loaded:
javascript// In browser console: typeof FalconAds; // Should return "object", not "undefined"
Common Issues and Solutions
"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? The SDK also supports an advanced API with:
- Custom user attributes for personalization
- Event callbacks (ready, click, close)
- Manual control over loading and display timing
- Programmatic show/hide control
- Support for dynamic content updates
Contact your Falcon Labs account manager to learn about advanced integration options.
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.