tickerbot-io Series API
The Series API from tickerbot-io — 1 operation(s) for series.
The Series API from tickerbot-io — 1 operation(s) for series.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/tickerbot-io:tickerbot-io-series-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Tickerbot Series API
version: 2.69.6
summary: The stock market API designed for agents.
description: 'Tickerbot is the stock market API designed for agents. We serve real-time and historical market data as one queryable table. You and your agents can ask it anything, without building anything custom. Every ticker is a row. Every data point is a column. 23,000+ tickers, covering US stocks and ETFs, FX, crypto, rates and metals. 452+ columns, covering raw data, calculations and conditions: price, volume, price action, technicals, fundamentals, events, profile, analyst ratings and news. Refreshed every minute, historized back to 2003. The table is the API: /v2/tickers/ returns one ticker''s whole row, /v2/signals/ returns every ticker that matches one column, /v2/scan returns every ticker that matches a SQL WHERE clause. Every read runs live or as of any date. The power is in the columns: every ticker gets the same columns, query any of them, in any combination. Ask any question: anything you want to know about the market is a query over the table. Build any trading tool: anything you want to build is a few queries in sequence. Get a free API key, or paste our setup prompt and your agent connects over MCP. Free plan: 10,000 calls a month, no card required.
All responses carry a top-level `as_of` ISO timestamp indicating data vintage. List and history responses use opaque cursor pagination — treat `next_cursor` as a black-box token and pass it back via `?cursor=` on the next request.'
contact:
name: Tickerbot Support
url: https://tickerbot.io/support
email: support@tickerbot.io
license:
name: Proprietary
url: https://tickerbot.io/terms
servers:
- url: https://api.tickerbot.io
description: Production
security:
- apiBearer: []
tags:
- name: Series
paths:
/v2/series:
get:
tags:
- Series
summary: Any signals for any tickers on one aligned time grid
operationId: get_series
description: 'Any signals for any tickers on one shared time grid — up to 50 tickers by 25 columns per call. Notes:
- The join across the OHLCV bar store and the indicator and boolean state tables that would otherwise take N history calls and a hand-rolled merge. Those two stores genuinely disagree — state has rows on non-trading days, intraday bars can lag behind state — so the endpoint owns the alignment policy: a missing cell is `null`, never a silently dropped row, and `_meta` reports per-column sources plus per-ticker coverage so a gap is always visible. - Column names resolve by source, invisibly at the call site: `open`/`high`/`low`/`close`/`volume`/`vwap`/`trades` (or `o`/`h`/`l`/`c`/`v`/`vw`/`n`) read licensed OHLCV bars; every signal on the schema page reads the state tables; your own custom signals compile per-row and behave exactly like built-ins. - With no `columns` the default set matches the deprecated Ticker history — a bare `/v2/series?ticker=AAPL` IS ticker history in its canonical spelling. - `1m` / `1h` / `1d` are stored tiers. `1w` is a real weekly resample: each signal samples the week''s last observation, bars aggregate (open of first bar, max high, min low, close of last, summed volume and trades, volume-weighted `vwap` — `null` for a zero-volume week), rows keyed by the week''s Monday. - `1q` serves quarterly fundamentals on the fiscal grid: `eps`, `eps_estimate`, `eps_surprise`, `eps_surprise_pct`, and every statement column `1y` serves (below), under the same names and definitions, except the per-share ones (`eps_basic`, `eps_diluted`, `shares_basic`, `shares_diluted`; quarterly EPS is `eps`). Income and cash flow columns cover the quarter; balance sheet columns are at quarter end. Rows are keyed by calendar quarter (`2026-Q2`) with each ticker''s exact `fiscal_period`, `reported` (the date the quarter was announced, `null` when unknown), `available_at` (when the market could first trade on it, ISO 8601) and `available_at_source` (what decided it: `report_time`, `filing_date` or `assumed`). `available_at` is the axis a point-in-time backtest filters on, and what `asof` gates on: a post-market report is dated the report day but tradable only from the next open. All three come from the same report: the earnings release when the quarter has one, else the statement filing. The three revenue breakdown lists (`revenue_by_segment`, `revenue_by_geography`, `revenue_by_product`, below) are quarterly columns too. Quarterly columns cannot mix with daily ones in one request — the grids are not joinable. - `1y` serves annual financial statements, one row per fiscal year from fiscal 2010 on, keyed by the company''s own fiscal-year label (`t: "2025"`; Walmart''s fiscal 2026 ended on January 31, 2026). Each row carries `fiscal_year`, `fiscal_period` (the year-end date), `reported` (the filing date of the ORIGINAL 10-K, 20-F or 40-F, from SEC EDGAR — a later filing that repeats or restates the year never moves it) and `available_at` (9:30 AM ET of the first session after `reported`).'
parameters:
- name: ticker
in: query
required: false
description: Single-symbol form — `/v2/series?ticker=AAPL` is ticker history in its canonical spelling. Exactly one of `ticker` or `tickers` is required.
schema:
type: string
example: AAPL
- name: tickers
in: query
required: false
description: Comma-separated symbols, up to 50 (POST accepts a JSON array). Exactly one of `tickers` or `ticker` is required; when both are passed, `ticker` wins — so sending both silently narrows the request to one symbol.
schema:
type: array
example: AAPL,MSFT
items:
type: string
- name: from
in: query
required: false
description: 'Earliest timestamp (inclusive), `YYYY-MM-DD` or ISO. At `1q` and `1y` it bounds the fiscal period end. Intraday requests default to a recent window (`1m`: 7 days, `1h`: 60 days) — the cursor keeps walking further back window-by-window, or pass `from` to widen it up front.'
schema:
type: string
example: '2026-03-25'
- name: to
in: query
required: false
description: Latest timestamp (inclusive), `YYYY-MM-DD` or ISO.
schema:
type: string
example: '2026-08-02'
- name: asof
in: query
required: false
description: 'Point-in-time read: ONE row per ticker — the state at that instant — rather than a range. `YYYY-MM-DD` or a full ISO timestamp, the same meaning `asof` carries on [`/v2/tickers`](/docs/endpoints/tickers/get), [`/v2/scan`](/docs/endpoints/scan/run) and [`/v2/signals`](/docs/endpoints/signals/get). Cannot be combined with `from`/`to` or `cursor` (400) — a point and a window are contradictory, and `limit` has no meaning under it. It also resolves WHICH COMPANY held the symbol at that instant: a ticker that changed hands returns the row of whoever traded it then, so `tickers=SHLD&asof=2010-06-30` returns Sears Holdings'' price and `asof=2026-01-01` returns the Global X defence ETF. Returns the most recent row at or before the instant, so a date inside a trading gap gives the last row before it; on the `1d` and `1w` grids a timestamp returns the previous session''s row, never that day''s close. Also: `next_cursor` is always `null` (every requested ticker is on the one page). A ticker with no row on the grid at or before the instant (outside the minute tier, say) comes back as an empty array with `_meta.coverage[ticker].rows: 0`, never a 404. A bare date on the `1m`/`1h` grid is accepted and means the last row of that UTC day (the state reads 400 that combination; this grid read does not). The look-back is the grid''s window: `1d` walks back without limit, `1h` 60 days and `1m` 7 days before the instant. At `interval=1q` a quarter is visible from its `available_at` — when the market could first trade on it: 9:30 AM ET on the report date for a pre-market earnings release, else 9:30 AM ET of the next session; statements the session after filing — and a bare date means that day''s 4 PM ET close, so you get the latest quarter that was public knowledge at the instant, with restatements after it excluded: `ticker=AAPL&interval=1q&asof=2026-07-30` returns 2026-Q1, `asof=2026-07-31T13:30:00Z` 2026-Q2 (the June quarter was reported after the close on 2026-07-30). See [availability](/docs/asof#availability). At `interval=1y` a fiscal year is visible from its `available_at` — 9:30 AM ET of the first session after the ORIGINAL annual report was filed — and a bare date means that day''s 4 PM ET close: `ticker=AAPL&interval=1y&asof=2025-10-31` returns fiscal 2024, `asof=2025-11-03` fiscal 2025 (the 10-K was filed after the close on Friday 2025-10-31). Response time: under 1.5 s cold, under 0.5 s warm.'
schema:
type: string
example: '2010-06-30'
- name: interval
in: query
required: false
description: 'Grid granularity. `1w` resamples the daily tier weekly (Monday-keyed); `1q` is the fiscal-quarter grid; `1y` is the fiscal-year grid of annual statements. This is the grid, not a state tier: there is no `auto` here and nothing blends — under `asof` you get the last row on this grid, and a column the grid does not carry is a `400`.'
schema:
type: string
enum:
- 1m
- 1h
- 1d
- 1w
- 1q
- 1y
default: 1d
- name: columns
in: query
required: false
description: 'Up to 25 columns (POST accepts an array): OHLCV names, signals, and your custom signals, freely mixed. Omitted → the ticker-history default set (price, change_1d_pct, relative_volume, market_cap), intersected with what the interval carries. At `1q`, `columns` is required and quarterly-only; at `1y`, required and annual-only (the list is under Notes).'
schema:
type: array
example: close,rsi_14,above_sma_200
items:
type: string
- name: transitions_only
in: query
required: false
description: 'Only rows where a boolean signal changed state. Accepted spellings: `true`/`1`/`yes` and `false`/`0`/`no` (case-insensitive) — anything else is a 400, never silently off. Requires at least one boolean signal (built-in boolean or custom signal); each returned row carries `transitions: {column: "enter"|"exit"}`, and `_meta` lists the driving columns. Strict truth: only literal `true` is "on", so `null → true` is an enter and `true → null` an exit (a backfill boundary reads as an edge). Edges need a prior observation — on the oldest page of a walk the first row has no predecessor and yields no edge. A flip is dated by the state table and does not move with the column list: one recorded on a non-trading carry row keeps that date, with any bar columns `null` on that row (no bar exists there).'
schema:
type: boolean
example: true
- name: limit
in: query
required: false
description: Grid steps per page (shared across tickers). Max 1000 — an over-cap `limit` is clamped to 1000 (house convention, `limit=10000` means "max"). Separately, tickers × limit may not exceed 25,000 rows per page — over THAT cap is an explicit 400.
schema:
type: integer
default: 252
example: 3
- name: cursor
in: query
required: false
description: Opaque cursor from the previous response — every ticker pages backward in lockstep on the shared grid, no per-ticker gaps or duplicates.
schema:
type: string
responses:
'200':
description: Success.
content:
application/json:
schema:
type: object
properties:
as_of:
type:
- string
- 'null'
description: Server time this response was assembled (ISO 8601).
interval:
type:
- string
- 'null'
description: The grid granularity served.
tickers:
type:
- array
- 'null'
description: Symbols in the response, echoed.
columns:
type:
- array
- 'null'
description: Columns in the response, echoed.
_meta:
type:
- object
- 'null'
description: 'This endpoint''s own keys: per-ticker `coverage` (`rows`, and `missing_bar_cells` when a bar column is read on a state spine), `non_trading_days_dropped`, `transitions_only` / `transition_drivers`, and on an intraday range read `from_defaulted` with a `note`. Shared keys: see [the `_meta` reference](/docs/asof#meta).'
count:
type:
- number
- 'null'
description: Rows per ticker in this page.
next_cursor:
type:
- string
- 'null'
description: Opaque token for the next page; `null` on the last page. Pass it back as `cursor`.
series:
type:
- object
- 'null'
description: 'Keyed by ticker: an array of flat rows, chronological, each keyed `t` plus the columns you asked for.'
'400':
description: Bad interval/bounds, unknown signal (`invalid_query`), daily-only signal at an intraday interval, quarterly/daily or annual/daily signal mix, over the tickers × limit cap, or `transitions_only` without a boolean signal.
'401':
description: Missing or invalid API key.
'402':
description: No active plan on the account (rare — new signups land on the Free plan automatically).
'429':
description: Rate limit exceeded for your plan.
components:
securitySchemes:
apiBearer:
type: http
scheme: bearer
bearerFormat: API key (tb_live_… or tb_test_…)
description: 'API keys are minted in the dashboard. Send as `Authorization: Bearer <key>`.'