Skip to main content

Overview

A custom fetcher is an optional processing layer applied on top of a datasource’s standard retrieval. Instead of returning the stored rows as-is, the datasource runs the data through additional logic every time it is queried — filtering it to a single user, reshaping columns into rows, excluding products, or computing an aggregation. Custom fetchers run at query time, so they always reflect the latest stored data and the runtime context (such as the user being personalised for). This page documents the generic custom fetchers — the ones available to any account. Some custom fetchers implement customer-specific logic and are not covered here.
Custom fetchers do not have a self-serve interface yet. They are configured on a Datasource by Reelevant. Contact your Technical Account Manager if you want to enable one.

Retrieval modes

A datasource retrieves data in one of three modes, and each custom fetcher is built for one or more of them: The summary table below shows which mode each generic custom fetcher applies to.

Setting up a custom fetcher

There is no self-serve interface for custom fetchers yet, so they are configured through the Datasources API on the datasource’s draft version. Setup is two steps: declare the fetcher with the configure_fetcher step, then promote the version with the validate step. Both calls require an access token — see Authentication for how to obtain one.
The payload.name is the fetcher identifier (e.g. per-user, generic-unwind-rows, product-exclusion), and payload.params holds the configuration fields documented for each fetcher below. For fetchers that take no configuration, send an empty object: "params": {}.
The validate step promotes the draft version to live. For pull-and-store datasources it also enqueues a verification job, so the new version only goes live once that job succeeds.

Per User

Restricts the datasource so a query returns only the records that belong to the user currently being personalised. It works on any retrieval mode and automatically targets the user identifier field defined in the Field Mapping (the CRM user field, or the purchase user field for a purchases datasource). When a datasource has a timestamp field, results are automatically sorted from most recent to oldest. The fetcher also exposes the resolved locale field so a Workflow can read the user’s locale alongside the data. This custom fetcher takes no configuration.
Use this on shared datasources (such as a CRM, purchases, or analytics feed) where a Workflow must only ever see the active user’s own rows.

Unwind Rows

Reshapes each stored row by turning its columns into several rows. One column is kept as an identifier, and every other column becomes its own row, with the original column name stored in one field and the cell value in another.

Configuration

Before and after

Consider a stored row that lists three category affinities for a user: With source = user, destination = user, and columnDestination = category, the fetcher unwinds it into:
Sorting by the value field is applied after unwinding, so you can rank the produced rows by their numeric value when valueType is number.

Product Exclusion

Filters a product datasource against a second datasource that lists items to keep or remove. A typical use is hiding products a user has already purchased, or restricting recommendations to an allow-list.

Configuration

How it works

  1. The fetcher reads the matching IDs from the exclusion datasource, respecting any query filters that apply to both datasources.
  2. In exclusion mode, those IDs are removed from the product results; in inclusion mode, only those IDs are kept.
  3. In inclusion mode, if the exclusion datasource returns no IDs, the product query returns no rows.
The exclusion list is read up to a configured limit. For very large lists, talk to your Technical Account Manager about the applicable threshold.

Expired Product Lifetime

Surfaces products that a user is due to repurchase, based on their purchase history and an expected product lifetime. It joins the current product datasource with a purchases datasource, computes when each previously bought product should run out, and returns only the products whose next purchase date falls inside a configured window.

Configuration

Each entry in temporalities describes one repurchase window:

How it works

The fetcher looks at each product the user previously bought and predicts when they will need it again. The way the lifetime is derived depends on how many times the user bought that product.
  1. It reads the user’s purchases (most recent first) and groups the purchase dates per product reference.
  2. For each product it derives an expected lifetime and an expected next purchase date (see the two behaviours below).
  3. It keeps the product only if today falls inside the matching temporality window — from windowStart days before the next purchase date to windowEnd days after it.
  4. Kept products are enriched with purchaseCount, lastPurchaseDate, and nextPurchaseDate, and can be sorted by any of these.

Behaviour 1 — single purchase (lifetime lookup)

When the product was bought once, the fetcher cannot measure a real repurchase interval, so it reads the expected lifetime from the product’s own lifetime field in the Field Mapping. The next purchase date is lastPurchaseDate + lifetime. Example — a coffee capsule pack with a lifetime field of 30 days, bought once on 1 March, using the default window (windowStart 0, windowEnd 90): The capsule pack is returned for any user query run between 31 March and 29 June. If the product has no lifetime field, a single-purchase product cannot be evaluated and is skipped.

Behaviour 2 — multiple purchases (computed average)

When the product was bought several times, the fetcher ignores the static lifetime field and instead computes the average interval between consecutive purchases for this specific user. The next purchase date is lastPurchaseDate + averageInterval. Example — the same capsule pack bought on 1 January, 1 February, and 1 March, using the default window: Using the user’s own cadence makes the prediction far more accurate than a single static lifetime. If the computed average is less than one day, the product is skipped.
When no temporalities are configured, a default rule is applied: products with a lifetime up to 365 days that are due within the next 90 days (maxLifetime 365, windowStart 0, windowEnd 90).

Proxy Lock

Applies only to real-time proxy datasources. When Reelevant receives many concurrent requests that would trigger the same upstream call, this fetcher lets the first call run and makes the others wait briefly, so the result can be served from cache instead of repeating the call.

Configuration

Use this to protect a rate-limited or expensive upstream API when a single delivery fans out into many identical real-time calls.

Proxy Aggregation

Applies only to real-time proxy datasources. After fetching the live response, it computes a single aggregation over a chosen field and adds the result to every returned row.

Configuration

Non-numeric and missing values are ignored. If no numeric values are found, the output field is empty.