Your dbt DAG is the pipeline.

Pull data from SaaS APIs as ordinary dbt models. Declare the source, add a model, and the data incrementally lands in your warehouse on every dbt run. Extract, load, and transform in one dbt project, one DAG.

Stripe API SaaS · REST warehouse.orders source · postgres stg_stripe_charges materialized: ingest ingest stg_stripe_customers materialized: ingest ingest stg_orders model · view mrr_by_month model · table customers_by_country model · table

the extract is just another node — dbt run does the rest

One tool fewer

Retire the standalone EL tool

Most stacks bolt a separate extract-and-load product onto dbt — its own scheduler, its own UI, its own copy of your data. With Datattach the extract is an ordinary dbt model: the body names the source object, dbt run triggers the pull, and the table lands where your models already build.

  • No separate EL tool — the extract is a node in your dbt DAG
  • No second scheduler — dbt run (core or Cloud) triggers everything
  • Data lands in a catalog you own — never a copy inside Datattach
  • Downstream models ref() the landed table in the same run
stg_stripe_customers.sql — the whole pipeline
-- models/ingest/stg_stripe_customers.sql
{{ config(cursor='created') }}
SELECT * FROM {{ source('stripe_prod', 'customers') }}
customers_by_country.sql — ref() it in the same run
-- models/marts/customers_by_country.sql
SELECT country, COUNT(*)
FROM {{ ref('stg_stripe_customers') }}
GROUP BY 1
Setup

Declared entirely in your dbt repo

An admin registers the API credential once. Everything else is plain dbt config, version-controlled with the rest of your project — and the Connect dbt page generates it for your registered sources.

sources.yml — name the objects you want
version: 2

sources:
  - name: stripe_prod     # the source registered in Datattach
    schema: stripe_prod
    tables:
      - name: customers
      - name: charges
dbt_project.yml — where the data lands
models:
  your_project:
    ingest:
      +materialized: ingest
      +database: your_warehouse   # a catalog you own
      +schema: raw
Incremental by default

Incremental loads, zero bookkeeping

Every run extracts only what's new — and there is no hidden state to babysit. No cursor tables, no staging schemas, no sync-state dashboard. The landed table itself is the source of truth.

  • State lives in the destination — Datattach reads max(cursor) from the landed table and asks the API only for newer records
  • No cursor store to manage or reset — drop the table and the next run is naturally a full extract
  • Rows upsert on the object's id — overlapping windows never duplicate
  • dbt run --full-refresh rebuilds from everything the API still serves
  • Nested objects flatten into columns; nested lists become queryable child tables
Run
What gets extracted
First dbt run
Everything the API serves — table created in your warehouse
Every run after
Only records newer than max(cursor) in the landed table
dbt run --full-refresh
Table replaced with a complete re-extract
Table dropped
Next run is naturally a full extract — nothing to reset
Sources & destinations

Any source. Any destination.

Extraction is destination-agnostic — every source can land in any supported warehouse you own, and new sources arrive with the full matrix from day one.

Stripe Available now

customers, charges, invoices, subscriptions, products, prices, payment intents, refunds, coupons, plans

On the roadmap

HubSpot Salesforce Shopify Zendesk Google Analytics Meta Ads + more

Lands in a warehouse you own

PostgreSQL MySQL SQL Server Amazon Redshift Snowflake Apache Iceberg

One DAG instead of two systems

Everything a dedicated EL tool does for SaaS sources — without the second system to run, sync, and secure.

Separate EL tool
Datattach ingest models
Scheduling
Its own scheduler, coordinated with dbt by hand
dbt run — the extract is just another node
Lineage
Stops at the loader; dbt sees a mystery table
Native dbt DAG — ref() from the first model
Where data lands
Often staged through the vendor's cloud
Directly into a warehouse you own
Configuration
A second UI and permission model
sources.yml + one model file, in your repo
Credentials
Spread across another vendor
Registered once, encrypted, never in dbt config
Security

Built for the governed stack

Credentials never leave the platform

The API key is registered once by an admin and encrypted at rest. It never appears in dbt config, logs, or model output — your repo stays secret-free.

Your warehouse, your data

The destination is a catalog owned by your organization. Datattach keeps no staging copy of your SaaS data — the landed table is the only copy, and it's yours.

Governed like every other write

The load runs as the admin-gated build principal through the query engine, subject to the same access rules as any query — and every job is audited end to end.

API to insight, in one dbt run.

See how Datattach turns dbt into your whole data platform — ingestion, transformation, and governance behind one connection.

Live demo

See Datattach in action

Book a 30-minute demo. We'll walk through a live workspace with multiple sources attached, run cross-source joins, and show row-level security applied from a BI tool.

  • Zero prep — nothing to install, nothing to connect
  • dbt in action: extract, load, and transform in one project
  • Bring your questions — architecture, pricing, your use case

Prefer email? Reach us at hello@datattach.com

Request a demo

We'll get back to you within one business day.