List webhooks: receive records from forms and tools
Every list can have its own webhook: a private URL that a form, Zapier, Make, n8n or your own code sends records to. Every record lands in the list, in the matching columns, and the list's own checks show what is wrong with it. If you like, doubtful records wait in the Inbox for your decision first — that is an option per webhook, off by default. It is free on every plan and uses no credits.
A list webhook is for structured records (JSON) that belong in one particular list. Forwarded emails, PDFs and pasted text still go to the Inbox itself — see "Sending into the Inbox from n8n, Zapier, Shortcuts, scripts and email".
Creating the webhook#
A list has at most one webhook. Anyone who can edit the list can create it, in any of three places:
- In the list: click the Set up icon next to the list's name (the two sliders; the ⋯ menu → List Settings... opens the same page) → Webhook → Create webhook.
- On a list without records: under "How do you want to fill this list?", click the Receive from a tool card (Get the webhook URL). It opens Set up on the Webhook section.
- In the Inbox: switch to Entries, then (with no entry selected) click Webhook for a list, choose the list and click Create webhook.
You then see the URL with a Copy button, the status (Active or Paused) and a counter such as "Today 14 / 100". Treat the URL like a password: anyone who has it can send records to this list.
A reference list that refreshes automatically from its source can't have a webhook — it takes its records from the source only ("This list is refreshed from its source and takes no data here.").
What to send#
Send a POST request with JSON: one object per record, or an array of objects for several records at once. The How to set up your tool section of the panel has a tab for each case:
- Fields — a JSON template built from this list's own columns. With these field names every value lands in its column right away.
- curl — the same body as a ready command for a terminal.
- n8n — add an "HTTP Request" node, choose "Import cURL" and paste the command from the curl tab.
- Zapier · Make — Zapier: the "Webhooks by Zapier" action with "POST"; Make: the "HTTP" module with "Make a request". Paste the URL, choose JSON and add the fields from the Fields tab.
- Typeform · Calendly — paste the URL as a webhook in Typeform ("Connect" → "Webhooks"), or point a Calendly webhook for "invitee.created" at it. These tools send their own format; ListPlus reads the answers, and the question's title becomes the field name.
Click Send test to check the setup: it sends the template as a dry run and tells you how many fields would be placed. Nothing is written to the list.
How fields find their columns#
There is no mapping step. The list knows what its columns are (email, first
name, company …), so common field names in English, German, French and
Spanish are placed on their own — email, E-Mail, first_name,
Vorname, company. A field name ListPlus has never seen is looked at by
AI once per webhook, and the answer is remembered, so the same form never
asks twice. A full-name field fills the first-name and last-name columns
when the list has no full-name column.
A field without a matching column is not lost: its value stays with the record. After the first call, the Mapping section lists every field that arrived, with an example value and the column it goes to. There you can pick another column, choose No column, or pick + Create as column to add a column named like the field. A change applies to the records that arrive from then on.
What happens to a record#
By default every record goes into the list. The webhook doesn't judge your leads: the list's own checks in Analyze flag an invalid email, a placeholder or a test entry like in any other list, and an evaluation shows which records are ready, enrichable or unusable (see "What the Analyze panel checks and how the quality score works").
- New records are added. Triggers on the list act on them like on any new record, so webhook → list → trigger → pipeline works.
- Duplicates are merged: a record that matches an existing one by email, LinkedIn URL, phone or name + company fills that record's empty fields instead of adding a second row.
Two things are always held back in the Inbox instead, whatever you set:
- records that match your workspace's Block list ("On the block list");
- records the list can't take: "Plan's record limit reached" (the workspace is over its plan's record limit — see "Record limit"), "List takes no data" or "Could not be written".
Hold back (optional)#
The Hold back section of the panel has two checkboxes, both off at first. What you tick waits in your Inbox for your decision instead of going into the list; a change is saved at once and applies to the records that arrive from then on.
- Hold back invalid, disposable and test addresses — simple rules on the email address: not a valid address, a throwaway provider, or a test domain. No AI involved.
- Hold back spam and test entries (AI check) — records with nothing that says who it is (no name, email, company, phone or LinkedIn), placeholder values, and what an AI check clearly judges to be a test entry, keyboard mashing or spam. When the AI is unsure, the record goes through. This is the only setting that sends record values to an AI — see "What the AI sees of your data".
Leave both off if a trigger or your own checks sort the records anyway; tick them if every record in the list should be worth a look, for example when a public form feeds a list that hands records straight to your CRM.
Deciding held-back records in the Inbox#
Held-back records appear in the Inbox as an entry named after the list, marked "n to review", in the All and To review tabs. A very large batch is spread over several entries of up to 200 records each. Open it to see each record with its Reason — "On the block list" or "Plan's record limit reached", and with a Hold back option on also "Invalid email", "Disposable address", "Test address", "No name, no email", "Placeholder" or "Looks like a test or spam". Then click Add anyway or Discard. The list is already set, so there is nothing to choose. Tick single rows to decide only those; without a tick the buttons act on all open records.
Add anyway puts the records into the list without checking them again; a duplicate is still merged. Like every Inbox entry, an entry with held-back records is deleted 14 days after it arrived, so decide within that time. The Inbox keeps up to 500 live entries; if it is full, held-back records can't be stored and the panel's log says "Inbox full – rows dropped".
Once at least one list has a webhook, the Inbox shows a small tree on the left: Inbox on top, and under Lists every list with a webhook, with the number of records waiting. Click a list there to see its entries and its webhook page (the same panel as under Set up → Webhook, plus Open list). Webhook for a list at the bottom of the tree adds another one.
When the same person comes in again#
A record that matches an existing one only fills that record's empty fields. Under When the same person comes in again in the webhook section you can set what a repeated entry changes beyond that — useful for sources that report every visit or every event:
- Overwrite these columns with the newer value — for example Last seen and Last page.
- Count in this column how often the person came in — a new record starts at 1, every further entry adds 1.
A value that arrives as a moment in time (for example
2026-10-02T09:15:00Z) is stored as its day in a date column.
Triggers that react to matching records run again when such a column changes — for example "Last page contains /pricing".
RB2B: identified website visitors#
RB2B sends a fixed set of fields per visitor. Under How to set up your tool, choose RB2B and click Set up for RB2B: ListPlus shows which columns it will add (it uses the ones the list already has — e-mail, name, company and so on — and adds the rest, including Last seen, Last page, Referrer and Visits), places RB2B's fields and sets the rule for repeated visits. No mapping, no AI question.
Then, in RB2B:
- Open Integrations → Webhook, paste the list's webhook URL and save.
- Switch on Send repeat visitor data if you want Last seen, Last page and Visits kept up to date. Leave Sync company-only profiles off — the list holds people, and a visitor without a person has nothing to be matched by, so every such visit would add a row.
- Click Send a Test Event. The test visitor appears in the list.
RB2B often identifies a visitor by LinkedIn profile without an e-mail address. Such records show as enrichable in the list's checks — enrich only the ones that fit your audience. RB2B does not resend an event that was missed, and on Basic the daily limit is 100 records.
Limits#
| Plan | Records per day | Records per call | Calls per minute |
|---|---|---|---|
| Basic | 100 | 100 | 30 |
| Pro | 5,000 | 500 | 60 |
| Premium | 50,000 | 500 | 120 |
The daily number counts all list webhooks of a workspace together; calls per minute count per webhook. The workspace owner's plan decides. Over a limit the sender gets an error (HTTP 429) instead of the record being dropped silently, so tools like Zapier or n8n can try again; a call that hit the daily limit also shows in the panel as "refused – daily limit reached".
Pause, new URL, delete#
The ⋯ menu next to the counter offers:
- Pause / Resume — a paused webhook refuses calls; nothing is stored while it is paused.
- Create a new URL — the current URL stops working right away; mapping and log are kept. Use it if the URL may have leaked.
- Delete webhook — the URL stops working, mapping and log are deleted. The records in the list stay.
Under Recent calls you see what the latest calls did, for example "3 received · 1 new · 2 held back".
For advanced users#
- Request:
POSTwithContent-Type: application/json. A form post (application/x-www-form-urlencoded) works too. AGETon the URL returns a description: the list's fields, an example body, the limits and the response codes. - Body shapes: an object, an array of objects, or an object that wraps
an array under
rows,records,items,leads,contactsordata. Nested objects are flattened:company.namebecomescompany_name, while a mere wrapper such ascontact.emailbecomesemail. Arrays of question/answer pairs become fields. - Sizes: body up to 1 MB, up to 100 fields per record, up to 2,000 characters per value.
- Responses:
202with{ "success": true, "received": n }— the answer comes at once, and placing, checking and writing happen right after it.400no JSON object or array of objects,401invalid or replaced URL,409webhook paused or the list takes no data,413too many records in one call or body too large,429limit reached (per minute or per day). - Dry run: add
?test=1to the URL. The answer shows where each field would go and which names are not placed yet; nothing is written or counted. - Where a call came from: add
?source=…to the URL (for example?source=partner-acmeor?source=booth-qr) to tell several senders of one webhook apart.utm_source,utm_medium,utm_campaign,utm_termandutm_contentwork the same way. The value is kept with every record of the call like any other field: in a column of that name if the list has one, otherwise with the record. A field of the same name in the record itself wins. Values are cut at 200 characters. - If something is busy for a moment: an accepted call is kept until its records are stored. If the list is busy with another change, the call is tried again (up to three times, about 30 seconds apart) before its records are held in the inbox as "Could not be written".
- Daily counter: runs on UTC days. A call that would pass the daily limit is refused as a whole.
- What the AI gets: with both Hold back boxes off and field names the list knows, a call uses no AI at all. An unknown field name is sent once, with one example value (up to 80 characters) and the list's column names and types. With "Hold back spam and test entries" on, each record's values (up to 12 fields, 120 characters each) go to the AI check. Details in "What the AI sees of your data".
- Log: the panel shows the latest 8 calls; 50 are kept.
- There is no signature header; the secret is the URL.
Related topics: send-to-inbox-from-tools · inbox · zapier-make-n8n · list-triggers · record-limit · what-the-ai-sees · quality-checks-overview.
FAQ#
What is a list webhook?#
A private URL that belongs to one list: a form, Zapier, Make, n8n or your own code sends records to it as JSON, and they land in that list's matching columns. By default every record goes into the list and the list's checks show what is wrong with it; if you like, doubtful records wait in the Inbox for your decision first. Each list can have one webhook, on every plan.
How do I create a webhook for a list?#
In the list, click the Set up icon next to the list's name, open the Webhook section and click Create webhook, then copy the URL. On a list without records, the card "Receive from a tool" opens the same section, and in the Inbox you can switch to Entries and click Webhook for a list (with no entry selected) and choose the list; anyone who can edit the list can do this.
What format does a list webhook expect?#
A POST request with JSON: one object per record, or an array of objects for several records in one call. The Fields tab under "How to set up your tool" shows a ready JSON template built from the list's own columns, and the curl tab the same as a command. Typeform and Calendly webhooks and plain form posts are understood too.
Do I have to map the webhook's fields to my columns?#
No. Fields find their column by the list's column types (email, first_name, company …), and a name ListPlus doesn't know is looked at by AI once and then remembered. Fields without a column are kept with the record; in the Mapping section you can assign them to a column or pick "+ Create as column", which applies to records arriving from then on.
How do I connect Zapier, Make, n8n, Typeform or Calendly to a list webhook?#
Zapier: the "Webhooks by Zapier" action with POST; Make: the HTTP module with "Make a request"; n8n: an HTTP Request node with "Import cURL" and the command from the panel's curl tab. Typeform ("Connect" → "Webhooks") and Calendly (a webhook for "invitee.created") can call the URL directly, and the question's title becomes the field name. The panel's "How to set up your tool" tabs show these steps next to your URL.
Does a list webhook block bad leads, spam or test entries?#
Not by default: every record goes into the list, and the list's checks in Analyze flag invalid emails, placeholders and test entries. To keep them out, tick "Hold back invalid, disposable and test addresses" and/or "Hold back spam and test entries (AI check)" in the Hold back section of the webhook panel (Set up → Webhook); those records then wait in your Inbox for Add anyway or Discard. Contacts on your workspace's Block list are always held back, whatever you tick.
Why did a record sent to my list webhook not appear in the list?#
Look in the Inbox for an entry named after the list, marked "to review": the record was held back because it is on your Block list, your plan's record limit is reached, or you ticked a Hold back option that caught it. It may also have been merged into an existing record as a duplicate (the Recent calls log says "merged"), or the call was refused — a paused webhook, an old URL or a limit all return an error to the sender. Recent calls in the webhook panel shows what each call did.
Where do held-back webhook records go, and how do I add them?#
Records on your Block list, records the list can't take and whatever you chose to hold back wait in the Inbox as an entry named after the list, marked "n to review" and shown in the To review tab. Open it to see each record with its reason, then click Add anyway or Discard — the list is already set, and you can tick single rows to decide only those. The entry is deleted 14 days after it arrived, like every Inbox entry, so decide before then.
Does a list webhook create duplicates?#
No. A record that matches an existing one in the list by email, LinkedIn URL, phone or name + company is merged: it fills that record's empty fields instead of adding a second row. The "Recent calls" log shows this as "merged".
How do I send RB2B visitors into a ListPlus list?#
Open the list's Set up page → Webhook, choose RB2B under "How to set up your tool" and click "Set up for RB2B": ListPlus adds the columns RB2B's fields need (using the ones the list already has), places the fields and sets the rule for repeated visits. Then paste the webhook URL in RB2B under Integrations → Webhook and click "Send a Test Event". No field mapping is needed.
Can a list webhook update a contact that comes in again, for example on a repeat visit?#
Yes. By default a repeated record only fills the existing record's empty fields; under "When the same person comes in again" you choose columns that take the newer value (for example Last seen and Last page) and a column that counts the visits. "Set up for RB2B" sets this for you.
Does a list webhook cost credits, and what are its limits?#
It is free on every plan and uses no credits — only enriching the records afterwards costs. The plans differ in the limits: Basic 100 records a day (100 per call, 30 calls a minute), Pro 5,000 (500 per call, 60 a minute), Premium 50,000 (500 per call, 120 a minute), counted for all list webhooks of the workspace and shown as "Today 14 / 100". Over a limit the sender gets an HTTP 429 error so the tool can retry; nothing is dropped silently.
How do I pause a list webhook, get a new URL or delete it?#
Open the ⋯ menu next to the "Today" counter under Set up → Webhook: Pause stops it taking calls until you click Resume, and nothing is stored while it is paused. "Create a new URL" makes the old URL stop working at once and keeps mapping and log — use it if the URL leaked. "Delete webhook" removes URL, mapping and log; the records in the list stay.
How do I test a list webhook and see what arrived?#
Click Send test in the panel: it sends the list's field template as a dry run and reports how many fields would be placed, without writing anything to the list. After real calls, "Recent calls" shows per call how many records were received, new, merged and held back. Before the first call the Mapping section says "Waiting for the first call …".
Do triggers and pipelines run for records that arrive by webhook?#
Yes. A record the webhook adds to the list is a new record like any other, so the list's triggers check it and can hand it to a pipeline, set a status or tag it. Since the webhook lets every record through by default, give the trigger conditions or tick a Hold back option if only good records should be handed on; held-back records reach the list, and its triggers, only after you click Add anyway.