Skip to main content

Entity Conditions API

Base URL: https://ecs-api.retailsvc.com/api/v1

Authenticate with an OCMS bearer token (a client_credentials token, or an IAM user token) — your tenant is resolved from it and is never accepted as a request parameter. Each endpoint below lists the permission your token needs.

Before using this reference, read Entity condition, Rules, Project restrictions, and Decisions and outcomes for what these calls actually mean.


Entity conditions​

List entity conditions​

GET /entity-conditions — permission ecs.condition.read

Returns every global entity condition (read-only, platform-owned) plus the conditions your tenant owns. On an id collision, the global condition wins.

[
{
"id": "alcohol_se",
"rule": "AGE_RESTRICTION",
"scope": "GLOBAL",
"enabled": true,
"condition_value": { "minimum_age": 18 }
}
]

Get an entity condition​

GET /entity-conditions/{id} — permission ecs.condition.read

Returns the global condition for the given id if one exists, otherwise your tenant's own. 404 if neither exists.

Create or update a tenant-scoped entity condition​

PUT /entity-conditions/{id} — permission ecs.condition.write

Creates or replaces your tenant's condition for {id}. Rejected with 409 if {id} is already used by a global condition — global ids are reserved by the platform.

Request body:

{
"rule": "AGE_RESTRICTION",
"enabled": true,
"condition_value": { "minimum_age": 18 }
}

enabled defaults to true when omitted. rule is one of AGE_RESTRICTION or LICENSE_REQUIREMENT (see Rules), and condition_value depends on it:

  • AGE_RESTRICTION: { "minimum_age": <int> }
  • LICENSE_REQUIREMENT: { "license_type": <string>, "minimum_level": <int ≥ 1, optional> }
{
"rule": "LICENSE_REQUIREMENT",
"condition_value": { "license_type": "explosives_se", "minimum_level": 3 }
}

Any other field in condition_value is rejected with 400.

Returns 200 on update or 201 on create, with the resulting condition in the same shape as the list endpoint.

Delete a tenant-scoped entity condition​

DELETE /entity-conditions/{id} — permission ecs.condition.delete

Deletes your tenant's condition for {id}. 404 if it doesn't exist; 409 if {id} is a global condition — those can't be deleted through this API.


Previewing a decision​

Both endpoints below run the same checks a real checkout would, against a single item you supply, without needing a full transaction. Useful for testing a condition or project restriction before relying on it.

Evaluate one entity condition​

POST /conditions/{conditionId}/evaluate — permission ecs.condition.evaluate

Resolves {conditionId} from your tenant's catalog, falling back to the global catalog, and evaluates one item against it.

Request:

{
"item": { "id": "item-1" },
"context": {
"customer": { "customer_age": 16 }
}
}

context.customer is optional — pass {} when there's nothing to supply. See Rules for what each rule reads from it (customer_age for age restriction, licenses for license requirement).

licenses is a list of the licenses the shopper holds, each with a type and an optional level. level is a string, e.g. "3". A plain list of strings is rejected with 400.

{
"item": { "id": "item-1" },
"context": {
"customer": { "licenses": [{ "type": "explosives_se", "level": "3" }] }
}
}

404 if no enabled condition with that id exists in either catalog, so a disabled condition can't be previewed. A condition you've only just created previews as a soft deny (condition.unknown) until it has reached checkout, the same delay checkout itself sees.

Response (ItemDecisionDto):

{
"id": "item-1",
"allow": false,
"results": [
{
"id": "alcohol_se",
"allow": false,
"decision": "HARD_DENY",
"reason": "age_restriction.underage",
"rule": "AGE_RESTRICTION"
}
]
}

Evaluate project restrictions​

POST /project-restrictions/evaluate — permission ecs.condition.evaluate

Looks up the given project's restrictions and evaluates one item against them.

Request:

{
"projectId": "fc03c9aa-bbb9-413d-997a-be8e9f6f28f0",
"item": {
"id": "item-1",
"additionalProperties": { "department": "hardware", "ecoLabel": false }
}
}

additionalProperties carries whatever item attributes your project's whitelist/blacklist restrictions check against (see Project restrictions) — omit it entirely if the item has none.

Response is the same ItemDecisionDto shape as above. A project-restriction result's id names what was checked: the property name, or "itemId" for the item-id restrictions. It's null when the project's restrictions couldn't be looked up.

{
"id": "item-1",
"allow": false,
"results": [
{
"id": "department",
"allow": false,
"decision": "HARD_DENY",
"reason": "project_restriction.whitelist_not_met",
"rule": "PROJECT_RESTRICTION"
}
]
}

Response fields reference​

ItemDecisionDto:

FieldTypeNotes
idstringEchoes the item id you sent
allowbooleantrue only if every entry in results allows
resultsarrayOne entry per check that ran, whether it allowed or denied

Each entry in results:

FieldTypeNotes
idstring or nullEntity condition id; for a project-restriction result, the property name or "itemId". null when no single restriction applies (the project lookup failed, or the restriction type isn't recognized)
allowboolean
decisionALLOW | SOFT_DENY | HARD_DENYSee Decisions and outcomes
reasonstring or nullMachine-readable reason code; null when decision is ALLOW
ruleAGE_RESTRICTION | LICENSE_REQUIREMENT | PROJECT_RESTRICTION | nullnull on a condition.unknown result