V1 vs V2 Recommendations
Sarucci ships two recommendation engines side-by-side under the same API surface. They are not versions of each other — both are actively supported and serve different needs.
At a glance
| V1 — Rule-based | V2 — Reinforcement learning | |
|---|---|---|
| Compute | POST /v1/recommendations | POST /v2/recommendations |
| Read | (not persisted — recomputed each call) | GET /v2/recommendations (persisted runs) |
| Inputs | company_id + date range; runs over the budgets, demand, events, and competitor data already ingested for the company | Same plus the trained policy and historical performance |
| Output | Per-day recommended rate + justification text | Per-day recommended rate + confidence, phase, feature drivers, guardrails |
| Training | None | Per-property RL policy, retrainable via POST /v2/training |
| Cold start | Works immediately | Falls back to rules until a policy is trained — check GET /v2/model |
| Latency | <100ms typical | 200–500ms typical |
| Determinism | Deterministic on the same inputs | Stochastic during exploration phase |
| Explainability | Plain-text justification | Per-feature impact drivers |
| HITL hook | None | hitl_required: true when confidence is low or guardrails trip |
When to choose V1
- You're integrating for the first time and want a working pipeline today.
- You want recommendations from the data Sarucci already holds, with no model to train.
- Your operator team needs a one-line "why" they can read in a dashboard.
- You require strict determinism (e.g. regulated environments where every rate must be reproducible from inputs).
When to choose V2
- You have at least 90 days of booking history per property loaded into Sarucci.
- You want the model to learn from outcomes over time (acceptance rates, occupancy, revenue).
- You can build a UI that surfaces confidence and driver explanations.
- You're willing to operate a human-in-the-loop queue for low-confidence recommendations.
Migration path
You don't have to choose — many partners run V1 in production for cold-start properties and V2 for mature properties. Route per-property to the appropriate engine:
def get_recommendation(client, company_id, start_date, end_date, has_trained_model):
body = {"company_id": company_id, "start_date": start_date, "end_date": end_date}
if has_trained_model:
# V2 reads the latest persisted run; company_id goes in the query string.
return client.get("/v2/recommendations", params=body)
return client.post("/v1/recommendations", json=body)
Check model readiness with GET /v2/model. It reports which artifact backs inference for the
company — approved, latest, or rule (the rule-based fallback). When it reports an
approved (or latest) policy, V2 is backed by a trained model; while it reports rule, V2
returns rule-based output and you may as well call V1.