Nobody buys market data for the pleasure of receiving it. The value is realized in the consuming system — the repricing engine, the BI model, the alerting workflow — and the distance between a dataset and that system is where intelligence programs most often die. Delivery design is not plumbing. It's the difference between insight and installation art.
Three delivery shapes, honestly compared
| Pattern | Best for | Watch out for |
|---|
| Point-in-time API | Applications needing current values: pricing UIs, alerts, lookups | Backfill pain; design pagination and history endpoints from day one |
| Batch/warehouse sync | Analytics, modeling, joins with first-party data | Schema drift; make contracts versioned and deprecations loud |
| Event/webhook push | Threshold-based workflows: price alerts, availability changes | Ordering and replay; consumers need idempotency guidance |
Most serious deployments end up hybrid: an API for the current-state questions, scheduled syncs for analytical history. The mistake to avoid is treating these as separate products with separate schemas — one canonical contract, materialized differently.
Contracts are the product
What engineers actually buy is the schema contract: typed fields, documented semantics, units stated explicitly, null-sense explained, deprecations announced with real timelines. The response below is deliberately boring — every field's meaning is unambiguous, and that is the feature.
GET /v2/prices/{productId} — example response
{
"product_id": "p_8412",
"match_confidence": 0.97,
"observations": [
{
"source_id": "retailer_23",
"observed_at": "2026-09-08T06:12:00Z",
"price": 129.00,
"currency": "EUR",
"availability": "in_stock",
"promo": { "type": "strikethrough", "was_price": 149.00 }
}
],
"schema_version": "2026.07"
}
observed_at is not ingested_at. Observation time is what models need for point-in-time correctness.promo is structured, not flattened into a price — automation can distinguish perception plays from real cuts.schema_version in every response. Consumers pin, migrate on their schedule, and never get surprised.
Backfills and idempotency
Two questions reveal a delivery layer's maturity in minutes: "how do I rebuild 18 months of history?" and "what happens if I run this sync twice?" Cursor-paginated history endpoints and idempotent batch operations are the honest answers. If backfills require a support ticket, the API is a demo, not infrastructure.
Adoption is a design outcome
The integration patterns that consistently stick: a sandbox with production-shaped test data, copy-paste examples in the languages teams actually use, a change calendar subscribed to by humans, and quality metadata delivered with the data so consumers can gate ingestion on their side. Adoption isn't a training problem when onboarding is a Tuesday afternoon instead of a quarterly project.
Engineers don't avoid data products because they dislike data. They avoid them because they dislike unreliable contracts.
— Arjun Mehta
Deliver like a dependency — versioned, observable, boring — and your data stops being a project and starts being infrastructure.
2 comments
“Insight vs installation art” — calling our last data project exactly that in the retro. The backfill litmus test is going into our vendor checklist.