Skip to content

michaeljboscia/attio-instantly

Repository files navigation

attio-instantly

A native Attio app that syncs Instantly.ai cold-email campaign events into your Attio CRM — in real time, with no external server to host.

When Instantly fires a webhook (email sent, opened, clicked, replied, meeting booked, …), this app receives it inside Attio, upserts the matching Person by email, stamps campaign engagement attributes, logs replies as Notes, and advances (or creates) the associated Deal — without ever regressing a deal that has already progressed.

Instantly campaign event ──webhook──▶  Attio app handler  ──▶  People  (upsert + engagement attrs)
   (sent/opened/clicked/                (src/webhooks/             Notes   (reply bodies)
    replied/meeting/…)                   instantly.webhook.ts)     Deals   (stage advance / create)

Why a native Attio app (not an external relay)

The webhook handler runs on Attio's own infrastructure as a .webhook.ts entry point. There is no server to deploy, no relay to babysit, no second set of credentials in flight — Attio receives Instantly's POST directly and writes to the CRM with the app-scoped token it injects at runtime. Connecting Instantly in the workspace UI auto-registers the webhook; disconnecting tears it down.

What it writes

Target What happens
People Upserted by email_addresses. Stamps instantly_status, instantly_campaign_*, instantly_current_step/variant, and per-event timestamps (instantly_opened_at, instantly_replied_at, …). Enriches name / phone from merged lead fields.
Notes On replies — the reply subject + body + a deep link back to the Instantly unibox thread.
Deals Strong signals (meeting booked/completed) create a deal if none exists; weaker signals (reply, interest) advance an existing deal. A monotonic stage rank guarantees an out-of-order event never moves a deal backwards.

See docs/EVENT-MAPPING.md for the full event → outcome table.

Quick start

npm install
cp .env.example .env          # add an Attio API key (for the setup script only)
export $(grep -v '^#' .env | xargs)
python3 setup/create-attributes.py --apply   # provision the instantly_* attributes
# edit src/config.ts → your deal-owner member id + your funnel stage names
npm run dev                   # local Attio dev runtime

Then connect Instantly in your Attio workspace settings. Full instructions in SETUP.md; how to verify it end-to-end in docs/TESTING.md.

Before you deploy — edit one file

Everything specific to your workspace lives in src/config.ts:

  • DEAL_OWNER_MEMBER_ID — the workspace member who owns auto-created deals
  • DEAL_STAGES_LOW_TO_HIGH — your Deals funnel, in order (drives the no-regression rank)
  • DEAL_BY_EVENT — which Instantly events create vs. advance deals, and to which stage

Nothing else in the codebase hardcodes a workspace value.

Docs

Scope & limitations

  • One-way: Instantly → Attio. It does not push Attio changes back to Instantly.
  • People + Deals only (v1). No Companies/Workspaces objects yet.
  • Requires the custom instantly_* attributes from setup/create-attributes.py.

License

MIT — see LICENSE.

About

Native Attio app that syncs Instantly.ai campaign webhook events into Attio People & Deals

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages