---
title: "System rules"
method: PUT
path: "/v25-10-beta/agentic-logic/system-rules/{systemKey}"
tags: ["Agentic Logic"]
---

# System rules

`PUT /v25-10-beta/agentic-logic/system-rules/{systemKey}`

## Request

- Base URL: `https://api.intelligems.io`
- URL: `https://api.intelligems.io/v25-10-beta/agentic-logic/system-rules/{systemKey}`
- Auth: API key in header `intelligems-access-token`
- TypeScript: <https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta/docs/v25-10-beta/agentic-logic/system-rules/:systemKey/put.ts> (a function with typed inputs; its response is checked against the schema)

```http
PUT /v25-10-beta/agentic-logic/system-rules/{systemKey}
```

Ensures the store's built-in rule for `systemKey` exists. Idempotent: the first
call creates the rule and enqueues its first publish; every later call returns
the same rule unchanged. The response carries `rule` and `latestPublishJob`,
which tells a still-`draft` rule's first version being on its way from having
failed.

Use the `intelligems-access-token` header. The token selects the organization; do not send `orgId`. The organization must have Agentic Logic enabled.

**Rate Limit:** 50 requests per 30s window, refilling 25 tokens every 30s.

## Path parameters

- `systemKey` 'shopify-recommendations', required: Which built-in rule to ensure. The call is idempotent: the first call for a store creates the rule and enqueues its first publish, and every later call returns the same rule.

## Response `200`

OK

- object
  - `rule` object, required: The store's built-in rule for this key.
    - `id` string, required: Server-issued rule id (uuid).
    - `organizationId` string, required: Owning organization id (uuid).
    - `name` string, required: Merchant-facing rule name.
    - `description` string, required: Plain-language summary of what the rule recommends, in what order, and for which shoppers.
    - `managedBy` 'builder' | 'code', required: 'builder' = configured from a template (templateId + templateParams + templateVersion); 'code' = a custom-code workspace rule.
    - `state` 'draft' | 'active' | 'paused', required: Lifecycle state: draft → active → paused. Paused renders as rule-absent on serving. Retiring a rule is a hard delete, legal from any state but never while referenced.
    - `templateId` string, nullable, required: Template identifier for builder rules; null for code rules.
    - `templateParams` object, nullable, required: Template parameters for builder rules, validated against the template's params schema at write time; null for code rules.
    - `templateVersion` integer, nullable, required: Template artifact version the rule was configured against (echo-on-execute model); null for code rules.
    - `targetSurfaces` string[], nullable, required: Surfaces a code rule declares it is written for, fixed at creation and never editable; the rule may only be assigned to placements on these surfaces. Null for builder rules, whose eligibility comes from their template instead. Declared, never inferred: it states which request context the rule was written against, since a surface cannot supply data it never has (post-purchase has no cart, onsite has no customer).
    - `settings` object, required: The rule's recommendation settings — item cap, the two product exclusions, and the empty-result policy. The EDITABLE copy: serving reads the copy frozen onto the active version, so changing this changes nothing until the rule is republished.
      - `maxItems` integer, required: Most products the rule may return, 1-10. The engine supplies it to the rule as `context.slotsNeeded` and trims the envelope to it. One bound for every surface, because one rule can serve several. A surface may still show fewer at once: the checkout block's grid paginates the returned list into a carousel, which is presentation and stays with the placement.
      - `excludeOutOfStock` boolean, required: Drop products with no purchasable variant. Applied where the product data already is: inside the template for a builder rule, inside the generated source for a code rule, and again as a floor when the engine hydrates the result — so the setting is true on every surface rather than only the ones that remembered to pass it.
      - `excludeItemsInCart` boolean, required: Drop products the shopper already has in the cart. Runs before the emptiness test, so an envelope this empties falls through to `onEmpty` rather than reporting itself as a result.
      - `excludePdpProduct` boolean, required: Drop the product the shopper is viewing (`request.pageProduct`, PDP only). Applied inside builder templates before the item cap, so the slot backfills, and again by the engine on every rule's result. Turn it off when the viewed product belongs in the result, e.g. a bundle built around it.
      - `onEmpty` 'hide' | 'smart-recs', required: What the slot does when the rule returns zero items: 'hide' the placement or fall back to 'smart-recs'. Errors and timeouts take the same route as a miss — there is no separate error policy — and stay distinct in telemetry.
    - `authoringSessionId` string, nullable, required: Id of the AI chat session that most recently authored this rule, or null for a rule created outside a chat (and for every rule created before the association was recorded). Follows the latest authoring conversation: creating the rule sets it, and a later revision session repoints it, so the transcript the workspace loads back after a reload — including the diagnosis of a build that gave up — is the one that explains the rule's current state.
    - `systemKey` 'shopify-recommendations', nullable: Set only on a built-in rule Intelligems provisions for every store (e.g. 'shopify-recommendations'); null or absent on every rule a merchant or Atlas created. A built-in rule is read-only: it cannot be renamed, edited, paused, resumed or deleted, and there is at most one per key per store.
    - `createdAtTs` number, required: Creation time, Unix epoch-ms.
    - `lastUpdateTs` number, required: Last update time, Unix epoch-ms.
  - `latestPublishJob` object, nullable, required: One publish job: the async unit that runs the gate pipeline against a frozen draft snapshot and, in publish mode, promotes a new active version on success.
    - `id` string, required: Publish-job id (uuid) — the handle returned by the publish endpoint.
    - `ruleId` string, required: Rule the job publishes (uuid).
    - `status` 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled', required: 'queued' | 'running' | 'succeeded' | 'failed'.
    - `mode` 'publish' | 'dry_run', required: 'publish' (runs every gate and promotes a version on success) | 'dry_run' (validation gates only, never promotes). What the job IS — a reader cannot infer it from status while the job is still in flight.
    - `startedAtTs` number, nullable, required: Worker start time, Unix epoch-ms; null while queued.
    - `finishedAtTs` number, nullable, required: Terminal time, Unix epoch-ms; null until the job finishes.
    - `resultingVersionId` string, nullable, required: Version the job promoted, when it succeeded in publish mode; null otherwise (and null again if that version is later deleted by retention).
    - `gates` object[], required: Per-gate results, in pipeline order.
      - `gateKey` 'static_contract' | 'deps_locked' | 'org_secrets_resolved' | 'required_tests_passed' | 'bundle_size' | 'runtime_timeout' | 'chain_cost' | 'scan_cost' | 'graph_consistency' | 'ai_tests_generated' | 'ai_tests_passed' | 'user_tests_passed' | 'lambda_deploy', required: Which gate this result belongs to.
      - `status` 'pending' | 'running' | 'passed' | 'failed' | 'warning' | 'blocked', required: 'pending' | 'running' | 'passed' | 'failed' | 'warning' | 'blocked'. 'warning' passes with caveats; 'blocked' means an earlier gate's failure prevented this one from running.
      - `result` string, nullable: Human-readable gate summary, when available.
      - `detailsJson` object, nullable: Structured gate details, when available.
      - `startedAtTs` number, nullable: Gate start time, Unix epoch-ms, when started.
      - `finishedAtTs` number, nullable: Gate finish time, Unix epoch-ms, when finished.

## Other responses

- `429`: Too Many Requests

---

[API](https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta.md) - [All operations](https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta/llms.txt) - [OpenAPI document](https://skmtc.dev/intelligems/apis/intelligems-external-api-v25-10-beta/revisions/7b769b2f90b1?raw)
