> For the complete documentation index, see [llms.txt](https://docs.abtasty.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.abtasty.com/commerce/recommendations/create-a-recommentation-strategy/repurchase-recommendation-algorithm/integrating-and-calling-the-repurchase-algorithm.md).

# 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.

{% hint style="info" %}
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.
{% endhint %}

### 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.

```json
{
  "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.

{% hint style="warning" %}
Requests carrying a `purchase_history` are inherently per-user, so cache keys are effectively individual. Cache misses are expected and acceptable for this strategy.
{% endhint %}

### 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. |

{% hint style="info" %}
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.
{% endhint %}

#### 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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.abtasty.com/commerce/recommendations/create-a-recommentation-strategy/repurchase-recommendation-algorithm/integrating-and-calling-the-repurchase-algorithm.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
