Who can see it
Only your traders. A symbol you publish is visible to a trader linked to your firm — one holding an account you issued, or one whose registration their own venue login satisfied. To everyone else on the platform, including other firms, the symbol does not exist: it is absent from search, absent from symbol resolution, and a request naming it directly answers exactly as a symbol nobody published does. There is no request shape and no error message that tells one case from the other. Your symbols also cannot collide with the shared catalog. The engine namespaces every published symbol under your firm, so you can publishES without touching the CME contract of the same name —
your traders resolve yours, everyone else resolves theirs.
What your firm builds
A UDF datafeed: three read-only JSON endpoints over HTTPS. The contract is the one Quick Charts already documents and tests against increateUdfDatafeed (src/udfDatafeed.ts), which is the
authority for every shape below — a server that already drives Quick Charts drives this engine
unchanged, with nothing to add.
GET /config
Declare what you serve. Fetched once and cached.
supported_resolutions is a promise the engine holds you to: a resolution you did not declare is
refused before a request goes out, because a UDF server asked for an unlisted bar size often answers
a different one rather than an error. Declare an empty list, or serve no /config at all, and the
engine assumes the protocol’s defaults and restricts nothing.
GET /search?query=&limit=
Return the matching symbols.
type is your own vocabulary. It is passed through to the trader verbatim rather than remapped, so
call an index an index.
If you answer supports_search: false, serve GET /symbol_info?group=<exchange> instead, in the
protocol’s columnar form — parallel arrays keyed symbol, ticker, description,
exchange-listed, type, with a scalar applying to every row. The engine fetches each exchange you
listed in /config once and searches them locally. In that mode /config must list at least one
exchange, or there is nothing to enumerate.
GET /history?symbol=&resolution=&from=&to=&countback=
Return OHLCV bars in the protocol’s columnar form. Times are epoch seconds.
s: "ok"with the arrays — bars, oldest first.s: "no_data"— an honest empty window. The chart stops paging back.s: "error"witherrmsg— this symbol or this window is bad. It is a per-symbol answer and does not count against your feed’s health, so one trader’s typo never takes your feed off the air.
to as exclusive, the way the protocol writes it — the rightmost bar is not included. The
engine bridges its own inclusive window to yours, so page seams never drop a bar. countback, when
present, outranks from: return that many bars at or before to.
Resolutions use the protocol’s own grammar: seconds as 30S, minutes bare as 5, hours as minutes
(60 is one hour), then 1D, 1W, 1M. Omit v and every bar reads as volume 0.
What you do not build
No quotes endpoint. The engine reads bars only, and a chart on a published symbol shows— for
bid/ask rather than a number nobody quoted. No push channel either — the engine polls, so an
ordinary HTTP server is the whole requirement.
Register it with us
Registration runs through us during onboarding. Send your account manager:- the base URL of your feed, e.g.
https://feed.yourfirm.com/udf; - the
Authorizationheader value your server expects, if it wants one — we send it verbatim on every request, and it is stored as a secret that no read of your firm’s record returns.
How the engine reads it
- History comes straight from
/historyon the window the chart asks for. - Live bars come from polling the tail of
/historyevery 10 seconds — the same cadence Quick Charts uses, so a server tuned for that adapter sees the same request rate from us. The newest bar re-emits as it forms and seals when the next one opens. - Traders share the poll. Ten of your traders watching one symbol cost your server one request every 10 seconds, not ten, and those subscriptions are counted against the same engine capacity every other feed is counted against.
- Every request carries a 10-second deadline, so a slow answer never hangs a chart.
When your feed goes down
Your feed going down costs your symbols and nothing else. After three consecutive transport failures — a timeout, a connection error, a non-2xx answer, an unparseable body — the engine marks your feed down and your symbols become absent for your traders: they stop listing in search, and a request naming one answers as an unknown symbol would. The rest of the platform is untouched, other firms are untouched, and no shared request fails because of it. While your feed is down the engine stops asking on every chart and probes once every 30 seconds instead, so a server that is already struggling is not hammered by the platform. One successful answer clears the state and your symbols return. We log the transition each way and see it on our own dashboards, so a feed that stays down is something we will raise with you. As: "error" answer is never counted as down. That is you telling us about one symbol, which is
the feed working.