Skip to content

Full Flow Guide

This guide walks through the four major workflows in the Imbrace SDK from start to finish. Each section is self-contained — follow them in order or jump to the one you need.


1. Create an AI Agent and Start Chatting

  1. Initialize the client

    import { ImbraceClient } from "@imbrace/sdk"
    const client = new ImbraceClient({
    accessToken: process.env.IMBRACE_ACCESS_TOKEN,
    env: "stable",
    })
    import { ImbraceClient } from "@imbrace/sdk"
    const client = new ImbraceClient({
    apiKey: process.env.IMBRACE_API_KEY,
    organizationId: process.env.IMBRACE_ORGANIZATION_ID,
    env: "stable",
    })
  2. Create an AI agent

    workflow_name must be unique within your organization.

    const agent = await client.chatAi.createAiAgent({
    name: "Support Bot",
    workflow_name: "support_bot_v1",
    description: "Handles tier-1 customer support queries",
    instructions: "You are a helpful support agent. Be concise and friendly.",
    provider_id: "system", // use the org's default LLM provider
    model_id: "Default", // routes to the org's configured default model
    streaming: true, // emit text-delta SSE events (see Aside below)
    })
    const aiAgentId = agent.id // UUID — use this for all subsequent calls
    console.log("AI agent created:", aiAgentId)

    provider_id and model_id are optional — the SDK auto-fills { provider_id: "system", model_id: "Default" } when omitted. "Default" routes to whatever the org has configured as its system default model and is the org-portable choice. Pass them explicitly to override: provider_id: "<uuid>" to pin a custom LLM provider, or model_id: "gpt-4o" etc. — but a literal model name only works in orgs whose system provider actually exposes it. List your org’s models with client.ai.listModels() (TypeScript) / client.ai.list_models() (Python) before hardcoding.

  3. Stream a chat response using the AI agent

    Use streamChatText / stream_chat_text — it wraps streamChat, parses the SSE event stream, and yields plain text chunks. Assumes the agent was created with streaming: true (see the Aside in step 2).

    for await (const chunk of client.aiAgent.streamChatText({
    assistant_id: aiAgentId,
    messages: [{ role: "user", content: "How do I reset my password?" }],
    // id is the session UUID — reuse it to maintain conversation history.
    // If omitted, a new UUID is auto-generated each call.
    })) {
    process.stdout.write(chunk)
    }
  4. Maintain conversation history (session ID)

    Pass the same id (must be a UUID) across calls to keep context:

    import { randomUUID } from "crypto"
    const sessionId = randomUUID()
    // First message
    await client.aiAgent.streamChat({
    assistant_id: aiAgentId,
    id: sessionId,
    messages: [{ role: "user", content: "What's your refund policy?" }],
    })
    // Follow-up — same session, AI agent remembers context
    await client.aiAgent.streamChat({
    assistant_id: aiAgentId,
    id: sessionId,
    messages: [{ role: "user", content: "How long does it take?" }],
    })

2. Create a Workflow and Bind it to an AI Agent

  1. Get your project ID

    Copy your Project ID from the Imbrace Dashboard → Workflows, or resolve it programmatically if your org already has flows:

    // Option A — hardcode from the Dashboard (recommended for new orgs)
    const projectId = "your_project_id"
    // Option B — resolve from an existing flow (throws if org has no flows yet)
    const projectId = await client.workflows.resolveProjectId()
  2. Create a new flow

    const flow = await client.workflows.createFlow({
    displayName: "CRM Update on New Lead",
    projectId,
    })
    console.log("Flow created:", flow.id)
  3. Add a Webhook trigger and publish the flow

    A freshly created flow is in DRAFT with no trigger — the webhook URL doesn’t exist yet, so triggerFlow would 404. Add the Webhook piece as the trigger, then publish:

    // Set the Webhook piece as the flow's trigger
    await client.workflows.applyFlowOperation(flow.id, {
    type: "UPDATE_TRIGGER",
    request: {
    name: "trigger",
    type: "PIECE_TRIGGER",
    valid: true,
    displayName: "Webhook",
    settings: {
    pieceName: "@activepieces/piece-webhook",
    pieceVersion: "0.1.24",
    triggerName: "catch_webhook",
    input: { authType: "none" },
    propertySettings: {},
    },
    },
    })
    // Publish — flow status flips DISABLED → ENABLED and webhook URL becomes live
    await client.workflows.applyFlowOperation(flow.id, {
    type: "LOCK_AND_PUBLISH",
    request: {},
    })
  4. Trigger the flow manually with a payload

    // Fire and forget (async)
    await client.workflows.triggerFlow(flow.id, {
    contact_name: "Jane Smith",
    email: "jane@example.com",
    })
    // Sync trigger — for this to actually return data instead of timing out,
    // the flow needs a "Return Response" action added via applyFlowOperation
    // ADD_ACTION (otherwise the gateway waits 30s for a response and gives up).
    const result = await client.workflows.triggerFlowSync(flow.id, {
    contact_name: "Jane Smith",
    email: "jane@example.com",
    })
    console.log("Flow result:", result)
  5. Bind the flow to your AI agent

    Open your AI agent in the Imbrace dashboard, go to Tools → Workflows, and attach the flow. The AI agent will be able to trigger it during a conversation when appropriate.

    Alternatively, update the AI agent to reference the workflow by name:

    await client.chatAi.updateAiAgent(aiAgentId, {
    name: "Support Bot",
    workflow_name: "support_bot_v1",
    workflow_function_call: [{ flow_id: flow.id, description: "Update CRM on new lead" }],
    })
  6. Check run history

    const { data: runs } = await client.workflows.listRuns({
    flowId: flow.id,
    limit: 10,
    })
    for (const run of runs) {
    console.log(run.id, run.status, run.startTime)
    }

3. Manage Knowledge Hubs and Attach to an AI Agent

Knowledge Hub files and folders live in the data-board service (client.boards). The folder’s _id is what you pass to an AI agent as its knowledge source.

  1. Create a folder

    const folder = await client.boards.createFolder({
    name: "Product Documentation",
    organization_id: process.env.IMBRACE_ORGANIZATION_ID,
    parent_id: "root",
    })
    console.log("Folder ID:", folder._id)
  2. Upload a file to the folder

    import { readFileSync } from "fs"
    const fileBuffer = readFileSync("./docs/faq.pdf")
    const formData = new FormData()
    formData.append("file", new Blob([fileBuffer], { type: "application/pdf" }), "faq.pdf")
    formData.append("folder_id", folder._id)
    formData.append("organization_id", process.env.IMBRACE_ORGANIZATION_ID ?? "")
    const uploaded = await client.boards.uploadFile(formData)
    console.log("File uploaded:", uploaded.file_id)
  3. Attach the folder to the AI agent

    Pass the folder _id in folder_ids — the AI agent retrieves from every file in that folder. Use board_ids to attach a CRM data-board (its items become a knowledge source — see Resources → Boards & items). The legacy knowledge_hubs field is deprecated.

    await client.chatAi.updateAiAgent(aiAgentId, {
    name: "Support Bot",
    workflow_name: "support_bot_v1",
    folder_ids: [folder._id],
    // board_ids: [boardId], // optional: attach a CRM data-board too
    })
  4. Inspect and manage folders and files

    // Search folders
    const folders = await client.boards.searchFolders({ q: "Product" })
    // Get folder with contents
    const contents = await client.boards.getFolderContents(folder._id)
    console.log("Files:", contents.files?.length)
    // Rename a folder
    await client.boards.updateFolder(folder._id, { name: "Product Docs v2" })
    // Search files in a folder
    const files = await client.boards.searchFiles({ folderId: folder._id })
    // Delete folders
    await client.boards.deleteFolders({ ids: [folder._id] })

4. Manage Data Boards and Items (CRM Pipelines)

  1. Create a board

    A board is a CRM pipeline — leads, deals, tasks, or any structured data.

    const board = await client.boards.create({
    name: "Sales Pipeline",
    description: "Track all active deals",
    })
    console.log("Board ID:", board._id)
  2. Add a custom field

    Field types are ShortText, LongText, Number, Dropdown, Date, Checkbox, etc. createField returns the newly-created field. To inspect all fields on the board, fetch the board separately.

    await client.boards.createField(board._id, {
    name: "Company",
    type: "ShortText",
    })
    // Boards auto-create an identifier field — fetch the board to see all fields
    const boardWithFields = await client.boards.get(board._id) as any
    const identifierField = boardWithFields.fields?.find((f: any) => f.is_identifier)
  3. Create board items (records)

    Items use { fields: [{ board_field_id, value }] } format:

    const item = await client.boards.createItem(board._id, {
    fields: [
    { board_field_id: identifierField._id, value: "Acme Corp" },
    ],
    })
    console.log("Item ID:", item._id)
  4. List and search items

    // Paginate through items
    const { data: items } = await client.boards.listItems(board._id, { limit: 20, skip: 0 })
    // Full-text search
    const { data: results } = await client.boards.search(board._id, {
    q: "Acme",
    limit: 10,
    })
  5. Update and delete items

    Update uses { data: [{ key, value }] } (note: key, not board_field_id):

    await client.boards.updateItem(board._id, item._id, {
    data: [{ key: identifierField._id, value: "Acme Corp — Closed Won" }],
    })
    await client.boards.deleteItem(board._id, item._id)
  6. Export to CSV

    const csv = await client.boards.exportCsv(board._id)
    // csv is a string — write to a file or send as a download

Next steps

  • Resources → — per-namespace method reference for all four workflows
  • AI Agent → — deeper dive into streamChat, embeddings, and parquet
  • Workflows → — flow operations, MCP servers, and run history
  • Document AI → — AI-powered document parsing and extraction
  • Data Board → — board fields, items, search, segments, and CSV