View as markdown
Endpoints · Events

List events

GEThttps://api.tickerbot.io/v2/events

The unified cross-ticker event stream — "all splits this month", "every analyst action in my universe this week" — one call instead of one per ticker. Four kinds, each backed by its own archive: dividend, split, insider, analyst. Rows are { ticker, ts, kind, payload }, newest first; payload fields per kind are identical to [/v2/tickers/{ticker}/events](/docs/endpoints/tickers/events) (corporate kinds) and [/v2/analyst/events](/docs/endpoints/analyst/events) (analyst), so consumers can switch scope without reshaping.

Those two endpoints remain as the single-ticker and analyst-specialized (firm/action filters) views of the same data.

The endpoint speaks the SQL grammar over a normalized projection of exactly four columns — ticker, ts, kind, and payload (jsonb). Optional q filters rows (kind='analyst' AND payload->>'action'='downgrades'); group_by (with optional select/having) switches to aggregate rollups (group_by=payload->>'firm' AS firm). Payload fields are reached with jsonb operators and cast as needed: (payload->>'shares')::numeric > 1e6. No other identifiers are accepted — this is the event log's own grammar, not the ticker-state scan grammar. Aggregates don't paginate: past limit you get truncated: true — narrow the window instead.

Requires at least one bound — a ticker scope or a time window (q alone does not count); a bare kind over millions of rows is refused. Both GET and POST are supported; POST takes the same parameters in the body for long queries. Pagination note: the cursor pages strictly *older* than the last row's timestamp, and the corporate archives are date-grained — same-date remainders can fall on a page boundary. Raise limit (max 1000) to avoid boundaries. A q longer than 600 chars is not carried inside the cursor — resend q alongside cursor on later pages.

Plan access

Available on every plan, alongside the live `last_rating_date` / `last_rating_firm` / `last_rating_action` columns on the ticker object and the `recent_*` analyst flags on /v2/scan.

Rate limit

Hobby 600/min · Pro 6,000/min · Scale 60,000/min.

Per-call cap

1000 rows per call on every plan. History back to 2012.

string

Comma list of kinds to include.

string

Single-ticker filter.

string

Comma list of tickers (max 50). Mutually exclusive with `universe`.

string

Universe slug (`top_10`, `top_100`, or one of yours) to scope the stream. Mutually exclusive with `tickers`.

string

Events at/after this ISO date or datetime.

string

Events strictly before this ISO date or datetime.

string

SQL WHERE over the projection — only `ticker`, `ts`, `kind`, `payload` may appear. Max 4000 chars. ANDs with the filter params. See the schema for columns + flags you can compose.

string

Aggregate-mode output columns (requires `group_by`). Default: group keys + `COUNT(*) AS events`.

string

Comma list of rollup keys — switches the response to aggregate rows.

string

Post-aggregation filter. Requires `group_by`.

string

Aggregate-mode sort column or alias. Default: `events`. (Row mode is always newest-first.)

stringdefault desc

Aggregate-mode sort direction.

integerdefault 50

Page size (row modes) / max rollup rows (aggregate mode). Max 1000.

string

Opaque cursor from the previous response — carries the original filters (and `q` when short), so pass it alone. Not valid with `group_by`.

200
Envelope with query, count, next_cursor, and results of { ticker, ts, kind, payload } (row modes) or rollup rows plus truncated: true when the aggregate exceeds limit.
400
Bad kind, >50 tickers, tickers+universe together, no bound at all, invalid timestamps/cursor, or invalid_query — an identifier outside the four projection columns, a disallowed function, select/having/order without group_by, or cursor with group_by.
404
Referenced universe does not exist.