Skip to content

Latest commit

 

History

379 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenGTM logo

OpenGTM

Build pipeline. Not busywork.

The open-source, self-hosted Clay alternative for sourcing, enrichment,
AI research, buying signals, and outbound workflows.

AGPL v3 license Documentation GitHub stars GitHub forks

OpenGTM is a free, open-source, self-hostable alternative to Clay.com, licensed under AGPLv3.

Source leads, run enrichment waterfalls, research them with AI, and push the results to your CRM, Sheets, or a webhook — all on your own infrastructure, with your own provider keys, and with the bill shown to you before you run.

Read the docs  ·  Run it locally  ·  Request a provider

OpenGTM demo in light mode: inspect a populated enrichment workbook, source leads, and see cost controls

The 30-second version: give OpenGTM a market, a list, or a workbook. It sources companies, enriches rows through cost-ordered provider waterfalls, researches the hard cells with agents, and sends qualified results where your team works. You keep the data, keys, and infrastructure.

In plain terms, OpenGTM combines lead enrichment, AI sales research, buying signals, and programmable GTM automation in one self-hosted application.

Quickstart · Features · Compare with Clay · API · Contribute


Why OpenGTM

  • See the exact bill before you run. Every workbook has a spend estimate endpoint that prices a run as rows × providers = $X with a per-column breakdown of paid providers, so the UI can gate the run behind a confirmation ("N rows, worst-case $X — proceed?"). Set a spend ceiling and paid providers are skipped once the budget is spent.
  • Bring your own keys (BYOK). LLM providers, enrichment vendors, and destinations are all configured with your API keys via the Settings UI (or .env). OpenGTM is the engine; you own the spend and the data.
  • Self-host the whole thing. No seats, no per-credit markup, no data leaving your box. AGPLv3.

One engine, four GTM loops

Start with OpenGTM does Finish with
A market definition Sources matching companies and people A deduplicated workbook
Domains or names Runs cost-ordered provider waterfalls Verified, provenance-backed fields
An account question Browses and researches within bounded steps A cited answer in each row
Qualified rows Applies conditions and idempotent outputs CRM, Sheet, webhook, or sequence

Our promises (in writing)

These are structural commitments, not marketing — the whole point of OpenGTM is that a closed, seat-priced, credit-metered incumbent cannot match them without undoing its own business model:

  • The REST API, webhooks, and MCP tools are never plan-gated. Automating OpenGTM from your terminal, your own agent, or n8n is a first-class use, not an upsell. Metering the API is the single most-hated move of the tools we're an alternative to; we commit, in writing, never to make it.
  • BYOK at direct cost, zero markup. You pay the LLM/enrichment vendor directly with your own key. Any future managed-key option bills at provider cost plus one disclosed flat fee — never a per-credit markup.
  • See the bill before you run — always. The spend estimate and per-provider cost ledger are core, not a premium tier.
  • Self-host is fully functional, forever. No feature is held back to force a cloud upgrade; the paid cloud line will be governance (SSO/audit/DPA/support), never capability.

What it does

OpenGTM is a spreadsheet-shaped enrichment engine ("workbooks") plus an agentic layer that can build and run those workbooks for you.

Capability What it is Status
Lead sourcing ~90 discovery sources plus typed connectors. Durable connector runs page, checkpoint, resume, deduplicate by provider record ID, and report whether the requested target was actually met Implemented
Enrichment waterfalls A column tries providers in sequence (cost-ordered) until one returns a confident value, with cross-row caching and confidence early-exit Implemented
Providers ~35 enrichment providers (32 built-in + declarative YAML manifests) across email find/verify, phone, firmographics, decision-makers, social, tech-stack, hiring, IP/domain, scoring Implemented
AI columns LLM transforms over row data (classify, rewrite, extract) Implemented
Research / "Claygent" columns A bounded ReAct agent that browses the web per row to answer a question and cite a source Implemented
Agent columns Goal-directed enrichment — the agent picks tools dynamically and records a reasoning trace per cell Implemented
Agentic chat / autopilot CopilotKit-style chat that can draft a plan from a goal ("build a list of 50 IT firms in Pune and find founders' emails") and execute it: create a sourcing workbook, add agent columns, set refresh Implemented
Dynamic audiences Workspace-wide saved segments with materialized membership, entry/exit history, restart-safe scheduled refresh, and automation triggers Implemented
Audience activation Durable, idempotent per-member sync runs to webhooks, HubSpot, and Salesforce with field mapping, health, retries, and automatic sync after audience changes Implemented
Output / push loop output columns push each row to a webhook, HubSpot, Salesforce, Google Sheets, Airtable, or an email sequencer — run-once idempotent, executed after enrichment Implemented
Email outreach Multi-step SMTP sequences with per-lead state and rate limiting Implemented
Buying signals Detects 7 signal types (hiring, funding, tech change, website change, news, growth, social) Implemented
Dedup Blocking + Jaro-Winkler fuzzy matching to find/merge duplicate leads Implemented
Multi-tenancy Workspace roles at the API boundary plus fail-closed PostgreSQL RLS on leads, signals, workbooks, connector runs, automations, outreach, ingest, and audit data Implemented for the single-node deployment; control-plane HA remains
Spend transparency Pre-run cost estimate + per-provider cost/yield ledger + spend ceiling Implemented
SSRF-guarded scraping Tenant-facing custom HTTP, scraper, webhook, research, and website-enrichment paths reject private/loopback/metadata targets and re-check redirects/browser requests Implemented; hosted deployments should add an egress proxy

Workbook column types

lead_field · source · enrichment · waterfall · ai_formula · agent · conditional · output · research · http (call any API + JSONPath extract) · formula.


Quickstart

One command brings up the full stack — web app, API, worker, scheduler, Postgres, Redis, and nginx — with a populated zero-key demo:

git clone https://github.com/debpalash/opengtm.git
cd opengtm
cp .env.example .env        # boots without keys; add providers later in Settings
docker compose up           # API + worker + Postgres + Redis + nginx

Open http://localhost:3000 and sign in with admin / admin. The seeded workbook uses free, no-key providers, so you can inspect the complete workflow before connecting a paid service. Change the demo password before exposing the deployment beyond your machine.

Your first five minutes

  1. Open Workbooks → Demo — Zero-Key Enrichment.
  2. Inspect any populated cell to see its provider and provenance.
  3. Open the cost control to preview the next run and set a spend ceiling.
  4. Add a provider key in Settings → API Keys when you want paid enrichment or AI research.
  5. Export the grid or add an output column for your CRM, Sheet, or webhook.

To point at an existing database instead of the bundled Postgres, set DATABASE_URL in .env (SQLite is also supported for local dev).

Stable local URLs with Portless

Portless is included as a development dependency. It gives the Vite app a stable opengtm hostname and can also alias the Docker/nginx service that already listens on port 3010:

# Local machine: HTTPS at https://opengtm.localhost
bun --cwd apps/web dev

# Existing Docker stack: register its stable name
bun run portless:docker

# LAN sharing on an unprivileged port (Linux requires avahi-utils)
portless proxy stop
bun run portless:lan
bun run portless:docker
# http://opengtm.local:1355

Run bun run portless:list to inspect routes and bun run portless:doctor to check proxy, DNS, certificates, and route health. A root-installed proxy may use ports 80/443 for a URL without :1355.

You need at least one LLM provider key for AI/agent/research features (OpenRouter, Google AI, Groq, Cerebras, NVIDIA, Mistral, and GitHub Models all have free tiers — see .env.example). Enrichment vendors (Hunter, Apollo, AbstractAPI, NumVerify, IPInfo, LeadMagic, …) and destinations (HubSpot, Salesforce, Sheets, Airtable) are all optional and configurable at runtime in Settings → API Keys.

Local dev (without Docker)

uv sync                                                      # Python backend deps
uv run uvicorn apps.api.main:app --reload --port 8000       # API
cd apps/web && bun install && bun run dev                    # frontend

Background enrichment and source imports run on the durable SQL-queue worker: python -m apps.api.worker (claims jobs atomically; scale with docker compose up --scale worker=N). Redis is optional for single-process development and carries tenant-isolated live progress plus bounded reconnect history in Compose. A scheduler recovers stale jobs and enqueues recurring refreshes; it does not execute user work itself.


Frequently asked questions

What is OpenGTM?

OpenGTM is an open-source GTM platform for sourcing leads, enriching company and contact data, researching accounts with AI, tracking buying signals, and routing results into sales tools.

Is OpenGTM an alternative to Clay?

Yes. It covers the core workbook, enrichment-waterfall, AI-column, sourcing, and output workflow while taking a self-hosted, BYOK approach. It is not a pixel-for-pixel clone and its integration catalog is still growing. See the detailed comparison.

Is OpenGTM free?

The software is free under AGPLv3. You pay infrastructure and any third-party providers you connect. The seeded demo works without provider keys.

Does OpenGTM send data to its own cloud?

No OpenGTM-operated cloud is required for the self-hosted edition. Data stays on the infrastructure you run, except when a workflow calls providers or destinations you configure.

Can agents and automations use OpenGTM?

Yes. OpenGTM exposes a REST API, webhooks, an MCP server, and an n8n community node in addition to the web interface.


Architecture

apps/
├── api/          FastAPI backend (Python 3.11+)
│   ├── routers/  HTTP/WS endpoints (auth, leads, workbooks, copilotkit,
│   │             signals, scraper, crm, outreach, settings, analytics, …)
│   ├── services/ workbook engine, enrichment providers + waterfalls,
│   │             agent/autopilot, crm, outreach, signals, workspace, dedup
│   └── core/     config, SSRF url_guard, shared utilities
├── web/          React + TypeScript + ShadcnUI + Tailwind (Vite)
├── docs/         Documentation site (Astro + Starlight) → opengtm.palash.dev
└── mcp/          MCP server exposing OpenGTM tools to agents
packages/
├── chrome-extension/   Capture tables / LinkedIn results into a workbook
└── n8n-nodes-yupcha/   n8n community node
Layer Technology
API FastAPI, SQLAlchemy 2
Database Postgres (recommended; SQLite supported for dev)
Queue / pub-sub Postgres job queue + isolated worker processes; Redis pub/sub for live UI updates
Frontend React, TypeScript, ShadcnUI, Tailwind, Vite
Scraping httpx, curl-cffi, Playwright, BeautifulSoup
Agentic chat CopilotKit-style chat protocol with a gated ReAct tool loop
Monorepo Turborepo + Bun

Durable source orchestration

REST / agent tool
      │ validates workspace role and source query
      ▼
connector_runs + jobs  ── one atomic transaction
      │
      ▼
SQL queue worker ── fetch page ── normalize typed records
      │                              │
      ├── checkpoint cursor          └── stable provider + record identity
      ▼
workbook_rows upsert + run counters ── one page transaction
      │
      └── Redis event → workbook table + progress indicator

Connector adapters return a shared page/collection contract with source totals, pagination state, exhaustion, warnings, and explicit partial-result status. A worker commits each page and its cursor together, so a crash repeats at most one idempotent upsert instead of losing or duplicating rows. Postgres enforces unique (workbook_id, source_provider, source_record_id) identities, and both rows and run history are protected by fail-closed workspace RLS.

See docs/architecture.md for the complete process/data ownership map, queue state machine, tenant boundary, failure behavior, and scaling limits.


Not yet / Roadmap

The production data plane is tenant-scoped and PostgreSQL/RLS protected, and all user work runs through the durable worker. The remaining boundaries are:

  • The workspace control plane is single-node. Workspace membership, active workspace selection, encrypted per-workspace secrets, consent-gated paid-media audience sync (Meta, Google Ads, and LinkedIn), and the detailed collection-stage ledger live in SQLite files on the shared data/ volume. This is reliable for the documented Compose topology, but replicas on separate hosts need those stores moved to PostgreSQL first.
  • A few legacy utilities are global and admin-only. The legacy person/scrape history, CRM-data utility, and reusable-function catalog are isolated from normal workspace users rather than fully tenantized.
  • Hosted-SaaS hardening is not complete. OIDC SSO (including enforceable member-only sessions with owner break-glass), SCIM, and audit export are built; mutation audit events accept bounded endpoint-supplied action/count metadata while stripping credential-like keys and never storing request bodies; the complete filtered audit ledger streams to CSV, and retention policies cover tenant LLM-usage aggregates alongside operational history, but still need controlled-live IdP validation. Before exposing OpenGTM to mutually hostile public tenants, also add a controlled outbound egress proxy, validate the shipped Vault Transit custody path, regularly execute the integrity-checked backup/restore drill, and complete an external security review.
  • Billing is an optional mechanism, not a hosted billing operation. The feature-flagged credit ledger, idempotent debit, 402 gate, and Stripe top-up webhook exist. Tax, refunds, subscriptions, and customer lifecycle operations do not.
  • Clay's breadth and polish remain a product gap. The open provider catalog, indexed JSON search/custom-sort cursors and arbitrary cross-page selection at million-row scale, direct Clay API migration beyond the shipped dry-run-audited Clay CSV importer, templates, integrations, and real-user accuracy benchmarks need continued work. Workbook edits now recompute transitive downstream columns through the durable queue; side-effecting output columns require explicit reactive: true. The virtualized grid supports keyboard navigation, Shift-range selection, selection copy, F2 editing, Ctrl/Cmd+D fill-down, atomic multi-row TSV paste, and server-driven 1,000-row page navigation into editable columns. Search plus saved-view filters/sorts execute globally before pagination, and CSV export streams every matching row with spreadsheet-formula injection neutralized. Run and fill-missing operations use that same complete-query scope and matching-row cost estimate. “Select all matching” supports full-query export and count-locked deletion that aborts if membership changes before the write. Default-order navigation uses a stable opaque (position,id) cursor backed by a composite database index; custom saved-view sorts retain offset paging until typed cursor keys ship.

See docs/plans/clay-parity-specs.md for the work-item breakdown and sequencing.


License & "can I use this at work?"

OpenGTM is licensed under the GNU Affero General Public License v3.0 (LICENSE).

In plain terms:

  • Self-host it for your own team — free, no strings on internal use. Use it, modify it, run it on your own servers.
  • The AGPL network clause applies only if you offer OpenGTM (or a modified version) as a service to other people over a network. In that case you must make your modified source available to those users. Running it internally does not trigger that obligation.

This is not legal advice — read the full license if you plan to offer it as a hosted service.


Docs & Contributing

Contributions welcome — open an issue or a PR. Code is grounded with file/line references in the docs above; start there to find the right entry point. See CONTRIBUTING.md (DCO sign-off, conventions), SECURITY.md (private vulnerability reporting), and CHANGELOG.md.

Releasing

Maintainers: scripts/release/preflight.sh checks a ref for anything that must not ship (databases, .env, lead exports, submodule pointers, credential-shaped strings); scripts/release/build-public-snapshot.sh builds the public/main branch with maintainer-only paths stripped, and prints — but never runs — the push command. Pushing a v* tag builds the container image on GHCR and drafts a GitHub release.

About

Open-source, self-hosted Clay alternative for lead sourcing, enrichment waterfalls, AI research, buying signals, and outbound automation.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages