One clean source for your whole business.
From every system you run.

Shopify calls her a customer, Business Central calls her a debtor, and she's in there three times. beetl's agent writes the SQL that matches, merges and cleans those records, and a person approves it before anything runs.

Ask for the result.
The agent builds the pipeline.

Describe what you need in your own words. The agent finds the sources, checks your workspace's rules, validates the SQL against your data and saves the pipeline as a draft. Nothing runs until someone deploys it.

Ask anything about your workspace…

Follow one customer through it.
Every step is SQL you can read.

Four stages, each a SQL query that reads the one before it. Scroll, and watch Anna Huber go from three records in two systems to one row.

Same shape, both systems

Trimmed, lower-case emails and tidy names, so the same person looks the same wherever she came from.

1normalized
SELECT  'shopify' AS source, id AS source_id,  lower(trim(email)) AS email,  initcap(trim(first_name || ' ' || last_name)) AS name,  updated_atFROM shopify.customersUNION ALLSELECT  'business_central', no, lower(trim(e_mail)), initcap(trim(name)), last_modifiedFROM business_central.customers

Puts both systems in one shape: trimmed, lower-case emails and tidy names.

Preview · 3 of 1,904 rows182ms
sourceUtf8source_idUtf8emailUtf8nameUtf8
shopify4410anna@huber.atAnna Huber
shopify4471anna@huber.atAnna Huber
business_centralD10023anna@huber.atHuber Anna

One row per customer

Records that share an email become one. The newest name wins, and every source ID stays attached.

2matched
SELECT  email,  first_value(name ORDER BY updated_at DESC) AS name,  array_agg(source || ':' || source_id) AS sourcesFROM normalizedGROUP BY email

One row per email. The newest name wins; every source ID is kept.

Preview · 2 of 1,613 rows214ms
emailUtf8nameUtf8sourcesList(Utf8)
anna@huber.atAnna Huber[business_central:D10023, shopify:4410, shopify:4471]
qa@test.exampleTest Order[shopify:4999]

Bad rows go to one side

Test orders and records without an email are kept apart, visible and countable, not deleted.

3quarantined
SELECT * FROM matchedWHERE email IS NULL OR email LIKE '%@test.%'

Test orders and rows without an email, kept apart instead of deleted.

Preview · 1 of 1 rows97ms
emailUtf8nameUtf8sourcesList(Utf8)
qa@test.exampleTest Order[shopify:4999]

The table the business reads

A stable ID, the email masked for analysis, and the records it came from. Dashboards, chat and exports all read this.

4customers_unified
SELECT  md5(email) AS customer_id,  name,  regexp_replace(email, '^(.)[^@]*@', '${1}***@') AS email_masked,  sourcesFROM matchedWHERE email IS NOT NULL AND email NOT LIKE '%@test.%'

Stable ID, masked email and sources. The table the business reads.

Preview · 1 of 1,612 rows203ms
customer_idUtf8nameUtf8email_maskedUtf8sourcesList(Utf8)
28b30203406926b77de424cdf2b15ca6Anna Hubera***@huber.at[business_central:D10023, shopify:4410, shopify:4471]

Nothing goes live by accident.
Working and deployed are two versions.

The agent and your team edit the working version. What runs is the deployed one, and it only changes when a person deploys. Every change is a diff you can read.

stage matcheddeployed v3 → working v4

SELECT

email,

- max(name) AS name,

+ first_value(name ORDER BY updated_at DESC) AS name,

array_agg(source || ':' || source_id) AS sources

FROM normalized

GROUP BY email

customers_unified

Working v4 · Deployed v3

Deploy v4

Replaces v3. Runs whenever shopify.customers or business_central.customers change.

  • It transfers. A new engineer can read a SQL stage on day one. A proprietary mapping tool has to be learned before anyone can judge it.
  • It diffs. Because each stage is text, a change shows exactly what moved between the deployed version and the next one.
  • It stays yours. If we ever part ways, you keep definitions of what your data means, in a language your team already reads.

Specialist apps are next.

Ready-made apps for deduplication, reconciliation, identity matching and redaction are on the way. Until they ship, the agent writes these rules as SQL, and they stay yours to read and change.

  • DeduplicationPlanned
  • ReconciliationPlanned
  • Identity matchingPlanned
  • RedactionPlanned

Tell us what your teamneeds to get done.

A rough description of the task is enough to start. We agree the scope and who looks after it with you.