Skip to content

Reference

Limits

Every number the embed enforces, in one place, read out of the code that enforces it. Most are far above anything a real integration reaches; they are here so that hitting one is a thing you can look up rather than discover.

What a URL may say

LimitValueWhat happens past it
Symbol length32 charactersThe chart draws its refusal instead. A symbol is echoed into that page, so an unbounded attacker-supplied string in a document is how a small mistake becomes a large one.
Length of the whole live= string256 charactersThe value is ignored and the full chart is drawn. The longest valid value is a fraction of this.
A live chart's window60 to 31,622,400 secondsOutside that range the window falls back to its default, 60 bars of the interval.
Bars a live chart asks for and keeps1000A window that would need more starts part-way in. It bounds both the history request and what an open page holds in memory.
Indicators named5The rest are dropped. Each is a fetch, a compile and a Worker in the reader's browser.
Length of the whole indicators= string512 charactersThe list is refused entirely rather than truncated. Five ids at their own limit plus separators is a small fraction of this, so no honest URL is near it.
Display currencies offered8The rest are dropped. The FIRST is the one the chart opens in.
Session bands in sessions=8The rest are dropped. Each band is a full-plot fill per visible run on every repaint, so the list is bounded on its output like the indicators.
A session band's label in the URL32 charactersLetters, digits, spaces and _ . + & / -. A longer or stranger label costs its own band, never the rest.
Session bands in setSessions16Wider than the URL's, because a host naming full band objects is writing code rather than a query string; past it the whole call is refused by name.
The two behaviours differ on purpose. An indicator LIST is bounded on its output, so a sixth id is simply not run; the RAW STRING is bounded on its input, because the loop that fills the list only exits early once it has enough VALID ids, so a list made entirely of junk is walked in full and the URL is written by a stranger.

Things you draw on the chart

LimitValueWhat happens past it
A loadState document, or one setDrawings call512,000 characters of JSONcommandError, naming the size. The caps are generous, since a chart state is a whole document, and they bound what the frame will hold rather than what the product allows. Anything larger is a defect or an attack.
Starred timeframes in a loadState (favoriteIntervals)24commandError, naming the key, and nothing in the state is applied. More than any interval menu offers, so a list the reader built always fits.
Drawings in one setDrawings500commandError. Each is hit-tested on every pointer move, so this bounds the reader's cursor rather than our memory.
Lines and markers on one chart200commandError, naming the count. Every one is drawn each frame, so this bounds the reader's frame rate rather than our memory.
text and tooltip length200 characterscommandError. It is drawn on a canvas at a fixed size; a ten-thousand-character label is not a label.
lineWidth, arrowHeight, arrowSpacing1 to 100 pixelscommandError. Zero and negative are not widths, and a five-figure one is painting over the reader's chart rather than drawing on it.
Labels drawn ON a line (takeProfitLabel, addTakeProfitLabel, …)24 characterscommandError. The box MEASURES the label and grows to hold it, so a long one is not an ugly label, it is a pill reaching across the plot and covering the price action underneath. A line's own text is capped far higher because its body is meant to be wide.
bodyFont, quantityFont, font120 characterscommandError, and so does any url(): a canvas that fetches from a page we do not control is a beacon we would be hosting, the same rule a colour follows. The string is measured on every frame a line is drawn, so the cap is a cost the reader would otherwise pay.
Points on a createMultipointShape2 to 8commandError. Two is a trend line, three a triangle; past a handful it is not a drawing, it is a series, and a series belongs in the datafeed.

Colours

LimitValueWhat happens past it
Roles you may set10That IS the whole list, so nobody reaches it by using the feature. It bounds the work a stranger's URL can ask for: the parser stops once it has enough VALID pairs, so a string of nothing but invalid ones is walked in full.
Length of the whole colors= string632 charactersThe palette is dropped ENTIRELY rather than truncated, so the chart keeps the theme's own colours. Derived from the roles rather than picked: every role at its full spelling with an eight-digit value is a quarter of this.
A value in data-colors or setStyle#rgb · #rrggbb · #rrggbbaaThe attribute drops that pair; setStyle refuses the call by name. Nothing else is accepted, including rgb() and colour names. See Styling for why a strict grammar is a security property here.

Buttons you add to the toolbar

LimitValueWhat happens past it
Buttons on one chart8commandError. A header has finite room, and past it the displaced controls are the chart's own.
A button's text32 characterscommandError. Much shorter than a line's label, because this one sits in a fixed row rather than on a canvas.
A chart with no toolbardata-toolbar="1" requiredcommandError naming the attribute. The engine would create the button, since the header is only hidden rather than absent, so refusing the call is what prevents a control no reader can see.

Indicators you add

LimitValueWhat happens past it
Indicator name, and each string input64 characterscommandError.
Inputs to one createStudy16commandError. Inputs may be numbers, short strings or booleans; nothing else is accepted.

There is no cap on how many indicators a HOST may add, because removeAllStudies exists and the reader's frame rate is the only thing at stake. The indicators= parameter is capped because that list runs somebody else's code.

Trading

LimitValueWhat happens past it
setTrading unit label24 charactersTRUNCATED, and this is the one exception on the page. See below.
setTrading quantityany positive numbercommandError. A declared size that is absent, zero, negative or not a number withdraws the one-click rows rather than defaulting: the rows PRINT it, and "Buy NaN" is a control whose label is untrue about an order.
The unit label is the only value the chart shortens instead of refusing. Everything else on this page is refused by name, which is the rule the whole command API follows. A label is a decoration beside a number, so a shortened one still reads correctly where a refused setTrading would withdraw the Buy and Sell rows over a cosmetic string. Worth knowing rather than worth changing, and it is here because a silent truncation nobody documented is exactly the kind of thing this page exists for.

The frame

LimitValueWhat happens past it
Height in a ready or resize message40 to 10,000 pixelsThe message is refused, not clamped. A clamp would silently accept a hostile ten-million-pixel value as a legitimate 4,000, which teaches a host nothing and leaves a wrong-looking page.

That bound is on the MESSAGE, not on your CSS. You may size the iframe however you like; see Styling for what a chart at each size is actually like to read.

Seeing a refusal

Everything above except the frame height comes back on the same channel, so one handler catches all of them.

Every refusal, in one place
try {
  await chart.createOrderLine({ text: 'x'.repeat(1000) });
} catch (err) {
  // "text must be a string of at most 200 characters"
  console.warn(err.message);
}
Writing your own bridge rather than using the loader? The same reason arrives as a commandError message carrying { id, reason }. The loader turns it into a rejected promise and nothing else; there is no extra information it holds back.

Limits that are not here

Two kinds are deliberately absent. Rate limits are not published as a number, because the per-IP backstop in front of this app is a denial-of-service ceiling rather than a product rule and a figure would invite designing against it. And nothing here bounds YOUR datafeed: how many bars you return, how often you tick and how much history you hold are yours, and the chart asks for what it needs.

The reader's sign-in credential has its own bounds, which are a security property rather than an integration one and are described on the security model.