Resources
Examples
Real code against the real 11-endpoint v1 API — see the full endpoint list on the API Reference page.
REST / cURL
List paid orders
curl "https://bot-forge-coral.vercel.app/api/v1/orders?status=paid&limit=25" \
-H "Authorization: Bearer bf_live_xxx"Create a product
curl -X POST https://bot-forge-coral.vercel.app/api/v1/products \
-H "Authorization: Bearer bf_live_xxx" \
-H "Content-Type: application/json" \
-d '{"name":"Blue Hoodie","price_cents":4999,"currency":"usd"}'TypeScript client
A minimal typed wrapper — expand it with the schemas from /api/v1/openapi.json.
botforge-client.ts
const BASE = "https://bot-forge-coral.vercel.app/api/v1";
async function bf<T>(path: string, init?: RequestInit): Promise<T> {
const res = await fetch(`${BASE}${path}`, {
...init,
headers: { Authorization: `Bearer ${process.env.BOTFORGE_API_KEY}`, ...init?.headers },
});
if (!res.ok) throw new Error(`BotForge API error ${res.status}: ${await res.text()}`);
return res.json();
}
interface Order { id: string; number: number; status: string; total_cents: number; currency: string }
export const listOrders = (status?: string) =>
bf<{ data: Order[]; pagination: { total: number; limit: number; offset: number } }>(
`/orders${status ? `?status=${status}` : ""}`,
);Webhook handler (Next.js route)
app/api/botforge-webhook/route.ts
import crypto from "crypto";
export async function POST(req: Request) {
const rawBody = await req.text();
const signature = req.headers.get("x-botforge-signature") ?? "";
const expected = "sha256=" + crypto.createHmac("sha256", process.env.BOTFORGE_WEBHOOK_SECRET!)
.update(rawBody).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
return new Response("Invalid signature", { status: 401 });
}
const { event, data } = JSON.parse(rawBody);
if (event === "order.paid") {
// fulfil the order
}
return new Response("ok", { status: 200 });
}Full event list and retry schedule on the Webhooks page.
Error handling
Retry on 429 with backoff
async function bfWithRetry<T>(path: string, attempt = 1): Promise<T> {
try {
return await bf<T>(path);
} catch (err) {
if (String(err).includes("429") && attempt <= 3) {
await new Promise((r) => setTimeout(r, 2 ** attempt * 1000));
return bfWithRetry<T>(path, attempt + 1);
}
throw err;
}
}Full error code table on API Reference.
Pagination walkthrough
Fetch every customer, one page at a time
async function allCustomers() {
const out: unknown[] = [];
let offset = 0;
while (true) {
const { data, pagination } = await bf<{ data: unknown[]; pagination: { total: number; limit: number; offset: number } }>(
`/customers?limit=100&offset=${offset}`,
);
out.push(...data);
offset += pagination.limit;
if (offset >= pagination.total) break;
}
return out;
}