Market signals.
Meet your next integration.
Create alerts for the stocks you follow, retrieve market-wide event feeds, and deliver matching signals straight to your application.
https://api.stocklet.app/v1HTTPS · JSONOne API key
Bearer authentication for every request.
Two ways to query
Your own alerts and market-wide feeds.
Events, delivered
Signed callbacks for your matching alerts.
Your first alert, end to end
Start with breaking news for AAPL. These examples share the same alert ID so you can follow it from creation to delivery. All sample events are fictional.
1 Authenticate and create an alert
Request an API key from support@stocklet.app. Set STOCKLET_API_KEY in your server environment, then send your first request.
The response contains data.id. Use this ID to retrieve the alert or connect it to a webhook.
{
"data": {
"id": "alt_breaking_news_01",
"type": "breaking_news",
"ticker": "AAPL",
"enabled": true,
"conditions": {},
"created_at": "2026-11-08T14:30:00Z"
}
}curl -X POST 'https://api.stocklet.app/v1/alerts/breaking-news' \
-H "Authorization: Bearer $STOCKLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ticker": "AAPL",
"enabled": true,
"conditions": {}
}'2 Retrieve your existing alerts
List alerts for a ticker or fetch a single rule by its ID. This retrieves saved configuration; it does not return news stories.
Explore alert management →curl 'https://api.stocklet.app/v1/alerts?type=breaking_news&ticker=AAPL' \
-H "Authorization: Bearer $STOCKLET_API_KEY"3 Connect your webhook
Register a public HTTPS endpoint and subscribe to your alert. The creation response includes a signing secret; store it securely.
When a matching story is processed, Stocklet sends the event payload to your endpoint. Verify its signature before processing.
curl -X POST 'https://api.stocklet.app/v1/webhooks' \
-H "Authorization: Bearer $STOCKLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.example/webhooks/stocklet",
"types": [
"breaking_news"
],
"alert_ids": [
"alt_breaking_news_01"
]
}'Need the wider picture? Query market-wide feeds independently of your saved alerts.
Authenticate every request
Use a server-side API key in the Authorization header. The key determines the account that owns your alerts and webhook registrations.
Missing or invalid keys return 401. Requests outside your access permissions return 403.
Keep keys in environment variables. Never embed them in frontend code, URLs, or public repositories. Contact support to provision or replace a key.
Authorization: Bearer <API_KEY>
Content-Type: application/jsonPredictable requests and responses
Requests and responses use JSON with snake_case fields. Timestamps are ISO 8601 UTC strings. IDs are opaque strings; preserve them exactly.
Single-resource responses use { "data": { ... } }. Lists are newest first and include next_cursor; null means the last page. Tied timestamps are ordered by ID.
Use limit and cursor for pagination. A cursor belongs to its original filters. An invalid cursor returns 400.
Creation returns 201, reads and updates return 200, and successful deletion returns 204 without a response body.
{
"data": [
{
"id": "evt_breaking_news_01",
"type": "breaking_news",
"created_at": "2026-11-08T14:30:00Z",
"ticker": "AAPL",
"data": {
"headline": "Example company expands its manufacturing capacity",
"publisher": "Example News",
"url": "https://example.com/news/manufacturing-expansion",
"published_at": "2026-11-08T14:30:00Z"
}
}
],
"next_cursor": null
}{
"error": {
"code": "unauthorized",
"message": "A valid API key is required."
},
"request_id": "req_example_01"
}| Field | Type | Description |
|---|---|---|
400 | invalid_request | Malformed JSON, invalid conditions, unsupported ticker, filters, or cursor. Read error.message for details. |
401 | unauthorized | Missing, invalid, or revoked API key. |
403 | forbidden | Your key does not grant access to this operation. |
404 | not_found | Resource does not exist or is not owned by this account. |
429 | rate_limited | Wait for the Retry-After duration in seconds before retrying. |
5xx | server_error | Temporary failure. Retry reads with backoff. Check whether a resource was created before retrying a failed POST. |
Rate limits and available history depend on your access. No fixed quota or complete historical coverage is implied. Feeds contain supported events as they become available; they are not an exchange price feed.
Your alerts, in one place
An alert is an account-owned rule for one ticker. Create it through its type-specific endpoint, then retrieve, update, pause, or delete it.
GET /alerts returns saved alerts across types. Filter by the singular type identifier, ticker, or enabled state. To retrieve actual matching events, use your alert event history.
| Field | Type | Description |
|---|---|---|
type | string | Optional. One of the event identifiers listed below. |
ticker | string | Optional supported ticker, e.g. AAPL. |
enabled | boolean | Optional true or false. |
limit / cursor | integer / string | Pagination. Default limit 20; maximum 100. |
/alertsRetrieve the authenticated account’s saved rules.
curl 'https://api.stocklet.app/v1/alerts?type=breaking_news&ticker=AAPL&enabled=true&limit=20' \
-H "Authorization: Bearer $STOCKLET_API_KEY"{
"data": [
{
"id": "alt_breaking_news_01",
"type": "breaking_news",
"ticker": "AAPL",
"enabled": true,
"conditions": {},
"created_at": "2026-11-08T14:30:00Z"
}
],
"next_cursor": null
}| Field | Type | Description |
|---|---|---|
ticker | string | Required on create. Uppercase supported listing symbol. Immutable; create a new alert to change ticker. |
enabled | boolean | Optional on create, defaults to true. PATCH false to pause or true to resume. |
conditions | object | Required for price rules; optional for other types. Defaults to {}. PATCH replaces the full conditions object; omitted fields remain unchanged. |
Unsupported tickers and invalid conditions return 400. Repeated creation requests create separate alerts. Price alerts disable after a match; the other types stay enabled until paused or deleted. Access is isolated to the authenticated account.
Price Changes
Your price level. Your percentage move. A signal when the condition is met.
price_changeConditions
Use mode target_price with direction above or below and a positive value in the listing currency. Or use mode percent_change with direction up or down, a positive percentage value, and window day (relative to the previous trading close). Price rules trigger once and become disabled; re-enable to arm them again.
{
"mode": "target_price",
"direction": "above",
"value": 250
}All operations require Bearer authentication. Missing alerts and alerts from another account return 404. Invalid request fields return 400.
View the incoming webhook example →/alerts/price-changesCreate a price changes alert for one ticker.
curl -X POST 'https://api.stocklet.app/v1/alerts/price-changes' \
-H "Authorization: Bearer $STOCKLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ticker": "AAPL",
"enabled": true,
"conditions": {
"mode": "target_price",
"direction": "above",
"value": 250
}
}'{
"data": {
"id": "alt_price_change_01",
"type": "price_change",
"ticker": "AAPL",
"enabled": true,
"conditions": {
"mode": "target_price",
"direction": "above",
"value": 250
},
"created_at": "2026-11-08T14:30:00Z"
}
}Insider Trades
Follow publicly disclosed buying, selling, and option exercises.
insider_tradeConditions
Optional transactions filter: purchase, sale, or option_exercise. Omit it to follow all supported disclosed transactions. Events describe processed public disclosures, not the time a trade was executed.
{
"transactions": [
"purchase",
"sale"
]
}All operations require Bearer authentication. Missing alerts and alerts from another account return 404. Invalid request fields return 400.
View the incoming webhook example →/alerts/insider-tradesCreate a insider trades alert for one ticker.
curl -X POST 'https://api.stocklet.app/v1/alerts/insider-trades' \
-H "Authorization: Bearer $STOCKLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ticker": "AAPL",
"enabled": true,
"conditions": {
"transactions": [
"purchase",
"sale"
]
}
}'{
"data": {
"id": "alt_insider_trade_01",
"type": "insider_trade",
"ticker": "AAPL",
"enabled": true,
"conditions": {
"transactions": [
"purchase",
"sale"
]
},
"created_at": "2026-11-08T14:30:00Z"
}
}Earnings
Keep earnings releases, conference calls, and transcripts in view.
earningsConditions
Optional events filter: release, call, or transcript. Omit it to receive all three. A call event announces available call information; it is not a configurable reminder.
{
"events": [
"release",
"call",
"transcript"
]
}All operations require Bearer authentication. Missing alerts and alerts from another account return 404. Invalid request fields return 400.
View the incoming webhook example →/alerts/earningsCreate a earnings alert for one ticker.
curl -X POST 'https://api.stocklet.app/v1/alerts/earnings' \
-H "Authorization: Bearer $STOCKLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ticker": "AAPL",
"enabled": true,
"conditions": {
"events": [
"release",
"call",
"transcript"
]
}
}'{
"data": {
"id": "alt_earnings_01",
"type": "earnings",
"ticker": "AAPL",
"enabled": true,
"conditions": {
"events": [
"release",
"call",
"transcript"
]
},
"created_at": "2026-11-08T14:30:00Z"
}
}Press Releases
Official company announcements, delivered as structured events.
press_releaseConditions
No additional conditions required. An enabled alert follows supported official press releases for its ticker.
{}All operations require Bearer authentication. Missing alerts and alerts from another account return 404. Invalid request fields return 400.
View the incoming webhook example →/alerts/press-releasesCreate a press releases alert for one ticker.
curl -X POST 'https://api.stocklet.app/v1/alerts/press-releases' \
-H "Authorization: Bearer $STOCKLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ticker": "AAPL",
"enabled": true,
"conditions": {}
}'{
"data": {
"id": "alt_press_release_01",
"type": "press_release",
"ticker": "AAPL",
"enabled": true,
"conditions": {},
"created_at": "2026-11-08T14:30:00Z"
}
}Breaking News
Stay close to the stories that matter to the stocks you follow.
breaking_newsConditions
No additional conditions required. An enabled alert follows supported breaking news associated with its ticker.
{}All operations require Bearer authentication. Missing alerts and alerts from another account return 404. Invalid request fields return 400.
View the incoming webhook example →/alerts/breaking-newsCreate a breaking news alert for one ticker.
curl -X POST 'https://api.stocklet.app/v1/alerts/breaking-news' \
-H "Authorization: Bearer $STOCKLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ticker": "AAPL",
"enabled": true,
"conditions": {}
}'{
"data": {
"id": "alt_breaking_news_01",
"type": "breaking_news",
"ticker": "AAPL",
"enabled": true,
"conditions": {},
"created_at": "2026-11-08T14:30:00Z"
}
}Analyst Ratings
Track upgrades, downgrades, initiations, and price target changes.
analyst_ratingConditions
Optional actions filter: upgrade, downgrade, initiation, or price_target_change. Omit it to follow all supported analyst actions.
{
"actions": [
"upgrade",
"downgrade",
"initiation",
"price_target_change"
]
}All operations require Bearer authentication. Missing alerts and alerts from another account return 404. Invalid request fields return 400.
View the incoming webhook example →/alerts/analyst-ratingsCreate a analyst ratings alert for one ticker.
curl -X POST 'https://api.stocklet.app/v1/alerts/analyst-ratings' \
-H "Authorization: Bearer $STOCKLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ticker": "AAPL",
"enabled": true,
"conditions": {
"actions": [
"upgrade",
"downgrade",
"initiation",
"price_target_change"
]
}
}'{
"data": {
"id": "alt_analyst_rating_01",
"type": "analyst_rating",
"ticker": "AAPL",
"enabled": true,
"conditions": {
"actions": [
"upgrade",
"downgrade",
"initiation",
"price_target_change"
]
},
"created_at": "2026-11-08T14:30:00Z"
}
}Read market-wide event feeds
Retrieve events across supported stocks, even if you have not created an alert. Omit ticker for market-wide results or add it to focus on one stock.
| Field | Type | Description |
|---|---|---|
ticker | string | Optional. One supported listing symbol, for example AAPL. Omit to include all supported tickers. |
since / until | ISO 8601 | Optional UTC timestamps. since is inclusive; until is exclusive. since must precede until. |
limit | integer | Page size, 1–100. Default: 20. |
cursor | string | Opaque next_cursor from the preceding page. Keep all other filters unchanged. |
Personal price rules are not a market-wide feed. Retrieve triggered price alerts through GET /alerts/events.
The same event ID identifies an event in feeds, alert history, and webhook messages. A feed event has no alert_id.
/feeds/insider-tradesAll insider trades across supported tickers.
curl 'https://api.stocklet.app/v1/feeds/insider-trades?limit=20' \
-H "Authorization: Bearer $STOCKLET_API_KEY"{
"data": [
{
"id": "evt_insider_trade_01",
"type": "insider_trade",
"created_at": "2026-11-08T14:30:00Z",
"ticker": "AAPL",
"data": {
"insider_name": "Example Insider",
"position": "Director",
"transaction": "purchase",
"shares": 1000,
"price_per_share": 249.5,
"currency": "USD",
"filed_at": "2026-11-08T14:30:00Z"
}
}
],
"next_cursor": null
}Retrieve your matching alert events
Retrieve historical matches for your account’s own alerts, including price rules. The optional type, ticker, and alert_id filters combine with the feed time and pagination parameters.
Each result includes its matching alert_id. One event can match several alerts; deduplicate a match by the pair (id, alert_id).
Deleting an alert stops future matching but does not remove existing event history.
/alerts/eventsRetrieve matching price alerts for AAPL.
curl 'https://api.stocklet.app/v1/alerts/events?type=price_change&ticker=AAPL&limit=20' \
-H "Authorization: Bearer $STOCKLET_API_KEY"{
"data": [
{
"id": "evt_price_change_01",
"type": "price_change",
"created_at": "2026-11-08T14:30:00Z",
"ticker": "AAPL",
"data": {
"price": 250.12,
"currency": "USD",
"previous_close": 244.5,
"change_percent": 2.3
},
"alert_id": "alt_price_change_01"
}
],
"next_cursor": null
}Connect your endpoint
Register an HTTPS endpoint to receive events from your own alerts. A webhook does not create alerts and does not subscribe to market-wide feeds.
| Field | Type | Description |
|---|---|---|
url | string | Required on create. Public HTTPS endpoint that accepts POST requests. |
types | string[] | Required, non-empty event type identifiers. Filters your matching alerts. |
alert_ids | string[] | Optional, non-empty IDs owned by this account. Omit for all your alerts of the selected types. When present, both filters must match. |
enabled | boolean | Optional. Defaults to true; PATCH false to pause delivery. |
The signing secret is included only in the creation response. Store it immediately. List and retrieve responses never expose it. To replace a secret, create a new webhook and retire the old one.
PATCH accepts URL, filters, and enabled state. Arrays replace their previous values; alert_ids: null clears the ID filter. Disabling or deleting a webhook cancels pending retries.
/webhooksRegister an endpoint and save the returned signing secret.
curl -X POST 'https://api.stocklet.app/v1/webhooks' \
-H "Authorization: Bearer $STOCKLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.example/webhooks/stocklet",
"types": [
"breaking_news"
],
"alert_ids": [
"alt_breaking_news_01"
]
}'{
"data": {
"id": "wh_01",
"url": "https://your-app.example/webhooks/stocklet",
"types": [
"breaking_news"
],
"alert_ids": [
"alt_breaking_news_01"
],
"enabled": true,
"created_at": "2026-11-08T14:30:00Z",
"signing_secret": "whsec_example_replace_with_your_secret"
}
}What arrives at your webhook
Every alert type uses the same envelope. The type-specific data lives inside data. Select a type to inspect its full incoming message.
| Field | Type | Description |
|---|---|---|
id | string | Stable event ID, unchanged across retries. |
type | string | Singular event identifier, e.g. breaking_news. |
created_at | UTC string | When Stocklet created the event. Source publication or filing dates appear in data where relevant. |
alert_id | string | Your saved alert that matched this event. |
ticker | string | Supported listing symbol associated with this match. |
data | object | Event-specific fields shown in the examples. Prices include their currency; source links identify external content. |
{
"id": "evt_breaking_news_01",
"type": "breaking_news",
"created_at": "2026-11-08T14:30:00Z",
"ticker": "AAPL",
"data": {
"headline": "Example company expands its manufacturing capacity",
"publisher": "Example News",
"url": "https://example.com/news/manufacturing-expansion",
"published_at": "2026-11-08T14:30:00Z"
},
"alert_id": "alt_breaking_news_01"
}Verify the signature first
Each delivery includes a Unix timestamp in seconds and a versioned HMAC-SHA256 signature. Use the signing secret returned when creating your webhook.
Content-Type: application/json
Stocklet-Timestamp: 1794148200
Stocklet-Signature: v1=<64-character lowercase hex>Signing input
Compute HMAC-SHA256 over the timestamp, a literal period, and the exact raw request bytes: timestamp + "." + raw_body.
Compare signatures in constant time. Reject timestamps more than five minutes from your server clock. Do not parse and re-serialize the JSON before verification.
Timestamp and signature are regenerated for every retry; event IDs stay unchanged. The sample timestamp is illustrative.
import { createHmac, timingSafeEqual } from "node:crypto";
// Supply the exact raw request body, before JSON parsing.
export function verifyStocklet(rawBody, headers, secret) {
const timestamp = headers["stocklet-timestamp"];
const signature = headers["stocklet-signature"];
if (typeof timestamp !== "string" || !/^\d+$/.test(timestamp)) return false;
if (typeof signature !== "string" || !/^v1=[a-f0-9]{64}$/.test(signature)) return false;
const age = Math.abs(Date.now() / 1000 - Number(timestamp));
if (!Number.isFinite(age) || age > 300) return false;
const expected = createHmac("sha256", secret)
.update(timestamp + ".")
.update(rawBody)
.digest();
const received = Buffer.from(signature.slice(3), "hex");
return received.length === expected.length
&& timingSafeEqual(received, expected);
}Acknowledge quickly. Process reliably.
After verification, persist or enqueue the event and return any 2xx response within ten seconds. Process the event asynchronously.
- Network failures, timeouts, and non-2xx responses trigger retries with increasing delays for up to 24 hours.
- Delivery order is not guaranteed. Duplicate messages can occur.
- Deduplicate event processing by
id. If each alert match needs separate handling, use(id, alert_id). - Alerts created or re-enabled later do not replay historical events. Use GET endpoints to retrieve available history.
- Successful webhook registration does not test your receiver. Verify it in your own environment before depending on deliveries.