Novalink

Documentation

Workflow API: run workflows from your own code

Updated September 21, 2026

Every workflow is also an API. Publish it, create an API key, and your backend can send it input and read its output in one request. Each workflow has a Playground, a chat that runs it the same way the API does, with ready-to-copy cURL and Python beside it.

Create an API key

Open API keys in the sidebar and choose Create key. A key can run all of your workflows or only the ones you pick. It is shown once: Novalink keeps only a hash and its first few characters, so copy it straight into an environment variable.

Call a workflow

Send the key as a bearer token and the workflow's ID in the path. Only the published version runs, so edits in the editor never reach callers until you publish. The playground shows your exact URL and ID.

cURL
curl $NOVALINK_API_URL/v1/workflows/WORKFLOW_ID/runs \
  -H "Authorization: Bearer $NOVALINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "input": "Summarise this ticket" }'
Python
import os

import requests

response = requests.post(
    f"{os.environ['NOVALINK_API_URL']}/v1/workflows/WORKFLOW_ID/runs",
    headers={"Authorization": f"Bearer {os.environ['NOVALINK_API_KEY']}"},
    json={"input": {"ticket_id": 4812, "priority": "high"}},
    timeout=70,
)
run = response.json()
print(run["status"], run["output"])

Input and output

input becomes the run's trigger payload. An object is used as it is, so { "ticket_id": 4812 } is read as {{ trigger.ticket_id }}. Text becomes { "message": ... }, read as {{ trigger.message }}, which suits chat-style workflows.

The reply's output is the value of the workflow's Output node. With several Output nodes it is an object keyed by node ID.

Response
{
  "run_id": "495f5053-...",
  "workflow_id": "c43324cb-...",
  "status": "succeeded",
  "output": { "summary": "Customer cannot sign in since the update" },
  "error": null,
  "total_tokens": 812,
  "duration_ms": 2140,
  "status_url": null
}

Waiting, polling and streaming

  • Wait (the default): the request holds until the run ends, up to timeout seconds (30 by default, at most 60). A run that is still going answers 202 with a status_url.
  • Poll: send "wait": false to get a 202 straight away, then GET /v1/runs/RUN_ID with the same key until status is succeeded, failed or cancelled.
  • Stream: send "stream": true for Server-Sent Events. Agent replies arrive as token events while they are written, steps as node.started and node.succeeded, and the last event is run.completed with the full result.

Errors and limits

Errors come back as { "detail": "..." } with one readable sentence. A run that starts but fails is not an error: it answers 200 with "status": "failed" and the reason in error.

  • 401: the key is missing, wrong or revoked.
  • 403: the key is limited to other workflows.
  • 404: no workflow with that ID belongs to the key's account.
  • 409: the workflow has not been published.
  • 429: more than 60 runs a minute on one key. Wait for the seconds in Retry-After.

Test it in the playground

Open a workflow and choose Playground. Each message runs the workflow once, as Text or as JSON, against the published version or your current draft. Replies show the output, the time and tokens it took, and a link to the run. The panel beside the chat holds the endpoint, the workflow ID and cURL and Python samples built from your last message. Playground runs appear in run history like any other.

Build it on the canvas

Create a free account, describe the workflow or wire it yourself, and run it in the browser.