Beyond Markets does not connect to Bookmap. Bookmap has no cloud API — the only programmatic surface is an add-on running inside the Bookmap desktop app. So the data flows the other way: a small add-on you run in Bookmap computes derived order-flow signals from the live book and POSTs them to us. The raw order book never leaves your machine, which keeps us clear of feed-redistribution licensing.
Phase 0 is a display-only validation feed: signals are stored and shown to bot/admin users so we can judge their quality before anything is wired to live orders. No LLM touches this path; no orders are placed.
Bookmap desktop ──(your add-on: L1 Java / BrAPI consumer)──▶ POST /api/ingest/bookmap
│
.data/orderflow.db (48h)
│
GET /api/orderflow ──▶ "Order Flow" view
POST https://beyondmarkets.ai/api/ingest/bookmap
Content-Type: application/json
Authorization: Bearer <BOOKMAP_INGEST_TOKEN>
Auth is a shared secret. Set BOOKMAP_INGEST_TOKEN in the server environment and send the
same value as a Bearer header (or ?secret=<token> if your HTTP client can't set headers).
Until the env var is set the endpoint rejects everything with 403 — it never accepts
anonymous writes.
Send one event object, a bare JSON array of events, or {"events": [...]}.
Max 500 events per request (over that → 413).
| Field | Required | Type | Notes |
|---|---|---|---|
symbol |
yes | string | Ticker, ≤16 chars, [A-Z0-9.-] only. Upper-cased server-side. |
event_type |
yes | string | One of the whitelist below. Upper-cased server-side. |
side |
no | string | BUY / SELL / NEUTRAL. Anything else → stored as null. |
price |
no | number | Level the signal fired at. |
size |
no | number | Contracts / shares involved. |
strength |
no | number | Your confidence / magnitude score (free scale). |
event_time |
no | string | ISO-8601 of when the signal fired in Bookmap. Falls back to receive time. |
id |
no | string | Your dedup key, ≤64 chars. Re-POSTing the same id is ignored (idempotent). Omit → server generates one. |
meta |
no | object | Any extra JSON (levels, ratios, notes). Serialized, capped at 2000 chars. |
event_type whitelistABSORPTION, SWEEP, ICEBERG, STOP_RUN, IMBALANCE, LIQUIDITY_WALL,
VWAP_CROSS, STRENGTH
Anything not on the list is dropped (counted in rejected, not an error). Ask to extend
the list — it's a one-line change server-side.
{ "received": 3, "accepted": 2, "rejected": 1, "stored": 2 }
accepted = passed validation; stored = actually written (accepted minus id
duplicates already on file).
curl -X POST https://beyondmarkets.ai/api/ingest/bookmap \
-H "Authorization: Bearer $BOOKMAP_INGEST_TOKEN" \
-H "Content-Type: application/json" \
-d '{"events":[
{"id":"bm-8842","symbol":"ES","event_type":"ABSORPTION","side":"BUY",
"price":5512.25,"size":1840,"strength":0.82,
"event_time":"2026-07-28T14:31:07Z",
"meta":{"levels":3,"bid_ask_ratio":4.1}},
{"symbol":"NQ","event_type":"STOP_RUN","side":"SELL","price":19880.5}
]}'
GET /api/orderflow?symbol=ES&hours=48&limit=200
Authorization: Bearer <user token>
Bot/admin users only (403 otherwise). symbol optional (omit = all), hours clamped to
48, limit clamped to 500. Also surfaced in the gated Order Flow nav view.
.data/orderflow.db (SQLite, WAL) is created on first write and persists on the VPS
(the .data/ dir is excluded from deploys).No order placement, no trade triggers, no sizing changes. Wiring these signals into the swing-trade / propose loop is a later phase and a separate decision.
See routes/orderflow.py for the implementation and its selfcheck.