@inbin/core
v0.2.0
Published
Official Inbin SDK: typed client for the Inbin REST API (email in, JSON out) plus webhook signature verification.
Downloads
24
Maintainers
Readme
@inbin/core
Official SDK for Inbin — email in, JSON out. Typed client for the REST API plus webhook signature verification. Zero dependencies, Node 18+.
Install
npm i @inbin/coreQuickstart
import { Inbin } from "@inbin/core";
const inbin = new Inbin({ apiKey: process.env.INBIN_API_KEY! });
// 1. Create an inbox — a permanent forwarding address
const inbox = await inbin.inboxes.create({ name: "going-deals" });
console.log(inbox.address); // [email protected]
// 2. Declare what to extract from every email
await inbin.schemas.put({
extract: {
deals: {
type: "array",
items: {
destination_city: { type: "string", required: true },
price_usd: { type: "number", required: true },
},
},
},
hallucination_guard: true,
});
// 3. Point Inbin at your webhook
await inbin.apps.update({ webhook_url: "https://your.app/webhooks/inbin" });Verify webhooks
Always verify the HMAC before trusting a delivery. Pass the raw request body — the signature covers the exact bytes Inbin sent.
import { verifyWebhook } from "@inbin/core";
// Next.js route handler
export async function POST(request: Request) {
const raw = await request.text();
const event = verifyWebhook(raw, request.headers, process.env.INBIN_WEBHOOK_SECRET!);
// event.extracted is your schema-shaped JSON
return new Response("ok");
}// Express
app.post("/webhooks/inbin", express.raw({ type: "*/*" }), (req, res) => {
const event = verifyWebhook(req.body, req.headers, process.env.INBIN_WEBHOOK_SECRET!);
res.sendStatus(200);
});Throws InbinError (code: "bad_signature") on any mismatch.
API surface
| Method | Endpoint |
| --- | --- |
| inbin.inboxes.create({ name? }) | POST /v1/inboxes |
| inbin.inboxes.list() | GET /v1/inboxes |
| inbin.inboxes.get(id) | GET /v1/inboxes/:id |
| inbin.inboxes.rename(id, name) | PATCH /v1/inboxes/:id |
| inbin.inboxes.delete(id) | DELETE /v1/inboxes/:id |
| inbin.schemas.put({ extract, hallucination_guard? }) | PUT /v1/schemas |
| inbin.schemas.current() | GET /v1/schemas/current |
| inbin.events.list(params?) | GET /v1/events |
| inbin.events.get(id) | GET /v1/events/:id |
| inbin.events.redeliver(id) | POST /v1/events/:id/redeliver |
| inbin.query(q) | POST /v1/query |
| inbin.apps.me() | GET /v1/apps |
| inbin.apps.update({ name?, webhook_url? }) | PATCH /v1/apps |
All methods throw InbinError with .status and .code on failure.
Query
Your inbox as a table. Filter, sort, project, flatten array records, group and aggregate over everything your schemas extracted. One request, no database on your side.
const { rows } = await inbin.query({
flatten: "deals",
where: [{ field: "price_usd", op: "lt", value: 300 }],
group_by: "destination_city",
aggregate: [{ fn: "avg", field: "price_usd", as: "avg_price" }],
});
// [{ destination_city: "Lisbon", avg_price: 274.5 }, ...]Ops: eq, neq, gt, gte, lt, lte, contains, in,
exists. Aggregates: count, sum, avg, min, max. Limit
caps at 200.
MCP
Every Inbin application is also an MCP server — see
@inbin/mcp to connect
Claude Desktop, Cursor, or any MCP client to your parsed events.
License
MIT.
