Convert a B3OS workflow
Converts a workflow from the original B3OS JSON node tree into a routine definition and returns it with diagnostics for anything that did not map (unsupported nodes, actions without a pack, connectors to bind). Nothing is created; publish the result with `PUT /v1/routines/{routine}`.
POST
/v1/routines/import
Converts a workflow from the original B3OS JSON node tree into a routine definition and returns it with
diagnostics for anything that did not map (unsupported nodes, actions without a pack, connectors to bind).
Nothing is created; publish the result with `PUT /v1/routines/{routine}`.
Authentication
Bearer Token (b3os_sk_ API key or b3os_pat_ token) API Key (cookie: __Host-b3os_session)
Request Body required
application/jsonformat
string
REQUIRED
Enum:
b3os-workflow-v1workflow
object
REQUIRED
The workflow JSON exported from the original B3OS app.
Responses
200
The converted definition.
application/jsonobject
string
REQUIRED
Enum:
routine_importdefinition
object
REQUIRED
A routine as sent to PUT /v1/routines/{id} (ARCHITECTURE 5.4). GitHub-Actions-shaped: triggers, defaults and an ordered list of steps; expressions are CEL inside ${{ }}. Steps run in array order unless a step lists needs. Contexts, status functions, template rules and the divergences from GitHub Actions are in packages/spec/schemas/README.md. Compile-time rules JSON Schema cannot express (unique ids, needs pointing at earlier steps, references only to ancestors, retry forbidden on irreversible steps) are listed there under 'Routine publish checks'. Owner after freeze: routines.
$schema
string (uri)
Optional pointer to this schema for editors.
name
string
REQUIRED
Routine slug, unique within the project. Used by the CLI (b3os routine deploy); an MCP server that lists routines as tools names the tool routine_<name> with - mapped to _. runs, hooks, validate and import are reserved: they are API paths under /v1/routines.
description
string
What the routine does; an MCP server that lists routines as tools uses it as the tool description.
inputs
object | boolean & object
JSON Schema 2020-12 for the run input, available as inputs. Defaults declared here are applied before the run starts. Absent: the run takes no input ({}).
output
unknown
The run's result, evaluated once after every step has finished and the run succeeded. Absent: the result is {}. Context: inputs, vars, env, trigger, run, steps (all).
env
object
Non-secret strings evaluated once at run start (context: inputs, vars, trigger, run) and exposed as env.<NAME>. Not passed to sandboxes implicitly; put what a step needs in its with.
vars
object
Read-only JSON constants exposed as vars.<name>. Values are literals; strings in them are not evaluated as templates.
triggers
object[]
How runs start besides POST /v1/routines/{id}/runs. Triggers switch atomically when a new version is published. Action triggers are trigger subscriptions (tsub_): publishing a version creates or updates them, and a rollback or delete removes them (README, 'Pack triggers').
Array of:
type
unknown
REQUIRED
Enum:
cron, interval, webhook, actionid
string
REQUIRED
A CEL identifier (so steps.<id>.outputs parses): lowercase letters, digits and _, not a CEL reserved word.
uses
string
action only: the pack trigger to subscribe to.
with
object
cron, interval, webhook: the run input built from the event (context: trigger, vars), validated against inputs; absent: {} plus input defaults. action: the pack trigger's configuration, validated against its configSchema and evaluated once when the version is published (context: vars only); action runs start with {} plus input defaults and read the event from trigger.data.
connections
object
action only: binds the pack trigger's connection keys (its requires.connections) to vault connections. A key left out is resolved when the version is published (the most recently created connection for that pack the publishing key may use) and pinned in the subscription; when there is none the publish fails with routine_invalid.
if
string
Start a run only when true (context: trigger, vars). A webhook delivery that does not match is acknowledged with 202 and starts nothing; an action event that does not match is dropped. Status functions are not available here.
cron
string
Six fields with seconds: second minute hour day-of-month month day-of-week, single spaces. Numbers, names (JAN, MON), *, a-b, a,b, */n and ? are accepted; L, W and # in the day fields.
tz
string
IANA zone for cron, default UTC. A local time skipped by a DST change fires at the first instant after the gap; a local time that occurs twice fires once, at its first occurrence.
every_ms
integer
Interval period. Plans may raise the floor (GET /v1/limits).
anchor
unknown
interval: epoch fires at Unix-epoch multiples of every_ms (clock aligned); publish fires every_ms after the version became active, then every every_ms.
Enum:
epoch, publishcatch_up
unknown
Occurrences missed while the node was down or the routine was paused: skip runs none, latest runs only the newest one, all runs each one in order. Only occurrences inside catch_up_window_s count. Required on every schedule (ARCHITECTURE 8).
Enum:
skip, latest, allcatch_up_window_s
integer
overlap
unknown
When an occurrence fires while a run started by this trigger is still active: skip drops it, buffer_one keeps at most one pending occurrence (a newer one replaces it), allow starts it anyway, cancel_running cancels the active run first. defaults.concurrency still applies on top.
Enum:
skip, buffer_one, allow, cancel_runningverify
object
Mandatory verification for POST /v1/routines/hooks/{hk_id} (ARCHITECTURE 4.3); the hk_ id is created when the version is published. b3os: B3OS-Signature 't=<unix>,v1=<hex HMAC-SHA256(secret, "<t>.<body>")>' with a per-hook secret B3OS generates (shown once by the API). github, stripe, slack, standard_webhooks: the provider's scheme as in b3pack verify. hmac_sha256: generic, and always timestamped: the signature covers '<value of timestamp_header>.<body>', and a delivery whose timestamp header is missing or not a Unix time is refused. Timestamped schemes reject deliveries more than tolerance_s (at most 300 s) from the node clock. Secrets never appear in the URL.
scheme
unknown
REQUIRED
Enum:
b3os, github, stripe, slack, standard_webhooks, hmac_sha256secret
string
An api_key vault connection whose api_key field holds the provider's signing secret (vault.yaml field names). Store it as a verification-only connection, without pack and without hosts: B3OS reads it to check signatures, and a connection with no hosts is never injected into any request. Not used with b3os.
header
string
encoding
unknown
Enum:
hex, base64prefix
string
timestamp_header
string
hmac_sha256 only, and required there: header carrying the delivery's Unix timestamp.
tolerance_s
integer
dedupe
string
webhook: string key; a second delivery with the same key within 24 h returns the first delivery's response and starts nothing. Default per scheme: github X-GitHub-Delivery, stripe body.id, slack body.event_id, standard_webhooks webhook-id, b3os the Idempotency-Key header or else the v1 signature, hmac_sha256 none (then dedupe is required).
defaults
object
durability
unknown
ephemeral: memory only, nothing journaled (the agent tool-call fast path; a crash loses the run). standard: group-commit journal, effects durable before dependents run. strict: intent and result commits for every effect step (ARCHITECTURE 4.9, 5.4). A run may request a different tier at start.
Enum:
ephemeral, standard, stricttimeout_ms
integer
Default timeout for uses and map steps that do not set timeout_ms. Wait and sleep steps are not affected.
retry
object
Default retry policy, applied only to steps whose effect class is pure or read. A write step retries only when it sets retry itself; an irreversible step never retries.
max_attempts
integer
REQUIRED
Total attempts including the first.
initial_ms
integer
factor
number
max_ms
integer
jitter
boolean
concurrency
object
Admission for runs of this routine, shaped like GitHub's concurrency. At most limit runs are active per group; on_limit decides what a new run does when the group is full.
limit
integer
REQUIRED
group
string
Group key evaluated at run start (context: inputs, vars, trigger). Default: one group for the routine.
on_limit
unknown
queue: wait (FIFO) for a free slot. skip: the new run ends canceled with reason concurrency_skipped. cancel_running: cancel the oldest active run in the group, then start.
Enum:
queue, skip, cancel_runningsteps
(unknown | unknown | unknown | unknown)[]
REQUIRED
Array of:
One of:
Option 1unknown
Option 2unknown
Option 3unknown
Option 4unknown
diagnostics
object[]
REQUIRED
Array of:
severity
string
REQUIRED
Enum:
error, warningcode
string
REQUIRED
An error code from the catalog, such as `routine_invalid` or `connection_required`.
pointer
string
REQUIRED
JSON pointer into the definition.
detail
string
REQUIRED
400
The request failed validation (`invalid_request`, `invalid_url`).
401
Missing, malformed, expired or revoked credentials (`unauthorized`).
403
Authenticated but not allowed (`forbidden`, `egress_denied`).
413
The request body exceeds this operation's limit.
415
The Content-Type is not accepted by this operation.
422
The workflow has no action nodes to convert (`routine_invalid`); `errors` lists what could not be read.
429
A rate, concurrency or quota limit applies (`rate_limited`, `concurrency_limited`, `quota_exceeded`).
500
Something failed inside B3OS (`internal`). Retry with backoff.
503
The node or the product is not available right now (`node_unavailable`, `product_unavailable`, `capacity_unavailable`).
curl -X POST 'https://beta-api.b3os.org/v1/routines/import' \ -H 'Authorization: Bearer YOUR_API_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "format": "b3os-workflow-v1", "workflow": { "name": "ETH alert", "nodes": [] }}'
const response = await fetch('https://beta-api.b3os.org/v1/routines/import', { method: 'POST', headers: { "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" }, body: JSON.stringify({ "format": "b3os-workflow-v1", "workflow": { "name": "ETH alert", "nodes": [] } })});const data = await response.json();console.log(data);
import requestsheaders = { 'Authorization': 'Bearer YOUR_API_TOKEN'}response = requests.post('https://beta-api.b3os.org/v1/routines/import', headers=headers, json={ "format": "b3os-workflow-v1", "workflow": { "name": "ETH alert", "nodes": [] }})print(response.json())
200
Response
{ "object": "routine_import", "definition": { "name": "eth-alert", "steps": [ { "id": "price", "uses": "io.b3os/coingecko/get-token-price@1", "with": { "ids": [ "ethereum" ] } } ] }, "diagnostics": [ { "severity": "warning", "code": "connection_required", "pointer": "/steps/0", "detail": "Bind a CoinGecko connection before publishing" } ]}
API Playground
Try this endpoint
POST
/v1/routines/import