The best mailing-list tool — for your web-to-print application. Period.
DataWidget® is a patented, embeddable mailing-list builder that drops into your postcard / EDDM / direct-mail platform. Real-time counts, list previewing, demographic filters, AI chat assistant, interactive map — all inside your platform, white-labelled with your brand. Hundreds of millions of verified U.S. Consumer + Business records, USPS CASS-certified, with the new Intent Data overlay built right in. Plug-and-play install, instant retail-vs-wholesale margin on every list sale, used by printers, franchises, dealers, mortgage brokers, insurance agents, home-services, and restaurants.
The patented three-panel UI
DataWidget® is not just a list count widget. The patent (U.S. 12,482,026) covers the integrated three-panel architecture that makes list-building actually finishable inside a host site — chat assistant + interactive map + demographic controls, all wired together in real time.
AI Chat Assistant (left, 340px)
Customers describe their audience in plain English ("homeowners earning $100K+ in Phoenix"). The AI parses intent, sets the geography, picks the right list type, and toggles the demographic filters — no learning curve.
Interactive Leaflet Map (center, flex)
Radius circles, city/county/ZIP polygons via TIGER boundary data, free-form polygon drawing. Customers see exactly which households are inside their target.
Demographic Controls (right, 400px)
Database tabs (Consumer / Business / New Movers / New Homeowners), location search, filter sliders (income, age, home value), live count hero, quantity selector, Add-to-Cart that posts back to your platform.
Five steps to live in your platform
Sign up
Apply for an affiliate code on the Get Started tab. We provision your XML config in 1 business day.
Brand the XML
Logo, brand colours, demographic visibility, pricing tiers, minimum quantities — all in one XML file you control.
Embed
Drop the iframe / script snippet into your audience-selection page. Compact or full version — your choice.
Receive fulfilment
On checkout success, we deliver the CSV via signed URL or webhook into your existing print-fulfilment workflow.
Why W2P platforms add this
The unsolved problem in web-to-print: customers design a postcard, then bounce to a third-party list broker to buy the audience, then bounce back to upload the CSV — if they come back at all. Industry conversion at the audience step runs 30–50% drop-off for platforms that don't solve this. DataWidget® closes the loop entirely inside your platform; we've seen post-integration conversion lift of 40–120% across deployed affiliates.
“We were looking for a high-quality solution that was easy to implement. We found it.”
DataWidget® is powered by hundreds of millions of verified U.S. Consumer and Business records. New Homeowner and New Mover feeds refresh weekly; the Intent Data overlay refreshes daily. All records ship USPS CASS-certified for direct-mail deliverability.
Try DataWidget® right now
Below is the same widget your customers will use, embedded as you'd embed it — live, against the LeadsPlease® production data. Build a mailing list: type a query in the chat, draw a polygon on the map, or set a radius. Watch the count update in real time.
The full embed snippet — pop into your platform's audience step
Two-line install. Replace YOUR_AFFILIATE_CODE with the code we issue you. Pass callbackurl=... if you want fulfilment via webhook instead of PostMessage.
<!-- Full version with chat + map + controls --> <iframe src="https://widget.datawidget.com/widget?affiliatecode=YOUR_AFFILIATE_CODE" width="100%" height="720" frameborder="0" allow="geolocation; clipboard-write"></iframe> <!-- Compact version (no chat, sidebar widens to 700px) --> <iframe src="https://widget.datawidget.com/compact?affiliatecode=YOUR_AFFILIATE_CODE" width="100%" height="620" frameborder="0"></iframe> <!-- Listen for the audience-selected payload from your customer --> <script> window.addEventListener('message', function(e) { if (e.data && e.data.type === 'datawidget:add-to-cart') { // e.data contains: { criteriaId, count, price, audienceDescription } yourCheckout.attachAudience(e.data); } }); </script>
URL parameters — tune the display per page
# All optional — default values shown ?affiliatecode=YOUR_CODE # required — provisioned per platform &skin=#FF6633 # override accent colour &hideprices=true # suppress price display (if you mark up) &logourl=https://your.cdn/logo.png # logo override per page &conclusionurl=https://yourapp/api/dw-success # server-side webhook (XML POST) &datasetkey=customerABC123 # multi-customer pricing config &db=consumer # pre-select database tab &location=Phoenix,AZ # pre-fill geography &nochat=true # force compact mode
2. Conclusion webhook — what we POST to your conclusionurl
When the user hits "Buy List" inside the widget, we save the list criteria server-side and notify your Host Server via an HTTP POST. You don't have to charge anything yet — this is just the audience handoff. The XML payload your endpoint receives:
<!-- POST https://yourapp/api/dw-success --> <!-- Content-Type: application/xml --> <widget_conclusion> <list_criteria_id>123</list_criteria_id> <list_type>consumer</list_type> <qty>500</qty> <price_retail>50.00</price_retail> <price_wholesale>40.00</price_wholesale> <session_id>123456789</session_id> </widget_conclusion>
Same payload also fires as a JS callback in the host page (if you set the callback param) so you can update your shopping cart UI without a round-trip:
function myCallback(payload) { // payload = { criteriaid, listtype, price, qtycount, qtydesired, sessionid } yourCart.attachAudience({ audienceId: payload.criteriaid, type: payload.listtype, quantity: payload.qtydesired, chargeUSD: payload.price }); }
3. Fulfillment — get_list polling once your customer pays
When your checkout completes (customer charged on your platform), call our server-side fulfillment endpoint with the criteria_id from step 2. Bearer-style auth via u + p query params. We bill the wholesale price to your pre-registered card; you keep the retail-vs-wholesale margin.
# First request — usually returns PENDING curl -X POST "https://api.leadsplease.com/affiliatecode/get_list?u=usr123&p=pwd123&list_criteria_id=123&order_ref=YOUR-INVOICE-456" # Response (XML): <get_list> <list_criteria_id>123</list_criteria_id> <status_code>PENDING</status_code> </get_list> # Poll the SAME URL no more than every 30s until status=READY: <get_list> <list_criteria_id>123</list_criteria_id> <status_code>READY</status_code> <list_download_url>https://api.leadsplease.com/affiliatecode/download?...&filename=...csv</list_download_url> </get_list>
Then GET the list_download_url for the CSV — Excel-compatible, ready to ship to your print partner. Files stay live for 14 days. Add &test=true to the request for free, anonymized test data while you're integrating; no credit-card charge during testing.
4. Skinning — brand the widget per affiliate or per page
The widget is white-labelled per affiliate via the XML config we provision for you, and additionally tunable per page via the skin object on the JS constructor:
var w = new LeadsPlease.Widget({ widgetid: 'wid', affiliatecode: 'YOUR_CODE', conclusionurl: 'https://yourapp/api/dw-success', sessionid: userSessionId, skin: { buylistbtn: 'Add to Cart', // custom CTA text hideprices: true, // suppress price display (you mark up) }, datasetkey: 'customer-456' // pick a per-customer pricing config });
Multiple price sets per affiliate — pass a different datasetkey to load a different pricing/demographic config without changing affiliatecode. Useful when you're a 3rd-party integrator running the widget for many of your own clients (print platforms, franchise marketing tools).
5. Reference site — thedatawidget.com
The legacy reference site at www.thedatawidget.com has hosted the widget demo since 2018 and is still the public face of the integration. It carries the same backend you're integrating against, plus testimonials and printer case studies. The try-it page there is the canonical "this is what your customers will see" sandbox.
DataWidget® Integration Guide
A complete reference for developers integrating the DataWidget® into a web-to-print application. Embed snippet, widget lifecycle, conclusion webhook, server-side fulfillment, list download, skinning, multi-tenant pricing, and the test environment. Read this once, then keep it open while you build.
- What you need to get started
- Widget lifecycle — init, skinning, datasetkey, conclusion
- List fulfillment — create, poll, download, charge
- Testing — the
test=truesandbox - Database updates & criteria expiry
- Versioning
- 3rd-party integrators — configurable fields per client
- Browser compatibility & Terms of Service
1. What you need to get started
This guide is for a developer comfortable with JavaScript, HTML, and a server-side runtime (Node, Java EE, .NET, Ruby, Python — anything that can make HTTPS requests and parse XML). Before you start integrating, we'll provision the following for you:
affiliatecode— the unique code that identifies your company or clientusername— specific to the affiliate code; used for server-side fulfillmentpassword— specific to the affiliate code; used for server-side fulfillment
Your username + password let any caller create real mailing-list files and charge them to your account. Never commit them, never log them, never expose them in client-side code. They live exclusively on your Host Server.
You'll also need a Host Server — your application's backend. The Host Server is responsible for:
- Receiving the Widget Conclusion notification (HTTP POST from us when a customer hits "Buy List")
- Sending List Fulfillment requests to the Widget Server (the LP backend)
- Downloading the resulting CSV file from the Widget Server
No need to pre-register the Host Server with us — your conclusionurl is set per request at widget initialisation, and outbound fulfillment calls auth via your username + password.
Glossary
| Widget | The DataWidget® JavaScript loaded into your host page from the Widget Server. |
| Widget Server | The LeadsPlease® server hosting the widget JS, the count engine, and the list-fulfillment databases. |
| Host Server | Your application's backend. Listens for Conclusion POSTs and drives Fulfillment. |
| Host Webpage | The page in your application that embeds the widget. |
2. Widget lifecycle
2.1 Initialisation
Drop two script tags into your audience-selection page and a target <div> for the widget to render into:
<script src="https://widget.datawidget.com/lp_widget_1.5.js"></script> <script> var w = new LeadsPlease.Widget({ widgetid: 'wid', affiliatecode: 'YOUR_CODE', conclusionurl: 'https://yourapp.com/api/dw-conclusion', sessionid: 'host-session-12345' }); </script> <div id="wid"></div> <a href="http://www.leadsplease.com" target="_new">Mailing Lists by LeadsPlease</a>
The trailing link to www.leadsplease.com must appear OUTSIDE the widget container, with the exact text "Mailing Lists by LeadsPlease". The widget styles it discreetly to blend in.
2.2 Constructor parameters
| Parameter | Description | Required | Example |
|---|---|---|---|
widgetid | HTML DOM element ID where the widget mounts. | Yes | 'wid' |
affiliatecode | Unique code identifying your company or client. Determines pricing, branding, security. | Yes | 'banner' |
conclusionurl | URL on your Host Server that we POST list criteria to when the customer hits "Buy List". | Yes | 'https://app/api/dw' |
sessionid | Your Host Server session ID. Echoed back at conclusion so you know which user just bought. | Yes | 'sess-xyz-789' |
callback | JS function called in the host page at "Buy List" time, with the same payload as the conclusion POST. | No | function(d){...} |
onload | JS function called once the widget has finished loading. | No | function(){...} |
skin | JS object with skinning properties (see 2.4). | No | { buylistbtn: 'Add to Cart' } |
datasetkey | Pricing/demographics config selector (see 2.5). | No | 'customer-456' |
2.3 Widget size & appearance
The widget renders as a rectangle approximately 900 × 570 pixels by default. The new three-panel widget (used on this microsite) is responsive and will adapt up to your container width — see the Try It tab for the live look.
2.4 Skinning
Pass a skin object to tune the widget per page (per-affiliate XML controls global branding; skin is for per-page overrides):
| Property | Description | Example |
|---|---|---|
buylistbtn | Custom text on the "Buy List" button. | buylistbtn: 'Add to Cart' |
hideprices | Suppress all price display on the widget (useful when you mark up). | hideprices: true |
2.5 Multiple price sets & demographics — the datasetkey
By default each affiliatecode has a single pricing/demographics configuration. But sometimes you want different configs under one code — for example, a web-to-print platform integrating the widget for many of its own clients, where each client has different retail pricing or different demographic visibility. We pre-configure each as a named datasetkey; you pass the right one at constructor time. If you omit it on a multi-config affiliate the first config is used as the default.
2.6 Widget interaction
Once initialised the customer interacts with the widget UI — tabs (Consumer / Business / New Mover / New Homeowner), location search, demographic filters, count display, polygon drawing, etc. The new three-panel widget adds an AI chat assistant on the left so customers can describe their audience in plain English ("homeowners earning $100K+ in Phoenix"). All of this is self-contained inside the widget DOM — you don't need to wire up any of the interactions yourself.
2.7 Widget conclusion — what fires when "Buy List" is clicked
Two things happen simultaneously:
- The widget POSTs an XML payload to your
conclusionurlfrom the Widget Server. - If you supplied a JS
callback, it fires in the host page with the same data as a JS object.
XML payload to conclusionurl
POST https://yourapp.com/api/dw-conclusion Content-Type: application/xml <widget_conclusion> <list_criteria_id>123</list_criteria_id> <list_type>consumer</list_type> <qty>500</qty> <price_retail>50.00</price_retail> <price_wholesale>40.00</price_wholesale> <session_id>123456789</session_id> </widget_conclusion>
JS callback payload
function myCallback(payload) { // payload object: // criteriaid: '123' // listtype: 'consumer' // price: 50.00 // retail price shown to user // qtycount: 1247 // total available records // qtydesired: 500 // how many user wants // sessionid: '123456789' // your host session yourCart.attachAudience(payload); }
| Field | Description | Example |
|---|---|---|
list_criteria_id | Unique ID for the criteria the customer built. Save this — you need it for fulfillment. | 123 |
list_type | One of: consumer, business, newhomeowner, newmover. | consumer |
qty | Number of records the user requested. | 500 |
price_retail | Total price in USD shown to the customer (you charge this). | 50.00 |
price_wholesale | Total price you owe LeadsPlease® (retail − 20%). | 40.00 |
session_id | Whatever sessionid you passed at constructor time. | 123456789 |
3. List fulfillment
The conclusion event is just the audience handoff — no list file exists yet. When you're ready to actually place an order (typically right after your own checkout completes), call our server-side get_list endpoint with the list_criteria_id you saved at conclusion.
3.1 List creation request
POST https://api.leadsplease.com/YOUR_AFFILIATECODE/get_list?u=usr123&p=pwd123&list_criteria_id=123&order_ref=YOUR-INVOICE-456
| Param | Description | Required |
|---|---|---|
u | Your affiliate username | Yes |
p | Your affiliate password | Yes |
list_criteria_id | The ID returned at Widget Conclusion | Yes |
order_ref | Your internal order/invoice reference. Echoed in our reporting. | No |
test | Pass test=true for the sandbox (no charge, anonymized data). | No |
3.2 Response shapes
Three possible outcomes — Pending (typical first response), Ready (file generated, download URL inside), or Error. The first call usually returns Pending; you poll the same URL no more than every 30 seconds until you see Ready.
Pending — keep polling
<get_list> <list_criteria_id>123</list_criteria_id> <status_code>PENDING</status_code> </get_list>
Ready — download the file
<get_list> <list_criteria_id>123</list_criteria_id> <status_code>READY</status_code> <list_download_url>https://api.leadsplease.com/.../uploaded_12345.csv</list_download_url> </get_list>
Error
<get_list> <list_criteria_id>123</list_criteria_id> <status_code>ERROR</status_code> <message>List criteria has expired. You must rerun the Count.</message> </get_list>
Common error messages: "List criteria has expired", "Invalid list criteria ID", "Permission denied", "Payment failure", "Too many queries".
No more than once every 30 seconds per criteria_id. We rate-limit aggressive pollers; sustained violations can lead to "Too many queries" errors. Most lists complete inside 30–90 seconds end-to-end.
3.3 Downloading the CSV
Once you have a Ready response, GET the list_download_url. The file is a standard Excel-compatible CSV and stays available for 14 days from creation. After 14 days you'll need to re-create the list (which will re-charge if non-test).
3.4 File format — sample CSVs
Each list type has its own column set. Reference samples:
- Consumer database sample
- Business database sample
- New Mover database sample
- New Homeowner database sample
3.5 Charging
List creation triggers an actual mailing-list file being generated and made available for download. The wholesale price (retail − 20%) is charged to your pre-registered card at the moment of fulfillment. You charge the customer the retail price on your own platform; the difference is your margin. No reconciliation, no invoice cycle, no per-customer billing decisions — the widget enforces it.
4. Testing — the test=true sandbox
While integrating, append &test=true to your fulfillment URL to use our test service:
POST https://api.leadsplease.com/YOUR_CODE/get_list?u=usr123&p=pwd123&list_criteria_id=123&order_ref=test-001&test=true
Test-mode features:
- List file generated and available via
list_download_urlexactly as in production - No charge for list creation
- No requirement for a pre-registered credit card
- Anonymized list contents (PII fields masked) so test data can never be misused as real leads
- Pass an invalid
list_criteria_idto trigger the error response shape for negative-path testing - Can be exercised in a browser tab — no special tooling needed
5. Database updates & criteria expiry
We refresh the underlying mailing-list databases regularly. If a database is updated between widget conclusion and list fulfillment, one of two things can happen:
- The list fulfills successfully but the records may differ slightly from the preview (typically by <5%)
- The Widget Server rejects the request with
"List criteria has expired. You must rerun the Count."
If you see the expired-criteria error, send the customer back through the widget — their selections (location, demographics, qty) are not preserved across the criteria rebuild today, but recovering is fast.
6. Versioning
Current stable widget version: v1.5 — loaded from https://widget.datawidget.com/lp_widget_1.5.js. The version number is embedded in the file path so bug fixes apply immediately to all integrations without a code change on your end. Breaking API changes ship under a new file path (lp_widget_1.6.js etc.) so existing integrations keep running unchanged until you opt in.
7. 3rd-party integrators — configurable fields per client
If you're a platform integrating the widget for many of your own clients (web-to-print SaaS, multi-location franchise tools, etc.), you'll want to expose certain widget config fields to your clients. The fields most commonly surfaced:
affiliatecodeusername/password(server-side only — never in the browser)- Widget version number
buylistbtnskinning property (custom CTA text per client)- Multiple price sets via
datasetkey
Talk to us when you onboard — we'll provision a parent affiliate code for your platform plus per-client datasetkeys for differentiated pricing.
8. Compliant browsers & Terms of Service
Modern browsers (Chrome 90+, Firefox 80+, Safari 14+, Edge 90+) are fully supported. The new three-panel widget uses modern React + Leaflet; older versions degraded gracefully but the new widget targets evergreen browsers exclusively.
Terms of service
- Test data may be used only for testing your integration. Reselling or mailing to test data is a TOS violation.
- You must sign the LeadsPlease® Mutual Non-Disclosure + Confidentiality Agreement before integration. We email these on first signup.
- Full Terms of Service on leadsplease.com.
Email tech@leadsplease.com · phone (866) 306-8674 · the live reference site at thedatawidget.com has additional case studies and a sandbox.
Six common deployments
The patterns we see most across deployed affiliates. If your platform fits any of these archetypes, DataWidget® is a direct lift.
Postcard / direct-mail design platforms
Your customer designs in your editor; at the audience step they hit DataWidget®; geography + demographic + count returns to your checkout with a price. CSV delivered to your print partner on payment confirmation. We've seen 40–80% conversion lift at the audience step vs sending users to a third-party list broker. Pairs with the Direct-Mail Campaign playbook for cadence + tracking guidance.
Every Door Direct Mail platforms
EDDM is geography-only by USPS rule, so the map panel does most of the work. The compact version (no chat) is ideal here. Customers paint a route on the map; the widget converts to a EDDM-compliant carrier-route count automatically.
Just-sold / farming postcard platforms
Real-estate platforms layer the New Homeowner daily feed (~750K/month) on top of demographic farming. Agents pick a ZIP, see live counts of homeowners 7+ years in residence, and the platform schedules a 90-day cadence drop. See the Real-Estate playbook.
Franchisor marketing-management platforms
Each franchisee logs in, hits DataWidget® scoped to their territory (radius around their address), pulls a list, runs the corporate-approved postcard template. Brand consistency at HQ; geographic precision at the unit. White-label per franchisor. Same data backend as the Data API — if your franchisor app already uses the API, the widget plugs in for the audience-build UX without changing your data layer.
AI agent that builds the audience for the user
Pair the embedded DataWidget® with the LeadsPlease® MCP Server running inside Claude / ChatGPT / Cursor / n8n. The user types "high-income households 7+ years in residence in Phoenix, ~5,000 records"; the agent calls the MCP count_audience + preview_audience tools and configures the widget accordingly. Audience built before the user even opens the map.
Multi-channel campaign platforms
Platforms that orchestrate direct mail alongside email + SMS + display. DataWidget® handles the audience-build step; the platform pipes the resulting CSV into the print queue, the email ESP, and the connected-TV audience. See the Direct-Mail Campaign playbook.
Account-based marketing platforms
B2B ABM platforms layer DataWidget® for the direct-mail channel of multi-touch sequences. SIC + employee count + geography filters carve the target account list; the widget posts back contact + address records for postcard or executive-gift drops.
Frequently asked
How long does the integration take?
How does the customer-facing flow work?
What data is available?
Can I customise the look?
skin, hideprices, logourl) tweak the display per page.Is there a Patent?
What happens if I exceed my plan's quota?
Prices
Two ways to start. Apply for free TEST credentials to evaluate the embed against our test environment, or buy the production setup for a single $1,000 one-time customisation fee. No monthly subscription. No order minimum on widget orders.
$1K one-time setup · + per-record data fee on each customer order. 20% margin on every list, automatic.
The one-time fee covers the embeddable widget setup, white-label affiliate XML configuration (logo, colours, demographic visibility, list-type selection), and any first-pass customisation required for your specific platform. No monthly subscription: after setup you pay LeadsPlease® only for the records actually delivered, and you bill your own customers at the published retail rates.
Records billed at the standard LeadsPlease® per-record data rates shown below — the same per-unit prices the public LeadsPlease.com checkout uses. The website enforces a $125–$300 minimum per order; via the widget there is no minimum.
You earn 20% on every list sold through the widget.
Retail prices = the standard LeadsPlease® rates shown below. Your customers see and pay these on your platform. Trade prices = retail minus 20% — the rate you pay LeadsPlease® for each record. The difference is your margin, on every list, automatically. No reconciliation, no per-customer pricing decisions, no markup engineering — the widget enforces it for you.
Worked examples — your customer's order → your margin
⚡ Two ways to get started
Free TEST credentials
Get an affiliate code wired against the LeadsPlease® TEST environment. Embed and integrate at your own pace. No card required.
- Affiliate code provisioned within 1 business day
- Full + compact widget embed against TEST data
- conclusionurl webhook +
get_listpolling work end-to-end - Capped at 100 test list orders / month
- No live data, no charges — safe to integrate
- Promote to production when you're ready
Production setup
Production-ready embed with full white-label customisation. No monthly fee — you keep 20% margin on every list sold.
- One-time setup + customisation fee
- Custom affiliate XML (logo, colours, pricing tiers, demographics)
- Full LIVE LP environment access
- All 4 list types · Subscriptions API access
- Intent Data overlay (live now via Subscriptions)
- Priority email support · 1 business day
- 99.9% uptime SLA
- Trade prices = retail − 20% · no order minimum
High-volume platform (1,000+ orders/month)? OEM, white-label resale, or custom data scope? Contact sales for a custom Enterprise arrangement — setup fee waived for qualified volume commitments and trade prices negotiable below standard.
Get started
Two paths. Most platforms start with free TEST credentials, build their integration, and graduate to LIVE when their first customer is ready to buy a real list. Pick the one that matches where you are right now — you can come back for the other anytime.
Spec, status, support
📘 Embed snippet templates — Try It tab
📊 Data API spec — embedded Swagger UI
📄 U.S. Patent 12,482,026 — the patented three-panel architecture; embedding via our official channel grants you a license
✉️ Tech support — tech@leadsplease.com · phone (866) 306-8674