@tickerbot/mcp-server 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -15
- package/dist/handler.js +18 -2
- package/dist/index.js +4 -2
- package/dist/tools.d.ts +15 -0
- package/dist/tools.js +1319 -895
- package/package.json +2 -2
package/dist/tools.js
CHANGED
|
@@ -14,412 +14,560 @@
|
|
|
14
14
|
// Refresh with: node scripts/regen-tools.mjs (or --live)
|
|
15
15
|
export const tools = [
|
|
16
16
|
{
|
|
17
|
-
"name": "
|
|
18
|
-
"description": "
|
|
17
|
+
"name": "tickerbot_scan",
|
|
18
|
+
"description": "Screens every ticker with a SQL `WHERE` clause and returns the matches. Run it now, or add `asof` to backtest it on any past date. The `q` grammar is a flat SQL WHERE over signal names: AND/OR/NOT, comparisons, numeric and string literals, custom signals by name. No JOIN or subqueries. With `group_by` the result is rollup rows, not tickers. Example: `gap_up AND market_cap < 2000000000 AND NOT earnings_this_week`.",
|
|
19
19
|
"inputSchema": {
|
|
20
20
|
"type": "object",
|
|
21
21
|
"properties": {
|
|
22
|
-
"
|
|
22
|
+
"q": {
|
|
23
23
|
"type": "string",
|
|
24
|
-
"description": "
|
|
24
|
+
"description": "SQL WHERE expression. Max 4000 chars; semicolons, comments and write keywords are rejected. Your custom signals are valid here — each expands to its SQL at run time. To scan named tickers: `ticker IN ('AAPL', 'MSFT')`; to scan one asset class: `asset_class = 'crypto'`."
|
|
25
25
|
},
|
|
26
|
-
"
|
|
27
|
-
"type": "integer",
|
|
28
|
-
"description": "Page size. Max 1000. Default 50."
|
|
29
|
-
},
|
|
30
|
-
"cursor": {
|
|
26
|
+
"universe": {
|
|
31
27
|
"type": "string",
|
|
32
|
-
"description": "
|
|
28
|
+
"description": "Slug of a system universe (`top_10`, `top_100`) or one of your own. Omitted, the screen runs across every ticker."
|
|
33
29
|
},
|
|
34
|
-
"
|
|
30
|
+
"asof": {
|
|
35
31
|
"type": "string",
|
|
36
|
-
"description": "
|
|
32
|
+
"description": "Target moment as `YYYY-MM-DD` (that day's close) or an ISO timestamp (that intraday moment; daily-only signals then carry the previous session's close, never that day's) — the same read as it stood then, unlimited depth. In `q`, `now()` and `current_date` mean that moment, so `last_earnings_date >= now() - interval '7 days'` backtests as written. Full contract under As of a past date."
|
|
37
33
|
},
|
|
38
|
-
"
|
|
34
|
+
"grain": {
|
|
39
35
|
"type": "string",
|
|
40
|
-
"description": "
|
|
36
|
+
"description": "Only with `asof`. Grain the past state is read at: `1m`, `1h`, `1d` or `auto` (default). `auto` blends: each signal comes from its freshest grain at or before the instant (minute, then hourly, then the last closed daily session), so nothing is refused for grain and no ticker is dropped; `_meta.blended` and `_meta.grains_present` say what contributed. Pin a grain for a faster read with every ticker on the same clock. A signal the pinned grain does not store is a `400 interval_unavailable` naming the grains that carry it (`rsi_14`, fundamentals and valuation ratios are `1d`-only).",
|
|
37
|
+
"enum": [
|
|
38
|
+
"1m",
|
|
39
|
+
"1h",
|
|
40
|
+
"1d",
|
|
41
|
+
"auto"
|
|
42
|
+
],
|
|
43
|
+
"default": "auto"
|
|
41
44
|
},
|
|
42
|
-
"
|
|
45
|
+
"select": {
|
|
43
46
|
"type": "string",
|
|
44
|
-
"description": "
|
|
47
|
+
"description": "What each result carries, as in SQL. Omitted: the default row (ticker, name, asset_class, asset_type, price, change_1d_pct, gap_pct, relative_volume, market_cap) plus every signal used in `q` and `order`; a custom signal appears as its own value, and a cross-ticker reference (`SPY.sma_50`) is not added. A list: exactly those items, `ticker` always included; expressions with `AS` work (`price / sma_50 AS dist`) and are validated like `q`. `*`: every signal in the catalog. All aggregates (`count(*), avg(rsi_14)`) without `group_by`: one summary row, in `groups`. With `group_by`, each item is an aggregate or a group key. Aggregates: count/avg/sum/min/max/stddev/string_agg/bool_and/bool_or, plus `FILTER (WHERE …)`."
|
|
45
48
|
},
|
|
46
|
-
"
|
|
49
|
+
"group_by": {
|
|
47
50
|
"type": "string",
|
|
48
|
-
"description": "
|
|
51
|
+
"description": "GROUPED SCAN: 1–6 group keys (signals, expressions or one of your custom signals as a boolean key). Results become rollups in `groups`, each carrying its keys. Name a key with `AS` to choose its JSON key (`market_cap > 1e11 AS mega`); an un-named expression is named for you rather than returned as `?column?`. Default `select`: the keys + `COUNT(*) AS tickers`. Works with `asof`; does not paginate."
|
|
49
52
|
},
|
|
50
|
-
"
|
|
51
|
-
"type": "number",
|
|
52
|
-
"description": "Minimum market cap in USD. Orders results by market_cap desc."
|
|
53
|
-
},
|
|
54
|
-
"universe": {
|
|
53
|
+
"having": {
|
|
55
54
|
"type": "string",
|
|
56
|
-
"description": "
|
|
55
|
+
"description": "Only with `group_by`. Filter the rollups. Custom signals are valid here too."
|
|
57
56
|
},
|
|
58
|
-
"
|
|
57
|
+
"order": {
|
|
59
58
|
"type": "string",
|
|
60
|
-
"description": "
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"endpoint": {
|
|
65
|
-
"method": "GET",
|
|
66
|
-
"path": "/v2/tickers",
|
|
67
|
-
"paramLocation": {
|
|
68
|
-
"tickers": "query",
|
|
69
|
-
"limit": "query",
|
|
70
|
-
"cursor": "query",
|
|
71
|
-
"search": "query",
|
|
72
|
-
"asset_type": "query",
|
|
73
|
-
"exchange": "query",
|
|
74
|
-
"sector": "query",
|
|
75
|
-
"min_market_cap": "query",
|
|
76
|
-
"universe": "query",
|
|
77
|
-
"asset_class": "query"
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
"name": "tickerbot_get_ticker",
|
|
83
|
-
"description": "Get the full current row for one ticker — every column on the schema (price, change, indicators like rsi_14, every boolean flag like above_sma_50, fundamentals like pe_ratio). Pass `asof` (YYYY-MM-DD or ISO timestamp like 2026-07-20T15:30:00Z) for the row as it stood at that past moment — date-only gives the close of that day.",
|
|
84
|
-
"inputSchema": {
|
|
85
|
-
"type": "object",
|
|
86
|
-
"properties": {
|
|
87
|
-
"ticker": {
|
|
59
|
+
"description": "Signal to sort by; it joins the default row. On a grouped scan the default is the count alias `tickers` (or, with a custom `select`, the last item's alias, so alias it with `AS`), sorted NULLS LAST with the group keys as tiebreak.",
|
|
60
|
+
"default": "change_1d_pct"
|
|
61
|
+
},
|
|
62
|
+
"dir": {
|
|
88
63
|
"type": "string",
|
|
89
|
-
"description": "
|
|
64
|
+
"description": "Sort direction.",
|
|
65
|
+
"enum": [
|
|
66
|
+
"asc",
|
|
67
|
+
"desc"
|
|
68
|
+
],
|
|
69
|
+
"default": "desc"
|
|
90
70
|
},
|
|
91
|
-
"
|
|
71
|
+
"limit": {
|
|
72
|
+
"type": "integer",
|
|
73
|
+
"description": "Page size. Max 100. Grouped scans do not paginate: `truncated: true` when groups were cut, so sort with `order` to keep the ones you want.",
|
|
74
|
+
"default": 50
|
|
75
|
+
},
|
|
76
|
+
"cursor": {
|
|
92
77
|
"type": "string",
|
|
93
|
-
"description": "
|
|
78
|
+
"description": "Opaque cursor from the previous response's `next_cursor`. Row scans only."
|
|
94
79
|
}
|
|
95
80
|
},
|
|
96
81
|
"required": [
|
|
97
|
-
"
|
|
82
|
+
"q"
|
|
98
83
|
]
|
|
99
84
|
},
|
|
100
85
|
"endpoint": {
|
|
101
|
-
"method": "
|
|
102
|
-
"path": "/v2/
|
|
86
|
+
"method": "POST",
|
|
87
|
+
"path": "/v2/scan",
|
|
103
88
|
"paramLocation": {
|
|
104
|
-
"
|
|
105
|
-
"
|
|
89
|
+
"q": "body",
|
|
90
|
+
"universe": "body",
|
|
91
|
+
"asof": "body",
|
|
92
|
+
"grain": "body",
|
|
93
|
+
"select": "body",
|
|
94
|
+
"group_by": "body",
|
|
95
|
+
"having": "body",
|
|
96
|
+
"order": "body",
|
|
97
|
+
"dir": "body",
|
|
98
|
+
"limit": "body",
|
|
99
|
+
"cursor": "body"
|
|
100
|
+
},
|
|
101
|
+
"accepts": {
|
|
102
|
+
"as_of": "body",
|
|
103
|
+
"interval": "body",
|
|
104
|
+
"columns": "body",
|
|
105
|
+
"fields": "body",
|
|
106
|
+
"full": "body",
|
|
107
|
+
"asset_class": "body"
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
110
|
},
|
|
109
111
|
{
|
|
110
|
-
"name": "
|
|
111
|
-
"description": "
|
|
112
|
+
"name": "tickerbot_subscribe_scan",
|
|
113
|
+
"description": "Gets you an alert by webhook each time a ticker starts matching a screen. Webhooks need a paid plan (Free has no webhook slots). Use for \"alert me when this happens\" requests. A signal alert is a scan on it: `q: golden_cross`, or `q: rsi_14 > 70` for a numeric one.",
|
|
112
114
|
"inputSchema": {
|
|
113
115
|
"type": "object",
|
|
114
116
|
"properties": {
|
|
115
|
-
"
|
|
117
|
+
"q": {
|
|
116
118
|
"type": "string",
|
|
117
|
-
"description": "
|
|
119
|
+
"description": "WHERE-clause expression using signal names — the same grammar and the same 4000-char cap as `POST /v2/scan`, so anything scannable is subscribable. Custom signals are expanded and frozen in at creation."
|
|
118
120
|
},
|
|
119
|
-
"
|
|
121
|
+
"universe": {
|
|
122
|
+
"type": "string",
|
|
123
|
+
"description": "System or user-owned universe to scope the screen. Unknown universes are a 404 `universe_not_found`."
|
|
124
|
+
},
|
|
125
|
+
"select": {
|
|
126
|
+
"type": "string",
|
|
127
|
+
"description": "What each delivered match carries. Omitted: the scan default row (ticker, name, asset_class, asset_type, price, change_1d_pct, gap_pct, relative_volume, market_cap) plus every signal used in `q` and `order`. A list of signal names: exactly those, `ticker` always included. Each must be a real signal; unknown ones are rejected at creation."
|
|
128
|
+
},
|
|
129
|
+
"order": {
|
|
130
|
+
"type": "string",
|
|
131
|
+
"description": "Signal each delivery's match lists are sorted by before the 100-result cap applies, so a truncated list is the deterministic top 100 rather than an arbitrary sample. Must be a real signal (validated at creation).",
|
|
132
|
+
"default": "market_cap"
|
|
133
|
+
},
|
|
134
|
+
"dir": {
|
|
135
|
+
"type": "string",
|
|
136
|
+
"description": "Sort direction for `order`.",
|
|
137
|
+
"enum": [
|
|
138
|
+
"asc",
|
|
139
|
+
"desc"
|
|
140
|
+
],
|
|
141
|
+
"default": "desc"
|
|
142
|
+
},
|
|
143
|
+
"channel": {
|
|
144
|
+
"type": "string",
|
|
145
|
+
"description": "Delivery channel. `webhook` (POST to `target_url`), `discord` (embed to `discord_url`), `in_app` (dashboard only) or `mobile_push` (to `device_id`). Inferred when omitted: `webhook` if `target_url` is set, `discord` if `discord_url` is set, `mobile_push` if `device_id` is set, else `in_app`.",
|
|
146
|
+
"enum": [
|
|
147
|
+
"webhook",
|
|
148
|
+
"discord",
|
|
149
|
+
"in_app",
|
|
150
|
+
"mobile_push"
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
"target_url": {
|
|
154
|
+
"type": "string",
|
|
155
|
+
"description": "Only with `channel=webhook`. https:// URL to POST when a ticker starts matching."
|
|
156
|
+
},
|
|
157
|
+
"discord_url": {
|
|
158
|
+
"type": "string",
|
|
159
|
+
"description": "Only with `channel=discord`. Discord incoming-webhook URL. Stored as a posting credential: the create response echoes it back under `channel_config`, but every later read (list, get, deliveries) strips it and sets `channel_config_present: true` instead."
|
|
160
|
+
},
|
|
161
|
+
"device_id": {
|
|
162
|
+
"type": "string",
|
|
163
|
+
"description": "Only with `channel=mobile_push`. Device to notify, from `POST /v2/devices/register`. Unknown ids are a 404 `device_not_found`."
|
|
164
|
+
},
|
|
165
|
+
"cadence": {
|
|
166
|
+
"type": "string",
|
|
167
|
+
"description": "`realtime` (the default) is checked each time the data refreshes, about once a minute; `hourly` and `nyse_open` are checked on that schedule.",
|
|
168
|
+
"enum": [
|
|
169
|
+
"realtime",
|
|
170
|
+
"hourly",
|
|
171
|
+
"nyse_open"
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
"name": {
|
|
120
175
|
"type": "string",
|
|
121
|
-
"description": "
|
|
176
|
+
"description": "Human-readable label (up to 80 chars). Defaults to `scan: <q>`."
|
|
122
177
|
}
|
|
123
178
|
},
|
|
124
179
|
"required": [
|
|
125
|
-
"
|
|
126
|
-
"asof"
|
|
180
|
+
"q"
|
|
127
181
|
]
|
|
128
182
|
},
|
|
129
183
|
"endpoint": {
|
|
130
|
-
"method": "
|
|
131
|
-
"path": "/v2/
|
|
184
|
+
"method": "POST",
|
|
185
|
+
"path": "/v2/scan/subscribe",
|
|
132
186
|
"paramLocation": {
|
|
133
|
-
"
|
|
134
|
-
"
|
|
187
|
+
"q": "body",
|
|
188
|
+
"universe": "body",
|
|
189
|
+
"select": "body",
|
|
190
|
+
"order": "body",
|
|
191
|
+
"dir": "body",
|
|
192
|
+
"channel": "body",
|
|
193
|
+
"target_url": "body",
|
|
194
|
+
"discord_url": "body",
|
|
195
|
+
"device_id": "body",
|
|
196
|
+
"cadence": "body",
|
|
197
|
+
"name": "body"
|
|
198
|
+
},
|
|
199
|
+
"accepts": {
|
|
200
|
+
"universe_id": "body",
|
|
201
|
+
"columns": "body",
|
|
202
|
+
"fields": "body"
|
|
135
203
|
}
|
|
136
204
|
}
|
|
137
205
|
},
|
|
138
206
|
{
|
|
139
|
-
"name": "
|
|
140
|
-
"description": "
|
|
207
|
+
"name": "tickerbot_list_signals",
|
|
208
|
+
"description": "Lists every signal you can screen on: the built-ins and your custom signals, in one catalog you can filter, search and page. Use to discover the signal names and `q` vocabulary before composing a scan; custom signals appear with `kind: custom`. Narrow it with `category`, `group`, `type`, `search` and `select=type,description` rather than reading all ~460 rows.",
|
|
141
209
|
"inputSchema": {
|
|
142
210
|
"type": "object",
|
|
143
211
|
"properties": {
|
|
144
|
-
"
|
|
212
|
+
"kind": {
|
|
213
|
+
"type": "string",
|
|
214
|
+
"description": "Filter by kind (one or a comma list). Omit to return both.",
|
|
215
|
+
"enum": [
|
|
216
|
+
"builtin",
|
|
217
|
+
"custom"
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
"search": {
|
|
145
221
|
"type": "string",
|
|
146
|
-
"description": "
|
|
222
|
+
"description": "Case-insensitive text match on the name and description."
|
|
147
223
|
},
|
|
148
|
-
"
|
|
224
|
+
"group": {
|
|
149
225
|
"type": "string",
|
|
150
|
-
"description": "
|
|
226
|
+
"description": "One taxonomy group slug or a comma list (`technicals,fundamentals`). Groups and their categories are in `taxonomy`."
|
|
151
227
|
},
|
|
152
|
-
"
|
|
228
|
+
"category": {
|
|
153
229
|
"type": "string",
|
|
154
|
-
"description": "
|
|
230
|
+
"description": "One category slug or a comma list (`oscillators,trend`)."
|
|
155
231
|
},
|
|
156
|
-
"
|
|
232
|
+
"type": {
|
|
157
233
|
"type": "string",
|
|
158
|
-
"description": "
|
|
234
|
+
"description": "One value type or a comma list. Custom signals are always `boolean`.",
|
|
159
235
|
"enum": [
|
|
160
|
-
"
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"
|
|
236
|
+
"numeric",
|
|
237
|
+
"boolean",
|
|
238
|
+
"string",
|
|
239
|
+
"date",
|
|
240
|
+
"timestamp",
|
|
241
|
+
"jsonb",
|
|
242
|
+
"string[]"
|
|
165
243
|
]
|
|
166
244
|
},
|
|
167
|
-
"
|
|
245
|
+
"asset_class": {
|
|
168
246
|
"type": "string",
|
|
169
|
-
"description": "
|
|
247
|
+
"description": "Signals that apply to this asset class (one or a comma list), e.g. `crypto`."
|
|
170
248
|
},
|
|
171
|
-
"
|
|
249
|
+
"refresh": {
|
|
172
250
|
"type": "string",
|
|
173
|
-
"description": "
|
|
251
|
+
"description": "Signals that update on this schedule (one or a comma list).",
|
|
252
|
+
"enum": [
|
|
253
|
+
"1m_4am_8pm_et",
|
|
254
|
+
"1m_24_7",
|
|
255
|
+
"5m",
|
|
256
|
+
"10m",
|
|
257
|
+
"15m",
|
|
258
|
+
"30m",
|
|
259
|
+
"1h",
|
|
260
|
+
"daily",
|
|
261
|
+
"daily_after_close",
|
|
262
|
+
"weekly",
|
|
263
|
+
"monthly",
|
|
264
|
+
"quarterly",
|
|
265
|
+
"on_event",
|
|
266
|
+
"static",
|
|
267
|
+
"custom"
|
|
268
|
+
]
|
|
174
269
|
},
|
|
175
|
-
"
|
|
176
|
-
"type": "
|
|
177
|
-
"description": "
|
|
270
|
+
"grain": {
|
|
271
|
+
"type": "string",
|
|
272
|
+
"description": "Signals with stored history at this grain (one or a comma list): what an as-of read or the history read can serve at it.",
|
|
273
|
+
"enum": [
|
|
274
|
+
"1m",
|
|
275
|
+
"1h",
|
|
276
|
+
"1d"
|
|
277
|
+
]
|
|
278
|
+
},
|
|
279
|
+
"select": {
|
|
280
|
+
"type": "string",
|
|
281
|
+
"description": "The fields each row carries (`name` is always included), e.g. `type,description`."
|
|
178
282
|
},
|
|
179
283
|
"limit": {
|
|
180
284
|
"type": "integer",
|
|
181
|
-
"description": "
|
|
285
|
+
"description": "Page size over the whole list: your custom signals (newest first), then the built-ins A→Z. Max 500 until 2027-01-12, then 100 (a larger value is clamped to the max, not an error; `next_cursor` pages the rest; see Deprecations). Omitted, every matching signal comes back in one response until 2027-01-12; after that a call pages at a default limit."
|
|
182
286
|
},
|
|
183
287
|
"cursor": {
|
|
184
288
|
"type": "string",
|
|
185
|
-
"description": "Opaque cursor from a prior response
|
|
289
|
+
"description": "Opaque cursor from a prior response."
|
|
186
290
|
}
|
|
187
|
-
}
|
|
188
|
-
"required": []
|
|
291
|
+
}
|
|
189
292
|
},
|
|
190
293
|
"endpoint": {
|
|
191
294
|
"method": "GET",
|
|
192
|
-
"path": "/v2/
|
|
295
|
+
"path": "/v2/signals",
|
|
193
296
|
"paramLocation": {
|
|
194
|
-
"
|
|
195
|
-
"
|
|
196
|
-
"
|
|
197
|
-
"
|
|
198
|
-
"
|
|
199
|
-
"
|
|
200
|
-
"
|
|
297
|
+
"kind": "query",
|
|
298
|
+
"search": "query",
|
|
299
|
+
"group": "query",
|
|
300
|
+
"category": "query",
|
|
301
|
+
"type": "query",
|
|
302
|
+
"asset_class": "query",
|
|
303
|
+
"refresh": "query",
|
|
304
|
+
"grain": "query",
|
|
305
|
+
"select": "query",
|
|
201
306
|
"limit": "query",
|
|
202
307
|
"cursor": "query"
|
|
203
308
|
}
|
|
204
309
|
}
|
|
205
310
|
},
|
|
206
311
|
{
|
|
207
|
-
"name": "
|
|
208
|
-
"description": "
|
|
312
|
+
"name": "tickerbot_create_custom_signal",
|
|
313
|
+
"description": "Saves a named true/false SQL expression you can screen on anywhere a built-in signal works.",
|
|
209
314
|
"inputSchema": {
|
|
210
315
|
"type": "object",
|
|
211
316
|
"properties": {
|
|
212
|
-
"
|
|
317
|
+
"name": {
|
|
318
|
+
"type": "string",
|
|
319
|
+
"description": "Slug — `^[a-z][a-z0-9_]{0,63}$`. Must not collide with any built-in signal name, and 15 names are reserved outright: `columns`, plus the OHLCV aliases of the history read `open`/`high`/`low`/`close`/`volume`/`vwap`/`trades` and `o`/`h`/`l`/`c`/`v`/`vw`/`n` (those resolve to bars before custom lookup). This is the signal's API handle: it's what you reference in `q` and in the CRUD path."
|
|
320
|
+
},
|
|
321
|
+
"expr": {
|
|
213
322
|
"type": "string",
|
|
214
|
-
"description": "
|
|
323
|
+
"description": "Boolean SQL predicate. May reference built-in signals and other custom signals you own. Must evaluate to true/false. Max 4000 chars. Stricter grammar than scan `q`: comparisons, `AND`/`OR`/`NOT`, `IN`, `BETWEEN`, `IS [NOT] NULL`, arithmetic and the functions `abs`/`coalesce`/`round`/`least`/`greatest` only — no `LIKE`/`ILIKE`, no `CASE`, no `::` casts, no other functions. An expression that scans fine can still be rejected here with `compile_failed`. What you send is what you read back: responses echo your expression as stored, not its expansion. A signal referencing another custom of yours returns the reference as you typed it — the inlined SQL exists only internally, and is what a subscribe endpoint freezes into a webhook. The one rewrite: a signal named under its pre-2026-09-07 spelling (`bollinger_pct_b`) is stored under its current name (`bollinger_b`) and reported in `_meta.deprecated_signals`."
|
|
324
|
+
},
|
|
325
|
+
"description": {
|
|
326
|
+
"type": "string",
|
|
327
|
+
"description": "Free-form notes. Max 500 chars. Absent or empty comes back as `\"\"` rather than null."
|
|
215
328
|
}
|
|
216
329
|
},
|
|
217
330
|
"required": [
|
|
218
|
-
"
|
|
331
|
+
"name",
|
|
332
|
+
"expr"
|
|
219
333
|
]
|
|
220
334
|
},
|
|
221
335
|
"endpoint": {
|
|
222
|
-
"method": "
|
|
223
|
-
"path": "/v2/
|
|
336
|
+
"method": "POST",
|
|
337
|
+
"path": "/v2/signals",
|
|
224
338
|
"paramLocation": {
|
|
225
|
-
"
|
|
339
|
+
"name": "body",
|
|
340
|
+
"expr": "body",
|
|
341
|
+
"description": "body"
|
|
226
342
|
}
|
|
227
343
|
}
|
|
228
344
|
},
|
|
229
345
|
{
|
|
230
|
-
"name": "
|
|
231
|
-
"description": "
|
|
346
|
+
"name": "tickerbot_get_signal",
|
|
347
|
+
"description": "Returns what one signal is (its catalog entry, the same object List signals returns for it) and every ticker matching it, live or on any past date with `asof`: a screen on that one signal. Returns `catalog` (what the signal is) every time. Booleans list their matches with no `condition`; every other type lists them only with one, typed like the signal: \">70\" (numeric), \"<YYYY-MM-DDTHH:MM:SSZ\" (timestamp), \">=YYYY-MM-DD\" (date), \"=ETF\" (string); without it you get the catalog entry and a `note`. Without `order`, a non-boolean sorts by its value in the direction the condition implies (`<` ascending, `>` descending). To know when each ticker started matching, use tickerbot_list_events with kind=signal, signal=<name>, transition=enter.",
|
|
232
348
|
"inputSchema": {
|
|
233
349
|
"type": "object",
|
|
234
350
|
"properties": {
|
|
235
|
-
"
|
|
351
|
+
"signal": {
|
|
236
352
|
"type": "string",
|
|
237
|
-
"description": "
|
|
353
|
+
"description": "A signal name. Booleans (e.g. `golden_cross`, `above_sma_50`) are detected automatically; every other type (numeric `rsi_14`, timestamp `price_asof`, date `earnings_date`, string `asset_class`) requires a `condition`."
|
|
238
354
|
},
|
|
239
|
-
"
|
|
355
|
+
"condition": {
|
|
356
|
+
"type": "string",
|
|
357
|
+
"description": "Lists the matches of a non-boolean signal; without it the response carries the catalog entry and a `note` instead of `results`. The shape follows the signal's `type` in the catalog. Single bound, `<op><value>`. numeric: `>70`, `<=200`, `!=0` (operators `>`, `>=`, `=`, `!=`, `<`, `<=`). timestamp: an ISO instant, `<YYYY-MM-DDTHH:MM:SSZ` or `>=YYYY-MM-DD` (a bare date is midnight UTC). date: `>=YYYY-MM-DD` or `=YYYY-MM-DD`. string: `=ETF` or `!=ETF` (`=` and `!=` only; quotes optional). A relative window (\"older than 15 minutes\") is a `/v2/scan` query: `price_asof < now() - interval '15 minutes'`. Sending a condition with a boolean or custom signal returns 400 (it does not apply)."
|
|
358
|
+
},
|
|
359
|
+
"universe": {
|
|
360
|
+
"type": "string",
|
|
361
|
+
"description": "Scope to a system or caller-owned universe slug."
|
|
362
|
+
},
|
|
363
|
+
"asof": {
|
|
240
364
|
"type": "string",
|
|
241
|
-
"description": "
|
|
365
|
+
"description": "Target moment as `YYYY-MM-DD` (that day's close) or an ISO timestamp (that intraday moment; daily-only signals then carry the previous session's close, never that day's) — the same read as it stood then, unlimited depth. Full contract under As of a past date."
|
|
366
|
+
},
|
|
367
|
+
"grain": {
|
|
368
|
+
"type": "string",
|
|
369
|
+
"description": "Only with `asof`. Grain the past state is read at: `1m`, `1h`, `1d` or `auto` (default). `auto` blends: each signal comes from its freshest grain at or before the instant (minute, then hourly, then the last closed daily session), so nothing is refused for grain and no ticker is dropped; `_meta.blended` and `_meta.grains_present` say what contributed. Pin a grain for the fastest response: one grain is read instead of three, and every ticker is captured on the same clock. A signal the pinned grain does not store is a `400 interval_unavailable` naming the grains that carry it (`rsi_14`, fundamentals and valuation ratios are `1d`-only).",
|
|
242
370
|
"enum": [
|
|
243
|
-
"1s",
|
|
244
371
|
"1m",
|
|
245
|
-
"5m",
|
|
246
|
-
"15m",
|
|
247
|
-
"30m",
|
|
248
372
|
"1h",
|
|
249
|
-
"1d"
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
"type": "integer",
|
|
254
|
-
"description": "Most-recent N bars. Default 100."
|
|
373
|
+
"1d",
|
|
374
|
+
"auto"
|
|
375
|
+
],
|
|
376
|
+
"default": "auto"
|
|
255
377
|
},
|
|
256
|
-
"
|
|
378
|
+
"select": {
|
|
257
379
|
"type": "string",
|
|
258
|
-
"description": "
|
|
380
|
+
"description": "Signals each match carries beside `value`, e.g. `market_cap,sector`."
|
|
259
381
|
},
|
|
260
|
-
"
|
|
382
|
+
"order": {
|
|
261
383
|
"type": "string",
|
|
262
|
-
"description": "
|
|
384
|
+
"description": "Signal to sort by (or `ticker`). Omitted: a yes/no signal lists tickers A→Z; any other signal sorts by its value in the direction the condition implies (`<`/`<=` ascending, `>`/`>=` descending)."
|
|
263
385
|
},
|
|
264
|
-
"
|
|
386
|
+
"dir": {
|
|
265
387
|
"type": "string",
|
|
266
|
-
"description": "
|
|
388
|
+
"description": "Sort direction. Omitted: the direction the default order implies, else `desc`.",
|
|
389
|
+
"enum": [
|
|
390
|
+
"asc",
|
|
391
|
+
"desc"
|
|
392
|
+
]
|
|
267
393
|
},
|
|
268
|
-
"
|
|
269
|
-
"type": "
|
|
270
|
-
"description": "
|
|
394
|
+
"limit": {
|
|
395
|
+
"type": "integer",
|
|
396
|
+
"description": "Page size. Max 200 until 2027-01-12, then 100 (a larger value is clamped to the max, not an error; `next_cursor` pages the rest; see Deprecations).",
|
|
397
|
+
"default": 50
|
|
271
398
|
},
|
|
272
399
|
"cursor": {
|
|
273
400
|
"type": "string",
|
|
274
|
-
"description": "
|
|
401
|
+
"description": "Opaque cursor from the previous response."
|
|
275
402
|
}
|
|
276
403
|
},
|
|
277
404
|
"required": [
|
|
278
|
-
"
|
|
279
|
-
"interval"
|
|
405
|
+
"signal"
|
|
280
406
|
]
|
|
281
407
|
},
|
|
282
408
|
"endpoint": {
|
|
283
409
|
"method": "GET",
|
|
284
|
-
"path": "/v2/
|
|
410
|
+
"path": "/v2/signals/{signal}",
|
|
285
411
|
"paramLocation": {
|
|
286
|
-
"
|
|
287
|
-
"
|
|
288
|
-
"
|
|
289
|
-
"before": "query",
|
|
290
|
-
"from": "query",
|
|
291
|
-
"to": "query",
|
|
412
|
+
"signal": "path",
|
|
413
|
+
"condition": "query",
|
|
414
|
+
"universe": "query",
|
|
292
415
|
"asof": "query",
|
|
416
|
+
"grain": "query",
|
|
417
|
+
"select": "query",
|
|
418
|
+
"order": "query",
|
|
419
|
+
"dir": "query",
|
|
420
|
+
"limit": "query",
|
|
293
421
|
"cursor": "query"
|
|
422
|
+
},
|
|
423
|
+
"accepts": {
|
|
424
|
+
"as_of": "query",
|
|
425
|
+
"interval": "query",
|
|
426
|
+
"sort_by": "query",
|
|
427
|
+
"include_active_since": "query"
|
|
294
428
|
}
|
|
295
429
|
}
|
|
296
430
|
},
|
|
297
431
|
{
|
|
298
|
-
"name": "
|
|
299
|
-
"description": "
|
|
432
|
+
"name": "tickerbot_update_custom_signal",
|
|
433
|
+
"description": "Updates a custom signal you own: its expression, description or name.",
|
|
300
434
|
"inputSchema": {
|
|
301
435
|
"type": "object",
|
|
302
436
|
"properties": {
|
|
303
|
-
"
|
|
437
|
+
"signal": {
|
|
304
438
|
"type": "string",
|
|
305
|
-
"description": "
|
|
439
|
+
"description": "Custom signal slug (the signal name). A built-in name answers 404 — built-ins are read-only."
|
|
306
440
|
},
|
|
307
|
-
"
|
|
308
|
-
"type": "
|
|
309
|
-
"description": "
|
|
441
|
+
"new_name": {
|
|
442
|
+
"type": "string",
|
|
443
|
+
"description": "New slug — renames the signal and changes its API handle everywhere (same validation as create). Refused while other custom signals reference the current name."
|
|
444
|
+
},
|
|
445
|
+
"expr": {
|
|
446
|
+
"type": "string",
|
|
447
|
+
"description": "New SQL expression. Re-validated and re-inlined against your other custom signals. Same strict grammar as create: no `LIKE`/`ILIKE`, `CASE`, `::` casts or functions beyond `abs`/`coalesce`/`round`/`least`/`greatest`. The response echoes your expression as stored, not its expansion (a pre-2026-09-07 column spelling is stored under its current name and reported in `_meta.deprecated_signals`)."
|
|
448
|
+
},
|
|
449
|
+
"description": {
|
|
450
|
+
"type": "string",
|
|
451
|
+
"description": "New description. Not derived from `expr` — change both if the prose describes a threshold you are moving."
|
|
310
452
|
}
|
|
311
453
|
},
|
|
312
454
|
"required": [
|
|
313
|
-
"
|
|
455
|
+
"signal"
|
|
314
456
|
]
|
|
315
457
|
},
|
|
316
458
|
"endpoint": {
|
|
317
|
-
"method": "
|
|
318
|
-
"path": "/v2/
|
|
459
|
+
"method": "PATCH",
|
|
460
|
+
"path": "/v2/signals/{signal}",
|
|
319
461
|
"paramLocation": {
|
|
320
|
-
"
|
|
321
|
-
"
|
|
462
|
+
"signal": "path",
|
|
463
|
+
"new_name": "body",
|
|
464
|
+
"expr": "body",
|
|
465
|
+
"description": "body"
|
|
466
|
+
},
|
|
467
|
+
"accepts": {
|
|
468
|
+
"name": "body"
|
|
322
469
|
}
|
|
323
470
|
}
|
|
324
471
|
},
|
|
325
472
|
{
|
|
326
|
-
"name": "
|
|
327
|
-
"description": "
|
|
473
|
+
"name": "tickerbot_delete_custom_signal",
|
|
474
|
+
"description": "Deletes one of your custom signals. Refused by default if another of your signals references it.",
|
|
328
475
|
"inputSchema": {
|
|
329
476
|
"type": "object",
|
|
330
477
|
"properties": {
|
|
331
|
-
"
|
|
478
|
+
"signal": {
|
|
332
479
|
"type": "string",
|
|
333
|
-
"description": "
|
|
480
|
+
"description": "Custom signal slug (the signal name). A built-in name answers 404 — built-ins are read-only."
|
|
481
|
+
},
|
|
482
|
+
"force": {
|
|
483
|
+
"type": "boolean",
|
|
484
|
+
"description": "When `true`, skip the reference check and delete; referencing signals fail with `unknown_column` the next time they compile.",
|
|
485
|
+
"default": false
|
|
334
486
|
}
|
|
335
487
|
},
|
|
336
488
|
"required": [
|
|
337
|
-
"
|
|
489
|
+
"signal"
|
|
338
490
|
]
|
|
339
491
|
},
|
|
340
492
|
"endpoint": {
|
|
341
|
-
"method": "
|
|
342
|
-
"path": "/v2/
|
|
493
|
+
"method": "DELETE",
|
|
494
|
+
"path": "/v2/signals/{signal}",
|
|
343
495
|
"paramLocation": {
|
|
344
|
-
"
|
|
496
|
+
"signal": "path",
|
|
497
|
+
"force": "query"
|
|
345
498
|
}
|
|
346
499
|
}
|
|
347
500
|
},
|
|
348
501
|
{
|
|
349
|
-
"name": "
|
|
350
|
-
"description": "
|
|
502
|
+
"name": "tickerbot_subscribe_signal",
|
|
503
|
+
"description": "Gets you an alert by webhook each time a ticker starts matching one signal, bounded by a condition the way Get a signal is. Webhooks need a paid plan (Free has no webhook slots). A yes/no or custom signal takes no `condition`; any other signal needs one (`<30`). For a compound condition use tickerbot_subscribe_scan.",
|
|
351
504
|
"inputSchema": {
|
|
352
505
|
"type": "object",
|
|
353
506
|
"properties": {
|
|
354
|
-
"
|
|
507
|
+
"signal": {
|
|
355
508
|
"type": "string",
|
|
356
|
-
"description": "
|
|
357
|
-
"enum": [
|
|
358
|
-
"builtin",
|
|
359
|
-
"expression"
|
|
360
|
-
]
|
|
361
|
-
},
|
|
362
|
-
"limit": {
|
|
363
|
-
"type": "integer",
|
|
364
|
-
"description": "Page size for custom slice. Max 200. Default 50."
|
|
509
|
+
"description": "A signal name: a built-in signal or one of your custom signals. An unknown name is a 404."
|
|
365
510
|
},
|
|
366
|
-
"
|
|
511
|
+
"condition": {
|
|
367
512
|
"type": "string",
|
|
368
|
-
"description": "
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
},
|
|
372
|
-
"endpoint": {
|
|
373
|
-
"method": "GET",
|
|
374
|
-
"path": "/v2/signals",
|
|
375
|
-
"paramLocation": {
|
|
376
|
-
"kind": "query",
|
|
377
|
-
"limit": "query",
|
|
378
|
-
"cursor": "query"
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
},
|
|
382
|
-
{
|
|
383
|
-
"name": "tickerbot_get_signals_match",
|
|
384
|
-
"description": "Find tickers that match a single signal right now (or at a past moment with `asof`). Booleans need no condition. Numerics need a `condition` like \">70\" or \"<=200\". Sorted by signal value desc for numerics.",
|
|
385
|
-
"inputSchema": {
|
|
386
|
-
"type": "object",
|
|
387
|
-
"properties": {
|
|
388
|
-
"signal": {
|
|
513
|
+
"description": "The bound, in Get a signal's grammar: required for every signal that is not yes/no, shaped by its `type`. numeric: `>70`, `<30`, `!=0`. timestamp: `<YYYY-MM-DDTHH:MM:SSZ` or `>=YYYY-MM-DD`. date: `>=YYYY-MM-DD`. string: `=ETF` or `!=ETF`. A yes/no or custom signal takes none; sending one is a 400."
|
|
514
|
+
},
|
|
515
|
+
"universe": {
|
|
389
516
|
"type": "string",
|
|
390
|
-
"description": "
|
|
517
|
+
"description": "Restrict to a system or user-owned universe. Unknown universes are a 404 `universe_not_found`."
|
|
391
518
|
},
|
|
392
|
-
"
|
|
519
|
+
"select": {
|
|
393
520
|
"type": "string",
|
|
394
|
-
"description": "
|
|
521
|
+
"description": "What each delivered match carries. Omitted: the scan default row plus the signal. A list of signal names: exactly those, `ticker` always included."
|
|
395
522
|
},
|
|
396
|
-
"
|
|
523
|
+
"order": {
|
|
397
524
|
"type": "string",
|
|
398
|
-
"description": "
|
|
525
|
+
"description": "Signal each delivery's match lists are sorted by before the 100-result cap applies, so a truncated list is the deterministic top 100 rather than an arbitrary sample. Must be a real signal (validated at creation).",
|
|
526
|
+
"default": "market_cap"
|
|
399
527
|
},
|
|
400
|
-
"
|
|
528
|
+
"dir": {
|
|
401
529
|
"type": "string",
|
|
402
|
-
"description": "
|
|
530
|
+
"description": "Sort direction for `order`.",
|
|
531
|
+
"enum": [
|
|
532
|
+
"asc",
|
|
533
|
+
"desc"
|
|
534
|
+
],
|
|
535
|
+
"default": "desc"
|
|
403
536
|
},
|
|
404
|
-
"
|
|
537
|
+
"channel": {
|
|
405
538
|
"type": "string",
|
|
406
|
-
"description": "
|
|
539
|
+
"description": "Delivery channel. `webhook` (POST to `target_url`), `discord` (embed to `discord_url`), `in_app` (dashboard only) or `mobile_push` (to `device_id`). Inferred when omitted: `webhook` if `target_url` is set, `discord` if `discord_url` is set, `mobile_push` if `device_id` is set, else `in_app`.",
|
|
407
540
|
"enum": [
|
|
408
|
-
"
|
|
409
|
-
"
|
|
541
|
+
"webhook",
|
|
542
|
+
"discord",
|
|
543
|
+
"in_app",
|
|
544
|
+
"mobile_push"
|
|
410
545
|
]
|
|
411
546
|
},
|
|
412
|
-
"
|
|
413
|
-
"type": "
|
|
414
|
-
"description": "
|
|
547
|
+
"target_url": {
|
|
548
|
+
"type": "string",
|
|
549
|
+
"description": "Only with `channel=webhook`. https:// URL to POST when a ticker starts matching."
|
|
415
550
|
},
|
|
416
|
-
"
|
|
417
|
-
"type": "
|
|
418
|
-
"description": "
|
|
551
|
+
"discord_url": {
|
|
552
|
+
"type": "string",
|
|
553
|
+
"description": "Only with `channel=discord`. Discord incoming-webhook URL. Stored as a posting credential: the create response echoes it back under `channel_config`, but every later read (list, get, deliveries) strips it and sets `channel_config_present: true` instead."
|
|
419
554
|
},
|
|
420
|
-
"
|
|
555
|
+
"device_id": {
|
|
421
556
|
"type": "string",
|
|
422
|
-
"description": "
|
|
557
|
+
"description": "Only with `channel=mobile_push`. Device to notify, from `POST /v2/devices/register`. Unknown ids are a 404 `device_not_found`."
|
|
558
|
+
},
|
|
559
|
+
"cadence": {
|
|
560
|
+
"type": "string",
|
|
561
|
+
"description": "`realtime` (the default) is checked each time the data refreshes, about once a minute; `hourly` and `nyse_open` are checked on that schedule.",
|
|
562
|
+
"enum": [
|
|
563
|
+
"realtime",
|
|
564
|
+
"hourly",
|
|
565
|
+
"nyse_open"
|
|
566
|
+
]
|
|
567
|
+
},
|
|
568
|
+
"name": {
|
|
569
|
+
"type": "string",
|
|
570
|
+
"description": "Human-readable label (up to 80 chars). Defaults to the predicate: `golden_cross`, or `rsi_14 < 30`."
|
|
423
571
|
}
|
|
424
572
|
},
|
|
425
573
|
"required": [
|
|
@@ -427,603 +575,849 @@ export const tools = [
|
|
|
427
575
|
]
|
|
428
576
|
},
|
|
429
577
|
"endpoint": {
|
|
430
|
-
"method": "
|
|
431
|
-
"path": "/v2/signals/{signal}",
|
|
578
|
+
"method": "POST",
|
|
579
|
+
"path": "/v2/signals/{signal}/subscribe",
|
|
432
580
|
"paramLocation": {
|
|
433
581
|
"signal": "path",
|
|
434
|
-
"condition": "
|
|
435
|
-
"
|
|
436
|
-
"
|
|
437
|
-
"
|
|
438
|
-
"
|
|
439
|
-
"
|
|
440
|
-
"
|
|
582
|
+
"condition": "body",
|
|
583
|
+
"universe": "body",
|
|
584
|
+
"select": "body",
|
|
585
|
+
"order": "body",
|
|
586
|
+
"dir": "body",
|
|
587
|
+
"channel": "body",
|
|
588
|
+
"target_url": "body",
|
|
589
|
+
"discord_url": "body",
|
|
590
|
+
"device_id": "body",
|
|
591
|
+
"cadence": "body",
|
|
592
|
+
"name": "body"
|
|
593
|
+
},
|
|
594
|
+
"accepts": {
|
|
595
|
+
"universe_id": "body",
|
|
596
|
+
"columns": "body",
|
|
597
|
+
"fields": "body"
|
|
441
598
|
}
|
|
442
599
|
}
|
|
443
600
|
},
|
|
444
601
|
{
|
|
445
|
-
"name": "
|
|
446
|
-
"description": "
|
|
602
|
+
"name": "tickerbot_list_tickers",
|
|
603
|
+
"description": "Lists every ticker we track, active or delisted, with its identity. For everything about one, use Get a ticker.",
|
|
447
604
|
"inputSchema": {
|
|
448
605
|
"type": "object",
|
|
449
606
|
"properties": {
|
|
450
|
-
"
|
|
607
|
+
"search": {
|
|
451
608
|
"type": "string",
|
|
452
|
-
"description": "
|
|
609
|
+
"description": "Case-insensitive match on `ticker` or `name`, max 64 characters (longer is a 400). Results are ranked: an exact ticker match first, then symbols that start with the term, then name matches — alphabetical within each rank. The cursor carries the rank, so paging a search never repeats or skips."
|
|
453
610
|
},
|
|
454
611
|
"ticker": {
|
|
455
612
|
"type": "string",
|
|
456
|
-
"description": "
|
|
613
|
+
"description": "One symbol or a comma-separated list (up to 50; more is a 400): just those tickers' identity records, in the usual order. A symbol we don't track is simply absent. For everything about each one, put the list in the path of Get a ticker."
|
|
457
614
|
},
|
|
458
|
-
"
|
|
615
|
+
"asset_class": {
|
|
459
616
|
"type": "string",
|
|
460
|
-
"description": "
|
|
617
|
+
"description": "Filter by asset class — `stocks`, `rates`, `crypto`, `fx` or a comma-separated list (the live classes today; validated for shape, not against a fixed list, so a well-formed class we don't track simply matches nothing — same contract as scan). Omit for every class. This is the class of INSTRUMENT, distinct from `asset_type` below (the instrument type within equities). Every result carries its `asset_class`, so a non-equity result identifies itself."
|
|
461
618
|
},
|
|
462
|
-
"
|
|
619
|
+
"asset_type": {
|
|
463
620
|
"type": "string",
|
|
464
|
-
"description": "
|
|
621
|
+
"description": "Filter by instrument type WITHIN equities (one or a comma list) — the stored `asset_type` value (`CS`, `ETF`, `ADRC`, `PFD`, `FUND`, `UNIT`, `SP`, `ETS`, `WARRANT`, `RIGHT`, `ETN`, `ETV`), matched case-insensitively. `equity` is a convenience value expanding to the equity-like set. This is NOT an asset class: `asset_type=crypto` is rejected — use `asset_class=crypto`.",
|
|
622
|
+
"enum": [
|
|
623
|
+
"CS",
|
|
624
|
+
"ETF",
|
|
625
|
+
"ADRC",
|
|
626
|
+
"PFD",
|
|
627
|
+
"FUND",
|
|
628
|
+
"UNIT",
|
|
629
|
+
"SP",
|
|
630
|
+
"ETS",
|
|
631
|
+
"WARRANT",
|
|
632
|
+
"RIGHT",
|
|
633
|
+
"ETN",
|
|
634
|
+
"ETV",
|
|
635
|
+
"equity"
|
|
636
|
+
]
|
|
465
637
|
},
|
|
466
|
-
"
|
|
467
|
-
"type": "
|
|
468
|
-
"description": "
|
|
638
|
+
"exchange": {
|
|
639
|
+
"type": "string",
|
|
640
|
+
"description": "Filter by exchange name (one or a comma list) — the value results carry in their `exchange` field. MIC codes (`XNAS`, `XNYS`, `BATS`) are also accepted and match `exchange_mic`. A malformed value (non-letters, over 16 chars) is a 400."
|
|
641
|
+
},
|
|
642
|
+
"active": {
|
|
643
|
+
"type": "boolean",
|
|
644
|
+
"description": "`true` for tickers that trade today, `false` for delisted ones. Omit it for both."
|
|
469
645
|
},
|
|
470
646
|
"limit": {
|
|
471
647
|
"type": "integer",
|
|
472
|
-
"description": "Page size. Max 1000,
|
|
648
|
+
"description": "Page size. Max 1000 until 2027-01-12, then 100 (a larger value is clamped to the max, not an error; see Deprecations).",
|
|
649
|
+
"default": 50
|
|
473
650
|
},
|
|
474
651
|
"cursor": {
|
|
475
652
|
"type": "string",
|
|
476
|
-
"description": "Opaque cursor
|
|
653
|
+
"description": "Opaque cursor from the previous response's `next_cursor` field. Continues the walk from after that page. A cursor minted under `search` only resumes the same search."
|
|
477
654
|
}
|
|
478
|
-
}
|
|
479
|
-
"required": [
|
|
480
|
-
"signal",
|
|
481
|
-
"ticker"
|
|
482
|
-
]
|
|
655
|
+
}
|
|
483
656
|
},
|
|
484
657
|
"endpoint": {
|
|
485
658
|
"method": "GET",
|
|
486
|
-
"path": "/v2/
|
|
659
|
+
"path": "/v2/tickers",
|
|
487
660
|
"paramLocation": {
|
|
488
|
-
"
|
|
489
|
-
"ticker": "
|
|
490
|
-
"
|
|
491
|
-
"
|
|
492
|
-
"
|
|
661
|
+
"search": "query",
|
|
662
|
+
"ticker": "query",
|
|
663
|
+
"asset_class": "query",
|
|
664
|
+
"asset_type": "query",
|
|
665
|
+
"exchange": "query",
|
|
666
|
+
"active": "query",
|
|
493
667
|
"limit": "query",
|
|
494
668
|
"cursor": "query"
|
|
669
|
+
},
|
|
670
|
+
"accepts": {
|
|
671
|
+
"tickers": "query"
|
|
495
672
|
}
|
|
496
673
|
}
|
|
497
674
|
},
|
|
498
675
|
{
|
|
499
|
-
"name": "
|
|
500
|
-
"description": "
|
|
676
|
+
"name": "tickerbot_get_ticker",
|
|
677
|
+
"description": "Returns everything about one ticker or a comma list of up to 50 in the path (a screen's matches, say): every signal each one carries, live or on any past date with `asof`. Pass a comma list of up to 50 symbols for a batch (`data` keyed by symbol plus `not_found`). Crypto is the X-prefixed pair (X:BTCUSD) — bare BTC/ETH are US-listed ETFs.",
|
|
501
678
|
"inputSchema": {
|
|
502
679
|
"type": "object",
|
|
503
680
|
"properties": {
|
|
504
|
-
"
|
|
681
|
+
"ticker": {
|
|
505
682
|
"type": "string",
|
|
506
|
-
"description": "
|
|
683
|
+
"description": "One symbol, or a comma-separated list of up to 50 for a batch response keyed by symbol. Case-insensitive. Equities are bare symbols (`NVDA`); every other class carries a prefix — rates (`R:SOFR`), crypto (`X:BTCUSD`), fx (`X:EURUSD`). Bare `BTC`/`ETH` are US-listed ETFs, not spot crypto. See Tickers."
|
|
507
684
|
},
|
|
508
|
-
"
|
|
685
|
+
"asof": {
|
|
509
686
|
"type": "string",
|
|
510
|
-
"description": "
|
|
687
|
+
"description": "Target moment as `YYYY-MM-DD` (that day's close) or an ISO timestamp (that intraday moment; daily-only signals then carry the previous session's close, never that day's) — the same read as it stood then, unlimited depth. Full contract under As of a past date."
|
|
511
688
|
},
|
|
512
|
-
"
|
|
689
|
+
"grain": {
|
|
690
|
+
"type": "string",
|
|
691
|
+
"description": "Only with `asof`. Grain the past state is read at: `1m`, `1h`, `1d` or `auto` (default). `auto` blends: each signal comes from its freshest grain at or before the instant (minute, then hourly, then the last closed daily session), so nothing is refused for grain and no ticker is dropped; `_meta.blended` and `_meta.grains_present` say what contributed. Pin a grain for the fastest response: one grain is read instead of three. On this single-ticker read a pinned grain returns the signals that grain stores (`rsi_14`, fundamentals and valuation ratios are `1d`-only, so they are absent under `1h`/`1m` rather than refused), and a grain with no data for the ticker within its window (14 days for `1d`, 5 for `1h`/`1m`) is a `404 interval_unavailable`. A live read with `grain` is a 400.",
|
|
692
|
+
"enum": [
|
|
693
|
+
"1m",
|
|
694
|
+
"1h",
|
|
695
|
+
"1d",
|
|
696
|
+
"auto"
|
|
697
|
+
],
|
|
698
|
+
"default": "auto"
|
|
699
|
+
},
|
|
700
|
+
"select": {
|
|
513
701
|
"type": "string",
|
|
514
|
-
"description": "
|
|
702
|
+
"description": "Comma-separated signals to return: each row is `ticker` plus exactly these. Omit it for the full row (every signal the ticker carries). An unknown signal is a 400."
|
|
515
703
|
}
|
|
516
704
|
},
|
|
517
705
|
"required": [
|
|
518
|
-
"
|
|
519
|
-
"expr"
|
|
706
|
+
"ticker"
|
|
520
707
|
]
|
|
521
708
|
},
|
|
522
709
|
"endpoint": {
|
|
523
|
-
"method": "
|
|
524
|
-
"path": "/v2/
|
|
710
|
+
"method": "GET",
|
|
711
|
+
"path": "/v2/tickers/{ticker}",
|
|
525
712
|
"paramLocation": {
|
|
526
|
-
"
|
|
527
|
-
"
|
|
528
|
-
"
|
|
713
|
+
"ticker": "path",
|
|
714
|
+
"asof": "query",
|
|
715
|
+
"grain": "query",
|
|
716
|
+
"select": "query"
|
|
717
|
+
},
|
|
718
|
+
"accepts": {
|
|
719
|
+
"as_of": "query",
|
|
720
|
+
"interval": "query",
|
|
721
|
+
"fields": "query",
|
|
722
|
+
"columns": "query"
|
|
529
723
|
}
|
|
530
724
|
}
|
|
531
725
|
},
|
|
532
726
|
{
|
|
533
|
-
"name": "
|
|
534
|
-
"description": "
|
|
727
|
+
"name": "tickerbot_get_history",
|
|
728
|
+
"description": "Returns the signals of one ticker or a comma list of up to 50 in the path (a screen's matches, say) over time, all-time: up to 25 signals in `select`, every ticker on one shared grid. `ticker` takes one symbol or a comma list of up to 50 (a scan's matches) on one aligned grid. `data` is one flat row per grain step: the rows themselves for one symbol, keyed by symbol for a list. Paged backward: pass `next_cursor` back as `cursor`. For when a yes/no signal flipped, use tickerbot_list_events with kind=signal.",
|
|
535
729
|
"inputSchema": {
|
|
536
730
|
"type": "object",
|
|
537
731
|
"properties": {
|
|
538
|
-
"
|
|
732
|
+
"ticker": {
|
|
539
733
|
"type": "string",
|
|
540
|
-
"description": "
|
|
734
|
+
"description": "Ticker symbol, or a comma-separated list (up to 50) on one aligned grid. A page holds at most 25,000 points in all (tickers × `limit`), so 50 tickers page at up to 500 points each."
|
|
541
735
|
},
|
|
542
|
-
"
|
|
736
|
+
"from": {
|
|
543
737
|
"type": "string",
|
|
544
|
-
"description": "
|
|
738
|
+
"description": "Window start, `YYYY-MM-DD` or ISO: a bare date starts at the beginning of that day, a timestamp is included. 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."
|
|
545
739
|
},
|
|
546
|
-
"
|
|
740
|
+
"to": {
|
|
547
741
|
"type": "string",
|
|
548
|
-
"description": "
|
|
742
|
+
"description": "Window end, `YYYY-MM-DD` or ISO. A bare date covers that whole day. A timestamp is included until 2027-01-12 and exclusive from then, as everywhere else (Deprecations). At `1m`/`1h` a bare date on `from` or `to` is the ET calendar day for stocks and ETFs, and the UTC day when the request includes crypto or FX. See Time windows."
|
|
549
743
|
},
|
|
550
|
-
"
|
|
744
|
+
"asof": {
|
|
551
745
|
"type": "string",
|
|
552
|
-
"description": "
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
}
|
|
569
|
-
},
|
|
570
|
-
{
|
|
571
|
-
"name": "tickerbot_delete_custom_signal",
|
|
572
|
-
"description": "Delete one of the caller's custom signals. Cascade-safe by default: refused with 409 if another custom signal references it (the error lists the referencing signals). Pass `force: true` to delete anyway — existing references will break on next recompile. Available on every plan.",
|
|
573
|
-
"inputSchema": {
|
|
574
|
-
"type": "object",
|
|
575
|
-
"properties": {
|
|
576
|
-
"name": {
|
|
746
|
+
"description": "Point-in-time read: ONE result 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/{ticker}`, `/v2/scan` and `/v2/signals`. 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 state of whoever traded it then, so `/v2/tickers/SHLD/history?asof=2010-06-30` returns Sears Holdings' price and `asof=2026-01-01` returns the Global X defense ETF. Returns the most recent result at or before the instant, so a date inside a trading gap gives the last result before it; on the `1d` and `1w` grids a timestamp returns the previous session's result, never that day's close. Also: `next_cursor` is always `null` (every requested ticker is on the one page). A ticker with no data 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`; a 404 means only that we do not track the symbol. A bare date on the `1m`/`1h` grid is accepted and means the last result of that day: the ET calendar day for stocks and ETFs, the UTC day for crypto and FX (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 `grain=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: `/v2/tickers/AAPL/history?grain=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. At `grain=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: `/v2/tickers/AAPL/history?grain=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.6 s warm."
|
|
747
|
+
},
|
|
748
|
+
"grain": {
|
|
749
|
+
"type": "string",
|
|
750
|
+
"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 result on this grid, and a signal the grid does not carry is a `400`.",
|
|
751
|
+
"enum": [
|
|
752
|
+
"1m",
|
|
753
|
+
"1h",
|
|
754
|
+
"1d",
|
|
755
|
+
"1w",
|
|
756
|
+
"1q",
|
|
757
|
+
"1y"
|
|
758
|
+
],
|
|
759
|
+
"default": "1d"
|
|
760
|
+
},
|
|
761
|
+
"select": {
|
|
577
762
|
"type": "string",
|
|
578
|
-
"description": "
|
|
763
|
+
"description": "Up to 25 signals: built-in signals, your custom signals and OHLCV names, freely mixed. Omitted → the ticker-history default set (price, change_1d_pct, relative_volume, market_cap), intersected with what the grain carries. At `1q`, `select` is required and quarterly-only; at `1y`, required and annual-only (the list is under Notes)."
|
|
579
764
|
},
|
|
580
|
-
"
|
|
581
|
-
"type": "
|
|
582
|
-
"description": "
|
|
765
|
+
"limit": {
|
|
766
|
+
"type": "integer",
|
|
767
|
+
"description": "Grid steps per page. Max 1000 — an over-cap `limit` is clamped to 1000 (house convention, `limit=10000` means \"max\"). Separately, a page holds at most 25,000 points in all: tickers × `limit` over 25,000 is a 400 (50 tickers take `limit` up to 500; 25 take the full 1,000).",
|
|
768
|
+
"default": 252
|
|
769
|
+
},
|
|
770
|
+
"cursor": {
|
|
771
|
+
"type": "string",
|
|
772
|
+
"description": "Continue paging back: the previous response's `next_cursor`, unchanged, with the same tickers and parameters. It carries each ticker's own position, so every ticker continues from its own oldest row: nothing is skipped or repeated, even when the tickers trade on different calendars (a stock and a crypto pair)."
|
|
583
773
|
}
|
|
584
774
|
},
|
|
585
775
|
"required": [
|
|
586
|
-
"
|
|
776
|
+
"ticker"
|
|
587
777
|
]
|
|
588
778
|
},
|
|
589
779
|
"endpoint": {
|
|
590
|
-
"method": "
|
|
591
|
-
"path": "/v2/
|
|
780
|
+
"method": "GET",
|
|
781
|
+
"path": "/v2/tickers/{ticker}/history",
|
|
592
782
|
"paramLocation": {
|
|
593
|
-
"
|
|
594
|
-
"
|
|
783
|
+
"ticker": "path",
|
|
784
|
+
"from": "query",
|
|
785
|
+
"to": "query",
|
|
786
|
+
"asof": "query",
|
|
787
|
+
"grain": "query",
|
|
788
|
+
"select": "query",
|
|
789
|
+
"limit": "query",
|
|
790
|
+
"cursor": "query"
|
|
791
|
+
},
|
|
792
|
+
"accepts": {
|
|
793
|
+
"columns": "query",
|
|
794
|
+
"fields": "query",
|
|
795
|
+
"interval": "query",
|
|
796
|
+
"as_of": "query",
|
|
797
|
+
"transitions_only": "query"
|
|
798
|
+
},
|
|
799
|
+
"fixedQuery": {
|
|
800
|
+
"api_version": "2027-01-12"
|
|
595
801
|
}
|
|
596
802
|
}
|
|
597
803
|
},
|
|
598
804
|
{
|
|
599
|
-
"name": "
|
|
600
|
-
"description": "
|
|
805
|
+
"name": "tickerbot_subscribe_ticker",
|
|
806
|
+
"description": "Gets you an alert by webhook each time one ticker starts matching a condition. Webhooks need a paid plan (Free has no webhook slots). Omit `target_url` for in-app delivery.",
|
|
601
807
|
"inputSchema": {
|
|
602
808
|
"type": "object",
|
|
603
809
|
"properties": {
|
|
604
|
-
"
|
|
810
|
+
"ticker": {
|
|
605
811
|
"type": "string",
|
|
606
|
-
"description": "
|
|
812
|
+
"description": "Case-insensitive. Equities are bare symbols (`NVDA`); every other class carries a prefix — rates (`R:SOFR`), crypto (`X:BTCUSD`), fx (`X:EURUSD`). Bare `BTC`/`ETH` are US-listed ETFs, not spot crypto. See Tickers."
|
|
607
813
|
},
|
|
608
|
-
"
|
|
814
|
+
"q": {
|
|
609
815
|
"type": "string",
|
|
610
|
-
"description": "
|
|
816
|
+
"description": "WHERE-clause fragment using signal names from the catalog, the same grammar as `/v2/scan`. Custom signals are expanded and frozen in at creation."
|
|
611
817
|
},
|
|
612
|
-
"
|
|
818
|
+
"select": {
|
|
613
819
|
"type": "string",
|
|
614
|
-
"description": "
|
|
820
|
+
"description": "What each delivery carries. Omitted: the scan default row (ticker, name, asset_class, asset_type, price, change_1d_pct, gap_pct, relative_volume, market_cap) plus every signal used in `q`. A list of signal names: exactly those, `ticker` always included. Each must be a real signal; unknown ones are rejected at creation."
|
|
615
821
|
},
|
|
616
|
-
"
|
|
617
|
-
"type": "string",
|
|
618
|
-
"description": "Sort column. Default day_change_pct (rows) / tickers (aggregate)."
|
|
619
|
-
},
|
|
620
|
-
"dir": {
|
|
822
|
+
"channel": {
|
|
621
823
|
"type": "string",
|
|
622
|
-
"description": "
|
|
824
|
+
"description": "Delivery channel. `webhook` (POST to `target_url`), `discord` (post an embed to `discord_url`), `in_app` (dashboard only) or `mobile_push` (notify a phone signed in to the Tickerbot mobile app at `device_id`). Inferred when omitted: `webhook` if `target_url` is set, `discord` if `discord_url` is set, `mobile_push` if `device_id` is set, else `in_app`. See Delivery channels.",
|
|
623
825
|
"enum": [
|
|
624
|
-
"
|
|
625
|
-
"
|
|
826
|
+
"webhook",
|
|
827
|
+
"discord",
|
|
828
|
+
"in_app",
|
|
829
|
+
"mobile_push"
|
|
626
830
|
]
|
|
627
831
|
},
|
|
628
|
-
"
|
|
832
|
+
"target_url": {
|
|
629
833
|
"type": "string",
|
|
630
|
-
"description": "
|
|
834
|
+
"description": "Only with `channel=webhook`. https:// URL to POST when the condition fires."
|
|
631
835
|
},
|
|
632
|
-
"
|
|
836
|
+
"discord_url": {
|
|
633
837
|
"type": "string",
|
|
634
|
-
"description": "
|
|
838
|
+
"description": "Only with `channel=discord`. Discord incoming-webhook URL (`https://discord.com/api/webhooks/…`). Stored as a posting credential: the create response echoes it back under `channel_config`, but every later read (list, get, deliveries) strips it and sets `channel_config_present: true` instead."
|
|
635
839
|
},
|
|
636
|
-
"
|
|
840
|
+
"device_id": {
|
|
637
841
|
"type": "string",
|
|
638
|
-
"description": "
|
|
842
|
+
"description": "Only with `channel=mobile_push`. Device to notify, from `POST /v2/devices/register`. Unknown ids are a 404 `device_not_found`."
|
|
639
843
|
},
|
|
640
|
-
"
|
|
844
|
+
"cadence": {
|
|
641
845
|
"type": "string",
|
|
642
|
-
"description": "
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
846
|
+
"description": "How often to evaluate. `realtime` (the default) is checked each time the data refreshes, about once a minute; `hourly` and `nyse_open` are checked on that schedule.",
|
|
847
|
+
"enum": [
|
|
848
|
+
"realtime",
|
|
849
|
+
"hourly",
|
|
850
|
+
"nyse_open"
|
|
851
|
+
]
|
|
647
852
|
},
|
|
648
|
-
"
|
|
853
|
+
"name": {
|
|
649
854
|
"type": "string",
|
|
650
|
-
"description": "
|
|
651
|
-
},
|
|
652
|
-
"full": {
|
|
653
|
-
"type": "boolean",
|
|
654
|
-
"description": "Row mode: return the FULL wide row for each match (every column) instead of the slim default projection."
|
|
855
|
+
"description": "Human-readable label (up to 80 chars). Defaults to `<TICKER>: <query>`."
|
|
655
856
|
}
|
|
656
857
|
},
|
|
657
858
|
"required": [
|
|
859
|
+
"ticker",
|
|
658
860
|
"q"
|
|
659
861
|
]
|
|
660
862
|
},
|
|
661
863
|
"endpoint": {
|
|
662
|
-
"method": "
|
|
663
|
-
"path": "/v2/
|
|
864
|
+
"method": "POST",
|
|
865
|
+
"path": "/v2/tickers/{ticker}/subscribe",
|
|
664
866
|
"paramLocation": {
|
|
665
|
-
"
|
|
666
|
-
"
|
|
667
|
-
"
|
|
668
|
-
"
|
|
669
|
-
"
|
|
670
|
-
"
|
|
671
|
-
"
|
|
672
|
-
"
|
|
673
|
-
"
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
"
|
|
867
|
+
"ticker": "path",
|
|
868
|
+
"q": "body",
|
|
869
|
+
"select": "body",
|
|
870
|
+
"channel": "body",
|
|
871
|
+
"target_url": "body",
|
|
872
|
+
"discord_url": "body",
|
|
873
|
+
"device_id": "body",
|
|
874
|
+
"cadence": "body",
|
|
875
|
+
"name": "body"
|
|
876
|
+
},
|
|
877
|
+
"accepts": {
|
|
878
|
+
"condition": "body",
|
|
879
|
+
"columns": "body",
|
|
880
|
+
"fields": "body",
|
|
881
|
+
"order": "body",
|
|
882
|
+
"dir": "body"
|
|
677
883
|
}
|
|
678
884
|
}
|
|
679
885
|
},
|
|
680
886
|
{
|
|
681
|
-
"name": "
|
|
682
|
-
"description": "
|
|
887
|
+
"name": "tickerbot_get_bars",
|
|
888
|
+
"description": "Returns OHLCV bars from `1s` to monthly for one ticker or a comma list of up to 50 in the path, such as a screen's matches.",
|
|
683
889
|
"inputSchema": {
|
|
684
890
|
"type": "object",
|
|
685
891
|
"properties": {
|
|
686
|
-
"
|
|
892
|
+
"ticker": {
|
|
893
|
+
"type": "string",
|
|
894
|
+
"description": "Ticker symbol, or a comma-separated list (up to 50) for a bulk response keyed by symbol."
|
|
895
|
+
},
|
|
896
|
+
"interval": {
|
|
687
897
|
"type": "string",
|
|
688
|
-
"description": "
|
|
898
|
+
"description": "Bar interval. `2h`/`4h` roll up hourly bars; `1w`/`1mo` roll up daily bars into calendar weeks (Monday start) and months — the bar's `t` is the bucket start (UTC), and with `asof` the last bucket is the week/month to date.",
|
|
689
899
|
"enum": [
|
|
690
|
-
"
|
|
691
|
-
"
|
|
692
|
-
"
|
|
900
|
+
"1s",
|
|
901
|
+
"1m",
|
|
902
|
+
"5m",
|
|
903
|
+
"15m",
|
|
904
|
+
"30m",
|
|
905
|
+
"1h",
|
|
906
|
+
"2h",
|
|
907
|
+
"4h",
|
|
908
|
+
"1d",
|
|
909
|
+
"1w",
|
|
910
|
+
"1mo"
|
|
693
911
|
]
|
|
694
912
|
},
|
|
913
|
+
"from": {
|
|
914
|
+
"type": "string",
|
|
915
|
+
"description": "Window start: `YYYY-MM-DD`, ISO timestamp or epoch-ms. A bare date starts at the beginning of that day; a timestamp is included. Combines with `to` for an explicit window; page within it using `cursor`. Mutually exclusive with `asof` (400). See Time windows."
|
|
916
|
+
},
|
|
917
|
+
"to": {
|
|
918
|
+
"type": "string",
|
|
919
|
+
"description": "Window end: `YYYY-MM-DD`, ISO timestamp or epoch-ms. A bare date covers that whole day. A timestamp is included until 2027-01-12 (the newest bar returned is at or before it) and exclusive from then, as everywhere else (Deprecations). On sub-daily intervals a bare date on `from` or `to` is the ET calendar day for stocks and ETFs (the whole 04:00-20:00 ET session) and the UTC day for crypto and FX. Mutually exclusive with `asof` (400). See Time windows."
|
|
920
|
+
},
|
|
921
|
+
"asof": {
|
|
922
|
+
"type": "string",
|
|
923
|
+
"description": "Point-in-time: the most recent bar whose period had closed at or before that moment. A bare `YYYY-MM-DD` means that day's close. A full timestamp means the last FINISHED bar — at 10:00 ET on a Wednesday the day's close has not happened, so `1d` returns Tuesday's bar. A bare date on an intraday grid (`1m`, `1h`, …) is accepted and means the last bar of that day: the ET calendar day for stocks and ETFs (through the 19:59 ET bar), the UTC day for crypto and FX. Returns one bar unless you also pass `limit`, which gives the last `limit` closed bars; follow `next_cursor` with the same parameters to keep paging back: the cursor and `asof` both bound the page, so no bar after the instant is ever served and every page stays on the company that held the symbol at the instant. Unlimited depth. Response time: under 1.5 s cold, under 0.6 s warm."
|
|
924
|
+
},
|
|
925
|
+
"adjusted": {
|
|
926
|
+
"type": "boolean",
|
|
927
|
+
"description": "Default `true`: prices are split-adjusted — restated after each later split, as the tape is, so a series is continuous across a split. `false` returns the price as it printed that day (a name that later did a 1:10 reverse split reads `21.4` adjusted and `2.14` on the tape), which is what a broker fill or a chart from that time shows. Volume scales the other way."
|
|
928
|
+
},
|
|
929
|
+
"session": {
|
|
930
|
+
"type": "string",
|
|
931
|
+
"description": "Sub-hour intervals only. `all` (default) includes pre- and post-market bars. `regular` keeps bars whose start is in 09:30–16:00 ET (DST-aware). Why you might want it: the vendor buckets trades by SIP report time, and late-reported off-exchange (Form T) prints on thin names can land 20 min to hours late in a pre-market minute — a `$1.70` print at 08:13 ET on a `$3.85` stock. Daily high/low are untouched by those. `limit` counts after the filter; paging still works.",
|
|
932
|
+
"enum": [
|
|
933
|
+
"all",
|
|
934
|
+
"regular"
|
|
935
|
+
],
|
|
936
|
+
"default": "all"
|
|
937
|
+
},
|
|
695
938
|
"limit": {
|
|
696
939
|
"type": "integer",
|
|
697
|
-
"description": "
|
|
940
|
+
"description": "Most-recent N bars. Max 1000 — an over-cap value is clamped, not an error. On a comma list the cap is per symbol: each symbol returns its newest `limit` bars in the window.",
|
|
941
|
+
"default": 100
|
|
698
942
|
},
|
|
699
943
|
"cursor": {
|
|
700
944
|
"type": "string",
|
|
701
|
-
"description": "
|
|
945
|
+
"description": "Continue paging back: the previous response's `next_cursor`, unchanged, with the same symbols and parameters. On a comma list it carries each symbol's own position, so every symbol continues from its own oldest bar. A blank `cursor=` counts as absent."
|
|
702
946
|
}
|
|
703
|
-
}
|
|
947
|
+
},
|
|
948
|
+
"required": [
|
|
949
|
+
"ticker",
|
|
950
|
+
"interval"
|
|
951
|
+
]
|
|
704
952
|
},
|
|
705
953
|
"endpoint": {
|
|
706
954
|
"method": "GET",
|
|
707
|
-
"path": "/v2/
|
|
955
|
+
"path": "/v2/tickers/{ticker}/bars/{interval}",
|
|
708
956
|
"paramLocation": {
|
|
709
|
-
"
|
|
957
|
+
"ticker": "path",
|
|
958
|
+
"interval": "path",
|
|
959
|
+
"from": "query",
|
|
960
|
+
"to": "query",
|
|
961
|
+
"asof": "query",
|
|
962
|
+
"adjusted": "query",
|
|
963
|
+
"session": "query",
|
|
710
964
|
"limit": "query",
|
|
711
965
|
"cursor": "query"
|
|
966
|
+
},
|
|
967
|
+
"accepts": {
|
|
968
|
+
"as_of": "query",
|
|
969
|
+
"before": "query"
|
|
970
|
+
},
|
|
971
|
+
"fixedQuery": {
|
|
972
|
+
"api_version": "2027-01-12"
|
|
712
973
|
}
|
|
713
974
|
}
|
|
714
975
|
},
|
|
715
976
|
{
|
|
716
|
-
"name": "
|
|
717
|
-
"description": "
|
|
718
|
-
"inputSchema": {
|
|
719
|
-
"type": "object",
|
|
720
|
-
"properties": {}
|
|
721
|
-
},
|
|
722
|
-
"endpoint": {
|
|
723
|
-
"method": "GET",
|
|
724
|
-
"path": "/v2/universes/system",
|
|
725
|
-
"paramLocation": {}
|
|
726
|
-
}
|
|
727
|
-
},
|
|
728
|
-
{
|
|
729
|
-
"name": "tickerbot_get_universe",
|
|
730
|
-
"description": "Get one universe by slug, including its ticker list.",
|
|
977
|
+
"name": "tickerbot_get_ticker_coverage",
|
|
978
|
+
"description": "Reports what we hold for one ticker or a comma list of up to 50, and how far back, so an empty result is never ambiguous. Ask this before treating a gap in bars or history as an outage. An absent `1m` span is not a gap — sub-hour bars load on the first request for a symbol.",
|
|
731
979
|
"inputSchema": {
|
|
732
980
|
"type": "object",
|
|
733
981
|
"properties": {
|
|
734
|
-
"
|
|
982
|
+
"ticker": {
|
|
735
983
|
"type": "string",
|
|
736
|
-
"description": "
|
|
984
|
+
"description": "One symbol, or a comma-separated list of up to 50 for a response keyed by symbol. Case-insensitive. Equities are bare symbols (`NVDA`); every other class carries a prefix — rates (`R:SOFR`), crypto (`X:BTCUSD`), fx (`X:EURUSD`). Bare `BTC`/`ETH` are US-listed ETFs, not spot crypto. See Tickers."
|
|
737
985
|
}
|
|
738
986
|
},
|
|
739
987
|
"required": [
|
|
740
|
-
"
|
|
988
|
+
"ticker"
|
|
741
989
|
]
|
|
742
990
|
},
|
|
743
991
|
"endpoint": {
|
|
744
992
|
"method": "GET",
|
|
745
|
-
"path": "/v2/
|
|
993
|
+
"path": "/v2/tickers/{ticker}/coverage",
|
|
746
994
|
"paramLocation": {
|
|
747
|
-
"
|
|
995
|
+
"ticker": "path"
|
|
996
|
+
},
|
|
997
|
+
"accepts": {
|
|
998
|
+
"symbol": "path"
|
|
999
|
+
},
|
|
1000
|
+
"pathAliases": {
|
|
1001
|
+
"symbol": "ticker"
|
|
748
1002
|
}
|
|
749
1003
|
}
|
|
750
1004
|
},
|
|
751
1005
|
{
|
|
752
|
-
"name": "
|
|
753
|
-
"description": "
|
|
1006
|
+
"name": "tickerbot_get_etf_holdings",
|
|
1007
|
+
"description": "Returns an ETF's constituents and their weights, heaviest first, and its sector weights, for one ETF or a comma list of up to 50. Returns `data.holdings` and the sector mix `data.sectors`. When the ticker is not an ETF, `is_etf` is false and both are empty; `is_etf: true` with zero holdings means a real ETF whose holdings are not ingested yet. The reverse lookup (\"which ETFs hold NVDA\") is the `etf_holders` signal on tickerbot_get_ticker, or a scan: `'SMH' = ANY(etf_holders)`.",
|
|
754
1008
|
"inputSchema": {
|
|
755
1009
|
"type": "object",
|
|
756
1010
|
"properties": {
|
|
757
|
-
"
|
|
1011
|
+
"ticker": {
|
|
758
1012
|
"type": "string",
|
|
759
|
-
"description": "
|
|
1013
|
+
"description": "ETF symbol, or a comma-separated list of up to 50 for a response keyed by symbol. Case-insensitive."
|
|
760
1014
|
},
|
|
761
|
-
"
|
|
762
|
-
"type": "
|
|
763
|
-
"description": "
|
|
1015
|
+
"limit": {
|
|
1016
|
+
"type": "integer",
|
|
1017
|
+
"description": "Holdings per page, per ETF. Max 5000 until 2027-01-12, then 1000 (an over-cap `limit` is clamped to the max, not an error; see Deprecations). When more holdings follow the page, the ETF's object carries `truncated: true` and `total` (its full holding count), and `next_cursor` pages the rest.",
|
|
1018
|
+
"default": 500
|
|
764
1019
|
},
|
|
765
|
-
"
|
|
1020
|
+
"cursor": {
|
|
766
1021
|
"type": "string",
|
|
767
|
-
"description": "
|
|
768
|
-
},
|
|
769
|
-
"tickers": {
|
|
770
|
-
"type": "array",
|
|
771
|
-
"description": "List of ticker symbols.",
|
|
772
|
-
"items": {
|
|
773
|
-
"type": "string"
|
|
774
|
-
}
|
|
1022
|
+
"description": "Continue paging: the previous response's `next_cursor`, unchanged, with the same symbols and `limit`. On a comma list it carries each ETF's own position, so every ETF continues from its own last holding; a finished one returns an empty `holdings`."
|
|
775
1023
|
}
|
|
776
1024
|
},
|
|
777
1025
|
"required": [
|
|
778
|
-
"
|
|
779
|
-
"tickers"
|
|
1026
|
+
"ticker"
|
|
780
1027
|
]
|
|
781
1028
|
},
|
|
782
1029
|
"endpoint": {
|
|
783
|
-
"method": "
|
|
784
|
-
"path": "/v2/
|
|
1030
|
+
"method": "GET",
|
|
1031
|
+
"path": "/v2/tickers/{ticker}/holdings",
|
|
785
1032
|
"paramLocation": {
|
|
786
|
-
"
|
|
787
|
-
"
|
|
788
|
-
"
|
|
789
|
-
|
|
1033
|
+
"ticker": "path",
|
|
1034
|
+
"limit": "query",
|
|
1035
|
+
"cursor": "query"
|
|
1036
|
+
},
|
|
1037
|
+
"accepts": {
|
|
1038
|
+
"symbol": "path"
|
|
1039
|
+
},
|
|
1040
|
+
"pathAliases": {
|
|
1041
|
+
"symbol": "ticker"
|
|
790
1042
|
}
|
|
791
1043
|
}
|
|
792
1044
|
},
|
|
793
1045
|
{
|
|
794
|
-
"name": "
|
|
795
|
-
"description": "
|
|
1046
|
+
"name": "tickerbot_list_events",
|
|
1047
|
+
"description": "Queries events with SQL across every ticker or a screen's matches: earnings, dividends, splits, filings, insider trades and analyst actions, plus opt-in estimate revisions, news and signal firings. Requires at least one bound: a ticker scope (ticker/universe) or a time window (from/to) — `q` alone is not a bound. With one `kind`, its payload fields are bare names in `q`/`select`/`group_by` (`q: firm ILIKE 'Morgan Stanley'`, `q: relevance >= 0.8` on news); tickerbot_list_event_kinds lists them. `join: state` adds the ticker's signals as of each event. Every result has a stable `id`: use it to drop duplicates. `kind: signal` takes custom signals too.",
|
|
796
1048
|
"inputSchema": {
|
|
797
1049
|
"type": "object",
|
|
798
1050
|
"properties": {
|
|
799
|
-
"
|
|
1051
|
+
"kind": {
|
|
800
1052
|
"type": "string",
|
|
801
|
-
"description": "
|
|
1053
|
+
"description": "Comma list of kinds. Leave it out for earnings, dividend, split, filing, insider and analyst. News, signal and estimate_revision come back only when named. List event kinds lists each kind, its fields and its filters.",
|
|
1054
|
+
"enum": [
|
|
1055
|
+
"dividend",
|
|
1056
|
+
"split",
|
|
1057
|
+
"insider",
|
|
1058
|
+
"analyst",
|
|
1059
|
+
"earnings",
|
|
1060
|
+
"filing",
|
|
1061
|
+
"signal",
|
|
1062
|
+
"news",
|
|
1063
|
+
"estimate_revision"
|
|
1064
|
+
]
|
|
802
1065
|
},
|
|
803
|
-
"
|
|
1066
|
+
"ticker": {
|
|
804
1067
|
"type": "string",
|
|
805
|
-
"description": "
|
|
1068
|
+
"description": "One ticker or a comma list (up to 50). Not combinable with `universe`. A crypto, FX or rate symbol (`X:BTCUSD`) takes `kind=signal`; every other kind is equities-only and returns `400` naming the symbol's asset class."
|
|
806
1069
|
},
|
|
807
|
-
"
|
|
1070
|
+
"universe": {
|
|
808
1071
|
"type": "string",
|
|
809
|
-
"description": "
|
|
1072
|
+
"description": "Universe slug (`top_10`, `top_100` or one of yours) to scope the stream. Not combinable with `ticker`."
|
|
810
1073
|
},
|
|
811
|
-
"
|
|
812
|
-
"type": "
|
|
813
|
-
"description": "
|
|
814
|
-
"items": {
|
|
815
|
-
"type": "string"
|
|
816
|
-
}
|
|
1074
|
+
"from": {
|
|
1075
|
+
"type": "string",
|
|
1076
|
+
"description": "Events at/after this instant — strict ISO: `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM[:SS]Z`. A bare `YYYY-MM-DD` means from the start of that day. For news, analyst ratings and estimate revisions the day is the ET calendar day (a story at 21:00 ET on Nov 2 is Nov 2); dated kinds use their own dates."
|
|
817
1077
|
},
|
|
818
|
-
"
|
|
819
|
-
"type": "
|
|
820
|
-
"description": "
|
|
821
|
-
"items": {
|
|
822
|
-
"type": "string"
|
|
823
|
-
}
|
|
1078
|
+
"to": {
|
|
1079
|
+
"type": "string",
|
|
1080
|
+
"description": "Window end — same strict ISO subset. A bare `YYYY-MM-DD` means through the end of that day; a timestamp is exclusive (events strictly before it). For news, analyst ratings and estimate revisions the day is the ET calendar day; dated kinds use their own dates."
|
|
824
1081
|
},
|
|
825
|
-
"
|
|
826
|
-
"type": "
|
|
827
|
-
"description": "
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
1082
|
+
"signal": {
|
|
1083
|
+
"type": "string",
|
|
1084
|
+
"description": "Only with `kind=signal`. One signal or a comma list of up to 5: built-in yes/no signals or your custom signals. Required with `q` or `join=state`. See Signal firings."
|
|
1085
|
+
},
|
|
1086
|
+
"transition": {
|
|
1087
|
+
"type": "string",
|
|
1088
|
+
"description": "Only with `kind=signal`. `enter` (false→true) or `exit` (true→false).",
|
|
1089
|
+
"enum": [
|
|
1090
|
+
"enter",
|
|
1091
|
+
"exit"
|
|
1092
|
+
]
|
|
1093
|
+
},
|
|
1094
|
+
"merge_gap_seconds": {
|
|
1095
|
+
"type": "integer",
|
|
1096
|
+
"description": "Only with `kind=signal`. Merges an exit and re-entry closer than N seconds into one span. Needs one `signal` and a `ticker` list, and does not combine with `q`, `group_by` or `join=state`."
|
|
1097
|
+
},
|
|
1098
|
+
"q": {
|
|
1099
|
+
"type": "string",
|
|
1100
|
+
"description": "SQL WHERE over `id`, `ticker`, `ts`, `kind` and `payload` (plus the ticker's signals with `join=state`). With one `kind`, its payload fields are typed columns by bare name: `amount > 1`, `firm ILIKE 'Morgan Stanley'`, `relevance >= 0.8` on news (List event kinds lists them); with several kinds, use `payload->>'…'`. Max 4000 chars. ANDs with the other filters."
|
|
1101
|
+
},
|
|
1102
|
+
"join": {
|
|
1103
|
+
"type": "string",
|
|
1104
|
+
"description": "Set to `state` to use the ticker's signals in `q`, `select`, `group_by` and `having`, read as of each event's timestamp at the grain `grain` picks. On the daily grain an event on day D reads D-1's row, never D's close. A signal and a payload field with the same name (`price` on insider and signal events, `cik` on filing) resolve to the signal; spell the field `payload->>'price'`.",
|
|
1105
|
+
"enum": [
|
|
1106
|
+
"state"
|
|
1107
|
+
]
|
|
1108
|
+
},
|
|
1109
|
+
"grain": {
|
|
1110
|
+
"type": "string",
|
|
1111
|
+
"description": "With `kind=signal`, the grain the flips are read at: `1m`, `1h` or `1d` (default: the coarsest grain the signal is stored at). With `join=state`, the grain the ticker's signals are read at: `auto` (default) blends hourly and the last closed daily session per event; see as of a past date.",
|
|
1112
|
+
"enum": [
|
|
1113
|
+
"1m",
|
|
1114
|
+
"1h",
|
|
1115
|
+
"1d",
|
|
1116
|
+
"auto"
|
|
1117
|
+
],
|
|
1118
|
+
"default": "auto"
|
|
1119
|
+
},
|
|
1120
|
+
"select": {
|
|
1121
|
+
"type": "string",
|
|
1122
|
+
"description": "Without `group_by`: what each result carries. `id`, `ticker`, `ts` and `kind` always, then the names you list, each at the top level of the result: `payload`, a payload field of the one kind named (`firm`, or `payload->>'firm'`) and with `join=state` a ticker signal. With `group_by`: the rollup's output columns (default: the group keys + `COUNT(*) AS events`), named with `AS` or for you as on `group_by`."
|
|
1123
|
+
},
|
|
1124
|
+
"group_by": {
|
|
1125
|
+
"type": "string",
|
|
1126
|
+
"description": "Comma list of rollup keys — switches the response to rollups. Columns (`kind`, `ticker`), payload fields (`firm`, or the explicit `payload->>'firm'`) and expressions over them all roll up. Name a key with `AS` to choose its JSON key: `payload->>'firm' AS firm`. Un-named keys are named for you — a payload read takes its key (`payload->>'firm'` → `firm`), a function keeps the function's name (`lower(ticker)` → `lower`), and anything else falls back to `group_1`, `group_2`."
|
|
1127
|
+
},
|
|
1128
|
+
"having": {
|
|
1129
|
+
"type": "string",
|
|
1130
|
+
"description": "Only with `group_by`. Post-aggregation filter."
|
|
1131
|
+
},
|
|
1132
|
+
"order": {
|
|
1133
|
+
"type": "string",
|
|
1134
|
+
"description": "With `group_by`: the rollup sort, a bare column or output name (put expressions in `select` and sort by their alias); a group key's name works too: `group_by=payload->>'firm' AS firm&order=firm`. Default: `events`. A list is sorted by `ts`: `order=ts` is accepted there and changes nothing."
|
|
1135
|
+
},
|
|
1136
|
+
"dir": {
|
|
1137
|
+
"type": "string",
|
|
1138
|
+
"description": "A list: `desc` (default) is newest first, `asc` oldest first, paging forward. With `group_by`: the rollup's sort direction.",
|
|
1139
|
+
"enum": [
|
|
1140
|
+
"asc",
|
|
1141
|
+
"desc"
|
|
1142
|
+
],
|
|
1143
|
+
"default": "desc"
|
|
1144
|
+
},
|
|
1145
|
+
"limit": {
|
|
1146
|
+
"type": "integer",
|
|
1147
|
+
"description": "Page size (lists) / max groups (aggregate mode). A list takes up to 1000 until 2027-01-12, then 100, and pages the rest with `next_cursor`; a `group_by` rollup keeps up to 1000 groups and sets `truncated: true` past that. A larger value is clamped to the max, not an error; see Deprecations.",
|
|
1148
|
+
"default": 50
|
|
1149
|
+
},
|
|
1150
|
+
"cursor": {
|
|
1151
|
+
"type": "string",
|
|
1152
|
+
"description": "Opaque cursor from the previous response. It carries the filters, `dir`, `select` (and `q` when short), so pass it alone. Not valid with `group_by`."
|
|
831
1153
|
}
|
|
832
|
-
}
|
|
833
|
-
"required": [
|
|
834
|
-
"id"
|
|
835
|
-
]
|
|
1154
|
+
}
|
|
836
1155
|
},
|
|
837
1156
|
"endpoint": {
|
|
838
|
-
"method": "
|
|
839
|
-
"path": "/v2/
|
|
1157
|
+
"method": "GET",
|
|
1158
|
+
"path": "/v2/events",
|
|
840
1159
|
"paramLocation": {
|
|
841
|
-
"
|
|
842
|
-
"
|
|
843
|
-
"
|
|
844
|
-
"
|
|
845
|
-
"
|
|
846
|
-
"
|
|
1160
|
+
"kind": "query",
|
|
1161
|
+
"ticker": "query",
|
|
1162
|
+
"universe": "query",
|
|
1163
|
+
"from": "query",
|
|
1164
|
+
"to": "query",
|
|
1165
|
+
"signal": "query",
|
|
1166
|
+
"transition": "query",
|
|
1167
|
+
"merge_gap_seconds": "query",
|
|
1168
|
+
"q": "query",
|
|
1169
|
+
"join": "query",
|
|
1170
|
+
"grain": "query",
|
|
1171
|
+
"select": "query",
|
|
1172
|
+
"group_by": "query",
|
|
1173
|
+
"having": "query",
|
|
1174
|
+
"order": "query",
|
|
1175
|
+
"dir": "query",
|
|
1176
|
+
"limit": "query",
|
|
1177
|
+
"cursor": "query"
|
|
1178
|
+
},
|
|
1179
|
+
"accepts": {
|
|
1180
|
+
"tickers": "query",
|
|
1181
|
+
"since": "query",
|
|
1182
|
+
"until": "query",
|
|
1183
|
+
"interval": "query",
|
|
1184
|
+
"firm": "query",
|
|
1185
|
+
"action": "query",
|
|
1186
|
+
"min_relevance": "query"
|
|
847
1187
|
}
|
|
848
1188
|
}
|
|
849
1189
|
},
|
|
850
1190
|
{
|
|
851
|
-
"name": "
|
|
852
|
-
"description": "
|
|
1191
|
+
"name": "tickerbot_list_event_kinds",
|
|
1192
|
+
"description": "Returns every event kind: what it is, whether it is in the default stream and can be subscribed to, what its `ts` means, and the fields you can name in `q`, `select` and `group_by` when you ask for that kind alone. Call once to learn the kinds, which are in the default stream, which can be subscribed to, and the field names each accepts in `q`, `select` and `group_by`.",
|
|
853
1193
|
"inputSchema": {
|
|
854
1194
|
"type": "object",
|
|
855
|
-
"properties": {
|
|
856
|
-
"id": {
|
|
857
|
-
"type": "string",
|
|
858
|
-
"description": "Universe slug."
|
|
859
|
-
}
|
|
860
|
-
},
|
|
861
|
-
"required": [
|
|
862
|
-
"id"
|
|
863
|
-
]
|
|
1195
|
+
"properties": {}
|
|
864
1196
|
},
|
|
865
1197
|
"endpoint": {
|
|
866
|
-
"method": "
|
|
867
|
-
"path": "/v2/
|
|
868
|
-
"paramLocation": {
|
|
869
|
-
"id": "path"
|
|
870
|
-
}
|
|
1198
|
+
"method": "GET",
|
|
1199
|
+
"path": "/v2/events/kinds",
|
|
1200
|
+
"paramLocation": {}
|
|
871
1201
|
}
|
|
872
1202
|
},
|
|
873
1203
|
{
|
|
874
|
-
"name": "
|
|
875
|
-
"description": "
|
|
1204
|
+
"name": "tickerbot_subscribe_events",
|
|
1205
|
+
"description": "Gets you an alert by webhook when new events of the kinds you choose land, filtered on the event and on the ticker's signals. Webhooks need a paid plan (Free has no webhook slots). One `q` covers the event's fields (with one kind, bare: `firm = 'Goldman Sachs'`) and the ticker's signals at fire time (`market_cap > 1e10`); on a name clash (`price`, `cik`) the ticker signal wins; the event's own value is `payload->>'price'`. Latency is the ingest cadence (analyst ≤1h, corporate kinds daily), not sub-minute.",
|
|
876
1206
|
"inputSchema": {
|
|
877
1207
|
"type": "object",
|
|
878
1208
|
"properties": {
|
|
879
1209
|
"kind": {
|
|
880
1210
|
"type": "string",
|
|
881
|
-
"description": "
|
|
1211
|
+
"description": "Event kinds to fire on, an array or a comma list. `filing` fires when a 10-K, 20-F, 40-F or 10-Q lands (the next morning's EDGAR index read); `estimate_revision` when the nightly consensus refresh moves an EPS estimate (about 1,000 a night across the market, at most about one a day per ticker).",
|
|
1212
|
+
"enum": [
|
|
1213
|
+
"dividend",
|
|
1214
|
+
"split",
|
|
1215
|
+
"insider",
|
|
1216
|
+
"analyst",
|
|
1217
|
+
"earnings",
|
|
1218
|
+
"filing",
|
|
1219
|
+
"estimate_revision"
|
|
1220
|
+
]
|
|
882
1221
|
},
|
|
883
|
-
"
|
|
1222
|
+
"ticker": {
|
|
884
1223
|
"type": "string",
|
|
885
|
-
"description": "
|
|
1224
|
+
"description": "One ticker or a comma list (up to 50). Not combinable with `universe`. Omit both for every ticker."
|
|
886
1225
|
},
|
|
887
|
-
"
|
|
1226
|
+
"universe": {
|
|
888
1227
|
"type": "string",
|
|
889
|
-
"description": "
|
|
1228
|
+
"description": "Scope to a universe slug (`top_10`, `top_100` or one of yours)."
|
|
1229
|
+
},
|
|
1230
|
+
"q": {
|
|
1231
|
+
"type": "string",
|
|
1232
|
+
"description": "The filter, as on Query events with `join=state`: the event's own fields (`id`, `ticker`, `ts`, `kind`, `payload`, and with one kind its payload fields by bare name) and the ticker's signals at fire time, in one WHERE clause. A payload field and a signal with the same name resolve to the signal, as on Query events: `price` on insider, `cik` on filing. Spell the event's own value `payload->>'price'`. Custom signals are expanded and frozen at creation."
|
|
1233
|
+
},
|
|
1234
|
+
"select": {
|
|
1235
|
+
"type": "string",
|
|
1236
|
+
"description": "What each delivered event carries: `id`, `ticker`, `ts` and `kind` always, then the names you list, at the top level: `payload`, the payload fields of the one kind named, and ticker signals at fire time. Omitted: each event as on Query events (`payload` whole)."
|
|
1237
|
+
},
|
|
1238
|
+
"channel": {
|
|
1239
|
+
"type": "string",
|
|
1240
|
+
"description": "Delivery channel. Inferred when omitted: `webhook` if `target_url` is set, `discord` if `discord_url` is set, `mobile_push` if `device_id` is set, else `in_app`.",
|
|
890
1241
|
"enum": [
|
|
891
|
-
"
|
|
892
|
-
"
|
|
1242
|
+
"webhook",
|
|
1243
|
+
"discord",
|
|
1244
|
+
"in_app",
|
|
1245
|
+
"mobile_push"
|
|
893
1246
|
]
|
|
894
1247
|
},
|
|
895
|
-
"
|
|
1248
|
+
"target_url": {
|
|
896
1249
|
"type": "string",
|
|
897
|
-
"description": "
|
|
1250
|
+
"description": "Only with `channel=webhook`. HTTPS delivery URL."
|
|
898
1251
|
},
|
|
899
|
-
"
|
|
1252
|
+
"discord_url": {
|
|
900
1253
|
"type": "string",
|
|
901
|
-
"description": "
|
|
1254
|
+
"description": "Only with `channel=discord`. Discord incoming-webhook URL. Stored as a posting credential: the create response echoes it back under `channel_config`, but every later read (list, get, deliveries) strips it and sets `channel_config_present: true` instead."
|
|
902
1255
|
},
|
|
903
|
-
"
|
|
1256
|
+
"device_id": {
|
|
904
1257
|
"type": "string",
|
|
905
|
-
"description": "
|
|
1258
|
+
"description": "Only with `channel=mobile_push`. Device to notify, from `POST /v2/devices/register`. Unknown ids are a 404 `device_not_found`."
|
|
906
1259
|
},
|
|
907
|
-
"
|
|
1260
|
+
"name": {
|
|
1261
|
+
"type": "string",
|
|
1262
|
+
"description": "Display name. Defaults to `events: <kinds> · <scope>`."
|
|
1263
|
+
}
|
|
1264
|
+
},
|
|
1265
|
+
"required": [
|
|
1266
|
+
"kind"
|
|
1267
|
+
]
|
|
1268
|
+
},
|
|
1269
|
+
"endpoint": {
|
|
1270
|
+
"method": "POST",
|
|
1271
|
+
"path": "/v2/events/subscribe",
|
|
1272
|
+
"paramLocation": {
|
|
1273
|
+
"kind": "body",
|
|
1274
|
+
"ticker": "body",
|
|
1275
|
+
"universe": "body",
|
|
1276
|
+
"q": "body",
|
|
1277
|
+
"select": "body",
|
|
1278
|
+
"channel": "body",
|
|
1279
|
+
"target_url": "body",
|
|
1280
|
+
"discord_url": "body",
|
|
1281
|
+
"device_id": "body",
|
|
1282
|
+
"name": "body"
|
|
1283
|
+
},
|
|
1284
|
+
"accepts": {
|
|
1285
|
+
"kinds": "body",
|
|
1286
|
+
"tickers": "body",
|
|
1287
|
+
"universe_id": "body",
|
|
1288
|
+
"event_q": "body"
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
},
|
|
1292
|
+
{
|
|
1293
|
+
"name": "tickerbot_search_news",
|
|
1294
|
+
"description": "Queries news with SQL for any ticker or a screen's matches: articles with how each one treats every ticker it mentions, or rollups when you group them. `ticker` (one or a comma list) keeps articles that mention it; add `min_relevance: 0.8` to keep only articles about it. Each article carries `mentions`: per ticker, `relevance` and `sentiment_score`/`sentiment`. Naming `ticker`, `relevance`, `sentiment_score` or `sentiment` in `q`/`select`/`group_by` gives one row per article per mention: `q: ticker = 'NVDA' AND sentiment_score < -0.3` is articles negative about NVDA. `search` is full-text over title and summary. Rollups with group_by/having return `truncated: true` instead of paging.",
|
|
1295
|
+
"inputSchema": {
|
|
1296
|
+
"type": "object",
|
|
1297
|
+
"properties": {
|
|
1298
|
+
"search": {
|
|
908
1299
|
"type": "string",
|
|
909
|
-
"description": "
|
|
1300
|
+
"description": "Full-text search over `title` + `summary` — websearch grammar: `nvidia earnings` (all words), `\"price target\"` (phrase), `chips OR semiconductors`, `-crypto` (negation). Max 200 chars. ANDs with `q` and the other filters. Language-stemmed English."
|
|
910
1301
|
},
|
|
911
|
-
"
|
|
1302
|
+
"ticker": {
|
|
912
1303
|
"type": "string",
|
|
913
|
-
"description": "
|
|
1304
|
+
"description": "One ticker or a comma list (up to 50): articles that mention any of them. Not combinable with `universe`. Per-mention rows still list every ticker an article mentions; put `ticker = 'NVDA'` in `q` for one ticker's rows."
|
|
914
1305
|
},
|
|
915
|
-
"
|
|
1306
|
+
"universe": {
|
|
916
1307
|
"type": "string",
|
|
917
|
-
"description": "
|
|
918
|
-
"enum": [
|
|
919
|
-
"state"
|
|
920
|
-
]
|
|
1308
|
+
"description": "Universe slug: articles that mention any member. Not combinable with `ticker`."
|
|
921
1309
|
},
|
|
922
|
-
"
|
|
1310
|
+
"from": {
|
|
1311
|
+
"type": "string",
|
|
1312
|
+
"description": "Earliest `time_published` (inclusive) — strict ISO: `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM[:SS]Z`. A bare date starts at 00:00 ET that day."
|
|
1313
|
+
},
|
|
1314
|
+
"to": {
|
|
923
1315
|
"type": "string",
|
|
924
|
-
"description": "
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
]
|
|
1316
|
+
"description": "Articles strictly before this instant — same strict ISO subset, matching `/v2/events`. A bare `YYYY-MM-DD` means through the end of that day (the ET calendar day), so `from` and `to` on the same date return that day."
|
|
1317
|
+
},
|
|
1318
|
+
"min_relevance": {
|
|
1319
|
+
"type": "number",
|
|
1320
|
+
"description": "Only with `ticker` or `universe`. Keeps an article only when it is about one of the tickers, meaning that ticker's `relevance` (0 to 1) is at least this value. `0.8` drops passing mentions. Omitted: every article that mentions them. `400` without a ticker scope; in `q`, filter the mention itself: `ticker = 'NVDA' AND relevance >= 0.8`."
|
|
930
1321
|
},
|
|
931
1322
|
"q": {
|
|
932
1323
|
"type": "string",
|
|
933
|
-
"description": "
|
|
1324
|
+
"description": "WHERE clause over news articles. Max 4000 chars. Required unless `search`, `ticker`, `universe`, `from` or `to` is present. Takes every article field under Returns except `mentions`, plus the per-mention fields `ticker`, `relevance`, `sentiment_score` and `sentiment` (one article per mention). Signals are not joinable here."
|
|
934
1325
|
},
|
|
935
1326
|
"select": {
|
|
936
1327
|
"type": "string",
|
|
937
|
-
"description": "
|
|
1328
|
+
"description": "Fields or expressions to return (max 2000 chars). Defaults to the article row (no `group_by`) or `<group_by keys>, COUNT(*) AS volume` (with `group_by`). `mentions` is selectable on its own."
|
|
938
1329
|
},
|
|
939
1330
|
"group_by": {
|
|
940
1331
|
"type": "string",
|
|
941
|
-
"description": "Comma
|
|
1332
|
+
"description": "Comma-separated group keys, 1-6 (max 1000 chars); the response becomes rollups. `ticker` rolls up per ticker mentioned. Name a key with `AS` to choose its JSON key; an un-named expression is named for you rather than returned as `?column?`."
|
|
942
1333
|
},
|
|
943
1334
|
"having": {
|
|
944
1335
|
"type": "string",
|
|
945
|
-
"description": "
|
|
1336
|
+
"description": "Only with `group_by`. HAVING clause on the rollup (max 1000 chars)."
|
|
946
1337
|
},
|
|
947
1338
|
"order": {
|
|
948
1339
|
"type": "string",
|
|
949
|
-
"description": "
|
|
1340
|
+
"description": "Sort — a bare field name or SELECT alias only (put expressions in `select` and order by their alias). Defaults to `time_published` (articles) or `volume` (rollups; with your own `select` that has no `volume` column, its last column's alias)."
|
|
950
1341
|
},
|
|
951
1342
|
"dir": {
|
|
952
1343
|
"type": "string",
|
|
953
|
-
"description": "
|
|
1344
|
+
"description": "Sort direction.",
|
|
954
1345
|
"enum": [
|
|
955
1346
|
"asc",
|
|
956
1347
|
"desc"
|
|
957
|
-
]
|
|
1348
|
+
],
|
|
1349
|
+
"default": "desc"
|
|
958
1350
|
},
|
|
959
1351
|
"limit": {
|
|
960
1352
|
"type": "integer",
|
|
961
|
-
"description": "Page size.
|
|
1353
|
+
"description": "Page size (articles) / max groups (a `group_by` rollup). Articles take up to 1000 until 2027-01-12, then 100, and page the rest with `next_cursor`; a rollup keeps up to 1000 groups and sets `truncated: true` past that. A larger value is clamped to the max, not an error; see Deprecations.",
|
|
1354
|
+
"default": 50
|
|
962
1355
|
},
|
|
963
1356
|
"cursor": {
|
|
964
1357
|
"type": "string",
|
|
965
|
-
"description": "Opaque cursor from a prior response
|
|
1358
|
+
"description": "Opaque pagination cursor from a prior response's `next_cursor`."
|
|
966
1359
|
}
|
|
967
1360
|
}
|
|
968
1361
|
},
|
|
969
1362
|
"endpoint": {
|
|
970
1363
|
"method": "GET",
|
|
971
|
-
"path": "/v2/
|
|
1364
|
+
"path": "/v2/news",
|
|
972
1365
|
"paramLocation": {
|
|
973
|
-
"
|
|
1366
|
+
"search": "query",
|
|
974
1367
|
"ticker": "query",
|
|
975
|
-
"tickers": "query",
|
|
976
1368
|
"universe": "query",
|
|
977
1369
|
"from": "query",
|
|
978
1370
|
"to": "query",
|
|
979
|
-
"
|
|
980
|
-
"interval": "query",
|
|
981
|
-
"limit": "query",
|
|
982
|
-
"cursor": "query",
|
|
1371
|
+
"min_relevance": "query",
|
|
983
1372
|
"q": "query",
|
|
984
1373
|
"select": "query",
|
|
985
1374
|
"group_by": "query",
|
|
986
1375
|
"having": "query",
|
|
987
1376
|
"order": "query",
|
|
988
1377
|
"dir": "query",
|
|
989
|
-
"
|
|
990
|
-
"
|
|
1378
|
+
"limit": "query",
|
|
1379
|
+
"cursor": "query"
|
|
1380
|
+
},
|
|
1381
|
+
"accepts": {
|
|
1382
|
+
"tickers": "query",
|
|
1383
|
+
"since": "query",
|
|
1384
|
+
"until": "query"
|
|
991
1385
|
}
|
|
992
1386
|
}
|
|
993
1387
|
},
|
|
994
1388
|
{
|
|
995
|
-
"name": "
|
|
996
|
-
"description": "
|
|
1389
|
+
"name": "tickerbot_subscribe_news",
|
|
1390
|
+
"description": "Gets you an alert by webhook when a new article matches your search, tickers or SQL filter, with how it treats each ticker it mentions. Webhooks need a paid plan (Free has no webhook slots). Takes Query news's filters (search, ticker, universe, min_relevance, q); one of search/ticker/universe/q is required, since the whole market is about 6,000 articles a weekday. Fires as new matching articles land; each article fires once. Each delivery is `event: \"news.fired\"` with `articles`, each the Query news row (or `select`) plus `mentions`.",
|
|
997
1391
|
"inputSchema": {
|
|
998
1392
|
"type": "object",
|
|
999
1393
|
"properties": {
|
|
1000
|
-
"
|
|
1394
|
+
"search": {
|
|
1001
1395
|
"type": "string",
|
|
1002
|
-
"description": "
|
|
1396
|
+
"description": "Full-text search over `title` + `summary`, as on Query news."
|
|
1003
1397
|
},
|
|
1004
|
-
"
|
|
1398
|
+
"ticker": {
|
|
1005
1399
|
"type": "string",
|
|
1006
|
-
"description": "
|
|
1400
|
+
"description": "One ticker or a comma list (up to 50): articles that mention any of them. Not combinable with `universe`."
|
|
1007
1401
|
},
|
|
1008
1402
|
"universe": {
|
|
1009
1403
|
"type": "string",
|
|
1010
|
-
"description": "
|
|
1404
|
+
"description": "Universe slug (`top_10`, `top_100` or one of yours): articles that mention any member."
|
|
1011
1405
|
},
|
|
1012
|
-
"
|
|
1013
|
-
"type": "
|
|
1014
|
-
"description": "
|
|
1406
|
+
"min_relevance": {
|
|
1407
|
+
"type": "number",
|
|
1408
|
+
"description": "Only with `ticker` or `universe`. Only articles about one of the tickers (its `relevance` at least this value, 0 to 1)."
|
|
1015
1409
|
},
|
|
1016
|
-
"
|
|
1410
|
+
"q": {
|
|
1017
1411
|
"type": "string",
|
|
1018
|
-
"description": "
|
|
1412
|
+
"description": "The filter, as on Query news: article fields and the per-mention fields `ticker`, `relevance`, `sentiment_score` and `sentiment`. An article fires once when any of its mentions matches."
|
|
1019
1413
|
},
|
|
1020
|
-
"
|
|
1414
|
+
"select": {
|
|
1021
1415
|
"type": "string",
|
|
1022
|
-
"description": "
|
|
1416
|
+
"description": "The article fields each delivered article carries, besides `id` and `mentions` (always sent). Names only. Omitted: the Query news default row."
|
|
1023
1417
|
},
|
|
1024
1418
|
"channel": {
|
|
1025
1419
|
"type": "string",
|
|
1026
|
-
"description": "Delivery channel.",
|
|
1420
|
+
"description": "Delivery channel. Inferred when omitted: `webhook` if `target_url` is set, `discord` if `discord_url` is set, `mobile_push` if `device_id` is set, else `in_app`.",
|
|
1027
1421
|
"enum": [
|
|
1028
1422
|
"webhook",
|
|
1029
1423
|
"discord",
|
|
@@ -1031,351 +1425,388 @@ export const tools = [
|
|
|
1031
1425
|
"mobile_push"
|
|
1032
1426
|
]
|
|
1033
1427
|
},
|
|
1034
|
-
"
|
|
1428
|
+
"target_url": {
|
|
1035
1429
|
"type": "string",
|
|
1036
|
-
"description": "
|
|
1430
|
+
"description": "Only with `channel=webhook`. HTTPS delivery URL."
|
|
1037
1431
|
},
|
|
1038
|
-
"
|
|
1432
|
+
"discord_url": {
|
|
1039
1433
|
"type": "string",
|
|
1040
|
-
"description": "
|
|
1434
|
+
"description": "Only with `channel=discord`. Discord incoming-webhook URL. Stored as a posting credential: the create response echoes it back under `channel_config`, but every later read (list, get, deliveries) strips it and sets `channel_config_present: true` instead."
|
|
1041
1435
|
},
|
|
1042
|
-
"
|
|
1436
|
+
"device_id": {
|
|
1043
1437
|
"type": "string",
|
|
1044
|
-
"description": "
|
|
1045
|
-
"enum": [
|
|
1046
|
-
"realtime",
|
|
1047
|
-
"hourly",
|
|
1048
|
-
"nyse_open"
|
|
1049
|
-
]
|
|
1438
|
+
"description": "Only with `channel=mobile_push`. Device to notify, from `POST /v2/devices/register`. Unknown ids are a 404 `device_not_found`."
|
|
1050
1439
|
},
|
|
1051
1440
|
"name": {
|
|
1052
1441
|
"type": "string",
|
|
1053
|
-
"description": "Display name."
|
|
1442
|
+
"description": "Display name. Defaults to `news: <scope> · <search or q>`."
|
|
1054
1443
|
}
|
|
1055
|
-
}
|
|
1056
|
-
"required": [
|
|
1057
|
-
"kinds"
|
|
1058
|
-
]
|
|
1444
|
+
}
|
|
1059
1445
|
},
|
|
1060
1446
|
"endpoint": {
|
|
1061
1447
|
"method": "POST",
|
|
1062
|
-
"path": "/v2/
|
|
1448
|
+
"path": "/v2/news/subscribe",
|
|
1063
1449
|
"paramLocation": {
|
|
1064
|
-
"
|
|
1065
|
-
"
|
|
1450
|
+
"search": "body",
|
|
1451
|
+
"ticker": "body",
|
|
1066
1452
|
"universe": "body",
|
|
1453
|
+
"min_relevance": "body",
|
|
1067
1454
|
"q": "body",
|
|
1068
|
-
"
|
|
1069
|
-
"target_url": "body",
|
|
1455
|
+
"select": "body",
|
|
1070
1456
|
"channel": "body",
|
|
1457
|
+
"target_url": "body",
|
|
1071
1458
|
"discord_url": "body",
|
|
1072
1459
|
"device_id": "body",
|
|
1073
|
-
"cadence": "body",
|
|
1074
1460
|
"name": "body"
|
|
1461
|
+
},
|
|
1462
|
+
"accepts": {
|
|
1463
|
+
"tickers": "body",
|
|
1464
|
+
"universe_id": "body"
|
|
1075
1465
|
}
|
|
1076
1466
|
}
|
|
1077
1467
|
},
|
|
1078
1468
|
{
|
|
1079
|
-
"name": "
|
|
1080
|
-
"description": "
|
|
1469
|
+
"name": "tickerbot_list_universes",
|
|
1470
|
+
"description": "Lists every universe you can use: your own ticker lists and the built-in ones. `kind: builtin` lists the built-in universes (top_10, top_100); omit it for yours; `builtin,custom` lists both. Use a slug as `universe` on scan, signal, and subscribe tools.",
|
|
1081
1471
|
"inputSchema": {
|
|
1082
1472
|
"type": "object",
|
|
1083
1473
|
"properties": {
|
|
1084
|
-
"
|
|
1474
|
+
"kind": {
|
|
1085
1475
|
"type": "string",
|
|
1086
|
-
"description": "
|
|
1476
|
+
"description": "Which universes to list: `builtin` (`top_10`, `top_100`), `custom` (your own) or both as a comma list. Leave it out for your own; from the cut-off on Deprecations it lists both.",
|
|
1477
|
+
"enum": [
|
|
1478
|
+
"builtin",
|
|
1479
|
+
"custom"
|
|
1480
|
+
]
|
|
1087
1481
|
},
|
|
1088
|
-
"
|
|
1482
|
+
"search": {
|
|
1089
1483
|
"type": "string",
|
|
1090
|
-
"description": "
|
|
1484
|
+
"description": "Only universes whose id, name or description contains this text (case-insensitive)."
|
|
1091
1485
|
},
|
|
1092
|
-
"
|
|
1093
|
-
"type": "
|
|
1094
|
-
"description": "
|
|
1486
|
+
"limit": {
|
|
1487
|
+
"type": "integer",
|
|
1488
|
+
"description": "Page size. Max 100.",
|
|
1489
|
+
"default": 50
|
|
1095
1490
|
},
|
|
1096
|
-
"
|
|
1491
|
+
"cursor": {
|
|
1097
1492
|
"type": "string",
|
|
1098
|
-
"description": "
|
|
1493
|
+
"description": "Opaque cursor from the previous response."
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
},
|
|
1497
|
+
"endpoint": {
|
|
1498
|
+
"method": "GET",
|
|
1499
|
+
"path": "/v2/universes",
|
|
1500
|
+
"paramLocation": {
|
|
1501
|
+
"kind": "query",
|
|
1502
|
+
"search": "query",
|
|
1503
|
+
"limit": "query",
|
|
1504
|
+
"cursor": "query"
|
|
1505
|
+
},
|
|
1506
|
+
"accepts": {
|
|
1507
|
+
"owner": "query"
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
},
|
|
1511
|
+
{
|
|
1512
|
+
"name": "tickerbot_create_universe",
|
|
1513
|
+
"description": "Saves a named list of tickers to scope screens and subscriptions.",
|
|
1514
|
+
"inputSchema": {
|
|
1515
|
+
"type": "object",
|
|
1516
|
+
"properties": {
|
|
1517
|
+
"tickers": {
|
|
1518
|
+
"type": "array",
|
|
1519
|
+
"items": {
|
|
1520
|
+
"type": "string"
|
|
1521
|
+
},
|
|
1522
|
+
"description": "Ticker symbols, up to 10,000. Validated against the tickers we track. `[]` is accepted: an empty universe you can fill later via PATCH."
|
|
1099
1523
|
},
|
|
1100
|
-
"
|
|
1524
|
+
"name": {
|
|
1101
1525
|
"type": "string",
|
|
1102
|
-
"description": "
|
|
1526
|
+
"description": "Human-readable label, up to 80 characters. Display-only — never used to reference the universe."
|
|
1103
1527
|
},
|
|
1104
|
-
"
|
|
1528
|
+
"id": {
|
|
1105
1529
|
"type": "string",
|
|
1106
|
-
"description": "
|
|
1107
|
-
"enum": [
|
|
1108
|
-
"asc",
|
|
1109
|
-
"desc"
|
|
1110
|
-
]
|
|
1530
|
+
"description": "Optional slug — becomes the universe's permanent handle everywhere (`?universe=`, subscribe `universe`, CRUD path). Pattern `^[a-z][a-z0-9_]{0,62}$` — starts with a lowercase letter, then lowercase letters/digits/underscore, 63 chars max; the value is trimmed and lowercased before validation. `top_10` and `top_100` are reserved for system universes and rejected with 400. Must be unique within your account. Generated (`u_…`) if omitted."
|
|
1111
1531
|
},
|
|
1112
|
-
"
|
|
1113
|
-
"type": "integer",
|
|
1114
|
-
"description": "Page size."
|
|
1115
|
-
},
|
|
1116
|
-
"cursor": {
|
|
1532
|
+
"description": {
|
|
1117
1533
|
"type": "string",
|
|
1118
|
-
"description": "
|
|
1534
|
+
"description": "Free-form notes, up to 500 characters. Stored as `\"\"` when omitted."
|
|
1119
1535
|
}
|
|
1120
1536
|
},
|
|
1121
1537
|
"required": [
|
|
1122
|
-
"
|
|
1538
|
+
"tickers",
|
|
1539
|
+
"name"
|
|
1540
|
+
]
|
|
1541
|
+
},
|
|
1542
|
+
"endpoint": {
|
|
1543
|
+
"method": "POST",
|
|
1544
|
+
"path": "/v2/universes",
|
|
1545
|
+
"paramLocation": {
|
|
1546
|
+
"tickers": "body",
|
|
1547
|
+
"name": "body",
|
|
1548
|
+
"id": "body",
|
|
1549
|
+
"description": "body"
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
},
|
|
1553
|
+
{
|
|
1554
|
+
"name": "tickerbot_get_universe",
|
|
1555
|
+
"description": "Returns one universe: a built-in (`top_10`, `top_100`) or one you own.",
|
|
1556
|
+
"inputSchema": {
|
|
1557
|
+
"type": "object",
|
|
1558
|
+
"properties": {
|
|
1559
|
+
"universe": {
|
|
1560
|
+
"type": "string",
|
|
1561
|
+
"description": "Universe slug: a built-in (`top_10`, `top_100`) or one of yours."
|
|
1562
|
+
}
|
|
1563
|
+
},
|
|
1564
|
+
"required": [
|
|
1565
|
+
"universe"
|
|
1123
1566
|
]
|
|
1124
1567
|
},
|
|
1125
1568
|
"endpoint": {
|
|
1126
1569
|
"method": "GET",
|
|
1127
|
-
"path": "/v2/
|
|
1570
|
+
"path": "/v2/universes/{universe}",
|
|
1128
1571
|
"paramLocation": {
|
|
1129
|
-
"
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
"
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
"
|
|
1136
|
-
"cursor": "query"
|
|
1572
|
+
"universe": "path"
|
|
1573
|
+
},
|
|
1574
|
+
"accepts": {
|
|
1575
|
+
"id": "path"
|
|
1576
|
+
},
|
|
1577
|
+
"pathAliases": {
|
|
1578
|
+
"id": "universe"
|
|
1137
1579
|
}
|
|
1138
1580
|
}
|
|
1139
1581
|
},
|
|
1140
1582
|
{
|
|
1141
|
-
"name": "
|
|
1142
|
-
"description": "
|
|
1583
|
+
"name": "tickerbot_update_universe",
|
|
1584
|
+
"description": "Updates one of your universes: its name, description or members. `tickers` replaces the whole list; `add`/`remove` adjust it. System universes cannot be edited.",
|
|
1143
1585
|
"inputSchema": {
|
|
1144
1586
|
"type": "object",
|
|
1145
1587
|
"properties": {
|
|
1146
|
-
"
|
|
1588
|
+
"universe": {
|
|
1147
1589
|
"type": "string",
|
|
1148
|
-
"description": "
|
|
1590
|
+
"description": "Universe slug."
|
|
1149
1591
|
},
|
|
1150
|
-
"
|
|
1151
|
-
"type": "
|
|
1152
|
-
"
|
|
1592
|
+
"tickers": {
|
|
1593
|
+
"type": "array",
|
|
1594
|
+
"items": {
|
|
1595
|
+
"type": "string"
|
|
1596
|
+
},
|
|
1597
|
+
"description": "Replace the full ticker list (up to 10,000; validated against the tickers we track). Does not combine with `add`/`remove` (400)."
|
|
1153
1598
|
},
|
|
1154
|
-
"
|
|
1155
|
-
"type": "
|
|
1156
|
-
"
|
|
1599
|
+
"add": {
|
|
1600
|
+
"type": "array",
|
|
1601
|
+
"items": {
|
|
1602
|
+
"type": "string"
|
|
1603
|
+
},
|
|
1604
|
+
"description": "Add these tickers (deduplicated)."
|
|
1157
1605
|
},
|
|
1158
|
-
"
|
|
1159
|
-
"type": "
|
|
1160
|
-
"
|
|
1606
|
+
"remove": {
|
|
1607
|
+
"type": "array",
|
|
1608
|
+
"items": {
|
|
1609
|
+
"type": "string"
|
|
1610
|
+
},
|
|
1611
|
+
"description": "Remove these tickers."
|
|
1161
1612
|
},
|
|
1162
|
-
"
|
|
1613
|
+
"name": {
|
|
1163
1614
|
"type": "string",
|
|
1164
|
-
"description": "
|
|
1165
|
-
"enum": [
|
|
1166
|
-
"webhook",
|
|
1167
|
-
"discord",
|
|
1168
|
-
"in_app",
|
|
1169
|
-
"mobile_push"
|
|
1170
|
-
]
|
|
1615
|
+
"description": "New label. Non-empty, max 80 characters."
|
|
1171
1616
|
},
|
|
1172
|
-
"
|
|
1617
|
+
"description": {
|
|
1173
1618
|
"type": "string",
|
|
1174
|
-
"description": "
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1619
|
+
"description": "New notes. Max 500 characters."
|
|
1620
|
+
}
|
|
1621
|
+
},
|
|
1622
|
+
"required": [
|
|
1623
|
+
"universe"
|
|
1624
|
+
]
|
|
1625
|
+
},
|
|
1626
|
+
"endpoint": {
|
|
1627
|
+
"method": "PATCH",
|
|
1628
|
+
"path": "/v2/universes/{universe}",
|
|
1629
|
+
"paramLocation": {
|
|
1630
|
+
"universe": "path",
|
|
1631
|
+
"tickers": "body",
|
|
1632
|
+
"add": "body",
|
|
1633
|
+
"remove": "body",
|
|
1634
|
+
"name": "body",
|
|
1635
|
+
"description": "body"
|
|
1636
|
+
},
|
|
1637
|
+
"accepts": {
|
|
1638
|
+
"id": "path"
|
|
1639
|
+
},
|
|
1640
|
+
"pathAliases": {
|
|
1641
|
+
"id": "universe"
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
},
|
|
1645
|
+
{
|
|
1646
|
+
"name": "tickerbot_delete_universe",
|
|
1647
|
+
"description": "Permanently deletes one of your universes. Webhooks that reference the deleted universe fail on their next eval — clean those up first.",
|
|
1648
|
+
"inputSchema": {
|
|
1649
|
+
"type": "object",
|
|
1650
|
+
"properties": {
|
|
1651
|
+
"universe": {
|
|
1177
1652
|
"type": "string",
|
|
1178
|
-
"description": "
|
|
1653
|
+
"description": "Universe slug."
|
|
1179
1654
|
},
|
|
1180
|
-
"
|
|
1181
|
-
"type": "
|
|
1182
|
-
"description": "
|
|
1183
|
-
"
|
|
1184
|
-
"realtime",
|
|
1185
|
-
"hourly",
|
|
1186
|
-
"nyse_open"
|
|
1187
|
-
]
|
|
1655
|
+
"force": {
|
|
1656
|
+
"type": "boolean",
|
|
1657
|
+
"description": "A universe still referenced by live webhooks refuses to delete with `409 universe_referenced`. Pass `force=true` to delete anyway; those webhooks are disabled at their next evaluation.",
|
|
1658
|
+
"default": false
|
|
1188
1659
|
}
|
|
1189
1660
|
},
|
|
1190
1661
|
"required": [
|
|
1191
|
-
"
|
|
1192
|
-
"condition"
|
|
1662
|
+
"universe"
|
|
1193
1663
|
]
|
|
1194
1664
|
},
|
|
1195
1665
|
"endpoint": {
|
|
1196
|
-
"method": "
|
|
1197
|
-
"path": "/v2/
|
|
1666
|
+
"method": "DELETE",
|
|
1667
|
+
"path": "/v2/universes/{universe}",
|
|
1198
1668
|
"paramLocation": {
|
|
1199
|
-
"
|
|
1200
|
-
"
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
"
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
"
|
|
1669
|
+
"universe": "path",
|
|
1670
|
+
"force": "query"
|
|
1671
|
+
},
|
|
1672
|
+
"accepts": {
|
|
1673
|
+
"id": "path"
|
|
1674
|
+
},
|
|
1675
|
+
"pathAliases": {
|
|
1676
|
+
"id": "universe"
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
},
|
|
1680
|
+
{
|
|
1681
|
+
"name": "tickerbot_list_webhooks",
|
|
1682
|
+
"description": "Lists every webhook on your account, newest first.",
|
|
1683
|
+
"inputSchema": {
|
|
1684
|
+
"type": "object",
|
|
1685
|
+
"properties": {
|
|
1686
|
+
"status": {
|
|
1687
|
+
"type": "string",
|
|
1688
|
+
"description": "Filter by status: `active`, `disabled` or both as a comma list — the only two states a webhook has (`disabled` covers a user pause, the automatic disable after 72 hours with no successful delivery and the automatic disable of a trigger that can no longer run; `disabled_reason` on each record says which: `user_disabled`, `delivery_failure`, `evaluation_failure`, `plan_downgrade` or `subscription_canceled`). Omit for all.",
|
|
1689
|
+
"enum": [
|
|
1690
|
+
"active",
|
|
1691
|
+
"disabled"
|
|
1692
|
+
]
|
|
1693
|
+
},
|
|
1694
|
+
"limit": {
|
|
1695
|
+
"type": "integer",
|
|
1696
|
+
"description": "Page size. Max 100.",
|
|
1697
|
+
"default": 50
|
|
1698
|
+
},
|
|
1699
|
+
"cursor": {
|
|
1700
|
+
"type": "string",
|
|
1701
|
+
"description": "Opaque cursor from the previous response."
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
},
|
|
1705
|
+
"endpoint": {
|
|
1706
|
+
"method": "GET",
|
|
1707
|
+
"path": "/v2/webhooks",
|
|
1708
|
+
"paramLocation": {
|
|
1709
|
+
"status": "query",
|
|
1710
|
+
"limit": "query",
|
|
1711
|
+
"cursor": "query"
|
|
1207
1712
|
}
|
|
1208
1713
|
}
|
|
1209
1714
|
},
|
|
1210
1715
|
{
|
|
1211
|
-
"name": "
|
|
1212
|
-
"description": "
|
|
1716
|
+
"name": "tickerbot_get_webhook",
|
|
1717
|
+
"description": "Returns one webhook's current state.",
|
|
1213
1718
|
"inputSchema": {
|
|
1214
1719
|
"type": "object",
|
|
1215
1720
|
"properties": {
|
|
1216
|
-
"
|
|
1217
|
-
"type": "string",
|
|
1218
|
-
"description": "Column name (e.g. golden_cross_today, rsi_14)."
|
|
1219
|
-
},
|
|
1220
|
-
"ticker": {
|
|
1221
|
-
"type": "string",
|
|
1222
|
-
"description": "Optional ticker to restrict the watch to one symbol."
|
|
1223
|
-
},
|
|
1224
|
-
"universe": {
|
|
1225
|
-
"type": "string",
|
|
1226
|
-
"description": "Optional universe slug."
|
|
1227
|
-
},
|
|
1228
|
-
"condition": {
|
|
1229
|
-
"type": "string",
|
|
1230
|
-
"description": "Required for numerics: single bound like \">70\" or \"<=200\". Ignored for booleans."
|
|
1231
|
-
},
|
|
1232
|
-
"name": {
|
|
1233
|
-
"type": "string",
|
|
1234
|
-
"description": "Human-readable label."
|
|
1235
|
-
},
|
|
1236
|
-
"target_url": {
|
|
1237
|
-
"type": "string",
|
|
1238
|
-
"description": "Optional https URL for the `webhook` channel; omit for in-app."
|
|
1239
|
-
},
|
|
1240
|
-
"channel": {
|
|
1241
|
-
"type": "string",
|
|
1242
|
-
"description": "Delivery channel: `webhook` (POST to target_url), `discord` (embed to discord_url), `mobile_push` (to a registered device), or `in_app` (dashboard only). Inferred from the URL you pass if omitted.",
|
|
1243
|
-
"enum": [
|
|
1244
|
-
"webhook",
|
|
1245
|
-
"discord",
|
|
1246
|
-
"in_app",
|
|
1247
|
-
"mobile_push"
|
|
1248
|
-
]
|
|
1249
|
-
},
|
|
1250
|
-
"discord_url": {
|
|
1251
|
-
"type": "string",
|
|
1252
|
-
"description": "Discord incoming-webhook URL (https://discord.com/api/webhooks/…). Required when channel is \"discord\"."
|
|
1253
|
-
},
|
|
1254
|
-
"device_id": {
|
|
1255
|
-
"type": "string",
|
|
1256
|
-
"description": "Registered device id from the mobile app. Required when channel is \"mobile_push\"."
|
|
1257
|
-
},
|
|
1258
|
-
"cadence": {
|
|
1721
|
+
"webhook": {
|
|
1259
1722
|
"type": "string",
|
|
1260
|
-
"description": "
|
|
1261
|
-
"enum": [
|
|
1262
|
-
"realtime",
|
|
1263
|
-
"hourly",
|
|
1264
|
-
"nyse_open"
|
|
1265
|
-
]
|
|
1723
|
+
"description": "Webhook id, from a subscribe or from List webhooks."
|
|
1266
1724
|
}
|
|
1267
1725
|
},
|
|
1268
1726
|
"required": [
|
|
1269
|
-
"
|
|
1727
|
+
"webhook"
|
|
1270
1728
|
]
|
|
1271
1729
|
},
|
|
1272
1730
|
"endpoint": {
|
|
1273
|
-
"method": "
|
|
1274
|
-
"path": "/v2/
|
|
1731
|
+
"method": "GET",
|
|
1732
|
+
"path": "/v2/webhooks/{webhook}",
|
|
1275
1733
|
"paramLocation": {
|
|
1276
|
-
"
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
"
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
"
|
|
1283
|
-
"discord_url": "body",
|
|
1284
|
-
"device_id": "body",
|
|
1285
|
-
"cadence": "body"
|
|
1734
|
+
"webhook": "path"
|
|
1735
|
+
},
|
|
1736
|
+
"accepts": {
|
|
1737
|
+
"id": "path"
|
|
1738
|
+
},
|
|
1739
|
+
"pathAliases": {
|
|
1740
|
+
"id": "webhook"
|
|
1286
1741
|
}
|
|
1287
1742
|
}
|
|
1288
1743
|
},
|
|
1289
1744
|
{
|
|
1290
|
-
"name": "
|
|
1291
|
-
"description": "
|
|
1745
|
+
"name": "tickerbot_update_webhook",
|
|
1746
|
+
"description": "Edits a webhook in place; send only the fields you want to change. Send only what changes. The trigger takes the filters of the subscribe that made the webhook (subscription_origin.type: scan q/universe/select/order/dir; ticker q/select; signal condition/universe/select; event kind/ticker/universe/q/select; news search/ticker/universe/min_relevance/q/select), validated like a new subscribe; a change to the filters fires only on new matches (what already matches or already happened does not fire), while an edit of select/order/dir keeps what already matched. enabled=true turns a disabled webhook back on. Unknown fields are a 400.",
|
|
1292
1747
|
"inputSchema": {
|
|
1293
1748
|
"type": "object",
|
|
1294
1749
|
"properties": {
|
|
1295
|
-
"
|
|
1750
|
+
"webhook": {
|
|
1296
1751
|
"type": "string",
|
|
1297
|
-
"description": "
|
|
1752
|
+
"description": "Webhook id."
|
|
1298
1753
|
},
|
|
1299
|
-
"
|
|
1754
|
+
"kind": {
|
|
1300
1755
|
"type": "string",
|
|
1301
|
-
"description": "
|
|
1756
|
+
"description": "Only with event webhooks. The kinds to fire on, as on Subscribe to events.",
|
|
1757
|
+
"enum": [
|
|
1758
|
+
"dividend",
|
|
1759
|
+
"split",
|
|
1760
|
+
"insider",
|
|
1761
|
+
"analyst",
|
|
1762
|
+
"earnings",
|
|
1763
|
+
"filing",
|
|
1764
|
+
"estimate_revision"
|
|
1765
|
+
]
|
|
1302
1766
|
},
|
|
1303
|
-
"
|
|
1767
|
+
"search": {
|
|
1304
1768
|
"type": "string",
|
|
1305
|
-
"description": "
|
|
1769
|
+
"description": "Only with news webhooks. The full-text search, as on Subscribe to news."
|
|
1306
1770
|
},
|
|
1307
|
-
"
|
|
1771
|
+
"condition": {
|
|
1308
1772
|
"type": "string",
|
|
1309
|
-
"description": "
|
|
1773
|
+
"description": "Only with signal webhooks. The bound, in Get a signal's grammar (`<30`)."
|
|
1310
1774
|
},
|
|
1311
|
-
"
|
|
1775
|
+
"ticker": {
|
|
1312
1776
|
"type": "string",
|
|
1313
|
-
"description": "
|
|
1314
|
-
"enum": [
|
|
1315
|
-
"webhook",
|
|
1316
|
-
"discord",
|
|
1317
|
-
"in_app",
|
|
1318
|
-
"mobile_push"
|
|
1319
|
-
]
|
|
1777
|
+
"description": "Only with event or news webhooks. The symbols, one or a comma list. Replaces a `universe` scope."
|
|
1320
1778
|
},
|
|
1321
|
-
"
|
|
1779
|
+
"universe": {
|
|
1322
1780
|
"type": "string",
|
|
1323
|
-
"description": "
|
|
1781
|
+
"description": "Only with scan, signal, event or news webhooks. The universe to scope to; `null` for the whole market. On event and news webhooks it replaces a `ticker` scope."
|
|
1324
1782
|
},
|
|
1325
|
-
"
|
|
1783
|
+
"min_relevance": {
|
|
1784
|
+
"type": "number",
|
|
1785
|
+
"description": "Only with news webhooks. The least relevance (0–1) a scoped ticker needs; the webhook needs a `ticker` or `universe` scope."
|
|
1786
|
+
},
|
|
1787
|
+
"q": {
|
|
1326
1788
|
"type": "string",
|
|
1327
|
-
"description": "
|
|
1789
|
+
"description": "Only with scan, ticker, event or news webhooks. The filter, in the grammar of the subscribe that made the webhook. On an event webhook it replaces the whole filter. A change to the filters (`q`, `condition`, `universe`, `kind`, `ticker`, `search`, `min_relevance`) fires only on new matches; an edit of `select`, `order` or `dir` keeps what already matched."
|
|
1328
1790
|
},
|
|
1329
|
-
"
|
|
1791
|
+
"select": {
|
|
1330
1792
|
"type": "string",
|
|
1331
|
-
"description": "
|
|
1332
|
-
"enum": [
|
|
1333
|
-
"realtime",
|
|
1334
|
-
"hourly",
|
|
1335
|
-
"nyse_open"
|
|
1336
|
-
]
|
|
1337
|
-
}
|
|
1338
|
-
},
|
|
1339
|
-
"required": [
|
|
1340
|
-
"q"
|
|
1341
|
-
]
|
|
1342
|
-
},
|
|
1343
|
-
"endpoint": {
|
|
1344
|
-
"method": "POST",
|
|
1345
|
-
"path": "/v2/scan/subscribe",
|
|
1346
|
-
"paramLocation": {
|
|
1347
|
-
"q": "body",
|
|
1348
|
-
"name": "body",
|
|
1349
|
-
"universe": "body",
|
|
1350
|
-
"target_url": "body",
|
|
1351
|
-
"channel": "body",
|
|
1352
|
-
"discord_url": "body",
|
|
1353
|
-
"device_id": "body",
|
|
1354
|
-
"cadence": "body"
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
},
|
|
1358
|
-
{
|
|
1359
|
-
"name": "tickerbot_create_webhook",
|
|
1360
|
-
"description": "The canonical webhook create — POST /v2/webhooks with an explicit `trigger` object: { type: \"scan\" | \"ticker\" | \"signal\" | \"event\", … } plus delivery fields. The subscribe tools above are flat sugar over exactly this; use this form when composing the trigger programmatically or when a sugar door doesn't fit. Trigger shapes: scan {type:\"scan\", q, universe?}; ticker {type:\"ticker\", ticker, condition}; signal {type:\"signal\", signal, ticker?, universe?, condition?}; event {type:\"event\", kinds, tickers?, universe?, event_q?}.",
|
|
1361
|
-
"inputSchema": {
|
|
1362
|
-
"type": "object",
|
|
1363
|
-
"properties": {
|
|
1364
|
-
"trigger": {
|
|
1365
|
-
"type": "object",
|
|
1366
|
-
"description": "What fires the webhook: { type: \"scan\" | \"ticker\" | \"signal\" | \"event\", … } — see the tool description for each shape."
|
|
1793
|
+
"description": "What each delivery carries, as on the subscribe that made the webhook; `null` for the default."
|
|
1367
1794
|
},
|
|
1368
|
-
"
|
|
1795
|
+
"order": {
|
|
1369
1796
|
"type": "string",
|
|
1370
|
-
"description": "
|
|
1797
|
+
"description": "Only with scan or signal webhooks. The signal each delivery's match lists are sorted by."
|
|
1371
1798
|
},
|
|
1372
|
-
"
|
|
1799
|
+
"dir": {
|
|
1373
1800
|
"type": "string",
|
|
1374
|
-
"description": "
|
|
1801
|
+
"description": "Only with scan or signal webhooks. The sort direction for `order`.",
|
|
1802
|
+
"enum": [
|
|
1803
|
+
"asc",
|
|
1804
|
+
"desc"
|
|
1805
|
+
]
|
|
1375
1806
|
},
|
|
1376
1807
|
"channel": {
|
|
1377
1808
|
"type": "string",
|
|
1378
|
-
"description": "
|
|
1809
|
+
"description": "Moves the webhook to another channel: `webhook` (with `target_url`), `discord` (with `discord_url`), `in_app` or `mobile_push` (with `device_id`). Inferred from `discord_url` or `device_id` when you send one of those alone.",
|
|
1379
1810
|
"enum": [
|
|
1380
1811
|
"webhook",
|
|
1381
1812
|
"discord",
|
|
@@ -1383,166 +1814,148 @@ export const tools = [
|
|
|
1383
1814
|
"mobile_push"
|
|
1384
1815
|
]
|
|
1385
1816
|
},
|
|
1817
|
+
"target_url": {
|
|
1818
|
+
"type": "string",
|
|
1819
|
+
"description": "New https:// delivery URL. Alone, it moves a webhook between HTTPS (`target_url`) and in-app delivery (`null` or empty); a Discord or mobile-push webhook sends `channel: \"webhook\"` with it."
|
|
1820
|
+
},
|
|
1386
1821
|
"discord_url": {
|
|
1387
1822
|
"type": "string",
|
|
1388
|
-
"description": "Discord incoming-webhook URL
|
|
1823
|
+
"description": "Only with `channel=discord`. Discord incoming-webhook URL. Never returned after this call: reads show `channel_config_present: true`."
|
|
1389
1824
|
},
|
|
1390
1825
|
"device_id": {
|
|
1391
1826
|
"type": "string",
|
|
1392
|
-
"description": "
|
|
1827
|
+
"description": "Only with `channel=mobile_push`. Device to notify, from `POST /v2/devices/register`."
|
|
1393
1828
|
},
|
|
1394
1829
|
"cadence": {
|
|
1395
1830
|
"type": "string",
|
|
1396
|
-
"description": "Evaluation cadence.
|
|
1831
|
+
"description": "Evaluation cadence. Event and news webhooks deliver as they land, so only `realtime` is accepted on them.",
|
|
1397
1832
|
"enum": [
|
|
1398
1833
|
"realtime",
|
|
1399
1834
|
"hourly",
|
|
1400
1835
|
"nyse_open"
|
|
1401
1836
|
]
|
|
1402
1837
|
},
|
|
1403
|
-
"
|
|
1838
|
+
"name": {
|
|
1404
1839
|
"type": "string",
|
|
1405
|
-
"description": "
|
|
1840
|
+
"description": "New display name. Non-empty, max 80 characters."
|
|
1841
|
+
},
|
|
1842
|
+
"enabled": {
|
|
1843
|
+
"type": "boolean",
|
|
1844
|
+
"description": "`false` turns the webhook off. `true` turns a disabled webhook back on: your webhook limit is checked and the trigger is checked again. A plain re-enable starts clean and fires once for every current match; after a change to the trigger's filters (in this call or while it was off) it fires only on new matches."
|
|
1406
1845
|
}
|
|
1407
1846
|
},
|
|
1408
1847
|
"required": [
|
|
1409
|
-
"
|
|
1848
|
+
"webhook"
|
|
1410
1849
|
]
|
|
1411
1850
|
},
|
|
1412
1851
|
"endpoint": {
|
|
1413
|
-
"method": "
|
|
1414
|
-
"path": "/v2/webhooks",
|
|
1852
|
+
"method": "PATCH",
|
|
1853
|
+
"path": "/v2/webhooks/{webhook}",
|
|
1415
1854
|
"paramLocation": {
|
|
1416
|
-
"
|
|
1417
|
-
"
|
|
1418
|
-
"
|
|
1855
|
+
"webhook": "path",
|
|
1856
|
+
"kind": "body",
|
|
1857
|
+
"search": "body",
|
|
1858
|
+
"condition": "body",
|
|
1859
|
+
"ticker": "body",
|
|
1860
|
+
"universe": "body",
|
|
1861
|
+
"min_relevance": "body",
|
|
1862
|
+
"q": "body",
|
|
1863
|
+
"select": "body",
|
|
1864
|
+
"order": "body",
|
|
1865
|
+
"dir": "body",
|
|
1419
1866
|
"channel": "body",
|
|
1867
|
+
"target_url": "body",
|
|
1420
1868
|
"discord_url": "body",
|
|
1421
1869
|
"device_id": "body",
|
|
1422
1870
|
"cadence": "body",
|
|
1423
|
-
"
|
|
1871
|
+
"name": "body",
|
|
1872
|
+
"enabled": "body"
|
|
1873
|
+
},
|
|
1874
|
+
"accepts": {
|
|
1875
|
+
"kinds": "body",
|
|
1876
|
+
"tickers": "body",
|
|
1877
|
+
"universe_id": "body",
|
|
1878
|
+
"id": "path"
|
|
1879
|
+
},
|
|
1880
|
+
"pathAliases": {
|
|
1881
|
+
"id": "webhook"
|
|
1424
1882
|
}
|
|
1425
1883
|
}
|
|
1426
1884
|
},
|
|
1427
1885
|
{
|
|
1428
|
-
"name": "
|
|
1429
|
-
"description": "
|
|
1886
|
+
"name": "tickerbot_enable_webhook",
|
|
1887
|
+
"description": "Deprecated: works until 2027-01-12, then is removed. Turns a disabled webhook back on (a webhook disabled after repeated delivery failures, or one you turned off). It is tickerbot_update_webhook with enabled=true: call that instead.",
|
|
1430
1888
|
"inputSchema": {
|
|
1431
1889
|
"type": "object",
|
|
1432
1890
|
"properties": {
|
|
1433
|
-
"
|
|
1434
|
-
"type": "string",
|
|
1435
|
-
"description": "Webhook id (looks like `wh_…`)."
|
|
1436
|
-
},
|
|
1437
|
-
"name": {
|
|
1438
|
-
"type": "string",
|
|
1439
|
-
"description": "New display name."
|
|
1440
|
-
},
|
|
1441
|
-
"cadence": {
|
|
1442
|
-
"type": "string",
|
|
1443
|
-
"description": "New evaluation cadence.",
|
|
1444
|
-
"enum": [
|
|
1445
|
-
"realtime",
|
|
1446
|
-
"hourly",
|
|
1447
|
-
"nyse_open"
|
|
1448
|
-
]
|
|
1449
|
-
},
|
|
1450
|
-
"target_url": {
|
|
1891
|
+
"webhook": {
|
|
1451
1892
|
"type": "string",
|
|
1452
|
-
"description": "
|
|
1453
|
-
},
|
|
1454
|
-
"enabled": {
|
|
1455
|
-
"type": "boolean",
|
|
1456
|
-
"description": "false pauses deliveries; true resumes. (Re-enabling after auto-disable also works via tickerbot_enable_webhook, which additionally clears match-state.)"
|
|
1893
|
+
"description": "Webhook id."
|
|
1457
1894
|
}
|
|
1458
1895
|
},
|
|
1459
1896
|
"required": [
|
|
1460
|
-
"
|
|
1897
|
+
"webhook"
|
|
1461
1898
|
]
|
|
1462
1899
|
},
|
|
1463
1900
|
"endpoint": {
|
|
1464
1901
|
"method": "PATCH",
|
|
1465
|
-
"path": "/v2/webhooks/{
|
|
1466
|
-
"paramLocation": {
|
|
1467
|
-
"id": "path",
|
|
1468
|
-
"name": "body",
|
|
1469
|
-
"cadence": "body",
|
|
1470
|
-
"target_url": "body",
|
|
1471
|
-
"enabled": "body"
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
},
|
|
1475
|
-
{
|
|
1476
|
-
"name": "tickerbot_list_webhooks",
|
|
1477
|
-
"description": "List the caller's webhook subscriptions (rules created via the subscribe tools), newest-first. Use `status` to filter to active or disabled rules.",
|
|
1478
|
-
"inputSchema": {
|
|
1479
|
-
"type": "object",
|
|
1480
|
-
"properties": {
|
|
1481
|
-
"status": {
|
|
1482
|
-
"type": "string",
|
|
1483
|
-
"description": "Filter by status. Omit for all. (`pending_verification` = created but never successfully pinged.)",
|
|
1484
|
-
"enum": [
|
|
1485
|
-
"active",
|
|
1486
|
-
"pending_verification",
|
|
1487
|
-
"disabled"
|
|
1488
|
-
]
|
|
1489
|
-
},
|
|
1490
|
-
"limit": {
|
|
1491
|
-
"type": "integer",
|
|
1492
|
-
"description": "Page size. Max 100. Default 50."
|
|
1493
|
-
},
|
|
1494
|
-
"cursor": {
|
|
1495
|
-
"type": "string",
|
|
1496
|
-
"description": "Opaque cursor."
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
},
|
|
1500
|
-
"endpoint": {
|
|
1501
|
-
"method": "GET",
|
|
1502
|
-
"path": "/v2/webhooks",
|
|
1902
|
+
"path": "/v2/webhooks/{webhook}",
|
|
1503
1903
|
"paramLocation": {
|
|
1504
|
-
"
|
|
1505
|
-
|
|
1506
|
-
|
|
1904
|
+
"webhook": "path"
|
|
1905
|
+
},
|
|
1906
|
+
"accepts": {
|
|
1907
|
+
"id": "path"
|
|
1908
|
+
},
|
|
1909
|
+
"pathAliases": {
|
|
1910
|
+
"id": "webhook"
|
|
1911
|
+
},
|
|
1912
|
+
"fixedBody": {
|
|
1913
|
+
"enabled": true
|
|
1507
1914
|
}
|
|
1508
1915
|
}
|
|
1509
1916
|
},
|
|
1510
1917
|
{
|
|
1511
|
-
"name": "
|
|
1512
|
-
"description": "
|
|
1918
|
+
"name": "tickerbot_delete_webhook",
|
|
1919
|
+
"description": "Deletes a webhook and its delivery history.",
|
|
1513
1920
|
"inputSchema": {
|
|
1514
1921
|
"type": "object",
|
|
1515
1922
|
"properties": {
|
|
1516
|
-
"
|
|
1923
|
+
"webhook": {
|
|
1517
1924
|
"type": "string",
|
|
1518
|
-
"description": "Webhook id
|
|
1925
|
+
"description": "Webhook id."
|
|
1519
1926
|
}
|
|
1520
1927
|
},
|
|
1521
1928
|
"required": [
|
|
1522
|
-
"
|
|
1929
|
+
"webhook"
|
|
1523
1930
|
]
|
|
1524
1931
|
},
|
|
1525
1932
|
"endpoint": {
|
|
1526
|
-
"method": "
|
|
1527
|
-
"path": "/v2/webhooks/{
|
|
1933
|
+
"method": "DELETE",
|
|
1934
|
+
"path": "/v2/webhooks/{webhook}",
|
|
1528
1935
|
"paramLocation": {
|
|
1936
|
+
"webhook": "path"
|
|
1937
|
+
},
|
|
1938
|
+
"accepts": {
|
|
1529
1939
|
"id": "path"
|
|
1940
|
+
},
|
|
1941
|
+
"pathAliases": {
|
|
1942
|
+
"id": "webhook"
|
|
1530
1943
|
}
|
|
1531
1944
|
}
|
|
1532
1945
|
},
|
|
1533
1946
|
{
|
|
1534
1947
|
"name": "tickerbot_list_webhook_deliveries",
|
|
1535
|
-
"description": "
|
|
1948
|
+
"description": "Lists a webhook's recent deliveries: what was sent and what came back.",
|
|
1536
1949
|
"inputSchema": {
|
|
1537
1950
|
"type": "object",
|
|
1538
1951
|
"properties": {
|
|
1539
|
-
"
|
|
1952
|
+
"webhook": {
|
|
1540
1953
|
"type": "string",
|
|
1541
1954
|
"description": "Webhook id."
|
|
1542
1955
|
},
|
|
1543
1956
|
"status": {
|
|
1544
1957
|
"type": "string",
|
|
1545
|
-
"description": "Filter by delivery status.",
|
|
1958
|
+
"description": "Filter by delivery status (one or a comma list).",
|
|
1546
1959
|
"enum": [
|
|
1547
1960
|
"pending",
|
|
1548
1961
|
"delivered",
|
|
@@ -1551,11 +1964,16 @@ export const tools = [
|
|
|
1551
1964
|
},
|
|
1552
1965
|
"from": {
|
|
1553
1966
|
"type": "string",
|
|
1554
|
-
"description": "Only deliveries created at/after this moment — epoch seconds or ISO datetime
|
|
1967
|
+
"description": "Only deliveries created at/after this moment — epoch seconds, epoch milliseconds (13+ digits) or an ISO datetime; a date-only value starts at the beginning of that UTC day. Delivery history is retained for 90 days; deleting a webhook deletes its delivery history with it."
|
|
1968
|
+
},
|
|
1969
|
+
"to": {
|
|
1970
|
+
"type": "string",
|
|
1971
|
+
"description": "Only deliveries created before this moment — same value grammar as `from`. A date-only value covers that whole UTC day. A timestamp is included until 2027-01-12 and exclusive from then, as everywhere else (Deprecations). `from` after `to` is a 400. See Time windows."
|
|
1555
1972
|
},
|
|
1556
1973
|
"limit": {
|
|
1557
1974
|
"type": "integer",
|
|
1558
|
-
"description": "Page size. Max 100.
|
|
1975
|
+
"description": "Page size. Max 100.",
|
|
1976
|
+
"default": 50
|
|
1559
1977
|
},
|
|
1560
1978
|
"cursor": {
|
|
1561
1979
|
"type": "string",
|
|
@@ -1563,87 +1981,93 @@ export const tools = [
|
|
|
1563
1981
|
}
|
|
1564
1982
|
},
|
|
1565
1983
|
"required": [
|
|
1566
|
-
"
|
|
1984
|
+
"webhook"
|
|
1567
1985
|
]
|
|
1568
1986
|
},
|
|
1569
1987
|
"endpoint": {
|
|
1570
1988
|
"method": "GET",
|
|
1571
|
-
"path": "/v2/webhooks/{
|
|
1989
|
+
"path": "/v2/webhooks/{webhook}/deliveries",
|
|
1572
1990
|
"paramLocation": {
|
|
1573
|
-
"
|
|
1991
|
+
"webhook": "path",
|
|
1574
1992
|
"status": "query",
|
|
1575
1993
|
"from": "query",
|
|
1994
|
+
"to": "query",
|
|
1576
1995
|
"limit": "query",
|
|
1577
1996
|
"cursor": "query"
|
|
1997
|
+
},
|
|
1998
|
+
"accepts": {
|
|
1999
|
+
"since": "query",
|
|
2000
|
+
"until": "query",
|
|
2001
|
+
"id": "path"
|
|
2002
|
+
},
|
|
2003
|
+
"pathAliases": {
|
|
2004
|
+
"id": "webhook"
|
|
1578
2005
|
}
|
|
1579
2006
|
}
|
|
1580
2007
|
},
|
|
1581
2008
|
{
|
|
1582
|
-
"name": "
|
|
1583
|
-
"description": "
|
|
2009
|
+
"name": "tickerbot_redeliver_webhook_delivery",
|
|
2010
|
+
"description": "Resends a past delivery, with the exact body it carried, to the webhook's current target. Resends the exact original body to the webhook's current target. The webhook must be active (409 otherwise); take delivery ids from tickerbot_list_webhook_deliveries. Test fires cannot be resent.",
|
|
1584
2011
|
"inputSchema": {
|
|
1585
2012
|
"type": "object",
|
|
1586
2013
|
"properties": {
|
|
1587
|
-
"
|
|
2014
|
+
"webhook": {
|
|
1588
2015
|
"type": "string",
|
|
1589
2016
|
"description": "Webhook id."
|
|
2017
|
+
},
|
|
2018
|
+
"delivery": {
|
|
2019
|
+
"type": "string",
|
|
2020
|
+
"description": "The delivery to resend, from `GET /v2/webhooks/{webhook}/deliveries`."
|
|
1590
2021
|
}
|
|
1591
2022
|
},
|
|
1592
2023
|
"required": [
|
|
1593
|
-
"
|
|
2024
|
+
"webhook",
|
|
2025
|
+
"delivery"
|
|
1594
2026
|
]
|
|
1595
2027
|
},
|
|
1596
2028
|
"endpoint": {
|
|
1597
2029
|
"method": "POST",
|
|
1598
|
-
"path": "/v2/webhooks/{
|
|
2030
|
+
"path": "/v2/webhooks/{webhook}/deliveries/{delivery}/redeliver",
|
|
1599
2031
|
"paramLocation": {
|
|
1600
|
-
"
|
|
2032
|
+
"webhook": "path",
|
|
2033
|
+
"delivery": "path"
|
|
2034
|
+
},
|
|
2035
|
+
"accepts": {
|
|
2036
|
+
"id": "path",
|
|
2037
|
+
"delivery_id": "path"
|
|
2038
|
+
},
|
|
2039
|
+
"pathAliases": {
|
|
2040
|
+
"id": "webhook",
|
|
2041
|
+
"delivery_id": "delivery"
|
|
1601
2042
|
}
|
|
1602
2043
|
}
|
|
1603
2044
|
},
|
|
1604
2045
|
{
|
|
1605
|
-
"name": "
|
|
1606
|
-
"description": "
|
|
2046
|
+
"name": "tickerbot_test_webhook",
|
|
2047
|
+
"description": "Sends a real-shape test delivery to your endpoint, instantly. One-shot: a failed test never retries and never auto-disables the webhook. 400 when the webhook has no target_url.",
|
|
1607
2048
|
"inputSchema": {
|
|
1608
2049
|
"type": "object",
|
|
1609
2050
|
"properties": {
|
|
1610
|
-
"
|
|
2051
|
+
"webhook": {
|
|
1611
2052
|
"type": "string",
|
|
1612
2053
|
"description": "Webhook id."
|
|
1613
2054
|
}
|
|
1614
2055
|
},
|
|
1615
2056
|
"required": [
|
|
1616
|
-
"
|
|
2057
|
+
"webhook"
|
|
1617
2058
|
]
|
|
1618
2059
|
},
|
|
1619
2060
|
"endpoint": {
|
|
1620
2061
|
"method": "POST",
|
|
1621
|
-
"path": "/v2/webhooks/{
|
|
2062
|
+
"path": "/v2/webhooks/{webhook}/test",
|
|
1622
2063
|
"paramLocation": {
|
|
1623
|
-
"
|
|
1624
|
-
}
|
|
1625
|
-
}
|
|
1626
|
-
},
|
|
1627
|
-
{
|
|
1628
|
-
"name": "tickerbot_delete_webhook",
|
|
1629
|
-
"description": "Delete a webhook subscription by id. Use after listing webhooks when the user wants to remove an alert.",
|
|
1630
|
-
"inputSchema": {
|
|
1631
|
-
"type": "object",
|
|
1632
|
-
"properties": {
|
|
1633
|
-
"id": {
|
|
1634
|
-
"type": "string",
|
|
1635
|
-
"description": "Webhook id (looks like `wh_…`)."
|
|
1636
|
-
}
|
|
2064
|
+
"webhook": "path"
|
|
1637
2065
|
},
|
|
1638
|
-
"
|
|
1639
|
-
"id"
|
|
1640
|
-
]
|
|
1641
|
-
},
|
|
1642
|
-
"endpoint": {
|
|
1643
|
-
"method": "DELETE",
|
|
1644
|
-
"path": "/v2/webhooks/{id}",
|
|
1645
|
-
"paramLocation": {
|
|
2066
|
+
"accepts": {
|
|
1646
2067
|
"id": "path"
|
|
2068
|
+
},
|
|
2069
|
+
"pathAliases": {
|
|
2070
|
+
"id": "webhook"
|
|
1647
2071
|
}
|
|
1648
2072
|
}
|
|
1649
2073
|
}
|