Spoolis docs
Promise replay
Replay submitted history under candidate vendor terms and inspect hypothetical results.
What it does
Promise replay applies terms the vendor chooses to submitted historical units and corrections. Every remedy is hypothetical, and the result does not predict future results.
The vendor makes the promise. This API only calculates what those terms would have produced for the supplied history.
When to use it
Use it before adopting candidate terms, or when comparing thresholds and finality windows against the same history. It does not create a live Promise, Remedy Event, or signed artifact.
Authentication and scope
Send a full-scope API key as a bearer token. Missing keys return 401, and keys without full scope return 403.
Request
Send JSON to POST /api/v1/promise-replay. as_of is required, must include a UTC offset, and is the only clock used by the replay.
{
"promise": {
"promise_version": "replay/1",
"window": "month",
"threshold_bp": 8000,
"finality_days": 7,
"uncertain_treatment": "exclude_from_rate",
"fee_basis": "delivered_value",
"remedy_tiers": [
{
"min_rate_bp": 0,
"remedy_bp": 2000
}
],
"min_units": 1
},
"units": [
{
"unit_id": "unit-1",
"customer_id": "customer-1",
"delivered_at": "2026-01-01T00:00:00.000Z",
"verdict": "pass",
"value_cents": 1000
}
],
"corrections": [],
"as_of": "2026-02-08T00:00:00.000Z",
"sensitivity": {
"threshold_bp": [
7500,
8000
],
"finality_days": [
7,
14
]
}
}Response
run_id identifies the run. report contains the terms, history summary, measured periods, hypothetical results, concentration, correction effects, and sensitivity grids. markdown is a rendered readout.
A measured customer-period has at least min_units counted units. A not final period has not reached finality at as_of. An unmeasured period lacks enough counted units. The threshold and finality grids rerun the same history across the supplied sensitivity values.
This is a replay of your own history under terms you chose.
It does not predict future results.
Whether to offer a promise, and on what terms, is your decision.Limits
- Request body: 4,300,000 bytes.
- Historical units: 50,000.
- Corrections: 50,000.
- Values in each sensitivity list: 10.
- Characters in each identifier: 128.
- Requests: 20 per minute and 2,000 per day.
Errors
invalid_promise: Correct the candidate promise fields and retry.invalid_tiers: Provide valid hypothetical remedy tiers starting at zero and retry.invalid_unit: Correct the indicated historical unit or correction and retry.duplicate_unit_id: Give every historical unit a uniqueunit_idand retry.unknown_correction_unit: Reference onlyunit_idvalues present inunitsand retry.correction_before_delivery: Move each correction to or after its unit delivery time and retry.invalid_timestamp: Use valid ISO 8601 timestamps with a UTC offset and retry.invalid_as_of: Use a valid ISO 8601as_oftimestamp with a UTC offset and retry.invalid_sensitivity: Correct the sensitivity values and retry.empty_history: Add at least one historical unit and retry.
Transport failures use input_too_large, invalid_json, validation_failed, rate_limited, or internal_error. Follow remediation and Retry-After when present.
Privacy
The submitted history is processed in memory and is not stored or logged. The handler records run status, duration, and aggregate counts, not submitted units.