Developer documentation / Introduction
THE STOCKLET API

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.

BASE URLhttps://api.stocklet.app/v1HTTPS · JSON

One 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.

GET STARTED

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.

201 Created · response
{
  "data": {
    "id": "alt_breaking_news_01",
    "type": "breaking_news",
    "ticker": "AAPL",
    "enabled": true,
    "conditions": {},
    "created_at": "2026-11-08T14:30:00Z"
  }
}
POST /alerts/breaking-news
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 →
GET /alerts?type=breaking_news&ticker=AAPL
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.

POST /webhooks
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.

HTTP request headers
Authorization: Bearer <API_KEY>
Content-Type: application/json
Content-Type is required for JSON request bodies.

Predictable 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.

List response
{
  "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
}
401 Unauthorized · error response
{
  "error": {
    "code": "unauthorized",
    "message": "A valid API key is required."
  },
  "request_id": "req_example_01"
}
HTTP errors
FieldTypeDescription
400invalid_requestMalformed JSON, invalid conditions, unsupported ticker, filters, or cursor. Read error.message for details.
401unauthorizedMissing, invalid, or revoked API key.
403forbiddenYour key does not grant access to this operation.
404not_foundResource does not exist or is not owned by this account.
429rate_limitedWait for the Retry-After duration in seconds before retrying.
5xxserver_errorTemporary 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.

API REFERENCE

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.

Parameters
FieldTypeDescription
typestringOptional. One of the event identifiers listed below.
tickerstringOptional supported ticker, e.g. AAPL.
enabledbooleanOptional true or false.
limit / cursorinteger / stringPagination. Default limit 20; maximum 100.
GET/alerts

Retrieve the authenticated account’s saved rules.

GET /alerts?type=breaking_news&ticker=AAPL&enabled=true&limit=20
curl 'https://api.stocklet.app/v1/alerts?type=breaking_news&ticker=AAPL&enabled=true&limit=20' \
  -H "Authorization: Bearer $STOCKLET_API_KEY"
200 OK
{
  "data": [
    {
      "id": "alt_breaking_news_01",
      "type": "breaking_news",
      "ticker": "AAPL",
      "enabled": true,
      "conditions": {},
      "created_at": "2026-11-08T14:30:00Z"
    }
  ],
  "next_cursor": null
}
Common create and update fields
FieldTypeDescription
tickerstringRequired on create. Uppercase supported listing symbol. Immutable; create a new alert to change ticker.
enabledbooleanOptional on create, defaults to true. PATCH false to pause or true to resume.
conditionsobjectRequired 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.

EVENT TYPEprice_change

Conditions

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.

conditions
{
  "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 →
POST/alerts/price-changes

Create a price changes alert for one ticker.

POST /alerts/price-changes
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
  }
}'
201 Created
{
  "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.

EVENT TYPEinsider_trade

Conditions

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.

conditions
{
  "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 →
POST/alerts/insider-trades

Create a insider trades alert for one ticker.

POST /alerts/insider-trades
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"
    ]
  }
}'
201 Created
{
  "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.

EVENT TYPEearnings

Conditions

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.

conditions
{
  "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 →
POST/alerts/earnings

Create a earnings alert for one ticker.

POST /alerts/earnings
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"
    ]
  }
}'
201 Created
{
  "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.

EVENT TYPEpress_release

Conditions

No additional conditions required. An enabled alert follows supported official press releases for its ticker.

conditions
{}

All operations require Bearer authentication. Missing alerts and alerts from another account return 404. Invalid request fields return 400.

View the incoming webhook example →
POST/alerts/press-releases

Create a press releases alert for one ticker.

POST /alerts/press-releases
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": {}
}'
201 Created
{
  "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.

EVENT TYPEbreaking_news

Conditions

No additional conditions required. An enabled alert follows supported breaking news associated with its ticker.

conditions
{}

All operations require Bearer authentication. Missing alerts and alerts from another account return 404. Invalid request fields return 400.

View the incoming webhook example →
POST/alerts/breaking-news

Create a breaking news alert for one ticker.

POST /alerts/breaking-news
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": {}
}'
201 Created
{
  "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.

EVENT TYPEanalyst_rating

Conditions

Optional actions filter: upgrade, downgrade, initiation, or price_target_change. Omit it to follow all supported analyst actions.

conditions
{
  "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 →
POST/alerts/analyst-ratings

Create a analyst ratings alert for one ticker.

POST /alerts/analyst-ratings
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"
    ]
  }
}'
201 Created
{
  "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.

Parameters
FieldTypeDescription
tickerstringOptional. One supported listing symbol, for example AAPL. Omit to include all supported tickers.
since / untilISO 8601Optional UTC timestamps. since is inclusive; until is exclusive. since must precede until.
limitintegerPage size, 1–100. Default: 20.
cursorstringOpaque 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.

GET/feeds/insider-trades

All insider trades across supported tickers.

GET /feeds/insider-trades?limit=20
curl 'https://api.stocklet.app/v1/feeds/insider-trades?limit=20' \
  -H "Authorization: Bearer $STOCKLET_API_KEY"
200 OK
{
  "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.

GET/alerts/events

Retrieve matching price alerts for AAPL.

GET /alerts/events?type=price_change&ticker=AAPL&limit=20
curl 'https://api.stocklet.app/v1/alerts/events?type=price_change&ticker=AAPL&limit=20' \
  -H "Authorization: Bearer $STOCKLET_API_KEY"
200 OK
{
  "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
}
WEBHOOKS

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.

Parameters
FieldTypeDescription
urlstringRequired on create. Public HTTPS endpoint that accepts POST requests.
typesstring[]Required, non-empty event type identifiers. Filters your matching alerts.
alert_idsstring[]Optional, non-empty IDs owned by this account. Omit for all your alerts of the selected types. When present, both filters must match.
enabledbooleanOptional. 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.

POST/webhooks

Register an endpoint and save the returned signing secret.

POST /webhooks
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"
  ]
}'
201 Created
{
  "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.

Event envelope
FieldTypeDescription
idstringStable event ID, unchanged across retries.
typestringSingular event identifier, e.g. breaking_news.
created_atUTC stringWhen Stocklet created the event. Source publication or filing dates appear in data where relevant.
alert_idstringYour saved alert that matched this event.
tickerstringSupported listing symbol associated with this match.
dataobjectEvent-specific fields shown in the examples. Prices include their currency; source links identify external content.
breaking_news · incoming POST body
{
  "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"
}
Fictional sample data for illustration.

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.

Incoming request headers
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.

Node.js · signature verification
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);
}
Keep your signing secret on your server. Invalid signatures should return 401.

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.
RECEIVER CHECKLIST
Read the unmodified request body
Validate timestamp and signature
Persist or enqueue the matching event
Acknowledge with a 2xx response
Deduplicate before side effects
Integration questions?