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.
- 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_THRESHOLDthe verdict is published asnoiseEstimator: "riley"and the Greenhall path is skipped entirely. - 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". - 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:
- Per-request override. Pass
?presentToleranceMs=<ms>onGET /v1/spiral, or the matching body field onPOST /v1/spiral/batchandPOST /v1/full. Values outside the deployment's clamp range are silently clamped to[1 ms, 24 h]; non-finite input fails fast with400 INVALID_PRESENT_TOLERANCE_MS. The resolved number is echoed onanchor.displacement.presentToleranceMs. - 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.
- Deployment default. Set by the operator via
SPIRAL_PRESENT_TOLERANCE_MS(ships at1000 ms). Used when no per-request or tenant-wide value is supplied.
presentToleranceMs from the dashboard so every API key inherits the same "present" window.Sign in to set the tenant override →Temporal Focus Limiter
The Spiral coordinate carries every rung from microseconds to millennia at once. Most tasks only care about a slice of that range. The Focus Limiter is a band-pass over the rungs: you name the band you care about and the response marks which rungs are foreground and which are masked. It is a read-time view — it never edits the underlying coordinate, so the same moment always resolves to the same numbers.
Focus applies identically to GET /v1/spiral and POST /v1/full; both echo the result on meta.spiral.focus. Send any focus-family parameter to engage it; send none and you get the full coordinate as before.
Presets
Pass ?focus=<preset> for a named band, or ?focus=auto to let the server pick one from request context (task-phase hint, scale hint, or the resolved present tolerance):
reflex— sub-second → minutes (rapid control loops)default— seconds → hours (conversational)planning— hours → weeks (operational scheduling)historical— years → centuries (long-horizon reasoning)epoch— millennia and deep time. This band reads the coarse end off the radial deep-time rung (Ma/Ga), flagged onusesRadialRung.
Custom band
For an arbitrary slice, pass a rung pair instead of a preset: ?focusFrom=<rung>&focusTo=<rung> — for example focusFrom=s&focusTo=hr. Rung names run us, ms, s, min, hr, day, wk, mo, yr, dec, cen, mil. The pair is normalized fine → coarse, so order does not matter. An unknown rung name or a band combined with a preset fails fast with 400.
On POST /v1/full the same focus family travels in the JSON body — a custom band looks like:
curl -X POST 'https://api.temporalblock.com/api/v1/full' \
-H 'X-API-Key: tblk_live_…' \
-H 'Content-Type: application/json' \
-d '{
"query": "What changed since my last deploy?",
"syncProvider": "brave",
"syncApiKey": "…",
"focusFrom": "s",
"focusTo": "hr"
}'Mask vs prune
?focusMode=mask (the default) keeps every rung in the response and labels each foreground or masked on focus.rungs, so the masked backdrop stays available. ?focusMode=prune drops the out-of-band rungs from the focus view entirely while the coordinate itself stays byte-stable. Add ?focusLock=true to pin the band so auto-widening cannot move it; the choice is echoed on focus.locked.
Advisory present tolerance
Each focus result carries focus.suggestedPresentToleranceMs — the cycle length of the band's fine edge. A coarser band implies a wider sense of "now", so this advisory value grows with the band. It only ever widens the resolved present window, never narrows it, and an explicit presentToleranceMs override always wins.
Tier surface
The band, mode, foreground/masked rung labels, and the advisory tolerance are available on every tier, including Lite. Standard and above additionally receive the draw-from samples — focus.rollup (rungs finer than the band) and focus.context (rungs coarser than the band) — so you can pull a masked rung back in on demand without a second request.
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://api.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, default0) — the sim instant in ms since the Unix epoch that the clock's anchor maps to. Any finite value.rate(number, default1) — sim ms advanced per real ms (magnitude; must be finite and ≥ 0). Usedirectionto reverse — a negative rate is rejected so the model stays unambiguous.direction("forward"|"reverse", defaultforward) — direction of sim-time flow relative to real time.elapsedRealMs(number, default0) — real milliseconds elapsed since the anchor; the sole driver of the projection.precision(optional) — a precision floor for the full-resolution path (one ofus, 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://api.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.
Mathematical foundations: θ
Every rung in the Spiral is a phase angle θ (theta) ∈ [0, 2π) — the fractional angular position of the current moment within the rung's cycle. The encoding lifts each timestamp to a point on the unit circle: θ_i = 2π × frac(t / T_i), returned as (sin θ_i, cos θ_i) so a recurrent model can interpolate across time continuously without re-parsing strings.
The twelve rungs together define a point on the 12-dimensional torus T¹² — twelve independent unit circles, one per scale. The global (13th) rung adds a monotone radial coordinate using the logarithmic spiral r = log(1 + |Δt| / T₀), giving the encoding a handle on "how far along the trajectory am I?" that the cyclic angles alone cannot provide.
Related
- Angular coordinate θ — phase angle referenceHow θ is computed per rung, the twelve scales table, and worked examples for robotics, AI inference, and orbital mechanics
- Sinusoidal Fourier encoding — feature map framingHow sin/cos pairs function as a Fourier feature map and why that matters for ML models
- Orbital mechanics — Spiral in practiceHow satellite and spacecraft pipelines use multi-scale Spiral coordinates for real-time trajectory correlation
- Robotics & real-time controlSub-millisecond Spiral integration for sensor fusion and control-loop scheduling on robotic platforms
- Gaming & simulationUsing the Spiral coordinate to drive game-world clocks, sim-speed scaling, and custom calendar systems
- Time evolution — how coordinates changeHow Spiral coordinates evolve as time advances and what that means for downstream consumers tracking phase drift
Temporal Spiral is patent pending — U.S. Provisional Application No. 64/065,213 (filed 2026-05-14).