Integration guide · Patent Pending

Temporal Spiral

A multi-scale, NTP/NTS/PTP-disciplined coordinate for the present moment. Every /v1/spiral response carries an anchored wall clock, a per-rung confidence envelope, and — on paid tiers — a noise-classifier verdict that tells you what kind of jitter your upstream reference is exhibiting right now.

How the classifier picks a noise class

meta.spiral.stability.dominantNoiseType is not a single black-box verdict — it's the output of two independent estimators with a documented hand-off. The estimator that produced the verdict is reported alongside it as noiseEstimator on every paid-tier response, so you can audit the provenance after the fact.

  1. Riley B1 (fast path). The lag-1 autocorrelation of the recent residuals is fed to the closed-form Riley B1 discriminator. If its confidence clears SPIRAL_GREENHALL_FALLBACK_THRESHOLD the verdict is published as noiseEstimator: "riley" and the Greenhall path is skipped entirely.
  2. Greenhall ML (fallback). When Riley's confidence is below the fallback threshold (or returns unknown — typically because the residual buffer is too shallow or sits near a transition), a trained Greenhall-style classifier is consulted and its verdict is published as noiseEstimator: "greenhall".
  3. Agreement branch. When Riley is below-threshold but Greenhall independently picks the same class, the verdict is republished as noiseEstimator: "combined" with a deliberately softened confidence — the agreement is evidence, but neither estimator was confident on its own.

A fourth value, noiseEstimator: "none", means the rolling buffer is still too shallow for either estimator. Wait for more sync cycles before tuning anything against it.

All four fields — dominantNoiseType, noiseEstimator, rileyConfidence, greenhallConfidence — ship on GET /v1/spiral and POST /v1/spiral/batch under meta.spiral.stability for Pro+ keys, and the same numbers back the live dashboard panel.

Tuning the "present" window

The Pro+ anchor.displacement block tags every moment as "record", "present", or "projection" relative to the live anchor. The width of the "present" window — presentToleranceMs — is tunable so the classification lines up with how tight your own pipeline actually needs "now" to be.

The resolved value is picked from the first source in this chain that supplies one:

  1. Per-request override. Pass ?presentToleranceMs=<ms> on GET /v1/spiral, or the matching body field on POST /v1/spiral/batch and POST /v1/full. Values outside the deployment's clamp range are silently clamped to [1 ms, 24 h]; non-finite input fails fast with 400 INVALID_PRESENT_TOLERANCE_MS. The resolved number is echoed on anchor.displacement.presentToleranceMs.
  2. Tenant-wide override (Pro+). Persist one default for every API key under your account from the dashboard — no need to ship an override on every call. The per-request value still wins when both are present.
  3. Deployment default. Set by the operator via SPIRAL_PRESENT_TOLERANCE_MS (ships at 1000 ms). Used when no per-request or tenant-wide value is supplied.
Pro+ customers can persist a tenant-wide presentToleranceMs from the dashboard so every API key inherits the same "present" window.Sign in to set the tenant override →
The live per-deployment view — current Riley + Greenhall confidences, the active fallback threshold, and the flip-rate alert — lives in the customer dashboard.Sign in to view the live classifier →

Observer-frame correction (Pro+)

By default /v1/spiral returns the anchored wall clock in the same ECEF-geocentric coordinate frame the anchor itself runs in — fine for a server sitting in one rack. If your clock is somewhere else — on a drone, in a high-altitude balloon, on a moving vehicle, or in a classroom rig demonstrating GPS relativity — you can attach an observer block to the request and we will shift the returned instant by the textbook SR + GR offset (Schwarzschild weak-field, first order; the same model used by GPS, Galileo, and BIPM). The applied correction is reported back on meta.spiral.frameCorrection so the math is auditable on every response.

Position is given in WGS-84 geodetic latitudeDeg / longitudeDeg / altitudeM. Velocity is optional and may be supplied in either of two frames:

  • velocityEcefMps: [vx, vy, vz] — the Earth-Centered Earth-Fixed frame the anchor uses. Convenient when your telemetry is already in ECEF.
  • velocityEnuMps: [east, north, up] — the observer's local east-north-up tangent frame. The natural form for telemetry from a drone autopilot, a balloon flight computer, a vehicle GPS, or any "horizontal speed + climb rate" pipeline. We rotate it to ECEF at your lat/lon before applying the SR term; the rotation is exact, not a small-angle approximation.

The two velocity fields are mutually exclusive — supply one or the other, never both. Sending both is rejected with 400 INVALID_OBSERVER. Omitting velocity entirely treats the observer as stationary in ECEF (zero SR contribution); the GR term still fires off the altitude.

What it is good for, concretely:

  • Physics demos. Quote a moving clock's accumulated SR offset against a stationary reference without writing the Schwarzschild + ½v²/c² math yourself.
  • Classroom GPS-relativity labs. Reproduce the textbook +45 µs/day GR vs −7 µs/day SR numbers at GPS altitude end-to-end against a live anchored clock — useful for upper-division relativity and aerospace-engineering coursework.
  • Drone and balloon telemetry. Stream your autopilot's ENU velocity straight in — no client-side ECEF rotation, no quaternion plumbing — and get back the per-flight clock-drift budget.
  • Moving-clock setups. Train rigs, vehicle-mounted instruments, swung pendulums in outreach demos, anything with a known speed and a known location. ENU input means you can hand us the same numbers you already have on the dashboard.

An ENU example call:

curl 'https://temporalblock.com/api/v1/spiral?observer=%7B
  %22latitudeDeg%22%3A37.7749%2C
  %22longitudeDeg%22%3A-122.4194%2C
  %22altitudeM%22%3A1500%2C
  %22velocityEnuMps%22%3A%5B25%2C0%2C3%5D
%7D' \
  -H 'X-API-Key: tblk_live_…'

Observer-frame correction is a Pro+ feature, available on both GET /v1/spiral and POST /v1/spiral/batch. The batch route accepts either a single observer applied uniformly to every timestamp, or — new in trajectory mode — an observers array parallel to timestamps (length must match), so each sample is corrected against its own position and velocity. That turns one HTTP call into a one-shot trajectory upload for drone flights, balloon ascents, and vehicle telemetry where position + velocity actually change across the batch. In trajectory mode meta.spiral.frameCorrection is null and each results[i] carries its own frameCorrection. On GET /v1/spiral, Lite and Standard requests carrying an observer block receive 402 OBSERVER_FRAME_REQUIRES_PRO_TIER. On POST /v1/spiral/batch the route itself is paid-tier-only, so Lite is blocked up front with 402 VISION_BLOCK_REQUIRES_PAID_TIER before the observer is even parsed; Standard then sees the same OBSERVER_FRAME_REQUIRES_PRO_TIER as the GET route. A length mismatch on observers returns 400 OBSERVERS_LENGTH_MISMATCH; mixing observer and observers returns 400 INVALID_OBSERVERS.

Simulation clock (GET /v1/spiral/sim)

Everything above resolves the anchored present. GET /v1/spiral/sim is the other half: it encodes an instant produced by an abstract simulation clock — one that runs at a custom rate, from a custom epochSimMs, in either direction — then feeds it through the exact same Spiral encoder as GET /v1/spiral, so you get the same 12-rung coordinate, compact form, and spiral string back. It is the endpoint behind the SDK's simStamp helper.

The simulation domain is structurally isolated from the real anchored "now": it never reads the anchor loop and never writes into any stateful primitive (Skills triggers, output pacing, Causal ordering), so a rescaled or reversed sim clock cannot corrupt real-account state. Backward-moving time is permitted for the same reason. The isolation is echoed back on every response under isolation.affectsAnchoredLoop / isolation.affectsStatefulPrimitives (both false), and anchor.anchored is false with sourceLabel: "simulation".

The projection is deterministic in elapsedRealMs — the sim instant is epochSimMs + elapsedRealMs × rate × sign(direction) and the route never reads the server wall clock — so identical inputs always yield the same coordinate. Instants outside JS Date's representable range encode via the year-only deep-time path (microsecond..month phases zeroed) instead of being rejected, so synthetic and deep-time epochs work the same way. Auth-gated on the same X-API-Key chain as the other spiral endpoints.

Query parameters:

  • epochSimMs (number, default 0) — the sim instant in ms since the Unix epoch that the clock's anchor maps to. Any finite value.
  • rate (number, default 1) — sim ms advanced per real ms (magnitude; must be finite and ≥ 0). Use direction to reverse — a negative rate is rejected so the model stays unambiguous.
  • direction ("forward" | "reverse", default forward) — direction of sim-time flow relative to real time.
  • elapsedRealMs (number, default 0) — real milliseconds elapsed since the anchor; the sole driver of the projection.
  • precision (optional) — a precision floor for the full-resolution path (one of us, ms, s, min, hr, day, wk, mo, yr, dec, cen, mil). Ignored on the deep-time year-only path.

A 60×-fast-forward example (one real second becomes one sim minute):

curl 'https://temporalblock.com/api/v1/spiral/sim?epochSimMs=0&rate=60&direction=forward&elapsedRealMs=1000' \
  -H 'X-API-Key: tblk_live_…'

The response shape (abbreviated):

{
  "sim": { "epochSimMs": 0, "rate": 60, "direction": "forward", "elapsedRealMs": 1000, "simInstantMs": 60000 },
  "resolution": "full",
  "deepTime": false,
  "year": 1970,
  "precision": null,
  "compact": { "scales": ["us", "ms", "…", "mil"], "sin": [/* 12 */], "cos": [/* 12 */] },
  "spiralString": "<phase string>",
  "anchor": { "sourceLabel": "simulation", "anchored": false },
  "isolation": { "affectsAnchoredLoop": false, "affectsStatefulPrimitives": false },
  "requestId": "<id>"
}

Riley B1 and Greenhall ML on their own are well-known prior art; the hand-off rule, the agreement branch, and the per-deployment fallback threshold are the novel elements in the Spiral provisional.

Temporal Spiral is patent pending — U.S. Provisional Application No. 64/065,213 (filed 2026-05-14).