Skip to content

Enrichment Templates

Enrichment templates automatically transform and enhance your data during ingestion. Instead of defining custom fields, you specify a template and we handle the schema, parsing, and enrichment.

Available Templates

TemplateUse CaseAuto-Added Fields
clickstreamWeb analytics, user trackingSession, device, geo, domain classification
transactionPayment/purchase dataMCC, fees, region

Clickstream Template

Optimized for web analytics, product analytics, and user behavior tracking.

Features

FeatureDescription
Session trackingSHA-1 deterministic session IDs per user, 30-min gap = new session
Duration computationTime-to-next-event per user (capped at 30 min)
Anti-bot detectionFlags users with >50 hits/min for 4+ consecutive minutes
Stealth blockingFlagged users silently accepted but data dropped (200 OK)
Domain enrichmentBatch lookup for domain categories
Geo/DeviceIP, country, city, region, zip, ISP, ASN, colo, UA parsing

Create Stream

bash
curl -X POST https://enrich.sh/streams \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "stream_id": "clicks",
    "template": "clickstream"
  }'

Input Fields (Your Data)

FieldTypeDescription
ustringPage URL
rstringReferrer URL
tint64Client timestamp
bstringPage title
dstringPlatform (web/ios/android)
zstringTimezone
lstringLanguage
sobjectScreen size {w, h}
sidstringSource identifier (app name, SDK instance)
uidstringUser ID

Output Fields (Enriched)

After enrichment, your Parquet files contain:

CategoryFields
Originalurl, referrer, title, timestamp, timezone, language, screen_size, source_id, user_id
URL Parsingdomain, scheme, host
Geoip, country, city, region, zip, isp, asn, colo
Deviceua, os_name, browser_name, device_type
Sessionsession_id, session_start_ts, event_duration
Domain Datadomain_category, domain_subcategory, intent_type
Metadatacreated_at

Example

bash
curl -X POST https://enrich.sh/ingest \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "stream_id": "clicks",
    "data": [{
      "u": "https://example.com/pricing",
      "r": "https://google.com/search?q=example",
      "t": 1738776000,
      "b": "Pricing - Example",
      "d": "web",
      "uid": "user_123"
    }]
  }'

Query Enriched Data

sql
SELECT
  session_id,
  domain,
  browser_name,
  country,
  COUNT(*) as page_views
FROM read_parquet('s3://bucket/customer/clicks/2026/02/05/**/*.parquet')
GROUP BY 1, 2, 3, 4
ORDER BY page_views DESC;

Multiple Sources → Same Stream

Send data from multiple apps or SDKs into the same clickstream stream. Each source sends its own sid, and individual users are identified by uid:

bash
# Web app
curl -X POST https://enrich.sh/ingest \
  -H "Authorization: Bearer sk_live_your_key" \
  -d '{"stream_id": "clicks", "data": [{"u": "...", "sid": "web_app", "uid": "user_a"}]}'

# Mobile app (same stream, different source)
curl -X POST https://enrich.sh/ingest \
  -H "Authorization: Bearer sk_live_your_key" \
  -d '{"stream_id": "clicks", "data": [{"u": "...", "sid": "ios_app", "uid": "user_b"}]}'

Filter by sid when querying:

sql
SELECT * FROM read_parquet('s3://.../**/*.parquet')
WHERE source_id = 'web_app';

Anti-Bot Detection

Built-in bot detection — suspicious users are flagged in the data, not silently dropped. You keep all events and filter in your queries.

  1. Rate tracking — counts events per user per minute
  2. Scoring — minutes with >50 hits flagged as suspicious
  3. Flagging — 4+ consecutive suspicious minutes → is_flagged: true on events
sql
-- Filter bots in your warehouse queries
SELECT * FROM read_parquet('s3://.../**/*.parquet')
WHERE is_flagged = false;

TIP

All events are stored — even flagged ones. This lets you analyze bot patterns, detect fraud, or adjust thresholds in your own queries.

Session Tracking Details

ParameterValue
Session gap threshold30 minutes
Duration cap30 minutes per event
Session ID algorithmSHA-1({user_id}-{session_start_ts})
Session ID format40-char hex string
State scopePer user, per stream

Transaction Template

Optimized for payment processing, e-commerce, and financial data.

Create Stream

bash
curl -X POST https://enrich.sh/streams \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "stream_id": "payments",
    "template": "transaction"
  }'

Input Fields

FieldTypeDescription
txn_idstringTransaction ID
txn_amountstringAmount
txn_currencystringCurrency code (EUR, USD)
txn_regionstringRegion (INTRA_EEA, etc.)
entity_idstringYour entity ID
scheme_feesobjectCard scheme fee data

Output Fields (Enriched)

CategoryFields
Originaltxn_id, txn_amount, txn_currency, txn_region, entity_id
Parsedamount_cents, currency_code
Feesscheme_fees_json, total_fees
Geoip, country, region
Metadatacreated_at

Example

bash
curl -X POST https://enrich.sh/ingest \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "stream_id": "payments",
    "data": [{
      "txn_id": "txn_abc123",
      "txn_amount": "99.99",
      "txn_currency": "EUR",
      "txn_region": "INTRA_EEA",
      "entity_id": "merchant_xyz",
      "scheme_fees": {
        "visa": {"total_fee": "0.25", "currency": "EUR"}
      }
    }]
  }'

Choosing the Right Approach

ApproachWhen to Use
TemplateStandard use case (analytics, payments)
Custom FieldsUnique schema, no enrichment needed
None (Schemaless)Quick testing, raw JSON storage

Combining Template + Custom Fields

bash
curl -X POST https://enrich.sh/streams \
  -H "Authorization: Bearer sk_live_your_key" \
  -d '{
    "stream_id": "hybrid",
    "template": "clickstream",
    "fields": {
      "custom_score": { "type": "float64" },
      "experiment_id": { "type": "string" }
    }
  }'

Template fields are applied first, then your custom fields are added.

Serverless data ingestion for developers.