Skip to main content
A watch run can deliver its records two ways. By default they ride inside the notification. Set config.payload_delivery_type to "link" and the notification carries a pre-signed S3 URL instead, pointing at one file that holds every record of that run.
This is available on every watch: person, company, and job discovery watches, and person and company entity watches. It applies on create and on PATCH.

Why you would switch

Most receivers cap how large a request body they accept, and a body over the cap is refused whole. An AWS Lambda proxy integration stops at 6 MB, an ALB target at 1 MB. A run that delivers 1,000 enriched people can pass either of those. Inline delivery splits a large run across several requests to stay under a receiver’s cap. Link delivery sidesteps the cap instead. The body carries no records, so its size does not grow with the run. Pick link if your receiver has a small body cap, or if you would rather load a run as one file than reassemble it from several requests.

The two modes

Set it on a new watch

Switch an existing watch

payload_delivery_type is one of the mutable config keys, alongside the schedule and the result cap. Change it and the watch’s filters, tracked fields, and sort order stay exactly as they were. A config PATCH is validated as a whole block, so repeat the watch’s current trigger alongside the key you are changing. Leave it out and the request comes back 400 with config.trigger.type must be one of ['interval']. The keys you do send are merged into the stored config rather than replacing it, so anything you omit keeps its current value.
The change takes effect on the next run. Runs already delivered keep whatever they were delivered as.
The watch’s config in a create, GET, or PATCH response does not echo payload_delivery_type today. To confirm which mode a run used, read metadata.payload_delivery.type on the notification, or payload_delivery.type on the run summary.

What the notification looks like

Both modes carry the same metadata, including summary.delivered and summary.truncated, so your record counts do not move. Only the records themselves change places.
On a link delivery the body has no results key at all. Read metadata.payload_delivery.type and branch on it rather than testing for the presence of results.
metadata.payload_delivery is present on every delivery, inline and link alike. An inline delivery carries { "type": "inline" } with no other keys, so read type before you reach for url.

The file

One file per run, in NDJSON: one complete JSON object per line, newline terminated, with no wrapping array. You can stream it line by line without holding the whole run in memory. Each line is the same record the inline body would have carried, with no container around it.
A discovery watch’s lines are the raw dataset records, without the { "added": [ … ] } wrapper the inline body uses, because a file of lines needs no wrapper. An entity watch’s lines are the same { changes, record } objects the inline body carries. Fetch the file with a plain GET. The URL carries its own authentication in the query string, so send no authorization header:
The URL is signed for 5 days. Download the file when the notification arrives rather than storing the URL for later. If you need the run again after that, the run summary issues a fresh link over the same records.
A run writes its file once, before it fans out. A webhook, a Slack message, a Google Chat message, and an email from the same run all carry the same link to the same bytes. Slack, Google Chat, and email messages already show a bounded preview of a run rather than every record. On a link watch those messages keep their preview and gain the link, so a reader who wants the records the preview left out has the full file.

Reading a past run

The run-summary endpoint follows the watch’s mode too.
On a link watch the response carries a top-level payload_delivery block, and each entry in notifications keeps its delivery outcome but drops the records:
On an inline watch, payload_delivery is { "type": "inline" } and notifications[].payload carries the records as before. Reading a run hands you the same file the run delivered, so the bytes match what your channel received. A watch created with no channels never pushed anything, so the first read writes the file and links it. A run that delivered nothing offers no link. A SKIPPED or FAILED run reports { "type": "inline" } with an empty notifications list.

Inline is never overridden

A watch left on inline posts its records at any size. Delivery does not switch a large run to a link on its own, because the mode is your choice and a silent switch would change the body shape your receiver parses. A large inline run is split instead: records are grouped into requests of at most ~1 MB or 100 records, and each request carries its own notification_id (ntf_{run_id}_{index}) and a metadata.chunk.index. A run that fits in one request keeps the plain ntf_{run_id} id and no chunk key, so a small run looks exactly as it always has. If your receiver rejects an oversize body, that is the signal to move the watch to link.

If the file cannot be written

Writing the file can fail. When it does, the run falls back to delivering the records inline and says so: metadata.payload_delivery reports { "type": "inline" } and the body carries results as usual. The delivery still reaches you, without the link. This is the reason to branch on metadata.payload_delivery.type rather than on the watch’s configured mode. A link watch can still hand you an inline body.

Test sends

A test send on a link watch to a webhook mirrors a real delivery: the body carries metadata.payload_delivery with a link and no results, alongside the usual metadata.test: true. The file holds the sample records. Each test preview writes its own file rather than reusing the run’s, so a preview never overwrites the records of a real run.

Errors

A value other than "inline" or "link" is rejected on create and on PATCH:
400 Bad Request
The check is case sensitive, so "LINK" is rejected. Omitting the key, or sending it as null, means inline.

Pricing

Neither mode changes what a watch costs. You pay per record delivered, at the same rate either way, and reading the file costs no credits. See Pricing for the per-watch rates.

Person discovery watcher

Turn a person search filter into a recurring feed.

Person entity watcher

Watch a known list of people for profile changes.

Company discovery watcher

Turn a company search filter into a recurring feed.

Job watcher

Follow new job postings matching your filters.