Skip to main content
POST
Check a proposed change against the rules

Authorizations

x-api-key
string
header
required

Raw API key shown once when created in the Allocait app (Settings > API keys). Send it verbatim in this header; the server stores and compares only its SHA-256 hash. Allocait generates every key: alc_ followed by 64 lowercase hex characters. Keys issued before 2026-10-10 are 64 hex characters with no prefix and keep working. A key may carry an expiry (90 days or 1 year, or never). A malformed, unknown, revoked or expired key gets 401 with no further detail, and a malformed one is refused before any lookup. Keys cannot be created through this API.

Body

application/json
portfolio_id
string<uuid>
required
trades
object[]
required

The whole change, checked together. Trades in one symbol net.

Required array length: 1 - 50 elements
prices
object
required

Symbol-to-price map. Keys are ticker symbols, matched case-insensitively (normalised to uppercase); values are numbers, 0 or more. 0 is a real price, for example an option that expired worthless. On the agent surface, a symbol you leave out of this map is never priced from Allocait's own data (ADR-036); it comes back null, or the call is refused, depending on the endpoint. Two exceptions are the user's own numbers, not Allocait's: a held option with a mark is priced at its mark, so you may leave it out, and a price you pass for it replaces the mark for that call only and is never stored; an option past its expiry counts 0 whatever you pass (ADR-147).

Example:
scenario_id
string<uuid>

Default is the portfolio's active scenario, and only that (ADR-232).

Response

The rules the change puts outside their range, and the whole book after the change

portfolio_id
string<uuid>
required
scenario_id
string<uuid>
required
within_rules
boolean
required

True only when no rule is outside its range after the change, rules_judged_count is above 0 and cash.sufficient is true. A breach that existed before keeps it false. false with rules_judged_count: 0 means no rule was checked. Treat false as "not confirmed", never as a block Allocait enforces, and true as saying nothing about anything no rule covers.

newly_or_further_outside_count
integer
required

Rules with change newly_outside or further_outside. 0 means the change added no breach and deepened none.

rules_judged_count
integer
required

Class bands in the scenario plus holdings size-judged after the change (non-cash, above 0%, in a class with a range for the side the holding ends on: the position size range for a long, the short size range for a short).

rules
object[]
required

Only rules outside their range before or after the change. Rules inside both are counted in rules_judged_count, not listed.

not_covered
object[]
required

One entry per symbol no rule judges, so within_rules: true is never read as "a rule looked at this symbol". Traded symbols, and held symbols the change does not touch that have no class or that no rule judges (traded: false).

trades
object[]
required

One row per trade as sent.

cash
object
required
total_value
number
required

Priced non-cash holdings plus cash, at the prices you passed. The same before and after.

positions_updated_at
string<date-time> | null
required

When the newest holding record changed, null with no holdings. Report it with the verdict.

basis
string
required

What the result is computed from (the saved ranges, the recorded holdings, the prices you supplied). Always the same sentence.

checked_at
string<date-time>
required
exposure_after
object

The exposure reading once the whole change is applied, at the prices you supplied: the totals of ExposureReading without the by-class and per-holding lists. A fact about the book after the change, not a verdict, and within_rules does not read it. A symbol the change opens counts at Moves 1 in the class the trade named. Options count at their premium, as in ExposureReading (ADR-147).