API reference
Client SDKs and API
Official Python, .NET, Java and Node.js clients, generated from the live OpenAPI document.
Any service in your organisation can start and monitor workflows through the Kiwi Flow API. Four official client libraries wrap it, so your application code stays separate from workflow logic.
| Language | Package |
|---|---|
| Python | Python SDK |
| .NET / C# | .NET SDK |
| Java | Java SDK |
| Node.js | Node.js SDK |
The SDKs are generated from the platform's OpenAPI description, which is exported from the running API at build time. They cover every resource area of the API: authentication, users and API keys, roles, groups and permissions, workflows (create, run, publish, validate, versions, shares), triggers, runs, approval and external tasks, connections, templates, storage, AI generation and assistants, licensing, resource guards, the activity catalogue, OAuth2 authorisation and the audit log.
Note
The SDKs are currently pre-release (version 0.2.0) and are not yet published to the public package registries. Ask Kiwify Labs for access, or build each SDK from its folder in the Kiwi Flow source. The install commands below apply once the packages are published.
Install#
dotnet add package KiwiFlow.Client
# from the SDK folder: install the client into your local Maven repository
mvn clean install
# then depend on com.kiwify.flow:kiwiflow-client:0.2.0
npm install kiwiflow --save
pip install kiwiflow
The .NET SDK targets .NET 10. Choose your language in any sample below; the choice applies to every sample on the site and is remembered in your browser.
Authenticate and connect#
Create an API key for a user (kiwi flow key-add) and pass it to the client as a bearer token. Keep keys in a secret store, never in source control.
using KiwiFlow.Client.Api;
using KiwiFlow.Client.Client;
using KiwiFlow.Client.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = Host.CreateDefaultBuilder(args)
.ConfigureApi((context, options) =>
{
options.AddTokens(new BearerToken(apiKey));
options.AddApiHttpClients(client =>
{
client.BaseAddress = new Uri("https://your-kiwiflow-host");
});
})
.Build();
var workflowsApi = host.Services.GetRequiredService<IWorkflowsApi>();
var runsApi = host.Services.GetRequiredService<IRunsApi>();
import com.kiwify.flow.client.ApiClient;
import com.kiwify.flow.client.Configuration;
import com.kiwify.flow.client.api.RunsApi;
import com.kiwify.flow.client.api.WorkflowsApi;
import com.kiwify.flow.client.auth.HttpBearerAuth;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://your-kiwiflow-host");
((HttpBearerAuth) client.getAuthentication("ApiKey")).setBearerToken(apiKey);
WorkflowsApi workflowsApi = new WorkflowsApi(client);
RunsApi runsApi = new RunsApi(client);
import { Configuration, RunsApi, WorkflowsApi } from "kiwiflow";
const config = new Configuration({
basePath: "https://your-kiwiflow-host",
accessToken: apiKey,
});
const workflowsApi = new WorkflowsApi(config);
const runsApi = new RunsApi(config);
import kiwiflow
from kiwiflow.api import runs_api, workflows_api
config = kiwiflow.Configuration(host="https://your-kiwiflow-host")
config.access_token = api_key
client = kiwiflow.ApiClient(config)
workflows = workflows_api.WorkflowsApi(client)
runs = runs_api.RunsApi(client)
List workflows#
var response = await workflowsApi.ListWorkflowsAsync();
foreach (var wf in response.Ok())
Console.WriteLine($"{wf.WorkflowId} {wf.Name}");
for (var wf : workflowsApi.listWorkflows()) {
System.out.println(wf.getWorkflowId() + " " + wf.getName());
}
for (const wf of await workflowsApi.listWorkflows()) {
console.log(wf.workflowId, wf.name);
}
for wf in workflows.list_workflows():
print(wf.workflow_id, wf.name)
Run a workflow and wait for the result#
Start a run with its inputs, then poll the run until it is no longer Running. Do not use the /execute-stream endpoint from the SDKs; it is not supported there.
var started = (await workflowsApi.ExecuteWorkflowAsync(
workflowId,
new ExecuteRequest(new Dictionary<string, object?> { ["customerId"] = 42 }))).Ok()!;
var run = started;
while (run.Status == "Running")
{
await Task.Delay(TimeSpan.FromSeconds(2));
run = (await runsApi.GetRunAsync(started.RunId)).Ok()!;
}
Console.WriteLine($"{run.Status}: {run.OutputsJson}");
import com.kiwify.flow.client.model.ExecuteRequest;
import com.kiwify.flow.client.model.RunDetail;
import java.util.Map;
RunDetail started = workflowsApi.executeWorkflow(
workflowId, new ExecuteRequest().inputs(Map.of("customerId", 42)));
RunDetail run = started;
while ("Running".equals(run.getStatus())) {
Thread.sleep(2000);
run = runsApi.getRun(started.getRunId());
}
System.out.println(run.getStatus() + ": " + run.getOutputsJson());
const started = await workflowsApi.executeWorkflow({
workflowId,
executeRequest: { inputs: { customerId: 42 } },
});
let run = started;
while (run.status === "Running") {
await new Promise((resolve) => setTimeout(resolve, 2000));
run = await runsApi.getRun({ runId: started.runId });
}
console.log(`${run.status}: ${run.outputsJson}`);
import time
started = workflows.execute_workflow(
workflow_id, kiwiflow.ExecuteRequest(inputs={"customerId": 42}))
run = started
while run.status == "Running":
time.sleep(2)
run = runs.get_run(started.run_id)
print(f"{run.status}: {run.outputs_json}")
inputsJson, outputsJson and logJson on the run are JSON documents carried as strings. A run that has to wait for an approval or an external task reports another status, so handle it in your own loop if your workflows use those activities.
The kiwi flow CLI#
The CLI is built on the .NET SDK and runs inside the Kiwi shell as kiwi flow <command>. login returns a durable API key directly, and the CLI caches a protected session token and an optional saved URL and key under ~/.kiwiflow/. See the CLI reference.