No credential reaches the customer path
Database credentials are encrypted at rest on the server and never returned — not through a tool, not through the API. The customer integration holds a path-scoped key to the endpoint, nothing more.
Embedded analytics — the half that ships today
Every product team eventually gets the same request: customers want their numbers inside the product — their usage, their cohort, their region — not a login to somebody else's analytics portal. This page is that story: the expensive way it usually goes, and the shorter one — an agent authors the pipeline against your databases, a person releases it, and a versioned endpoint serves each customer their own rows. The API half ships today; the dashboard half is planned, and the page keeps them labelled.
The story this page is built on
A company buys the analytics platform. A consultancy builds beautiful dashboards over a dataset that took months of preparation flows, a warehouse nobody wanted, and a nightly job that breaks on the first schema change. The bill — licence plus engagement — lands in the six figures. Then the product team asks for the same numbers inside the application customers actually log into, and the answer comes back: the contract does not allow embedding on those terms.
So an engineer rebuilds the dashboard by hand — screen after screen, in the front-end framework of the month — against an API that does not exist yet. Because "expose the dataset as an API" is a second project: a service to write and deploy, an auth story to design, pagination, on-call. Three projects, then: the dataset, the API, the embedding. The dashboard — the thing everyone assumed was the point — was never the expensive part.
datapipelines collapses the first two. The dataset is a versioned pipeline across your databases, drafted
by an agent that reads your real schemas and released by a person. The API is one step after the release:
a published endpoint under /api/x, parameters bound from the request, keys scoped to the
path. What remains is the embedding — the dashboard your agent creates is a planned roadmap item.
It would consume the same published endpoint contract instead of needing a hand-built API.
Ships today
The mechanic: release the pipeline, publish it under a path, bind a key. A GET runs the
released version with the query string bound to its declared parameters and returns typed JSON — schema,
rows, cursor. The response carries Cache-Control: no-store on purpose: each call is a fresh
execution, so a customer never sees another customer's cached answer.
Per-viewer filtering rides on parameter binding: the customer id your backend already authenticates becomes a declared parameter of the released pipeline, and the released SQL filters on it as a bound scalar — never pasted SQL. One pipeline serves every tenant; the request decides whose rows come back.
The key you give each customer integration is bound to a path prefix: it reaches that endpoint subtree and nothing else — not your product API, not another tenant's endpoints — and revoking it is a checkbox that takes effect in about a minute.
The authoring half is where the agent earns the headline. It drafts the pipeline against your real schemas, iterates until the run succeeds, and — when your analyst changes the definition of "active customer" next quarter — redoes the walk and produces the diff. The artifact under review is always a JSON document of SQL nodes a person on your team can read end to end; the agent accelerates the drafting, and the release keeps the judgment where it belongs.
The whole integration
GET /api/x/usage/summary?customer_id=8841&month=2026-08
DP-API-Key: dpk_<id>.<secret>
200 OK
{
"schema": [ { "name": "metric", "type": "STRING" },
{ "name": "value", "type": "BIGDECIMAL", "precision": 18, "scale": 2 } ],
"rows": [ ["seats_active", "142.00"], ["storage_gb", "812.40"] ],
"row_count": 2, "total_rows": 2, "has_more": false
}
That is the entire server-side integration: a URL, a key, a typed JSON body your front-end renders. No
service to write, no deployment to schedule, no gateway to configure — and because the response is
no-store, every render is a fresh execution of the version you released. When the definition
of "active seats" changes, the fix is a new draft, a review, a release: the endpoint's contract stays
put and the version pointer moves, which is the change your customers actually feel — none.
Planned
The roadmap's words: "dashboards, created by your agent, you embed in your own product, fed by released pipelines and APIs, filtered per viewer." Created by the same agent that authors the pipeline; embedded behind your login, not hosted in a portal; fed by the released pipelines that already serve the endpoints; filtered so each viewer sees their rows. Named as roadmap here and on the roadmap page — not described as if it shipped, because it has not.
For planning purposes, the useful reading is architectural: the dashboard is a consumer of the same released pipeline and endpoint you can publish today — a rendering over the contract, not a new one. Teams that publish the endpoint now are not building throwaway work; they are building the exact surface the dashboard will render from.
For the reviewer
Database credentials are encrypted at rest on the server and never returned — not through a tool, not through the API. The customer integration holds a path-scoped key to the endpoint, nothing more.
An endpoint key reaches one path subtree and expires when you say; revoking it takes about a minute, and it never unlocks the product's own API. The surface you present a customer is exactly the surface you published.
The agent iterates drafts; releasing is a human verb and a release is immutable. The numbers customers see are a version your team named — and a change is a new release, not a surprise.
Each endpoint call is audited with the key, the endpoint and the execution — never the SQL text, the rows or the parameter values, which are your customers' data and stay out of the log.
GET only — every other method is refused; a released pipeline cannot carry a write-shaped node, and the check re-runs at serve time; timeouts and concurrency ceilings bound every run. The full trust model.
What it looks like
| endpoint | serves | key reach |
|---|---|---|
GET /api/x/demo/top-company-by-borough?anchor_date=2025-01-01 |
demo/top_company_by_borough · v1 | /demo/** |
from the demo workspace — released by a human, served as this version forever
Asked before
The API half of embedded analytics ships today: a released pipeline becomes a versioned GET endpoint your application calls, with per-viewer values bound as parameters. The dashboard half — created by your agent, embedded in your product — is the planned roadmap item. Publishing is docs/rest-api.md §19.
Every viewer's request carries a value — from the query string or the path — that binds to a declared parameter of the released pipeline, and the released SQL filters on it. The value is a bound scalar on a prepared statement, never pasted SQL. Binding is docs/templates.md §4.5.
One path subtree and nothing else: endpoint keys are bound to a path prefix under /api/x, cannot call your product's own API or another tenant's endpoints, and are revoked in about a minute. Key kinds and bindings are docs/auth.md §7.7.
A person on your team. The agent iterates drafts, but releasing is a human verb and a release is immutable — so the numbers your customers see are a version you can name, restore and audit. The lifecycle is docs/versioning.md §3.
Every call is audited with the key that made it, the endpoint and the execution — and never the SQL text, the row data or the parameter values, which are your customers' data. The audit log is docs/auth.md §10.
Point the demo stack at one real query your customers ask for, release it, and call the endpoint from your staging front-end. That afternoon is the whole pitch — the rest is the rest of your customers.