Public API · Rules

Rules API — pricing decisions, programmable.

Trigger + scope + actions. Build automations the same way the UI does, simulate against last-30-day data, then enable when it looks right.

Base URL
api.priceroom.com/api/public/v1
Format
application/json
Auth
Bearer token
Rate limit
600 req/min/key

Rule CRUD

A Rule is a trigger + scope + actions trio. The trigger watches for things like a competitor undercut, a margin drop, or a stale scrape; the scope limits which SKUs it touches; the actions decide what happens when it fires (in-app alert, email, propose price, auto-apply).

POST/api/rulesCookie session

Create an automation rule.

Body
name*, description?, enabled? (default false), priority? (0–1000, default 100), cooldownMinutes? (0–10080, default 60), when* (trigger + condition fields), scope* (mode: 'all' | 'attribute' | 'sku' + matches / list), marginFloor? ({ pct: 0–100 } | null), actions* (≥1; type: 'alert_inapp' | 'alert_email' | 'propose_price' | 'auto_apply_if_safe')
Returns
Created Rule document
curl -X POST https://app.priceroom.com/api/rules \
  -H "Content-Type: application/json" \
  -H "Cookie: pr_session=..." \
  -d '{
    "name": "Match cheapest competitor −1%",
    "enabled": false,
    "cooldownMinutes": 360,
    "when": {
      "trigger": "competitor_undercut",
      "competitorDeltaPct": 1.0
    },
    "scope": { "mode": "all" },
    "marginFloor": { "pct": 15 },
    "actions": [
      { "type": "alert_inapp", "severity": "high" },
      { "type": "propose_price", "formula": "min_competitor_minus_1pct" }
    ]
  }'
GET/api/rulesCookie session

List all rules in the tenant.

Body
Returns
Rule[]
GET/api/rules/[id]Cookie session

Fetch a single rule.

Body
Returns
Rule document
PATCH/api/rules/[id]Cookie session

Partial update — every field optional.

Body
Same shape as POST, all optional.
Returns
Updated Rule document
DELETE/api/rules/[id]Cookie session

Soft-delete the rule.

Body
Returns
{ ok: true }

Test before you enable

Two endpoints that let you understand exactly what a rule will do before flipping its switch.

POST/api/rules/[id]/simulateCookie session

Dry-run the rule across up to 25 in-scope products. Returns whether each would fire and the proposed price (if any).

Body
sampleProductIds?: ObjectId[]
Returns
{ firstFive: Array<{ sku, wouldFire, proposedCents?, reason }> }
curl -X POST https://app.priceroom.com/api/rules/RULE_ID/simulate \
  -H "Content-Type: application/json" \
  -H "Cookie: pr_session=..." \
  -d '{}'
{
  "firstFive": [
    {
      "sku": "WH-1000XM5",
      "wouldFire": true,
      "proposedCents": 28910,
      "reason": "mediamarkt.de at 29200; floor respected (margin 18.4%)"
    },
    {
      "sku": "AIRP-PRO-2",
      "wouldFire": false,
      "reason": "no competitor observation in 30d"
    }
  ]
}
POST/api/rules/[id]/toggleCookie session

Flip the enabled state. Audit-logged.

Body
Returns
{ ok: true, enabled: boolean }

Triggers and actions reference

The exhaustive enums used by `when.trigger` and `actions[].type`. All values are stable across versions of the public API.

GETTriggersCookie or Bearer

Which events can fire a rule.

Body
Returns
competitor_undercut · competitor_overcut · margin_below · margin_above · position_change · market_index · scrape_stale
GETActionsCookie or Bearer

What a rule can do when it fires.

Body
Returns
alert_inapp · alert_email · propose_price (formulas: match_cheapest, min_competitor_minus_1pct, target_margin_pct) · auto_apply_if_safe (respects marginFloor)

Errors

Every 4xx/5xx returns a stable JSON error. Use code for programmatic branching.

{
  "error": {
    "code": "invalid_api_key",
    "message": "The provided API key is invalid or revoked.",
    "requestId": "req_01HTX9..."
  }
}