Skip to main content
A measurement is a block that points at the causal edge it measured. Measuring again writes a new vintage of the same fact; the old one stays, so a read as of an earlier instant answers with what was known then. The caller computes the numbers. The server checks their shape, records when it learned them, and links the preregistration if there is one. Calling this route declares each new fact with policy latest_observed (the latest known vintage wins). A fact that is already declared is not declared again.

Request

string
required
Whose memory this is, as in write memories.
object[]
required
One object per measurement:
  • edge (required): {source_id, target_id, edge_type, regime?} of a causal edge already in memory. regime must match the edge’s properties.regime (both absent counts as a match).
  • horizon (required): e.g. 30d.
  • value (required): grade (0 to 3, integer), method, method_hash, and any other fields: beta, se, unit, n_dates, p_sign, lfsr, post_mean, post_sd, p_break, half_life, cs_lo, cs_hi, e_value, prereg_sha256, framework_hash. Unknown fields are kept. p_sign is in [0, 1]; with lfsr the two sum to 1.
  • asserted_at (required): when it was measured. valid_from (required): when the sample starts. valid_to: when it ends.
  • prereg: {commitment_id} of a commitment block already in memory. The measurement gets a DEPENDS_ON edge to it.
  • fact_key: must start with measure.. Default: measure.<source_id>.<edge_type lower case>.<target_id>[.<regime>].<horizon>.
  • id: default <fact_key>.<server time, YYYYMMDDTHHMMSS.ffffffZ>. statement: default Measured <source> -<TYPE>-> <target> (<horizon>): grade <g>.
  • batch: the key of one of backfills, for a measurement made in the past.
object[]
[{key, declared_captured_at, reason}], the same rules as write memories.
captured_at and known_at are never inputs: a row that sends one is refused. Any other top-level key (backfill, say) is a 400 (TCKG_UNKNOWN_FIELD) rather than being dropped.

Response

Always 200 for a well-formed body. A refused row does not cost the others.
integer
Measurements written (the DEPENDS_ON links are not counted).
object[]
{index, reason, why}, index being the row’s position (from 0), with fact_key when the row gave one. One reason per row, the first that applies: captured_at_supplied, not_causal_edge, unknown_edge, bad_measure_key, bad_measure_value, measure_fact_policy (the fact is declared with another policy), measure_edge_mismatch (the fact already measures another edge, regime or horizon), same_fact_twice (two or more rows of one fact in one request; all of them are refused, since vintages known at the same instant never resolve), prereg_not_found. The usual write refusals (overlapping_valid, unknown_batch, …) apply too.
object[]
Written, with a note: already_remembered for an identical resend.
timestamp
The server’s stamp, shared by every row of the request.
object
{key: batch id} for backfills.
What the server guarantees: a measurement is known from its captured_at (or its batch’s declared instant), and before_measurement means the preregistration was in memory first. What it does not: that the numbers are right, that method_hash matches any code, or when the data behind the measurement was first looked at. A measurement written the existing way, as a claim with fact_key: measure.*, fact_value and payload.edge through write memories, reads the same, apart from its id and times.