Workstreams

Workstreams

Reference article: Part of the API reference. For what workstreams are in the app, see What is a workstream.

A workstream is where a piece of work lives in Nimbus: its room, its runs, its decisions, and the context the agent uses. These endpoints list, create, rename, archive, and delete workstreams. Most other resources, such as messages, the agent, and decisions, are reached through a workstream.

Which workstreams a key can reach

An API key doesn't see every workstream in your organization. It reaches:

Every other workstream behaves as if it doesn't exist: a request for it fails with 404 and the code resource_missing, not 403. The same applies to anything inside it, such as its messages and decisions. This way a key can't learn which workstreams exist outside its reach.

Wherever a path has {workstream}, you can pass the workstream's id or its slug.

The Workstream object

{
  "id": "3f6c2a1e-8b4d-4e2f-9a7c-5d1b0e6f2a94",
  "object": "workstream",
  "name": "Q4 pricing review",
  "slug": "q4-pricing-review",
  "workspace": "default",
  "status": "active",
  "type": null,
  "run_count": 12,
  "active_run_count": 1,
  "last_activity_at": 1758792310,
  "created": 1756201845,
  "updated": 1758790022
}
Field Type Description
id string The workstream's ID, a UUID.
object string Always workstream.
name string or null Its display name.
slug string or null Its URL-friendly name. Usable in place of id in paths.
workspace string The workspace it belongs to.
status string active, archived, or pending_deletion (deleted and in the trash).
type string or null The workstream's type, when it has one.
run_count integer How many runs it has had.
active_run_count integer How many runs are in progress now.
last_activity_at integer or null When something last happened in it, in Unix seconds.
created integer When it was created, in Unix seconds.
updated integer or null When it was last changed, in Unix seconds.

List workstreams

Returns the workstreams this key can reach, newest first. Deleted workstreams are left out.

GET /v1/workstreams

Scope: workstreams:read

Parameter In Type Description
limit query integer, optional How many objects to return, 1–100. Default 20.
cursor query string, optional The next_cursor from the previous page. See Pagination.
status query string, optional Only workstreams with this status: active or archived.
workspace query string, optional Only workstreams in this workspace.

::: code-group

curl "https://api.gonimbus.ai/v1/workstreams?status=active&limit=50" \
  -H "Authorization: Bearer $NIMBUS_API_KEY"
const response = await fetch('https://api.gonimbus.ai/v1/workstreams?status=active&limit=50', {
  headers: { Authorization: `Bearer ${process.env.NIMBUS_API_KEY}` },
})
const { data, has_more, next_cursor } = await response.json()
response = requests.get(
    "https://api.gonimbus.ai/v1/workstreams",
    params={"status": "active", "limit": 50},
    headers={"Authorization": f"Bearer {os.environ['NIMBUS_API_KEY']}"},
)
page = response.json()

:::

Returns a list object of Workstream objects.

Create a workstream

Creates a workstream. The key that creates it can reach it straight away, and so can every other key it's granted to later.

POST /v1/workstreams

Scope: workstreams:write · Accepts Idempotency-Key

Body field Type Description
name string The display name, 1–120 characters.
workspace string, optional The workspace to create it in. Defaults to your default workspace.

A new workstream counts toward your plan's limit on live workstreams. Over the limit, the request fails with 402 and the code live_workstream_limit_exceeded. Archive or delete a workstream to free a slot, or upgrade your plan.

::: code-group

curl https://api.gonimbus.ai/v1/workstreams \
  -H "Authorization: Bearer $NIMBUS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7d3e9a52-1f4b-4c6d-8e2a-0b5c7f9d1e36" \
  -d '{"name": "Q4 pricing review"}'
const response = await fetch('https://api.gonimbus.ai/v1/workstreams', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NIMBUS_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': crypto.randomUUID(),
  },
  body: JSON.stringify({ name: 'Q4 pricing review' }),
})
const workstream = await response.json()
response = requests.post(
    "https://api.gonimbus.ai/v1/workstreams",
    headers={
        "Authorization": f"Bearer {os.environ['NIMBUS_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={"name": "Q4 pricing review"},
)
workstream = response.json()

:::

Returns 201 with the new Workstream object.

Retrieve a workstream

GET /v1/workstreams/{workstream}

Scope: workstreams:read

Parameter In Type Description
workstream path string The workstream's id or slug.

::: code-group

curl https://api.gonimbus.ai/v1/workstreams/q4-pricing-review \
  -H "Authorization: Bearer $NIMBUS_API_KEY"
const response = await fetch('https://api.gonimbus.ai/v1/workstreams/q4-pricing-review', {
  headers: { Authorization: `Bearer ${process.env.NIMBUS_API_KEY}` },
})
const workstream = await response.json()
response = requests.get(
    "https://api.gonimbus.ai/v1/workstreams/q4-pricing-review",
    headers={"Authorization": f"Bearer {os.environ['NIMBUS_API_KEY']}"},
)
workstream = response.json()

:::

Returns the Workstream object. A deleted workstream is still returned, with status set to pending_deletion, until it is purged.

Update a workstream

Renames a workstream, or archives or unarchives it. Send only the fields you want to change; a request with neither returns the workstream unchanged.

PATCH /v1/workstreams/{workstream}

Scope: workstreams:write

Parameter In Type Description
workstream path string The workstream's id or slug.

The request body takes these fields:

Body field Type Description
name string, optional The new display name, 1–120 characters.
status string, optional archived to archive it, active to unarchive it.

::: code-group

curl -X PATCH https://api.gonimbus.ai/v1/workstreams/q4-pricing-review \
  -H "Authorization: Bearer $NIMBUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "archived"}'
const response = await fetch('https://api.gonimbus.ai/v1/workstreams/q4-pricing-review', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.NIMBUS_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ status: 'archived' }),
})
const workstream = await response.json()
response = requests.patch(
    "https://api.gonimbus.ai/v1/workstreams/q4-pricing-review",
    headers={"Authorization": f"Bearer {os.environ['NIMBUS_API_KEY']}"},
    json={"status": "archived"},
)
workstream = response.json()

:::

Returns the updated Workstream object.

Delete a workstream

Moves the workstream to the trash. An organization admin can restore it in the app until it is purged. While it's in the trash, it's left out of List workstreams, and Retrieve a workstream returns it with status set to pending_deletion.

DELETE /v1/workstreams/{workstream}

Scope: workstreams:write

Parameter In Type Description
workstream path string The workstream's id or slug.

::: code-group

curl -X DELETE https://api.gonimbus.ai/v1/workstreams/q4-pricing-review \
  -H "Authorization: Bearer $NIMBUS_API_KEY"
const response = await fetch('https://api.gonimbus.ai/v1/workstreams/q4-pricing-review', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${process.env.NIMBUS_API_KEY}` },
})
const deleted = await response.json()
response = requests.delete(
    "https://api.gonimbus.ai/v1/workstreams/q4-pricing-review",
    headers={"Authorization": f"Bearer {os.environ['NIMBUS_API_KEY']}"},
)
deleted = response.json()

:::

{
  "id": "3f6c2a1e-8b4d-4e2f-9a7c-5d1b0e6f2a94",
  "object": "workstream",
  "deleted": true
}

Errors

Status Code When
400 parameter_invalid A field is the wrong type or out of range, such as a name over 120 characters.
400 parameter_unknown The body has a field these endpoints don't take.
402 live_workstream_limit_exceeded Creating it would go over your plan's live workstream limit.
403 insufficient_scope The key lacks workstreams:read or workstreams:write.
404 resource_missing No workstream has that id or slug, or the key can't reach it.

FAQ

Why does List workstreams return fewer workstreams than I see in the app?

A key only reaches the workstreams it was granted and the ones it created. An admin can grant it more from the key's ⋯ menu on the Developers page, under Workstream access…. See Workstream access.

Why do I get 404 for a workstream I know exists?

Either the key hasn't been granted it, or the id or slug is wrong. The API answers both the same way, with resource_missing, so it never reveals workstreams outside a key's reach.

Can I use the slug instead of the id?

Yes, anywhere a path takes {workstream}, and in the workstream filter of List runs. Store the id, though: it's what other objects, such as runs and messages, use to refer to the workstream.

Can I restore a deleted workstream through the API?

No. An organization admin can restore it from the trash in the app until it's purged.

Does archiving a workstream free a slot on my plan?

Yes. Archived and deleted workstreams don't count as live, so archiving one makes room to create another without hitting live_workstream_limit_exceeded.