Publish a routine version
Compiles the definition and publishes it as a new immutable version that becomes active at once: triggers switch atomically, runs already in progress keep the version they started with. `{routine}` is an ID or a name; a name that does not exist creates the routine (`201`), which makes `b3os routine deploy` idempotent. The definition's `name` must match a name in the path. The publishing key becomes the routine's `run_as` identity and its scopes are snapshotted. Hook IDs stay the same across versions for the same trigger ID. Pack triggers (`type: action`) are subscriptions: publishing creates or updates one trigger subscription (`tsub_`, read-only at `GET /v1/actions/subscriptions`) per action trigger, and removes the subscriptions of action triggers the new version no longer has.
/v1/routines/{routine}
Authentication
Path Parameters
routine
string
required
path
"nightly-digest"Header Parameters
Idempotency-Key
string
optional
header
Request Body required
application/json$schema
string (uri)
name
string
REQUIRED
description
string
inputs
object | boolean & object
output
unknown
env
object
vars
object
triggers
object[]
type
unknown
REQUIRED
cron, interval, webhook, actionid
string
REQUIRED
uses
string
with
object
connections
object
if
string
cron
string
tz
string
every_ms
integer
anchor
unknown
epoch, publishcatch_up
unknown
skip, latest, allcatch_up_window_s
integer
overlap
unknown
skip, buffer_one, allow, cancel_runningverify
object
scheme
unknown
REQUIRED
b3os, github, stripe, slack, standard_webhooks, hmac_sha256secret
string
header
string
encoding
unknown
hex, base64prefix
string
timestamp_header
string
tolerance_s
integer
dedupe
string
defaults
object
durability
unknown
ephemeral, standard, stricttimeout_ms
integer
retry
object
max_attempts
integer
REQUIRED
initial_ms
integer
factor
number
max_ms
integer
jitter
boolean
concurrency
object
limit
integer
REQUIRED
group
string
on_limit
unknown
queue, skip, cancel_runningsteps
(unknown | unknown | unknown | unknown)[]
REQUIRED
Responses
application/jsonid
string
REQUIRED
object
string
REQUIRED
routinename
string
REQUIRED
description
string | null
REQUIRED
status
string
REQUIRED
active, pausedpaused_reason
string | null
REQUIRED
manual, run_as_revoked, nullversion
object
REQUIRED
id
string
REQUIRED
number
integer
REQUIRED
created_at
string (date-time)
REQUIRED
triggers
object[]
REQUIRED
id
string
REQUIRED
type
string
REQUIRED
cron, interval, webhook, actionstatus
string
REQUIRED
active, pausednext_fire_at
string (date-time) | null
REQUIRED
hook
object | null
REQUIRED
id
string
REQUIRED
url
string (uri)
REQUIRED
verify
string
REQUIRED
b3os, github, stripe, slack, standard_webhooks, hmac_sha256secret
string
subscription_id
string | null
REQUIRED
run_as
object
REQUIRED
key
string | null
REQUIRED
scopes
string[]
REQUIRED
created_at
string (date-time)
REQUIRED
updated_at
string (date-time)
REQUIRED
metadata
object
REQUIRED
curl -X PUT 'https://beta-api.b3os.org/v1/routines/nightly-digest' \ -H 'Authorization: Bearer YOUR_API_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "name": "nightly-digest", "description": "Scrape the news page and post a summary", "triggers": [ { "type": "cron", "id": "nightly", "cron": "0 0 6 * * *", "tz": "America/Los_Angeles", "catch_up": "latest" }, { "type": "webhook", "id": "inbound", "verify": { "scheme": "b3os" } } ], "steps": [ { "id": "page", "uses": "vision/scrape@1", "with": { "url": "https://news.example.com" } } ]}'
const response = await fetch('https://beta-api.b3os.org/v1/routines/nightly-digest', { method: 'PUT', headers: { "Authorization": "Bearer YOUR_API_TOKEN", "Content-Type": "application/json" }, body: JSON.stringify({ "name": "nightly-digest", "description": "Scrape the news page and post a summary", "triggers": [ { "type": "cron", "id": "nightly", "cron": "0 0 6 * * *", "tz": "America/Los_Angeles", "catch_up": "latest" }, { "type": "webhook", "id": "inbound", "verify": { "scheme": "b3os" } } ], "steps": [ { "id": "page", "uses": "vision/scrape@1", "with": { "url": "https://news.example.com" } } ] })});const data = await response.json();console.log(data);
import requestsheaders = { 'Authorization': 'Bearer YOUR_API_TOKEN'}response = requests.put('https://beta-api.b3os.org/v1/routines/nightly-digest', headers=headers, json={ "name": "nightly-digest", "description": "Scrape the news page and post a summary", "triggers": [ { "type": "cron", "id": "nightly", "cron": "0 0 6 * * *", "tz": "America/Los_Angeles", "catch_up": "latest" }, { "type": "webhook", "id": "inbound", "verify": { "scheme": "b3os" } } ], "steps": [ { "id": "page", "uses": "vision/scrape@1", "with": { "url": "https://news.example.com" } } ]})print(response.json())
{ "id": "rtn_01m5t6vhkw4a8fa4tb5w4ffz37", "object": "routine", "name": "nightly-digest", "description": "Scrape the news page and post a summary", "status": "active", "paused_reason": null, "version": { "id": "ver_01m5t6ncrsssrysy1p2fbn2pgf", "number": 2, "created_at": "2026-10-25T19:20:00.000Z" }, "triggers": [ { "id": "nightly", "type": "cron", "status": "active", "next_fire_at": "2026-10-26T13:00:00.000Z", "hook": null, "subscription_id": null }, { "id": "inbound", "type": "webhook", "status": "active", "next_fire_at": null, "hook": { "id": "hk_01m5t3r2qwz23751t0x74bhahz", "url": "https://beta-api.b3os.org/v1/routines/hooks/hk_01m5t3r2qwz23751t0x74bhahz", "verify": "b3os", "secret": "whsec_ex4mple7ex4mple7ex4mple7ex4mple7" }, "subscription_id": null } ], "run_as": { "key": "key_01m5t5gb92a5zncjx654gevx4p", "scopes": [ "vision:run", "infer:run" ] }, "created_at": "2026-10-25T19:10:00.000Z", "updated_at": "2026-10-25T19:20:00.000Z", "metadata": {}}
Try this endpoint
/v1/routines/{routine}