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. Toggle the language tabs once and the rest of the page remembers your choice.
1. Create an AI Assistant and Start Chatting
-
Initialize the client
import { ImbraceClient } from "@imbrace/sdk"const client = new ImbraceClient({baseUrl: "https://app-gatewayv2.imbrace.co",accessToken: "acc_your_token",})from imbrace import ImbraceClientclient = ImbraceClient(base_url="https://app-gatewayv2.imbrace.co",access_token="acc_your_token",)import { ImbraceClient } from "@imbrace/sdk"const client = new ImbraceClient({baseUrl: "https://app-gatewayv2.imbrace.co",apiKey: "api_your_key",})from imbrace import ImbraceClientclient = ImbraceClient(base_url="https://app-gatewayv2.imbrace.co",api_key="api_your_key",)The header dropdown swaps these snippets between access token (user-facing apps where Imbrace is your backend) and api key (service-to-service where Imbrace is a feature inside your stack). See Authentication → which credential to use for the full decision tree.
-
Create an assistant
workflow_namemust be unique within your organization.const assistant = await client.chatAi.createAssistant({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 providermodel_id: "gpt-4o", // any model name the system provider exposes})const assistantId = assistant.id // UUID — use this for all subsequent callsconsole.log("Assistant created:", assistantId)assistant = client.chat_ai.create_assistant({"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": "gpt-4o", # any model name the system provider exposes})assistant_id = assistant["id"]print("Assistant created:", assistant_id)provider_idandmodel_idare required. Passprovider_id: "system"to delegate to the org’s default LLM provider, or pass a custom provider’s UUID. Withprovider_id: "system",model_idaccepts a model name like"gpt-4o", or the literal"Default"to fall back to the system default model. -
Stream a chat response using the assistant
const response = await client.aiAgent.streamChat({assistant_id: assistantId,organization_id: "org_your_org_id",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})const reader = response.body!.getReader()const decoder = new TextDecoder()while (true) {const { done, value } = await reader.read()if (done) breakconst text = decoder.decode(value)for (const line of text.split("\n")) {if (line.startsWith("data: ")) {const data = line.slice(6).trim()if (data && data !== "[DONE]") {try {const chunk = JSON.parse(data)process.stdout.write(chunk.delta ?? chunk.content ?? "")} catch {}}}}}response = client.ai_agent.stream_chat({"assistant_id": assistant_id,"organization_id": "org_your_org_id","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.})import jsonfor line in response.iter_lines():if isinstance(line, bytes):line = line.decode()if not line.startswith("data: "):continuedata = line[6:].strip()if data and data != "[DONE]":try:chunk = json.loads(data)print(chunk.get("delta") or chunk.get("content") or "", end="")except Exception:pass -
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 messageawait client.aiAgent.streamChat({assistant_id: assistantId,organization_id: "org_your_org_id",id: sessionId,messages: [{ role: "user", content: "What's your refund policy?" }],})// Follow-up — same session, assistant remembers contextawait client.aiAgent.streamChat({assistant_id: assistantId,organization_id: "org_your_org_id",id: sessionId,messages: [{ role: "user", content: "How long does it take?" }],})import uuidsession_id = str(uuid.uuid4())# First messageclient.ai_agent.stream_chat({"assistant_id": assistant_id,"organization_id": "org_your_org_id","id": session_id,"messages": [{"role": "user", "content": "What's your refund policy?"}],})# Follow-up — same session, assistant remembers contextclient.ai_agent.stream_chat({"assistant_id": assistant_id,"organization_id": "org_your_org_id","id": session_id,"messages": [{"role": "user", "content": "How long does it take?"}],})
2. Create a Workflow with Activepieces and Bind it to an Assistant
-
List existing flows to find your project ID
const { data: flows } = await client.activepieces.listFlows({ limit: 5 })const projectId = flows[0]?.projectIdconsole.log("Project ID:", projectId)res = client.activepieces.list_flows(limit=5)flows = res.get("data", [])project_id = flows[0]["projectId"] if flows else Noneprint("Project ID:", project_id) -
Create a new flow
const flow = await client.activepieces.createFlow({displayName: "CRM Update on New Lead",projectId,})console.log("Flow created:", flow.id)flow = client.activepieces.create_flow(display_name="CRM Update on New Lead",project_id=project_id,)print("Flow created:", flow["id"]) -
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
triggerFlowwould 404. Add the Webhook piece as the trigger, then publish:// Set the Webhook piece as the flow's triggerawait client.activepieces.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 liveawait client.activepieces.applyFlowOperation(flow.id, {type: "LOCK_AND_PUBLISH",request: {},})# Set the Webhook piece as the flow's triggerclient.activepieces.apply_flow_operation(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 — DISABLED → ENABLED, webhook URL becomes liveclient.activepieces.apply_flow_operation(flow["id"], {"type": "LOCK_AND_PUBLISH","request": {},}) -
Trigger the flow manually with a payload
// Fire and forget (async)await client.activepieces.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.activepieces.triggerFlowSync(flow.id, {contact_name: "Jane Smith",email: "jane@example.com",})console.log("Flow result:", result)# Fire and forget (async)client.activepieces.trigger_flow(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 apply_flow_operation# ADD_ACTION (otherwise the gateway waits 30s and gives up).result = client.activepieces.trigger_flow_sync(flow["id"], {"contact_name": "Jane Smith","email": "jane@example.com",})print("Flow result:", result) -
Bind the flow to your assistant
Open your assistant in the Imbrace dashboard, go to Tools → Workflows, and attach the flow. The assistant will be able to trigger it during a conversation when appropriate.
Alternatively, update the assistant to reference the workflow by name:
await client.chatAi.updateAssistant(assistantId, {name: "Support Bot",workflow_name: "support_bot_v1",workflow_function_call: [{ flow_id: flow.id, description: "Update CRM on new lead" }],})client.chat_ai.update_assistant(assistant_id, {"name": "Support Bot","workflow_name": "support_bot_v1","workflow_function_call": [{"flow_id": flow["id"], "description": "Update CRM on new lead"}],}) -
Check run history
const { data: runs } = await client.activepieces.listRuns({flowId: flow.id,limit: 10,})for (const run of runs) {console.log(run.id, run.status, run.startTime)}res = client.activepieces.list_runs(flow_id=flow["id"], limit=10)for run in res.get("data", []):print(run["id"], run.get("status"), run.get("startTime"))
3. Manage Knowledge Hubs and Attach to an Assistant
Knowledge Hub files and folders live in the data-board service (client.boards). The folder’s _id is what you pass to an assistant as its knowledge source.
-
Create a folder
const folder = await client.boards.createFolder({name: "Product Documentation",organization_id: "org_your_org_id",parent_folder_id: "root",source_type: "upload",})console.log("Folder ID:", folder._id)folder = client.boards.create_folder({"name": "Product Documentation","organization_id": "org_your_org_id","parent_folder_id": "root","source_type": "upload",})print("Folder ID:", folder["_id"]) -
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", "org_your_org_id")const uploaded = await client.boards.uploadFile(formData)console.log("File uploaded:", uploaded.file_id)from pathlib import Pathpath = Path("./docs/faq.pdf")files = {"file": (path.name, path.read_bytes(), "application/pdf"),"folder_id": (None, folder["_id"]),"organization_id": (None, "org_your_org_id"),}uploaded = client.boards.upload_file(files)print("File uploaded:", uploaded.get("file_id") or uploaded.get("_id")) -
Attach the folder to the assistant
Pass the folder
_idinfolder_ids— the assistant retrieves from every file in that folder. Useboard_idsto attach a CRM data-board (its items become a knowledge source — see Resources → Boards & items). The legacyknowledge_hubsfield is deprecated.await client.chatAi.updateAssistant(assistantId, {name: "Support Bot",workflow_name: "support_bot_v1",folder_ids: [folder._id],// board_ids: [boardId], // optional: attach a CRM data-board too})client.chat_ai.update_assistant(assistant_id, {"name": "Support Bot","workflow_name": "support_bot_v1","folder_ids": [folder["_id"]],# "board_ids": [board_id], # optional: attach a CRM data-board too}) -
Inspect and manage folders and files
// Search foldersconst folders = await client.boards.searchFolders({ q: "Product" })// Get folder with contentsconst contents = await client.boards.getFolderContents(folder._id)console.log("Files:", contents.files?.length)// Rename a folderawait client.boards.updateFolder(folder._id, { name: "Product Docs v2" })// Search files in a folderconst files = await client.boards.searchFiles({ folderId: folder._id })// Delete foldersawait client.boards.deleteFolders({ ids: [folder._id] })# Search foldersfolders = client.boards.search_folders(q="Product")# Get folder with contentscontents = client.boards.get_folder_contents(folder["_id"])print("Files:", len(contents.get("files") or []))# Rename a folderclient.boards.update_folder(folder["_id"], {"name": "Product Docs v2"})# Search files in a folderfiles = client.boards.search_files(folder_id=folder["_id"])# Delete foldersclient.boards.delete_folders([folder["_id"]])
4. Manage Data Boards and Items (CRM Pipelines)
-
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)board = client.boards.create(name="Sales Pipeline",description="Track all active deals",)print("Board ID:", board["_id"]) -
Add a custom field
Field types are
ShortText,LongText,Number,Dropdown,Date,Checkbox, etc.createFieldreturns the updated board — find your new field insideboard.fields.const updated = await client.boards.createField(board._id, {name: "Company",type: "ShortText",})// Find the identifier field (auto-created with every board)const identifierField = updated.fields.find(f => f.is_identifier)updated = client.boards.create_field(board["_id"], {"name": "Company","type": "ShortText",})identifier_field = next(f for f in updated["fields"] if f.get("is_identifier")) -
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)item = client.boards.create_item(board["_id"], {"fields": [{"board_field_id": identifier_field["_id"], "value": "Acme Corp"},],})print("Item ID:", item["_id"]) -
List and search items
// Paginate through itemsconst { data: items } = await client.boards.listItems(board._id, { limit: 20, skip: 0 })// Full-text searchconst { data: results } = await client.boards.search(board._id, {q: "Acme",limit: 10,})# Paginate through itemsitems = client.boards.list_items(board["_id"], limit=20, skip=0)# Full-text searchresults = client.boards.search(board["_id"], q="Acme", limit=10) -
Update and delete items
updateItemuses{ data: [{ key: fieldId, value }] }array format: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)client.boards.update_item(board["_id"], item["_id"], {"data": [{"key": identifier_field["_id"], "value": "Acme Corp — Closed Won"}],})client.boards.delete_item(board["_id"], item["_id"]) -
Export to CSV
const csv = await client.boards.exportCsv(board._id)// csv is a string — write to a file or send as a downloadcsv = client.boards.export_csv(board["_id"])# csv is a str — write to a file or send as a download