@bondi-labs/integration-sdk - v0.0.1
    Preparing search index...

    @bondi-labs/integration-sdk - v0.0.1

    @bondi-labs/integration-sdk

    npm version License: MIT Types Bundle size

    Define triggers and actions for the Bondi automation engine — bring your own API into Bondi workflows.

    Resource Link
    📚 API Reference integration-sdk.heybondi.com
    🚀 Examples github.com/heybondi/integration-sdk-examples
    📝 Changelog CHANGELOG.md
    🐛 Issues github.com/heybondi/monorepo/issues
    npm install @bondi-labs/integration-sdk
    
    # 1. Authenticate and create an integration in your workspace.
    npx bondi init

    # 2. Define your integration in code.
    # 3. Sync the definition to Bondi.
    npx bondi sync

    npx bondi init opens your browser for authentication, then writes:

    BONDI_API_URL=https://automation.heybondi.com
    BONDI_WORKSPACE_ID=ws-...
    BONDI_INTEGRATION_TOKEN=bnd_tok_...
    import {
    defineIntegration,
    defineAction,
    defineTrigger,
    createBondiClient,
    } from "@bondi-labs/integration-sdk/core";
    import { z } from "zod";

    const contactCreated = defineTrigger({
    name: "contact.created",
    label: "Contact Created",
    payload: z.object({ id: z.string(), email: z.string().email() }),
    });

    const myCRM = defineIntegration({
    name: "My CRM",
    slug: "my-crm",
    baseUrl: "https://api.mycrm.com/v1",
    services: [
    {
    name: "contacts",
    label: "Contacts",
    actions: [
    defineAction({
    name: "createContact",
    label: "Create Contact",
    method: "POST",
    endpoint: "/contacts",
    body: z.object({ name: z.string(), email: z.string() }),
    response: z.object({ id: z.string() }),
    }),
    ],
    triggers: [contactCreated],
    },
    ],
    });

    export default myCRM; // CLI sync reads `default` export

    // Runtime — emit events from your app
    const client = createBondiClient({
    workspaceId: process.env.BONDI_WORKSPACE_ID,
    token: process.env.BONDI_INTEGRATION_TOKEN,
    apiUrl: process.env.BONDI_API_URL,
    });
    const bondi = client.bind(myCRM);

    bondi.triggers["contact.created"].emit({ id: "123", email: "john@example.com" });

    emit() is fire-and-forget. Use emitAndWait() to await acknowledgement, or pass onEmitError to the client config to capture failures.

    import {
    BondiModule,
    BondiTrigger,
    BondiTriggerBase,
    BondiService,
    BondiAction,
    BondiGuard,
    } from "@bondi-labs/integration-sdk/nestjs";
    import { Module, Controller, Injectable, Post, Body, UseGuards } from "@nestjs/common";
    import { z } from "zod";

    const contactPayload = z.object({ id: z.string(), email: z.string() });

    @BondiTrigger({ name: "contact.created", label: "Contact Created", payload: contactPayload })
    export class ContactCreatedTrigger extends BondiTriggerBase<typeof contactPayload> {}

    @Injectable()
    export class ContactsService {
    constructor(private contactCreated: ContactCreatedTrigger) {}
    create(dto: { id: string; email: string }) {
    this.contactCreated.emit(dto); // type-safe via Zod
    }
    }

    @BondiService({ name: "contacts", label: "Contacts" })
    @Controller("contacts")
    export class ContactsController {
    @UseGuards(BondiGuard)
    @BondiAction({ name: "createContact", label: "Create Contact" })
    @Post()
    async create(@Body() dto: unknown) {
    /* ... */
    }
    }

    @Module({
    imports: [
    BondiModule.forRoot({
    integration: { name: "My CRM", slug: "my-crm", category: "crm" },
    triggers: [ContactCreatedTrigger],
    }),
    ],
    })
    export class AppModule {}

    BondiModule.forRoot reads BONDI_* env vars by default. To override, pass values directly:

    BondiModule.forRoot({
    integration: { /* ... */ },
    workspaceId: "ws-abc-123", // hard-coded
    token: { envKey: "MY_BONDI_TOKEN" }, // custom env var
    apiUrl: () => configService.get("BONDI_API_URL"), // factory
    })

    When Bondi calls your BondiAction endpoints, requests are signed with HMAC-SHA256 over {timestamp}.{action}.{rawBody}. The SDK's BondiGuard verifies this for you in NestJS. For other stacks, here's the equivalent in Python:

    import hmac, hashlib, time

    def verify_bondi(headers, raw_body, token):
    ts = headers["x-bondi-timestamp"]
    action = headers["x-bondi-action"]
    sig = headers["x-bondi-signature"]
    if abs(time.time() - int(ts)) > 300:
    return False
    expected = hmac.new(token.encode(), f"{ts}.{action}.{raw_body}".encode(), hashlib.sha256).hexdigest()
    return hmac.compare_digest(sig.removeprefix("sha256="), expected)
    Var Description
    BONDI_API_URL Bondi automation engine URL (set by npx bondi init)
    BONDI_WORKSPACE_ID Your workspace ID
    BONDI_INTEGRATION_TOKEN HMAC signing key — never sent over the wire
    Topic Link
    Getting started — NestJS docs/getting-started/nestjs.md
    Getting started — plain Node / Express docs/getting-started/plain-node.md
    Verifying webhooks (Python, Go, Ruby) docs/guides/webhook-verification.md
    Error handling, retries, dry-run docs/guides/error-handling.md
    Token rotation docs/guides/token-rotation.md
    internalMode (Bondi-only) docs/guides/internal-mode.md
    HTTP header reference docs/reference/headers.md

    MIT — see LICENSE.