@forumatlas/sdk
v0.2.0
Published
Official TypeScript SDK for the Forum Atlas B2A2B API. AI-native industry intelligence across 12 commercial sectors.
Downloads
82
Maintainers
Readme
@forumatlas/sdk
Official TypeScript SDK for Forum Atlas — the AI-native industry intelligence platform across 12 commercial sectors.
Request/response shapes mirror the live API (packages/contracts/openapi.yaml); every example below corresponds to a real route and real fields.
Install
npm install @forumatlas/sdk
# or
pnpm add @forumatlas/sdk
# or
yarn add @forumatlas/sdkGet an API key at app.forumatlas.com/app/api-keys.
Quickstart
import { ForumAtlas } from "@forumatlas/sdk";
const forum = new ForumAtlas({ apiKey: process.env.FORUMATLAS_API_KEY! });
// Ask a question — synthesized + cited (POST /v1/query)
const answer = await forum.query.ask({
query: "What did Anduril announce in May 2026?",
sectors: ["defense"],
});
console.log(answer.headline); // headline + lede + sections with inline [N] markers
console.log(answer.sources); // citation array resolving the [N] markers
console.log(answer.validator); // { passed, matched_claims, total_claims, failures }What this SDK gives you
- Query — natural-language question → Coordinator-synthesized, citation-validated answer
- Forum Brief — variant-driven brief generation + the persisted brief library
- Forum Forecast — Monte-Carlo probability distributions by forecast type
- Causal chains — trigger-event → multi-step, cited driver/effect analysis
- Forum AI Tutor — multi-turn, citation-grounded tutoring sessions
- Forum Network — cross-sector entity graph (search, profiles, relationships, alias resolution)
- Sources + documents — the public source catalog behind every citation
- Anomaly subscriptions — webhook/email/in-app alerts
- Usage — workspace metering rollups
Examples
Forum Brief
// variant is REQUIRED (the server rejects the request without it)
const brief = await forum.briefs.generate({
variant: "topic_synthesis",
sectors: ["cyber"],
persona: "ciso",
topic: "cyber-insurance market, Q2 2026",
});
console.log(brief.headline, brief.lede);
console.log(brief.sections); // [{ heading, body }] with [N] markers
console.log(brief.sources); // citations resolving the markers
// Or read the persisted brief library:
const { briefs } = await forum.briefs.list({ sector: "cyber", limit: 10 });
const bib = await forum.briefs.bibliography(briefs[0]!.brief_id, "apa");Forum Forecast
// forecast_type (enum) + subject (object) are REQUIRED
const forecast = await forum.forecasts.compute({
forecast_type: "m_and_a_probability",
subject: { entity_id: "<uuid from entities.search>" },
horizon_days: 540,
});
console.log(forecast.headline_probability); // number | null
console.log(forecast.distribution); // Monte-Carlo summary
console.log(forecast.evidence); // cited evidence chunksCausal chain
// trigger (>= 8 chars) is REQUIRED
const chain = await forum.causal.analyze({
trigger: "PJM capacity auction clears at record price",
horizon_months: 18,
affected_sectors: ["energy", "infra"],
});
if (chain.insufficient_evidence) {
console.log("No grounded chain:", chain.reason);
} else {
console.log(chain.headline, chain.sections);
}Forum AI Tutor
// First turn: sector_id + topic are REQUIRED to start a session
const turn1 = await forum.tutor.ask({
message: "Explain the GENIUS Act stablecoin reserve requirements.",
sector_id: "finance",
topic: "GENIUS Act",
});
// Continue the same session
const turn2 = await forum.tutor.ask({
message: "How does that affect Tether specifically?",
session_id: turn1.session_id,
});
console.log(turn2.answer, turn2.citations);Forum Network — cross-sector entity graph
const { results } = await forum.entities.search({
q: "Lockheed Martin",
sectors: ["defense", "space"],
});
const lockheed = await forum.entities.retrieve(results[0]!.entity_id);
console.log(lockheed.sectors); // sector tags
console.log(lockheed.primary_ticker); // "LMT"
const rels = await forum.entities.relationships(lockheed.entity_id, { depth: 2 });
console.log(rels.edges);
// Alias resolution
const { matches } = await forum.entities.byAlias("Lockmart");
const batch = await forum.entities.resolve(["Lockmart", "GD", "Raytheon"]);Anomalies
// sectors is an ARRAY; webhook delivery needs webhook_url + a >=24-char secret
const sub = await forum.anomalies.subscribe({
sectors: ["energy"],
anomaly_types: ["regulator_vocabulary_shift"],
delivery_channels: ["webhook"],
webhook_url: "https://your-app.com/webhooks/forum-anomalies",
webhook_secret: process.env.FORUM_WEBHOOK_SECRET!,
});
console.log(sub.subscription_id);Usage + billing
const usage = await forum.usage.current();
console.log(`Period: ${usage.period_start} → ${usage.period_end}`);
console.log(`Cost: $${usage.total_cost_usd.toFixed(2)}`);
console.log(usage.rollup); // per-meter breakdownPricing
The B2A2B API is metered per query — see forumatlas.com/pricing
for current per-meter rates by tier. Custom Enterprise volume rates: [email protected].
Error handling
The API returns RFC 7807 application/problem+json errors
({ type, title, status, detail, request_id }); the SDK surfaces them as typed exceptions.
import { RateLimitError, AuthenticationError, ValidationError } from "@forumatlas/sdk";
try {
const brief = await forum.briefs.generate({ variant: "sector_recap", sectors: ["defense"] });
} catch (err) {
if (err instanceof RateLimitError) {
// Auto-retried with backoff first (Retry-After honored); this is post-budget
console.error("Rate limited", err.requestId);
} else if (err instanceof AuthenticationError) {
console.error("Invalid API key or missing scope:", err.detail);
} else if (err instanceof ValidationError) {
console.error("Invalid params:", err.detail); // RFC 7807 detail
} else {
throw err;
}
}Retries + idempotency
- GETs retry on 429/5xx/network errors with exponential backoff (
maxRetries, default 3). - The synthesis POSTs (
/v1/query,/v1/brief,/v1/forecast,/v1/causal,/v1/tutor) automatically carry anIdempotency-Key— the server caches responses for 24h per (key, body-hash) — so their retries are replay-safe. - Non-idempotent POSTs (e.g.
/v1/anomalies/subscribe) are never auto-retried on 5xx or network failure, so a write cannot silently double-execute.
Configuration
const forum = new ForumAtlas({
apiKey: process.env.FORUMATLAS_API_KEY!,
baseUrl: "https://justin-19118--forum-intelligence-fastapi-app.modal.run", // override for staging
timeoutMs: 60000, // request timeout (default 60s)
maxRetries: 3, // retry budget (default 3)
fetch: customFetchImpl, // override fetch (default global fetch)
});Webhook signatures
Anomaly webhooks are signed with HMAC-SHA256 via the X-Forum-Signature header
(hex HMAC of the raw payload with your webhook_secret). Verify on receipt:
import crypto from "node:crypto";
const isValid = (body: string, signature: string, secret: string) => {
const expected = crypto.createHmac("sha256", secret).update(body).digest("hex");
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
};TypeScript types
All response shapes are typed against the live wire format. The Sector, BriefVariant,
ForecastType, and AnomalyType unions are enforced as the server-validated enums.
Runtime validation (optional)
import { BriefResponseSchema, CitationSchema } from "@forumatlas/sdk";
const brief = BriefResponseSchema.parse(rawResponse);Documentation
- API reference: forumatlas.com/docs/api-reference
- Recipes: forumatlas.com/docs/recipes
- Status: forumatlas.com/docs/status
Support
- Email:
[email protected] - Issues: github.com/forumatlas/forum-platform/issues
License
MIT — see LICENSE file in repo.
