Dibbla Docs Get started Guides Workflows Changelog
Open Console
Beyond apps

Connect it to your app

Two directions — your app calling a workflow over HTTP, and a worker of yours providing functions the graph can call.

A workflow is only useful when something calls it, or when it can call something of yours. Both directions are worth knowing; most people need the first.

Direction 1: your app calls the workflow

The workflow has an HTTP endpoint and an API key. Your app POSTs to it like any other service:

// Always bound the call: Node's default timeout is five minutes,
// which makes a hung workflow look like a hung app.
const ac = new AbortController();
const timer = setTimeout(() => ac.abort(), 60_000);

const res = await fetch(
`${process.env.WORKFLOW_URL}`,
{
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.WORKFLOW_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ question: userInput }),
  signal: ac.signal,
},
).finally(() => clearTimeout(timer));

Put the URL and key in secrets, not in the image — see Rotate secrets and env vars.

Prefer async for anything agentic

An agent workflow can take tens of seconds. Rather than holding a request open, start it with --async (or the equivalent HTTP call), store the run id, and fetch the output when it finishes. dibbla wf runs output <runId> is the CLI form of that fetch.

Direction 2: the workflow calls your code

Functions in the registry come from execution servers — long-lived worker processes that connect over gRPC, announce what they provide, and stay connected. You write one with the Go SDK:

package main

import (
  "log"
  "os"

  sdk "github.com/dibbla-agents/sdk-go"
)

func main() {
  server, err := sdk.New(
      sdk.WithServerName("my-worker"),
      sdk.WithServerApiToken(os.Getenv("SERVER_API_TOKEN")),
  )
  if err != nil {
      log.Fatal(err)
  }

  // Register before Start(): registration is what advertises them.
  server.RegisterFunction(myFunction)

  // Start() blocks forever, serving dispatches.
  if err := server.Start(); err != nil {
      log.Fatal(err)
  }
}

Once it connects, your functions appear in dibbla functions list and become selectable in the editor. They are addressed by their (server, function) pair, which is why the server name matters.

Set GRPC_SERVER_ADDRESS explicitly

The SDK defaults to grpc.dibbla.com:443 — production. A worker you meant to point at a development environment will connect to production instead, register there, and quietly start serving real traffic. Always set the address explicitly, in every environment, including the one you think is obvious.

# the gRPC listener is cluster-internal; forward it first
# on a Helm self-host the service is <release>-workflow-server
$kubectl -n dibbla-agents port-forward svc/workflow-server-service 50051:50051 &
 
$SERVER_NAME=my-worker \
$GRPC_SERVER_ADDRESS=127.0.0.1:50051 \
$GRPC_USE_TLS=false \
$SERVER_API_TOKEN="$TOKEN" go run .
Registered 1 functions

A connected server shows up on the dashboard with its function count. If your node says the function is unknown, the worker is not connected — that is the first thing to check, before the YAML.

See Custom functions for the handler signatures themselves.