API reference · Webhooks

Create a subscription

POST/v1/subscriptions

Follow phrases on an event, or one market by ticker, and optionally have every hit posted to your webhook, signed.

On this page

Auth. An API token: Authorization: Bearer lb_… (create one). Signed-in web sessions work too.

Limits. Each subscription counts toward your plan's subscriptions (5, 25 or 200); a new webhook URL toward its webhook endpoints (1, 5 or unlimited).

Parameters

Body

NameTypeRequiredDescription
event_idstringnoThe event to follow (ev_…). Send this with phrases, or market alone.
phrasesarray of stringnoPhrase keys to follow on the event.
subjectsarray of stringnoTyped-fact subjects to receive (fact_extracted).
webhook_urlstringnoAn HTTPS URL to post each hit to.
contextarray of stringnoContext kinds to receive about the market: on_air, topic, near_miss, typed.
marketstringnoA market ticker. Langbot follows that market's phrases on the event that settles it.

Request

Terminal
curl -X POST "https://api.langbot.ai/v1/subscriptions" \
  -H "Authorization: Bearer $LANGBOT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"market": "KXEARNINGSMENTIONNVDA-26OCT-BLACKWELL", "webhook_url": "https://example.com/hooks/langbot"}'

Response

201 Created

JSON
{
  "id": "sub_01J9…",
  "user_id": "usr_01J9…",
  "event_id": "ev_nvda_q3_2026",
  "phrases": ["blackwell"],
  "subjects": [],
  "webhook_url": "https://example.com/hooks/langbot",
  "secret": "9c1f…",
  "created_at": 1760050000000,
  "market_ticker": "KXEARNINGSMENTIONNVDA-26OCT-BLACKWELL",
  "context": [],
  "market": { "ticker": "KXEARNINGSMENTIONNVDA-26OCT-BLACKWELL", "venue": "kalshi", "event_id": "ev_nvda_q3_2026", "title": "Will NVIDIA say \"Blackwell\" on its Q3 earnings call?", "status": "open", "phrases": ["blackwell"], "close_ts": 1760058000000 },
  "market_title": "Will NVIDIA say \"Blackwell\" on its Q3 earnings call?"
}

Webhook delivery. Each hit is a POST of the event JSON to webhook_url with X-Langbot-Signature: sha256=<hex HMAC-SHA256 of the raw body, keyed with secret>. Up to 4 attempts, 1 s, 4 s and 16 s apart; any 2xx acknowledges. Without a webhook_url, hits land in your dashboard inbox.

TypeScript
import { createHmac, timingSafeEqual } from "node:crypto";
const expected = `sha256=${createHmac("sha256", secret).update(rawBody).digest("hex")}`;
const ok = timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-langbot-signature"]));

Errors

StatuscodeWhen
404not_foundUnknown event or market.
422validation_errorThe market is not yet attached to a live event, or the body mixes market with event_id.
401auth_requiredNo token was sent.
401token_invalidThe token was not recognised (mistyped, revoked or expired).
402quota_exceededYour plan's subscriptions or webhook endpoints are all in use; delete one or move up a plan.
429rate_limitedOver your request budget; wait Retry-After seconds.

Every error body is {"detail": …, "code": "…"}; branch on code. All codes: Errors.