For the complete documentation index, see llms.txt. This page is also available as Markdown.

Integrating & calling the repurchase algorithm

For each product a user has already bought, the algorithm estimates its repurchase cadence and surfaces the product when the user is approaching their next forecasted repurchase date.

The API does not fetch the user's purchase history for you. It doesn't know the user and reads no purchase database. The caller (site tag, integration, CRM job, client backend) fetches the history upstream and passes it on every request. See Provide the history on every request.

Provide the history on every request

The value of purchase_history is an object mapping each product id to a list of ISO 8601 purchase timestamps.

{
  "variables": {
    "purchase_history": {
      "SKU-001": ["2025-01-15T00:00:00", "2025-04-20T00:00:00", "2025-07-10T00:00:00"],
      "SKU-002": ["2025-03-01T00:00:00"]
    }
  }
}

Constraints

  • Type: a dictionary of { string : list of strings }.

  • Keys: the product's id in the catalog (the same id as in items).

  • Timestamps: ISO 8601 strings (datetime.fromisoformat). Time zones are accepted; a missing time zone is interpreted as UTC.

  • Cap: 50 products. Beyond that, only the 50 with the most recent last purchase are kept; the rest are dropped and a warning is logged.

  • An empty list ("SKU": []) and an empty dictionary ({}) are valid; they simply produce no recommendations.

What the source returns

The repurchase builtin behaves like a catalog source: it returns product rows, filtered to the products that are repurchase-eligible for this user. Each row carries all the usual items columns (id, name, price, img_link, absolute_link, categories, engagement metrics, and so on) plus three computed columns.

Column
Type
Meaning

repurchase_frequency

FLOAT (days)

Estimated cadence D actually used: the user's own cadence, or the site-wide average as a fallback

days_since_last_purchase

INT (days)

Days elapsed since the user last bought this product

urgency_score

FLOAT [0, 1]

Peaks at 1.0 at the forecasted repurchase date, tapering to 0 at the window edges

By default the preset sorts on urgency_score DESC and returns 12 products. You can sort or filter on any column, including the three computed ones.

Errors and edge cases

Validation errors (HTTP 422)

The value of purchase_history is validated at the API boundary. A malformed value returns 422 with an explicit message.

Cause
Message

Value is not an object

Variable purchase_history must be an ITEMS_HISTORY

A key is not a string

Variable purchase_history keys must be strings

A product's value is not a list

Variable purchase_history[<id>] must be a list

A timestamp is not a string

Variable purchase_history[<id>] must contain ISO 8601 strings

A timestamp is not valid ISO 8601

Variable purchase_history[<id>] contains invalid ISO 8601 timestamp: '<value>'

Empty or reduced results (no error)

These situations raise no error; they just yield fewer or zero rows, which lets you compose a fallback with union_all.

Situation
Behavior

purchase_history missing or empty

Source returns 0 rows. Combine with a union_all fallback.

Product bought once, no site-wide average

Product excluded (cadence not estimable).

Product in history but absent from catalog

Product excluded (filtered out naturally).

Product outside the repurchase window

Product excluded (urgency_score = 0).

No eligible product

Empty result set; plan a rule-level fallback.

Unparseable timestamps for a product

That product is skipped (warning logged); the others are processed.

Because a missing variable or an empty result returns nothing rather than erroring, wrap the repurchase source in a union_all with a fallback strategy so users always get recommendations.

Structural limitations

  • No GROUP BY. The three computed columns are materialized at request time; an aggregation step drops them. The builtin is not meant to sit behind an aggregation.

  • Not batch-precomputable. The strategy depends on the per-request, per-user purchase_history. A precompute attempt fails explicitly with VIRTUAL_SOURCE_NOT_PRECACHEABLE rather than producing a wrong result. Repurchase is a real-time strategy.

Last updated

Was this helpful?