Developer docs · v1

Build on the Ghost Signal.

Public, read-only, edge-cached API. Three sensor axes (EMF, EF, RF), live transmission feed, entropy analysis, AI chat, newsletter, and reproducible random numbers derived from electromagnetic phenomena.

Base URL

https://ghost.megabyte.space
EMF sensor.gq_emf390_emf_mg
EF sensor.gq_emf390_ef_v_m
RF sensor.gq_emf390_rf_total_density_mw_m2

GQ EMF-390 tri-axis meter. Cron storage: one D1 snapshot per minute per sensor. Earliest retained reading: 2026-04-03T02:47:58.394637+00:00.

What you can build

From dashboards to entropy art

Four real projects worth shipping with this signal.

Live EMF dashboard

Poll /api/v1/sensors every 3s. Plot EMF/EF/RF on a single chart with downsampled history.

Sensor endpoints →

Reproducible random

Hash a window of EMF snapshots into a deterministic uint32. Use it for art, lotteries, or test fixtures.

Random & exports →

Google Sheets feed

One =IMPORTDATA() cell pulls every reading. Auto-refreshes hourly. No code, no auth.

See formula →

Live transmission feed

Stream every hotline call and chat message into your app via /api/v1/transmissions/live.

Transmissions →

Endpoint map

Three families, one OpenAPI spec

Skim the surface here, then jump into the live reference for schemas and try-it-out.

Sensor data 6 endpoints

EMF, EF, RF + entropy

  • GET/api/v1/sensors
  • GET/api/v1/ghost-emf/current
  • GET/api/v1/ghost-emf/history
  • GET/api/v1/ghost-emf/entropy
  • GET/api/v1/ghost-emf/meta
  • GET/api/v1/ghost-emf/timeline
Open in reference →
Exports & derived 4 endpoints

Snapshots, CSV, random

  • GET/api/v1/ghost-emf/snapshot
  • GET/api/v1/ghost-emf/export
  • GET/api/v1/ghost-emf/google-sheets
  • GET/api/v1/ghost-emf/random
Open in reference →
Transmissions & chat 5 endpoints

Live feed, chat, newsletter

  • GET/api/v1/transmissions/live
  • GET/api/v1/transmission-count
  • POST/api/v1/chat
  • POST/api/v1/newsletter/subscribe
  • GET/health
Open in reference →

Caching

Cloudflare in front of Home Assistant

Edge-cached at Cloudflare to protect the upstream sensor. Cache behavior varies by data center.

  • Current/sensors: short TTL for near-live polling
  • History/entropy: longer TTL for charts and derived data
  • Snapshots: from D1 rows written every minute by cron
  • Transmissions: uncached, direct D1 query
  • Cache API is edge-local — global HIT behavior varies

Rate limits & tracing

Public, but not abusable

Read-only and rate-limited per IP via KV counters. Every response carries tracing headers.

  • X-Request-ID — unique request identifier
  • X-RateLimit-Limit — total budget per window
  • X-RateLimit-Remaining — remaining calls
  • CORS enabled for browser-based polling
  • Chat and newsletter require POST with JSON body

Quickstart

Start polling in seconds

curl
curl https://ghost.megabyte.space/api/v1/sensors
JavaScript
const sensors = await fetch(
  "https://ghost.megabyte.space/api/v1/sensors"
).then(r => r.json())

console.log(sensors.emf.numericValue) // 0.8 mG
console.log(sensors.ef.numericValue)  // 2.1 V/m
console.log(sensors.rf.numericValue)  // 0.003 mW/m²
Python
import requests

sensors = requests.get(
    "https://ghost.megabyte.space/api/v1/sensors",
    timeout=10,
).json()

print(f"EMF: {sensors['emf']['numericValue']} mG")
Google Sheets
=IMPORTDATA("https://ghost.megabyte.space/api/v1/ghost-emf/export?format=csv")
Polling (5s interval)
let latest = null

setInterval(async () => {
  const params = latest ? `?since=${latest}` : ""
  const res = await fetch(`/api/v1/transmissions/live${params}`)
  const data = await res.json()
  if (data.latestAt) latest = data.latestAt
  data.entries.forEach(e => console.log(e.type, e.content || e.transcript))
}, 5000)

Ready to ship

Open the live reference

Schemas, parameters, response examples, and one-click try-it-out for every endpoint.

Open Interactive Reference →