observed by real signal

Real Signal — public API

Real Signal publishes its substrate. Every endpoint below returns aggregate-only output, never per-individual data. All are readable without authentication and freely citable by journalists, urban planners, AI assistants, or any system that needs a verifiable read of Singapore neighbourhood commercial rhythm.

Doctrine: numbers do the work; the silence (the agent's choice not to surface) is also published; every forecast is cryptographically sealed at write time and revealed at the predicted hour with the actual outcome.

Substrate

The raw observational layer the agent reads from. Aggregate, pocket-level, never per-individual.

GET /api/pocket-live

params: pocket=cluny

Current pocket snapshot: latest atmosphere reading, last 5 narrations, last 5 revealed predictions, last 5 sustainability events, 24h resonance time-series.

example response
{ "pocket": {...}, "atmosphere_latest": {...}, "narrations_recent": [...], "resonance": { "score": 0.72, "should_surface": true, "layers": {...} }, "resonance_history_24h": [...] }

try it: curl -s "https://real-signal.ai/api/pocket-live?pocket=cluny"

GET /api/observed-patterns

params: id=<outlet_id>

Inferred patterns for an outlet — quiet windows, rain sensitivity, DNA descriptor, hours overlap. Each pattern carries confidence + basis.

example response
{ "outlet_id": "...", "patterns": [ { "kind": "quiet_window", "text": "Quieter rhythm observed in your building between 14:00–17:00 SGT...", "confidence": "medium", "basis": "84 atmosphere readings over the last 14 days" }, ... ] }

try it: curl -s "https://real-signal.ai/api/observed-patterns?id="

GET /api/intent

params: pocket=cluny&slug=quiet-now

Intent-shaped substrate for one of 72 (pocket × intent) combinations. Slugs: quiet-now, rain-friendly, late-lunch, work-friendly.

example response
{ "pocket": {...}, "intent": {...}, "match_ratio": 0.34, "confidence": "medium", "reasoning": [...], "signal_tier": {...} }

try it: curl -s "https://real-signal.ai/api/intent?pocket=cluny&slug=quiet-now"

Decisions

The brain — what the agent thinks about this moment, and what it would propose if asked.

GET /api/resonance

params: pocket=cluny[&outlet=<id>][&tier=experience]

The 7-layer resonance score: time × physical × human-energy × merchant-state × attention-density × intent × temporal. Below threshold (0.5) the system stays silent.

example response
{ "resonance": { "score": 0.78, "should_surface": true, "threshold": 0.5, "decay_at": "...", "decay_reason": "...", "layers": { "time": { "score": 0.80, "reasoning": "..." }, ... } } }

try it: curl -s "https://real-signal.ai/api/resonance?pocket=cluny[&outlet=][&tier=experience]"

GET /api/deal-proposal

params: outlet=<id>

The agent's current proposal for an outlet (or null when atmosphere tier — the moment doesn't call for a deal).

example response
{ "proposal": { "tier": "experience", "headline": "...", "math": { "regular_price_sgd": 10.5, "proposed_price_sgd": 8.5, "saving_sgd": 2.0 }, "merchant_reason": "...", "consumer_reason": "...", "mutual_benefit": "..." } }

try it: curl -s "https://real-signal.ai/api/deal-proposal?outlet="

GET /api/composed-narrative

params: pocket=cluny[&outlet=<id>][&format=narration|push|mastodon|whatsapp|email_para]

Channel-sized narrative line with math embedded inside the observational sentence. Three beats: observation · math · window.

example response
{ "line": "afternoon calm at one cafe in cluny court · pairing at S$8.50 (was S$10.50) · 15:00–17:00 SGT", "tier": "experience" }

try it: curl -s "https://real-signal.ai/api/composed-narrative?pocket=cluny[&outlet=][&format=narration|push|mastodon|whatsapp|email_para]"

Forecasting

Time-locked predictions ledger. Every projection sealed at write time with a SHA-256 hash; revealed at the predicted hour with the actual outcome. Publicly verifiable.

GET /api/predictions

params: [pocket=cluny][&since=7d][&revealed=only|pending|both]

Every prediction the platform has sealed, with the actual observation + accuracy score once revealed. Recompute the SHA-256 yourself to verify the platform committed before the predicted hour.

example response
{ "predictions": [ { "generator": "pocket_projection_60m", "sealed_at": "...", "reveal_at": "...", "prediction_payload": {...}, "actual_observation": {...}, "accuracy_score": 1.0, "payload_hash": "sha256:..." } ], "stats": { "by_generator": {...}, "mean_accuracy": 0.71 } }

try it: curl -s "https://real-signal.ai/api/predictions?[pocket=cluny][&since=7d][&revealed=only|pending|both]"

GET /api/pocket-futures

params: pocket=cluny

60/120/180-minute probabilistic outlook — current Moment plus per-horizon expected state, confidence, top environmental modifier, and the sensitivity factors that would shift the outlook. Probabilistic voice: "calm through ~16:30 SGT", never a promise.

example response
{ "pocket_id": "cluny", "now": { "primary_state": "calm-productive", "summary_line": "..." }, "horizons": [ { "minutes_ahead": 60, "expected_state": "calm_productive", "confidence": 0.72, "approx_clock": "16:30", "summary_line": "..." } ], "sensitivity_factors": [ { "factor": "rain", "shifts_outlook_to": "shelter_seeking" } ] }

try it: curl -s "https://real-signal.ai/api/pocket-futures?pocket=cluny"

Restraint & calibration

The Restraint API and its supporting ledgers — the agent's decision not to speak, made queryable, scored, and auditable.

POST /api/legitimacy

params: JSON body: pocket_id, candidate_action [, user_context] [, merchant_context] [, channel]

The Restraint API. Scores whether a candidate action against a pocket would be legitimate right now — a 0-100 scalar composed from Moment, MQS, user fatigue, signal saturation, and merchant pressure, with band, recommendation, and a dry-run of the 7-gate cascade.

example response
{ "legitimacy_score": 47, "band": "borderline", "recommendation": "borderline_remain_silent", "reasoning": [ "dominant factor signal saturation 0.61." ], "factors": { "environmental_alignment": 0.72, "fatigue": 0.30, "saturation": 0.61, "merchant_pressure": 0.55, "expected_value": 0.42 }, "gates": { "why_worth_attention": { "passed": false, "score": 0.18 }, ... } }

try it: curl -s "https://real-signal.ai/api/legitimacy?JSON body: pocket_id, candidate_action [, user_context] [, merchant_context] [, channel]"

GET /api/legitimacy-index

params: [pocket=cluny][&days=7]

The Daily Legitimacy Index — one 0-100 reading per pocket per day with a one-line voice-locked reason, written each morning at 08:30 SGT. Without params: network-wide list. With pocket: today's reading. With pocket + days: last N days (1..90).

example response
{ "readings": [ { "pocket_id": "cluny", "reading_date": "2026-06-09", "score": 72, "band": "legitimate", "reason": "environment stable. attention demand low. natural movement healthy." } ], "count": 6 }

try it: curl -s "https://real-signal.ai/api/legitimacy-index?[pocket=cluny][&days=7]"

GET /api/accuracy

params: [since=1h|1d|7d|30d|all][&pocket_id=cluny][&prediction_type=quiet_window][&include_shadow=1]

Public predictions-accuracy report. High-confidence-only by default (confidence ≥ 0.68, substrate completeness ≥ 0.75, no shadow rows) — the filter is pre-declared in the response so the public number cannot drift. Headline accuracy, naive-baseline gap, by-type and by-pocket breakdowns, calibration per confidence bucket, error taxonomy.

example response
{ "headline": { "overall_accuracy": 0.73, "revealed_count": 41, "inconclusive_count": 3 }, "baseline": { "baseline_accuracy": 0.58, "gap_vs_real_signal": 0.15 }, "by_type": [ { "prediction_type": "quiet_window", "accuracy": 0.78, "count": 18 } ], "calibration": [ { "bucket": "0.7-0.85", "predictions": 18, "observed_accuracy": 0.78, "delta": 0.005 } ], "error_taxonomy": [ { "type": "decay_misjudged", "count": 4 } ] }

try it: curl -s "https://real-signal.ai/api/accuracy?[since=1h|1d|7d|30d|all][&pocket_id=cluny][&prediction_type=quiet_window][&include_shadow=1]"

GET /api/counterfactuals

params: pocket=cluny[&hours=24][&limit=50]

The counterfactual ledger — for every silence the agent chose in the window, what could have been said, with what confidence, and which gate closed. Each row carries a voice-locked candidate emission (≤18 words), the legitimacy score and band, and the substrate snapshot the agent saw.

example response
{ "count": 12, "summary": { "remain_silent_count": 9, "borderline_count": 2, "legitimate_count": 1, "avg_legitimacy_score": 31.4, "avg_candidate_confidence": 0.44 }, "entries": [ { "pocket_id": "cluny", "legitimacy_band": "remain_silent", "candidate_confidence": 0.41, "sealed_at": "..." } ] }

try it: curl -s "https://real-signal.ai/api/counterfactuals?pocket=cluny[&hours=24][&limit=50]"

GET /api/silence-vindications

params: [pocket_id=cluny][&since=1h|1d|7d|30d|all][&revealed_only=1][&limit=50]

Retro-scored silence decisions — every silence sealed, then revealed against what actually happened in the pocket. A vindicated row means the choice not to speak was the right call; the rate aggregates over the window.

example response
{ "count": 38, "summary": { "vindication_rate": 0.92, "total_revealed": 36, "total_vindicated": 33 }, "entries": [ { "pocket_id": "cluny", "gate_name": "why_worth_attention", "sealed_at": "...", "revealed": true, "vindicated": true, "attention_minutes_preserved": 2 } ] }

try it: curl -s "https://real-signal.ai/api/silence-vindications?[pocket_id=cluny][&since=1h|1d|7d|30d|all][&revealed_only=1][&limit=50]"

GET /api/trust

params: [window=7d|14d|30d]

The public trust report — signals emitted by tier, signals withheld by gate, predictions sealed/revealed/accuracy, silence correctness, failure analysis. The same numbers the founder dashboard reads, published openly. Aggregate only.

example response
{ "window": "30d", "signals_emitted": { "total": 14, "by_tier": [...] }, "signals_withheld": { "total": 847, "by_gate": [...] }, "predictions": { "total_sealed": 412, "total_revealed": 380, "overall_accuracy": 0.71, "by_generator": [...] }, "silence_correctness": { "total_revealed": 36, "vindicated": 33, "missed": 2, "vindication_rate": 0.92 }, "failure_analysis": { "wrong_gate_fired": 1, "threshold_too_strict": 2 } }

try it: curl -s "https://real-signal.ai/api/trust?[window=7d|14d|30d]"

GET /api/explanations

params: [pocket=cluny][&decision_type=emit|silence|all][&since=24h|7d|30d][&limit=50] · /api/explanations/:id for one decision

Per-emission permalink ledger — every decision the agent made or held, each with a one-line templated summary and a permalink. The detail view returns the substrate trace (atmosphere + env snapshot at decision time) behind a single emit or silence.

example response
{ "since": "24h", "decision_type": "all", "count": 21, "items": [ { "id": "silence:5f2c...", "type": "silence", "pocket_id": "cluny", "decision": "remain_silent", "summary": "cluny: agent stayed silent — saturation above ceiling.", "permalink": "/explanations/silence:5f2c..." } ] }

try it: curl -s "https://real-signal.ai/api/explanations?[pocket=cluny][&decision_type=emit|silence|all][&since=24h|7d|30d][&limit=50] · /api/explanations/:id for one decision"

Citation reports

Sealed, dated, quotable publications composed by cron — the weekly and monthly reports an assistant or a journalist can cite by permalink.

GET /api/reports/weekly

params: [pocket=cluny][&week=2026-W23][&limit=4]

The Weekly Cluny Intelligence Report — five metrics (atmosphere score, quiet windows, rain-comfort alignment, attention saturation, stable periods) plus a voice-locked narrative. Composed Monday 09:00 SGT; permalink per ISO week. Without week: the most recent report.

example response
{ "report": { "pocket_id": "cluny", "week_iso": "2026-W23", "composed_at": "...", "metrics": { "atmosphere_score": {...}, "quiet_window_score": {...}, "rain_comfort_alignment": {...}, "attention_saturation": {...}, "stable_periods": [...] }, "narrative": "..." }, "_meta": { "attribution_required": true } }

try it: curl -s "https://real-signal.ai/api/reports/weekly?[pocket=cluny][&week=2026-W23][&limit=4]"

GET /api/state-of-restraint

params: [month=2026-05][&limit=12]

The Monthly State of Restraint — network-level: signals emitted vs withheld, high-confidence accuracy vs naive baseline, silence correctness, attention minutes preserved, plus voice-locked largest-failure and largest-success lines. Sealed on the 1st covering the prior month.

example response
{ "reports": [ { "month_iso": "2026-05", "composed_at": "...", "metrics": { "signals_emitted_count": 14, "signals_withheld_count": 847, "accuracy_high_confidence": 0.73, "naive_baseline_accuracy": 0.58, "silence_correctness_rate": 0.92, "attention_minutes_preserved": 1694 }, "narrative_top_failure": "...", "narrative_top_success": "..." } ] }

try it: curl -s "https://real-signal.ai/api/state-of-restraint?[month=2026-05][&limit=12]"

GET /api/state-of-pocket

params: pocket=cluny[&month=2026-05][&limit=6]

The Monthly State of Pocket digest — most stable day of week, strongest comfort signal, strongest calm window, anomaly count. Aggregate only — never names an outlet. When readings fell below the floor for the window, the report says so instead of inventing observations.

example response
{ "pocket_id": "cluny", "month_iso": "2026-05", "report": { "composed_at": "...", "observations": { "most_stable_day": { "day": "tuesday" }, "strongest_comfort": { "signal": "light rain" }, "strongest_calm_window": { "label": "14:00–17:00" }, "anomaly_count": 3 }, "narrative": "..." } }

try it: curl -s "https://real-signal.ai/api/state-of-pocket?pocket=cluny[&month=2026-05][&limit=6]"

Benchmark

The public scoring harness — submit sealed predictions, get scored against the same methodology Real Signal scores itself.

POST /api/benchmark/submit

params: JSON body: submitter_name, prediction_window_start, prediction_window_end, predictions[] ({ pocket_id, horizon_minutes, predicted_state, predicted_calm_probability, confidence }) [, contact_email] [, system_description]

Submit a sealed batch of predictions to the Real Signal Benchmark. Append-only — once sealed, predictions cannot be edited (DB trigger blocks update/delete). Scored against the canonical predictions ledger when the window closes. Rate-limited per IP.

example response
{ "submission_id": "...", "status": "queued_for_scoring", "_meta": { "attribution_required": true } }

try it: curl -s "https://real-signal.ai/api/benchmark/submit?JSON body: submitter_name, prediction_window_start, prediction_window_end, predictions[] ({ pocket_id, horizon_minutes, predicted_state, predicted_calm_probability, confidence }) [, contact_email] [, system_description]"

GET /api/benchmark/scores

params: [limit=50] · /api/benchmark/scores/:id for one submission

The public benchmark leaderboard — sorted by silence correctness desc, then accuracy desc. Each row carries accuracy, silence correctness, calibration error, gap vs Real Signal, gap vs naive baseline, prediction count. Contact emails are never exposed.

example response
{ "leaderboard": [ { "rank": 1, "submitter_name": "...", "accuracy": 0.66, "silence_correctness": 0.81, "calibration_error": 0.09, "gap_vs_real_signal": -0.07, "gap_vs_naive": 0.08, "prediction_count": 120, "scored_at": "..." } ], "count": 3 }

try it: curl -s "https://real-signal.ai/api/benchmark/scores?[limit=50] · /api/benchmark/scores/:id for one submission"

Publication & dashboards

What the agent surfaces publicly — including the silence.

GET /api/silence

params: window=7d|14d|30d

Count of every signal the agent chose NOT to send, plus an attention-minutes-preserved estimate. The doctrine's silence-as-infrastructure made measurable.

example response
{ "total_silenced": 847, "attention_minutes_preserved": 1694, "per_pocket": [...], "per_reason": [ { "reason": "resonance_low", "count": 583 }, ... ], "daily_counts": [...] }

try it: curl -s "https://real-signal.ai/api/silence?window=7d|14d|30d"

GET /api/sustainability

params: [pocket=cluny][&merchant=<uuid>][&window=7d|30d|90d|all][&format=narrative]

Layer 4 ledger: physical magnitude AND SGD valuation for every event where the agent kept commercial value from being wasted.

example response
{ "totals": { "dollar_value_recovered": 142, "waste_avoided_units": 87, "idle_reclaimed_hours": 4, "purposeful_trips": 11 }, "per_pocket": [...] }

try it: curl -s "https://real-signal.ai/api/sustainability?[pocket=cluny][&merchant=][&window=7d|30d|90d|all][&format=narrative]"

GET /api/notebook

params: month=YYYY-MM[&pocket=cluny]

Monthly aggregate substrate for the agent's notebook archive: atmosphere readings, prediction stats, sustainability dollar value, narrations rendered.

example response
{ "month": "2026-05", "atmosphere": { "total_readings": 324, "anomalies": 7 }, "predictions": { "total_sealed": 36, "revealed": 12, "mean_accuracy": 0.71 }, "sustainability": { "total_events": 48, "dollar_value_total": 1842.5 } }

try it: curl -s "https://real-signal.ai/api/notebook?month=YYYY-MM[&pocket=cluny]"

GET /api/changelog

params: days=14

Daily history of agent state — one row per UTC day. Aggregated on demand from existing substrate; same numbers reproducible from the other endpoints in this category.

example response
{ "entries": [ { "date": "2026-05-18", "atmosphere_readings": 96, "narrations_surfaced": 12, "notifications_deferred": 187, "surfaced_ratio": 6.0, "predictions_sealed": 54, "predictions_revealed": 36, "mean_accuracy": 0.71, "sustainability_sgd": 142, "top_pocket": { "pocket_id": "cluny", "count": 28 } } ] }

try it: curl -s "https://real-signal.ai/api/changelog?days=14"

GET /api/stream

params: limit=50&since=24h[&pocket=cluny]

Per-event chronological feed across narrations, revealed predictions, and sustainability ledger. Reverse-chronological, capped at 200, since-windowed (1h, 6h, 24h, 7d, all).

example response
{ "events": [ { "type": "narration", "timestamp": "2026-05-19T10:00:00Z", "pocket_id": "cluny", "tier": "experience", "body": "afternoon calm at one cafe..." }, { "type": "prediction", "timestamp": "2026-05-19T09:00:00Z", "pocket_id": "cluny", "generator": "pocket_projection_60m", "expected": "busy", "actual": "busy", "accuracy": 1.0 }, { "type": "sustainability", "timestamp": "2026-05-19T08:00:00Z", "pocket_id": "cluny", "kind": "waste_avoided", "value": 3, "dollar_value": 10.5 } ] }

try it: curl -s "https://real-signal.ai/api/stream?limit=50&since=24h[&pocket=cluny]"

Embeddable widgets

Iframe-friendly mini-views any merchant can drop on their own website. No app download, no API key, no cross-origin restrictions.

GET /widget/pocket/:pocket

Compact iframe-friendly view of one pocket: current atmosphere state, decay reason, resonance speaking/quiet badge, "powered by Real Signal" link. ~2 KB; no external JS; sized for 320–480 px wide embeds.

example response
<!DOCTYPE html><html><body><div class="widget">...</div></body></html>

try it: curl -s "https://real-signal.ai/widget/pocket/:pocket"

System health & discoverability

Public probes for platform health + indexing.

GET /api/heartbeat

9-row health scorecard: env_snapshots freshness, agent worker, gate pass rate, takedown SLA, human reviews backlog, inbound MX, LTA signals, migrations applied, stale crons.

example response
{ "status": "green", "checks": [ { "name": "env_snapshots", "status": "green", "value": "fresh: 4 min", "hint": "..." }, ... ] }

try it: curl -s "https://real-signal.ai/api/heartbeat"

GET /api/migration-status

Which schema migrations have been applied vs missing. Heartbeat-feeding probe.

example response
{ "all_applied": true, "missing_count": 0, "checks": [ { "key": "predictions_ledger", "applied": true }, ... ] }

try it: curl -s "https://real-signal.ai/api/migration-status"

GET /api/version

Build version (the deployed git SHA). The SPA auto-refresh hook reads this to detect new deploys.

example response
{ "version": "f41822f", "deployed_at": "..." }

try it: curl -s "https://real-signal.ai/api/version"

GET /api/health

Simple liveness probe.

example response
{ "ok": true }

try it: curl -s "https://real-signal.ai/api/health"

POST /api/mcp

params: JSON-RPC 2.0 body — methods: initialize, tools/list, tools/call, ping

The MCP server — 21 tools over the pocket cognition layer (atmosphere, moment quality, legitimacy index, silence + counterfactual ledgers, predictions accuracy, weekly/monthly citation reports, outlet autopilot simulator, benchmark). Read-only except the append-only benchmark submission. Every tools/call response carries the _meta attribution envelope. GET returns the discovery manifest; well-known copy at /.well-known/mcp.json.

example response
{ "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "observed pockets: cluny." } ], "structuredContent": { "pockets": ["cluny"] }, "_meta": { "source": "real-signal.ai", "license": "CC BY-NC-ND 4.0", "attribution_required": true } } }

try it: curl -s "https://real-signal.ai/api/mcp?JSON-RPC 2.0 body — methods: initialize, tools/list, tools/call, ping"

GET /sitemap.xml

XML sitemap of every indexable surface — ~140 URLs (static + per-pocket + per-intent + per-outlet). lastmod per surface drives crawler revisits.

example response
<urlset xmlns="..."><url><loc>https://real-signal.ai/intent/cluny/quiet-now</loc><lastmod>2026-05-19</lastmod><changefreq>daily</changefreq><priority>0.6</priority></url>...</urlset>

try it: curl -s "https://real-signal.ai/sitemap.xml"

What's NOT here

Endpoints that require authentication — admin / ops dashboards, merchant proposal publishing — are deliberately not documented here. Their shapes can change without notice; only authenticated callers should depend on them. Public endpoints above are stable.