listen · your own sources
Push and import connectors
Forwarding, share-to, exports and your own browser.
In Your own sources
Some of the best sources can't be polled. A newsletter arrives by email, a saved Instagram post lives behind a sign-in, a TikTok favorite only leaves the app in a data download. Push and import connectors take items when they arrive, from whoever has them, and store them in the same raw shape as every pulled item.
you or a service sends it → push or import connector · accept it → item · stored raw → detectors, drafting, research
rule 1 — Verify before you store · Every inbound route checks who sent it: a signed webhook, an allowed sender, a signed-in device. Anything else is dropped and logged.
rule 2 — Keep the original time · An import of last year's saves keeps each item's saved-at. Captured-at says when it reached your store. Both matter.
rule 3 — Your saves, your machine · Anything that needs the founder's own session runs on their machine and reads only what they saved.
what it is
Three ways in that don't involve polling.
Push: the source calls you (a webhook, a forwarded email, a share sheet). Import: the founder hands over a file, usually a platform's data export. Device-run: a small runner on the founder's own computer reads what only their signed-in session can see and sends it up. In integration terms these are inbound webhooks, batch file ingestion and an edge agent.
Inbound address — email ingestion · A private address per account. Forward a newsletter there and it becomes an item.
Webhook — event callback · A service posts an event to your endpoint, signed so it can't be faked.
Share target — share sheet · "Share to VibeDraft" from a phone or browser saves one link with a note.
Data export — takeout · data download · The file a platform gives you of your own activity: saves, likes, watch history.
Idempotency key — dedupe on arrival · The id that makes a resent webhook or a re-imported file land once.
how it works
Three lanes in, one store out.
Each lane has its own front door. After the door, every item goes through the same dedupe and write as a pulled item.
- Arrives — email · webhook · file · device
- Verify sender — signature · allow-list · sign-in
- Parse — per route and format
- Map to item — keep saved_at
- Dedupe — platform id or Message-ID
- Write raw — append-only
- Log the delivery — accepted · rejected
- Notify readers — item events
Accept at the door
Inbound email hits a per-account address; webhooks hit a signed endpoint; imports arrive as an upload; device runners call an authenticated upload with the account's token.
Verify, or drop and log
Check the webhook signature, the sender against the allow-list (and the email's DKIM), the device's sign-in. A rejection is logged with the reason so spoofing attempts are visible.
Parse with a versioned parser
Each route and export format has its own parser with a version. When a platform changes its export, the old parser fails loudly instead of writing garbage.
Map to the item shape, keeping the original time
A save from March keeps saved_at in March. A forwarded newsletter keeps its original sender and date from the forwarded headers, not the forward.
Dedupe
Use the platform's own id (post id, video id) or the email's Message-ID. Re-importing the same export changes nothing.
Write raw, then tell the readers
The same append-only store and the same item event as pulled items, plus a field saying which route it came in by.
the object
An inbound route, an import job and a device runner.
Each lane has a small object of its own. The items they write are the parent page's item record, with route set.
A runner on the founder's machine that owns session-only sources.
| Field | Type | What it holds |
|---|---|---|
device_id | uuid | One per machine |
account_id | uuid | Whose sources it runs |
sources | uuid[] | The sources it owns; others mark them elsewhere |
last_seen_at | timestamp | Heartbeat; drives the health state |
version | text | Runner build |
status | enum | online, asleep, revoked |
a desktop runner, as data
inbound route
{
"route_id": "rt_mail_3f9",
"kind": "email",
"address": "in+7k2q@inbound.example",
"allowed_senders": [
"news.example.com",
"substack.com"
],
"secret_ref": null,
"source_id": "src_newsletters",
"created_at": "2026-10-17T05:00:00Z",
"revoked_at": null
}import job
{
"import_id": "imp_ig_0921",
"kind": "instagram_saved",
"file_ref": "upl_7d1",
"parser_version": "ig-saved@2",
"rows_seen": 412,
"rows_new": 388,
"rows_skipped": 24,
"errors": [],
"status": "done"
}device runner
{
"device_id": "dev_macbook",
"sources": [
"src_youtube_playlists"
],
"last_seen_at": "2026-10-16T06:30:45Z",
"version": "1.4.0",
"status": "asleep"
}the push and import catalog
Twelve ways items arrive without a poll.
Platforms change what their APIs and exports include, so treat the "what's in it" lines as what to check, not a promise.
Push — the source or the founder sends it
push.newsletter — push
Newsletter forwarding address
Forward issues, or set an auto-forward rule, to a private per-account address.
- verify
- allowed senders + DKIM
- dedupe
- Message-ID
- keeps
- original sender, date and links
- feeds
- detectors, research, drafting
push.email_save — push
Email-to-save
Send any link or note to the same kind of address to save it as an item.
- verify
- the founder's own address
- dedupe
- url
- keeps
- the note as a label
- feeds
- drafting, research
push.share — push
Share to your store
A share-sheet or browser button that saves one link with an optional note.
- verify
- signed-in session
- dedupe
- url
- keeps
- where it was shared from
- feeds
- drafting, labels
push.command — push
Save from chat
"Save this" in an AI assistant chat with your connector writes an item.
- verify
- the connector's sign-in
- dedupe
- url or text hash
- keeps
- the chat's note
- feeds
- research, drafting
push.stripe — push
Stripe webhooks
Paid, failed and canceled events push in as they happen. These are warm triggers, not reading material.
- verify
- Stripe signature
- dedupe
- event id
- keeps
- customer, amount, plan
- feeds
- warm detectors, funnel
Events worth handling: invoice.paid, invoice.payment_failed and customer.subscription.deleted.
push.form — push
Form and waitlist webhooks
A form tool posts each answer: waitlist questions, surveys, "how did you hear about us".
- verify
- signing secret
- dedupe
- submission id
- keeps
- every answer, verbatim
- feeds
- labels, attribution
Import — a file the founder uploads
imp.instagram_saved — import
Instagram saved posts
Instagram's own data download includes saved items. Upload the file and parse it.
- verify
- the founder's upload
- dedupe
- post url
- keeps
- saved-at time
- feeds
- drafting, the taste ranker
imp.tiktok — import
TikTok favorites and likes
TikTok's data download lists favorited and liked videos.
- verify
- the founder's upload
- dedupe
- video url
- keeps
- the date
- feeds
- drafting, the taste ranker
imp.x_archive — import
X archive
X's archive download of your account. Check which of likes and bookmarks it includes before relying on it.
- verify
- the founder's upload
- dedupe
- post id
- keeps
- timestamps
- feeds
- voice, drafting
imp.youtube — import
YouTube history and Watch Later
Watch Later isn't readable through the API; a data export of your account is the route.
- verify
- the founder's upload
- dedupe
- video id
- keeps
- added-at
- feeds
- research, drafting
On your machine — needs the founder's own session
dev.saves — your machine
Threads and other session-only saves
A runner in the founder's own browser or desktop app reads their saved items and uploads them.
- verify
- device sign-in
- dedupe
- post id
- keeps
- saved-at
- feeds
- drafting, labels
dev.local_files — your machine
Files on your computer
Upload local files (renders, exports, notes) straight from disk.
- verify
- the local connector's sign-in
- dedupe
- content hash
- keeps
- the path and file time
- feeds
- media, research
failure modes
How push and import break.
Forwarding loses the sender — A forwarded issue looks like it came from the founder. · catch itParse the forwarded headers and List-Id; store the original sender and date.
Spoofed mail to the address — Anyone who learns the address can write into the store. · catch itAllowed senders plus a DKIM check; a revoke button that kills the address.
Export format changes — A platform renames a field and the parser writes empty items. · catch itVersioned parsers that fail loudly on unknown shapes, with row-level errors.
Double imports — The same file uploaded twice. · catch itDedupe on the platform id; the second import reports 0 new.
The device is asleep — Session-only sources stop with no error. · catch itA heartbeat; past the max staleness the source shows elsewhere or stalled, with the last-seen time.
Webhook replays — A service retries and the same payment event lands twice. · catch itDedupe on the event id before any detector sees it.
data to capture
What push and import record.
The same four lines every stage uses, under the guide's eight data rules: log the decision, version what decided, freeze the inputs, keep the negatives, log the odds, every human touch is a label, one chain of ids, keep the raw.
record
- every delivery: accepted or rejected, with the reason
- every import job with parser version and row counts
- the route each item arrived by
- original time (sent, saved) and captured time
label
- a save is valued; unsaved later, not
- a forward the founder deletes: not useful
- items used in drafts or replies: valued
trains
- the taste ranker from saves
- which newsletters produce signals
- spam and spoof detection on inbound mail
test
- auto-forward all vs chosen newsletters · A/B on signal yield
- monthly vs weekly imports · drafting freshness