7 days Pro+ free · no cardStart my free trial

Troubleshooting

Error identifiers you may encounter, what they mean, and what to do about them.

Charts stay blank or report WebGL problems

Charts are drawn with WebGL. If the browser cannot create a WebGL context at all, the chart reports that it failed to initialize and asks you to update your browser or enable hardware acceleration — those two steps are the remedy. If the graphics context is lost later, for example after a GPU reset, a discarded tab, or resuming a mobile device, the chart says rendering is paused and will resume when the GPU recovers. Recovery is automatic: when the browser restores the context the chart rebuilds its GPU resources and re-uploads the current candles, so no page reload is needed. If the rebuild itself fails, the chart stays paused and the failure is written to the browser console.

Initializingcontext createdRenderingGPU context lostPausedcontext restoredRebuildingcandles re-uploadedrecovery is automatic — no page reload neededStoppedreported in the browser consoleno context availablerebuild failed
The chart asks the canvas for a WebGL2 context on mount. If none is returned, initialization fails once and permanently for that page load, and the chart shows the update-browser or enable-hardware-acceleration message. If a context exists and is later lost, the chart cancels the browser's default handling of the loss — the step that makes restoration possible at all — and pauses rendering. On restoration it rebuilds its GPU resources and forces a full re-upload of the current candles, then resumes. If that rebuild throws, the chart returns to paused and writes the failure to the browser console; every transition leaves a `[WebGLChart]` console line.

What your browser has to provide

The candlestick and heatmap charts are drawn on a WebGL2 context. The renderer asks the canvas for webgl2 specifically and raises an error when the browser returns nothing, which is the point where the chart reports that WebGL failed to initialize and suggests updating the browser or enabling hardware acceleration. There is no software drawing path for the candles themselves — the annotation layer uses a plain 2D canvas, but without WebGL2 the price series does not render at all. A browser that supports only the first WebGL generation, or one running with acceleration disabled, therefore produces a blank chart with that exact message.

When a context is created and later lost — a GPU driver reset, a discarded background tab, a mobile device resuming — the chart cancels the browser's default handling of the loss, which is what makes automatic restoration possible in the first place, and switches to the paused state. On restoration it rebuilds its GPU resources, invalidates its buffer version so every candle is uploaded again, and returns to drawing. Each step leaves a line in the browser console prefixed [WebGLChart]: one for the loss, one for the successful rebuild, and an error line if the rebuild fails. Those three lines are the quickest evidence to include in a report about a blank chart.

Sign-in redirects, upgrade prompts and disabled features

Opening a protected page while signed out sends you to the sign-in page with your destination preserved, and returns you there afterwards; the same situation on an API request answers 401 with UNAUTHORIZED. If you are signed in but your plan does not cover the page, you are redirected to the upgrade page with the required tier in the query string, and the equivalent API request answers 402 with PAYMENT_REQUIRED plus the feature key. Live chat is gated the same way — on the preview tier the support page shows an upgrade call to action instead of chat. A feature switched off by an operator answers 503 with KILL_SWITCH and a Retry-After header.

In the browserOver the APIRequestSigned in?noSign-in page303 → /auth401UNAUTHORIZEDyesPlan covers it?noUpgrade page303 → /upgrade402PAYMENT_REQUIREDyesFeature enabled?noComing soon503503KILL_SWITCH + Retry-AfteryesThe page renders
The authorization gate decides once and then renders the decision twice. Not signed in sends a page to the sign-in screen with the destination preserved, and answers an API call with 401 UNAUTHORIZED. A plan that does not cover the route sends a page to the upgrade screen carrying the source, the original path and the required tier, and answers an API call with 402 PAYMENT_REQUIRED plus the feature key and required tier. A feature switched off renders the kill-switch error page for a browser and a problem+json document for an API caller. Both 503 variants carry the same Retry-After value from the feature's registry entry: 60 seconds for the funding heatmap, 1800 for the CME detector, 300 by default.

Locked, clamped and delayed — what is not a fault

Two visual signals mean "your plan does not include this", and neither is an error. A gated surface is covered by a padlock overlay that intercepts both mouse clicks and keyboard activation and opens the upgrade dialog instead of the underlying link. A partially visible data widget gets an inline gold pill instead — used where data is present but reduced, such as a delayed tick or a clamped history depth. If a chart shows fewer bars than you expect and carries that pill, the history was shortened on purpose rather than lost.

Timing explains a third observation. A gate stays deliberately indeterminate until your entitlements have loaded: before that it is hidden and inert, so paying users never see a locked state flash before it unlocks. The visible consequence is that a gated tile can be empty for a moment right after a page load. On the server, the same policy answers API requests with 402 and a payload naming the feature key and the required tier, while a browser navigation is redirected to the upgrade page with the source, the original path and the required tier in the query string — which is why the upgrade page can tell you exactly what you tried to open.

The error codes an API response carries

Every response from the app's own API has a fixed shape. A success carries success: true, a data payload and a timestamp. A failure carries success: false and an error object holding a machine-readable code, a human-readable message, and optionally a target naming the field at fault, a details object with extra context, and a doc_url. Quote the code when you report a problem: the code is stable, the message wording is not. Twelve codes exist, and each one is tied to a single HTTP status.

Two response shapes sit outside that set. Older endpoints answer in a legacy envelope of code, msg, data and success, where code is a numeric string grouped by class: 10xxx for input problems, 20xxx for authentication, 30xxx for authorization, 40xxx for missing or conflicting resources, 50xxx for server faults and 60xxx for upstream services. Database problems are translated before they reach you: a lost connection becomes 503 with "Database temporarily unavailable", a query that exceeds its time limit becomes 504 with "Request timed out", a duplicate becomes 409, and a constraint violation becomes 400. The first two are worth retrying; the last two will repeat until the input changes.

  • BAD_REQUEST — 400. The request was malformed. Check the parameters you sent.
  • VALIDATION_ERROR — 400. One input failed validation; the response names it in target.
  • UNAUTHORIZED — 401. No valid session. Sign in and repeat the request.
  • PAYMENT_REQUIRED — 402. Signed in, but the plan does not cover it. details carries featureKey, requiredTier and, for domain gates, requiredDomain.
  • FORBIDDEN — 403. Authenticated but not permitted. The precise reason is deliberately kept server-side.
  • NOT_FOUND — 404. No such resource at that address.
  • CONFLICT — 409. The resource changed underneath you, or already exists. Reload and retry.
  • PAYLOAD_TOO_LARGE — 413. The request body exceeds the accepted size.
  • RATE_LIMITED — 429. Too many requests. The response carries Retry-After, X-RateLimit-Limit and X-RateLimit-Remaining; AI endpoints have their own separate budget and answer with the distinct code AI_RATE_LIMITED.
  • INTERNAL_ERROR — 500. An unexpected server fault. Report it with your Error ID.
  • UPSTREAM_ERROR — 502. A service the endpoint depends on failed. Retry later.
  • SERVICE_UNAVAILABLE — 503. Temporarily unavailable. Note that a feature switched off on purpose uses a different 503 body, described below.

Kill switches: who turns a feature off, and for how long

A kill switch is an off switch for one named feature, operated by the Athenum team rather than by you, and it is the reason a page can be unreachable while the rest of the app is healthy. Two different situations produce the same 503. If the feature is switched off because its backend has not shipped yet, the error page reads "Coming Soon" and explains that the feature is in development. If an operator turned a working feature off, the page reads "Temporarily Unavailable". Both responses identify themselves with the code KILL_SWITCH and a stable public feature name such as funding-heatmap or cme-detector.

The response tells you how long to wait. Each switch carries its own Retry-After value: 60 seconds for the funding heatmap, 1800 seconds for the CME detector, and 300 seconds for anything without an explicit setting. API callers get the same information as application/problem+json, including a defaultKilled flag that distinguishes the unbuilt case from the operator case. The 503 itself is never cached, and successful responses on switchable endpoints are capped at ten seconds of caching, so a switch flip reaches you quickly; a shared cache may still serve the previous answer for roughly fifteen seconds after a flip.

A killed route is normally not reachable by clicking. Routes that a switch blocks entirely are filtered out of the home page cards and hidden from the command palette, so the 503 is mostly seen by people using a bookmark, a direct link or the API. Not every switch blocks a route: some change behavior in place instead, which is why a feature can be affected without any page returning 503. Kill-switch pages carry no Error ID, because the response is a deliberate decision rather than an incident, and no identifier is invented to fill the field.

Site-wide maintenance versus a single failing feature

A planned maintenance window looks different from every other failure. Instead of the usual error page you get a standalone document headed "We'll be back soon", with no navigation, no Error ID and no support link. It is served with HTTP 503 and a Retry-After of one hour. The page is fully self-contained — its styling and logo are embedded, and it makes no network calls — so it still renders when the backend, the database and analytics are all unreachable. It is also marked as non-indexable, so search engines treat the outage as temporary.

The gate is deliberately narrow. It only replaces browser page requests: GET or HEAD requests that ask for HTML. API calls under /api/ pass straight through, as do the container health endpoints and any request for scripts, styles or fonts. A consequence worth knowing: during maintenance an API client or an embedded integration can keep working normally while the browser shows the maintenance page. If you see "We'll be back soon" the whole site is affected; if you see a 503 error page naming one feature, only that feature is.

Nothing renderswork from the outside inEvery page blank?yesSite-wide maintenance503 with a retry hintnoOne whole page returns 503?yesKill switch on one featurecode KILL_SWITCHnoOnly the chart area blank?yesWebGL could not startenable hardware accelerationnoPanel says a read failed?yesUpstream read failedretryable — try again laternoPanel says it is waiting?yesNo data yetthe collector has not deliverednoPadlock badgea plan clamp, not a fault
Read the failure from the outside in. Every page blank means the site-wide maintenance gate is active (503 with a one-hour retry hint). A single page answering 503 with "Coming Soon" or "Temporarily Unavailable" is a kill switch on one named feature. Inside a page that loads, the chart area and a data panel fail differently: a chart with no WebGL2 context reports an initialization failure, while a panel states its own reason. "Fleet read failed" is a transport error with a retry button and the source may still be healthy; "Awaiting Fleet-Bridge" with the UNAVAILABLE badge means the read succeeded and returned nothing; a padlock badge means a plan limit, not a fault.

Reading an empty panel: the badge names the failure

Panels on the macro pages carry a small badge in the corner, and that badge is the fastest way to tell an outage from a quiet data source. Five of the badge states describe real data, and two describe the panel itself. Because the badge is derived from the same freshness rules the panel uses to draw, it cannot claim a state the data does not support: a panel with nothing to show is never labelled STALE, and a missing value is never replaced by a stand-in number.

Panel-level shells add a second layer of information. A first load in flight renders a skeleton with no verdict and no copy. A read that failed in transport renders an error card with the wording "Fleet read failed — the source may still be live. Retry to reload." and a retry button — the source may well be healthy, and retrying is the correct response. A read that succeeded but returned no rows renders "Awaiting Fleet-Bridge" with the UNAVAILABLE badge. Those two look similar and mean opposite things: the first is a connection problem you can retry, the second means the series has not started flowing yet.

TradeFI panels report the reason in words instead of a badge. When the data provider failed, the panel says the data is temporarily unavailable. When the provider answered with nothing, it says no data is available for that symbol. Institutional ownership adds a third case: a note explaining that the view is an official tracked-institution subset and representative rather than exhaustive — that is a scope statement, not a fault. Peer lists behave the same way and name a non-default source in a note above the panel when one was used.

  • LIVE — an intraday or realtime observation inside its expected cadence.
  • EOD — an honest period close for a daily, weekly, monthly or quarterly series.
  • STALE — a real value, but older than the series' expected update cadence.
  • FALLBACK — last-known-good cached data, explicitly not the current value.
  • MODEL — a computed heuristic or Athenum construction, not a direct observation.
  • UNAVAILABLE — the panel is in an error state and nothing is rendered.
  • LOADING — the first load is still in flight and freshness is not yet determined.

Reporting a problem: your Error ID

When a request fails, the error page shows the HTTP status, a short title and — when one was generated — an Error ID. That identifier is minted for your specific incident and attached to the recorded error report, so support can find exactly your case. Use the Copy button next to it, then choose “Chat with support”: the link carries the Error ID through to the support page. When reporting, include the Error ID, the page address and what you were doing. Not every error has one — for a temporarily disabled feature no placeholder is invented, so the field is simply absent.

Where your Error ID goes after you copy it

The identifier on the error page is minted on the server, once per incident, at the moment the failure is caught. The server writes a log entry containing that identifier together with the HTTP status, the error name, the request path, the request method and a timestamp; in production the entry deliberately omits stack traces and internal detail. The same identifier is attached to the incident sent to error tracking, so support can correlate your copy of the id with the recorded failure. Requests that simply hit a missing page are the exception: they still receive an identifier, but they are not forwarded to error tracking.

What the browser receives back is intentionally thin — a generic message plus the identifier — so no internal detail leaks through the page. Pressing "Chat with support" carries the identifier onward: the link opens the support page with an incident topic, the Error ID and a request to open chat, rather than launching a chat widget on the failing page. If the Copy button appears to do nothing, the clipboard write was refused — this happens on insecure origins or when clipboard permission is denied — and the failure is logged in the browser console; select the identifier by hand in that case.

Whether live chat is actually available on the support page depends on three checks made before the page renders. Chat requires a paid plan: on the preview tier the page shows an upgrade prompt in its place. Chat is also withheld while the support messenger switch is off, and while the request needs consent that has not been recorded — which is the case for requests that look European, British or Swiss, and for requests that carry no country signal at all, since the check fails closed. In every one of those cases the page still offers email and the Discord community, and those two are always present regardless of plan.

What to check before you report a problem

Most of what support would ask you is visible on the screen already. The checks below take under a minute and turn "it's broken" into a report that can be acted on. Work from the outside in — whole site, then page, then panel — because each layer has a different owner and a different fix. Nothing here requires developer tools except the two items that explicitly mention them.

  • Establish the scope. Is every page affected, one page, or one panel inside an otherwise working page? "We'll be back soon" means the whole site; a 503 page naming a feature means only that feature.
  • Read the wording verbatim. "Coming Soon" and "Temporarily Unavailable" are different situations even though both are 503, and the panel texts "Fleet read failed" and "Awaiting Fleet-Bridge" mean opposite things.
  • Look for a badge. LOADING, STALE, FALLBACK and UNAVAILABLE each describe a different condition, and a padlock or gold pill means a plan limit rather than a fault.
  • Retry once after waiting. Temporary responses state their own retry window in the Retry-After header, visible in the browser's network panel; retrying earlier will usually return the same answer.
  • For a blank chart, open the browser console and look for lines prefixed [WebGLChart], then confirm the browser is current and hardware acceleration is enabled.
  • Copy the Error ID if one is shown. If the Copy button does nothing, select it manually — the clipboard write can be refused by the browser.
  • Note the page address, the time, and what you did immediately before the failure. The Error ID identifies the incident; those three identify what you were trying to achieve.

Collector error codes

The futures data collector tags every failure with a stable code, and that code appears in square brackets wherever the error text is shown or logged. These are backend identifiers: seeing one in a support reply or a status note tells you which stage failed, and whether the collector retried, fell back to another source, or gave up.

CodeMeaningRecovery
FUT-1001HttpFailedThe request to the exchange never completed.HTTP request failed for {exchange}: {message}Retried
FUT-1002ExchangeErrorThe exchange answered, but with an error of its own.Exchange error for {exchange}: {message}Falls back to another source
FUT-1003RateLimitExceededThe exchange rejected the call for exceeding its rate limit.API rate limit hit for {exchange}Retried
FUT-1004ParseFailedA response arrived but could not be read in the expected shape.Parse error for {exchange}: {message}Falls back to another source
FUT-1005DatabaseErrorWriting or reading the collected data failed.Database error: {source}Retried
FUT-1006SerializationErrorA payload could not be encoded or decoded, so retrying will not help.Serialization error: {source}Fatal
FUT-1007RequestErrorThe HTTP client itself failed before or during the call.Request error: {source}Retried
FUT-1008ConfigErrorConfiguration or environment is wrong — this is not a market-data problem.Config error: {message}Fatal
FUT-1009RateLimiterInternalThe collector's own rate limiter failed.Rate limiter error: {message}Retried
FUT-1010UnknownA failure that does not match any of the categories above. No fixed recovery action is defined for it.{message}Unclassified

Volume-delta error codes

The volume-delta endpoint returns a VDLT_-prefixed code and a hint. Retryable errors are transient — the same request can succeed shortly afterwards; the others need the request itself to change.

CodeRetryableHint returned by the API
VDLT_EXCHANGE_TIMEOUTYesRetry after a few seconds. The exchange may be experiencing high load.
VDLT_EXCHANGE_RATE_LIMITEDYesRetry after 30s. Reduce request frequency.
VDLT_EXCHANGE_BAD_RESPONSENoThe exchange returned malformed data. Try a different exchange filter.
VDLT_EXCHANGE_UNAVAILABLEYesThe exchange API is down. Data from other exchanges is still available.
VDLT_OHLC_SOURCE_FAILEDYesBinance is the primary price source. Retry in a few seconds.
VDLT_NO_DATANoAll configured exchanges failed. Check the exchanges parameter or try again later.
VDLT_INVALID_INTERVALNoValid intervals: 1m, 3m, 5m, 15m, 30m, 1h, 4h, 8h, 12h, 1d
VDLT_INVALID_ASSETNoValid assets: BTC, ETH, SOL
VDLT_PARAM_TOO_LONGNoReduce the number of exchange IDs. Maximum 2000 characters.

The hint column reproduces the English string the API returns; it is not localized.

Still stuck

Contact support from inside the app. There is no published service-level target, uptime figure or guaranteed response time, so this page does not state one.