openapi: 3.1.0
info:
title: Bem Buckets Workflows API
version: 1.0.0
description: "Buckets are named partitions of the knowledge graph within an\naccount+environment. Entities, mentions, and relations are scoped to a\nbucket so a single account+environment can host multiple isolated graphs\n— for example one per data source or workspace.\n\nEvery account+environment has exactly one **default** bucket, used by\nunscoped flows. The default bucket can be renamed but never deleted.\n\nUse these endpoints to create, list, fetch, rename, and delete buckets:\n\n- **`POST /v3/buckets`** creates a non-default bucket.\n- **`GET /v3/buckets`** lists buckets with cursor pagination\n (`startingAfter` / `endingBefore` over `bucketID`).\n- **`PATCH /v3/buckets/{bucketID}`** updates `name` and/or `description`.\n- **`DELETE /v3/buckets/{bucketID}`** soft-deletes a bucket. A non-empty\n bucket is rejected with `409 Conflict` unless `?cascade=true` is\n passed; the default bucket can never be deleted."
servers:
- url: https://api.bem.ai
description: US Region API
variables: {}
- url: https://api.eu1.bem.ai
description: EU Region API
variables: {}
security:
- API Key: []
tags:
- name: Workflows
description: "Workflows orchestrate one or more functions into a directed acyclic graph (DAG) for document processing.\n\nUse these endpoints to create, update, list, and manage workflows, and to invoke them\nwith file input via `POST /v3/workflows/{workflowName}/call`.\n\nThe call endpoint accepts files as either multipart form data or JSON with base64-encoded\ncontent. In the Bem CLI, use `@path/to/file` inside JSON values to automatically read and\nencode files:\n\n```\nbem workflows call --workflow-name my-workflow \\\n --input.single-file '{\"inputContent\": \"@file.pdf\", \"inputType\": \"pdf\"}' \\\n --wait\n```"
paths:
/v3/workflows:
get:
operationId: v3-list-workflows
summary: List Workflows
description: '**List workflows in the current environment.**
Returns each workflow''s current version, including its node graph
and main node. Combine filters freely — they AND together.
## Filtering
- `workflowIDs` / `workflowNames`: exact-match identity filters.
- `displayName`: case-insensitive substring match.
- `tags`: returns workflows tagged with any of the supplied tags.
- `functionIDs` / `functionNames`: returns only workflows that
reference the named functions in any node. Useful for "which
workflows depend on this function?" lookups before changing or
deleting a function.
## Pagination
Cursor-based with `startingAfter` and `endingBefore` (workflowIDs).
Default limit 50, maximum 100.'
parameters:
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 50
- name: workflowIDs
in: query
required: false
schema:
type: array
items:
type: string
minItems: 1
explode: false
- name: workflowNames
in: query
required: false
schema:
type: array
items:
type: string
minItems: 1
explode: false
- name: displayName
in: query
required: false
schema:
type: string
explode: false
- name: sortOrder
in: query
required: false
schema:
type: string
enum:
- asc
- desc
default: asc
- name: startingAfter
in: query
required: false
schema:
type: string
- name: endingBefore
in: query
required: false
schema:
type: string
- name: tags
in: query
required: false
schema:
type: array
items:
type: string
minItems: 1
explode: false
- name: functionIDs
in: query
required: false
schema:
type: array
items:
type: string
minItems: 1
explode: false
- name: functionNames
in: query
required: false
schema:
type: array
items:
type: string
minItems: 1
explode: false
responses:
'200':
description: The request has succeeded.
content:
application/json:
schema:
$ref: '#/components/schemas/WorkflowsListResponseV3'
tags:
- Workflows
post:
operationId: v3-create-workflow
summary: Create a Workflow
description: '**Create a workflow.**
A workflow is a directed acyclic graph of nodes (each pointing at a
function) with one entry point (`mainNodeName`). The graph runs
end-to-end on every call.
## Required structure
- `name`: unique within the environment, alphanumeric plus hyphens
and underscores.
- `mainNodeName`: must match one of the `nodes[].name` values, and
must not be the destination of any edge.
- `nodes`: at least one. Each node has a unique `name` and a
`function` reference (by `functionName` or `functionID`, optionally
pinned to a `versionNum`).
- `edges`: optional for single-node workflows. For branching
sources (Classify, semantic Split), each edge carries a
`destinationName` matching a `classifications[].name` or
`itemClasses[].name` on the source function.
The created workflow is at `versionNum: 1`. Subsequent
`PATCH /v3/workflows/{workflowName}` calls produce new versions.
## Common patterns
- **Single-node**: one extract/classify function, no edges.
- **Sequential**: extract → enrich → payload_shaping (linear edges).
- **Branching**: classify → multiple extracts (one edge per
classification name).
- **Split-then-process**: split → multiple extracts (one edge per
item class).
See [Workflows explained](/guide/workflows-explained) for end-to-end
examples of each pattern.'
parameters: []
responses:
'200':
description: The request has succeeded.
content:
application/json:
schema:
$ref: '#/components/schemas/WorkflowV3CreateResponse'
tags:
- Workflows
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WorkflowCreateRequestV3'
/v3/workflows/copy:
post:
operationId: v3-copy-workflow
summary: Copy a Workflow
description: '**Copy a workflow to a new name.**
Forks the source workflow''s current version into a brand-new
workflow at `versionNum: 1`. The full node graph and edges are
carried over, but the *functions* the copied nodes reference are
shared, not duplicated — both workflows now point at the same
functions.
Useful for forking a production workflow to test a topology change
without disturbing the live caller.'
parameters: []
responses:
'200':
description: The request has succeeded.
content:
application/json:
schema:
$ref: '#/components/schemas/WorkflowCopyResponseV3'
'400':
description: The server could not understand the request due to invalid syntax.
content:
application/json:
schema:
$ref: '#/components/schemas/WorkflowCopyResponseV3'
'404':
description: The server cannot find the requested resource.
content:
application/json:
schema:
$ref: '#/components/schemas/WorkflowCopyResponseV3'
tags:
- Workflows
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WorkflowCopyRequest'
/v3/workflows/{workflowName}:
delete:
operationId: v3-delete-workflow
summary: Delete a Workflow
description: '**Delete a workflow and every one of its versions.**
Permanent. Running and queued calls against this workflow continue
to completion against the version they captured at call time;
subsequent attempts to call the workflow return `404 Not Found`.
Functions referenced by the deleted workflow are not removed — they
remain available to other workflows or for direct reference.'
parameters:
- name: workflowName
in: path
required: true
schema:
type: string
responses:
'204':
description: 'There is no content to send for this request, but the headers may be useful. '
tags:
- Workflows
get:
operationId: v3-get-workflow
summary: Get a Workflow
description: '**Retrieve a workflow''s current version by name.**
Returns the full workflow record: `currentVersionNum`, `mainNodeName`,
the `nodes` array (with each node''s function reference and pinned
`versionNum` if any), and the `edges` array. To inspect a historical
version, use `GET /v3/workflows/{workflowName}/versions/{versionNum}`.'
parameters:
- name: workflowName
in: path
required: true
schema:
type: string
responses:
'200':
description: The request has succeeded.
content:
application/json:
schema:
$ref: '#/components/schemas/WorkflowV3GetResponse'
tags:
- Workflows
patch:
operationId: v3-update-workflow
summary: Update a Workflow
description: '**Update a workflow. Updates create a new version.**
The previous version remains addressable and immutable. Pending and
running calls captured at the old version continue against it; new
calls run against the new version.
## Topology updates
To change the graph you must provide `mainNodeName`, `nodes`, AND
`edges` together — partial topology updates are rejected. The full
graph is replaced atomically.
## Metadata-only updates
Omit all three fields to update only `displayName`, `tags`, or
`name` while keeping the topology of the current version.
## Reverting
To roll back, fetch the desired prior version and resubmit its
`mainNodeName`/`nodes`/`edges` as a new update. Versions themselves
are immutable — there is no "pin to version N" operation at the
workflow level (use `nodes[].function.versionNum` to pin individual
functions).'
parameters:
- name: workflowName
in: path
required: true
schema:
type: string
responses:
'200':
description: The request has succeeded.
content:
application/json:
schema:
$ref: '#/components/schemas/WorkflowV3UpdateResponse'
tags:
- Workflows
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WorkflowUpdateRequestV3'
/v3/workflows/{workflowName}/call:
post:
operationId: v3-call-workflow
parameters:
- name: workflowName
in: path
required: true
description: The name of the workflow to invoke.
schema:
type: string
- name: wait
in: query
required: false
description: 'Block until the call completes (up to 30 seconds) and return the finished
call object. Default: `false`. This is a boolean flag — use `--wait` or
`--wait=true`, not `--wait true`.'
schema:
type: boolean
explode: false
description: "**Invoke a workflow.**\n\nSubmit the input file as either a multipart form request or a JSON request with\nbase64-encoded file content. The workflow name is derived from the URL path.\n\n## Input Formats\n\n- **Multipart form** (`multipart/form-data`): attach the file directly via the `file`\nor `files` fields. Set `wait` in the form body to control synchronous behaviour.\n- **JSON** (`application/json`): base64-encode the file content and set it in\n`input.singleFile.inputContent` or `input.batchFiles.inputs[*].inputContent`.\nPass `wait=true` as a query parameter to control synchronous behaviour.\n\n## Synchronous vs Asynchronous\n\nBy default the call is created asynchronously and this endpoint returns `202 Accepted`\nimmediately with a `pending` call object. Set `wait` to `true` to block until\nthe call completes (up to 30 seconds):\n\n- On success: returns `200 OK` with the completed call, `outputs` populated\n- On failure: returns `500 Internal Server Error` with the call and an `error` message\n- On timeout: returns `202 Accepted` with the still-running call\n\n## Tracking\n\nPoll `GET /v3/calls/{callID}` to check status, or configure a webhook subscription\nto receive events when the call finishes.\n\n## CLI Usage\n\nUse `@path/to/file` inside JSON string values to embed file contents automatically.\nBinary files (PDF, images, audio) are base64-encoded; text files are embedded as strings.\n\nSingle file (synchronous):\n```bash\nbem workflows call \\\n --workflow-name my-workflow \\\n --input.single-file '{\"inputContent\": \"@invoice.pdf\", \"inputType\": \"pdf\"}' \\\n --wait\n```\n\nSingle file (asynchronous, returns callID immediately):\n```bash\nbem workflows call \\\n --workflow-name my-workflow \\\n --input.single-file '{\"inputContent\": \"@invoice.pdf\", \"inputType\": \"pdf\"}'\n```\n\nBatch files:\n```bash\nbem workflows call \\\n --workflow-name my-workflow \\\n --input.batch-files '{\"inputs\": [{\"inputContent\": \"@a.pdf\", \"inputType\": \"pdf\"}, {\"inputContent\": \"@b.png\", \"inputType\": \"png\"}]}'\n```\n\nAlternative: pass the full `--input` flag as JSON:\n```bash\nbem workflows call \\\n --workflow-name my-workflow \\\n --input '{\"singleFile\": {\"inputContent\": \"@invoice.pdf\", \"inputType\": \"pdf\"}}' \\\n --wait\n```\n\n**Important:** `--wait` is a boolean flag. Use `--wait` or `--wait=true`.\nDo **not** use `--wait true` (with a space) — the `true` will be parsed as an\nunexpected positional argument.\n\nSupported `inputType` values: csv, docx, email, heic, heif, html, jpeg, json,\nm4a, mp3, pdf, png, text, wav, webp, xls, xlsx, xml."
summary: Call a Workflow Call a Workflow
responses:
'200':
description: The request has succeeded.
content:
application/json:
schema:
$ref: '#/components/schemas/CallGetResponseV3'
tags:
- Workflows
requestBody:
required: true
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/WorkflowCallMultipartFormData'
encoding:
file:
contentType: '*/*'
files:
contentType: '*/*'
application/json:
schema:
$ref: '#/components/schemas/WorkflowCallJsonBody'
/v3/workflows/{workflowName}/versions:
get:
operationId: v3-list-workflow-versions
summary: List Workflow Versions
description: '**List every version of a workflow.**
Versions are immutable. Each row captures what the workflow looked
like between updates: graph topology, metadata, and timestamps.
Returns newest-first by default. Cursor pagination via
`startingAfter` / `endingBefore` over `versionNum`.'
parameters:
- name: workflowName
in: path
required: true
schema:
type: string
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 50
- name: sortOrder
in: query
required: false
schema:
type: string
enum:
- asc
- desc
default: asc
- name: startingAfter
in: query
required: false
schema:
type: integer
- name: endingBefore
in: query
required: false
schema:
type: integer
responses:
'200':
description: The request has succeeded.
content:
application/json:
schema:
$ref: '#/components/schemas/ListWorkflowVersionsResponseV3'
tags:
- Workflows
/v3/workflows/{workflowName}/versions/{versionNum}:
get:
operationId: v3-get-workflow-version
summary: Get a Workflow Version
description: '**Retrieve a specific historical version of a workflow.**
Versions are immutable. Use this endpoint to see what a workflow
looked like at the moment a particular call was made — every call
record carries the workflow `versionNum` it ran against.'
parameters:
- name: workflowName
in: path
required: true
schema:
type: string
- name: versionNum
in: path
required: true
schema:
type: integer
responses:
'200':
description: The request has succeeded.
content:
application/json:
schema:
$ref: '#/components/schemas/GetWorkflowVersionResponseV3'
tags:
- Workflows
components:
schemas:
WorkflowV3CreateResponse:
type: object
properties:
workflow:
$ref: '#/components/schemas/WorkflowV3'
error:
type: string
description: Error message if the workflow creation failed.
connectorErrors:
type: array
items:
$ref: '#/components/schemas/WorkflowConnectorError'
description: 'Per-connector failures from the diff/apply phase. Empty or omitted when all
operations succeeded.'
FunctionCallCreateInput:
type: object
properties:
singleFile:
allOf:
- $ref: '#/components/schemas/FileInput'
description: 'A single file to process. Use `--input.single-file ''{"inputContent": "@file.pdf", "inputType": "pdf"}''` in the CLI.'
batchFiles:
allOf:
- $ref: '#/components/schemas/BatchFilesInput'
description: Multiple files to process in one call. Each item in the `inputs` array has its own `inputContent` and `inputType`.
description: 'Input file(s) for a call. Provide exactly one of `singleFile` or `batchFiles`.
In the CLI, use the nested flags `--input.single-file` or `--input.batch-files`
with `@path/to/file` for automatic file embedding:
`--input.single-file ''{"inputContent": "@invoice.pdf", "inputType": "pdf"}'' --wait`'
FunctionCallCreateInputResponse:
type: object
properties:
singleFile:
$ref: '#/components/schemas/SingleFileInputResponse'
batchFiles:
$ref: '#/components/schemas/BatchFilesInputResponse'
PayloadShapingEvent:
type: object
required:
- eventID
- referenceID
- functionID
- functionName
- transformedContent
properties:
functionCallTryNumber:
type: integer
description: The attempt number of the function call that created this event. 1 indexed.
eventID:
type: string
description: Unique ID generated by bem to identify the event.
createdAt:
type: string
format: date-time
description: Timestamp indicating when the event was created.
referenceID:
type: string
description: The unique ID you use internally to refer to this data point, propagated from the original function input.
inboundEmail:
allOf:
- $ref: '#/components/schemas/EventInboundEmail'
description: The inbound email that triggered this event.
metadata:
type: object
properties:
durationFunctionToEventSeconds:
type: number
eventType:
type: string
enum:
- payload_shaping
functionCallID:
type: string
description: Unique identifier of function call that this event is associated with.
functionID:
type: string
description: Unique identifier of function that this event is associated with.
functionName:
type: string
description: Unique name of function that this event is associated with.
functionVersionNum:
type: integer
description: Version number of function that this event is associated with.
callID:
type: string
description: Unique identifier of workflow call that this event is associated with.
workflowID:
type: string
description: Unique identifier of workflow that this event is associated with.
workflowName:
type: string
description: Name of workflow that this event is associated with.
workflowVersionNum:
type: integer
description: Version number of workflow that this event is associated with.
transformedContent:
type: object
unevaluatedProperties: {}
description: 'The reshaped payload produced by applying the function''s JMESPath
expressions to the input data.'
description: 'Emitted by `payload_shaping` functions, which restructure JSON payloads
using JMESPath expressions configured on the function. The shaped result
is carried in `transformedContent`.'
title: Payload Shaping Event
SendEvent:
type: object
required:
- eventID
- referenceID
- functionID
- functionName
- deliveryStatus
- destinationType
properties:
functionCallTryNumber:
type: integer
description: The attempt number of the function call that created this event. 1 indexed.
eventID:
type: string
description: Unique ID generated by bem to identify the event.
createdAt:
type: string
format: date-time
description: Timestamp indicating when the event was created.
referenceID:
type: string
description: The unique ID you use internally to refer to this data point, propagated from the original function input.
inboundEmail:
allOf:
- $ref: '#/components/schemas/EventInboundEmail'
description: The inbound email that triggered this event.
metadata:
type: object
properties:
durationFunctionToEventSeconds:
type: number
eventType:
type: string
enum:
- send
functionCallID:
type: string
description: Unique identifier of function call that this event is associated with.
functionID:
type: string
description: Unique identifier of function that this event is associated with.
functionName:
type: string
description: Unique name of function that this event is associated with.
functionVersionNum:
type: integer
description: Version number of function that this event is associated with.
callID:
type: string
description: Unique identifier of workflow call that this event is associated with.
workflowID:
type: string
description: Unique identifier of workflow that this event is associated with.
workflowName:
type: string
description: Name of workflow that this event is associated with.
workflowVersionNum:
type: integer
description: Version number of workflow that this event is associated with.
deliveryStatus:
allOf:
- $ref: '#/components/schemas/SendDeliveryStatus'
description: Whether the payload was successfully delivered or the send node was skipped.
destinationType:
allOf:
- $ref: '#/components/schemas/SendDestinationType'
description: The type of destination the payload was sent to.
deliveredContent:
type: object
unevaluatedProperties: {}
description: 'The full protocol event JSON that was delivered — identical to what subscription
publish would deliver for the same event. For ad-hoc calls with a JSON file input,
contains the raw input JSON. For ad-hoc calls with a binary file input, contains
{"s3URL": "<presigned-url>"}.'
webhookOutput:
allOf:
- $ref: '#/components/schemas/SendEventWebhookOutput'
description: Populated when destinationType is "webhook".
s3Output:
allOf:
- $ref: '#/components/schemas/SendEventS3Output'
description: Populated when destinationType is "s3".
googleDriveOutput:
allOf:
- $ref: '#/components/schemas/SendEventGoogleDriveOutput'
description: Populated when destinationType is "google_drive".
title: Send Event
AnyType:
anyOf:
- type: object
unevaluatedProperties: {}
- type: array
items: {}
- type: string
- type: number
- type: integer
- type: boolean
- type: 'null'
AnalyzeEvent:
type: object
required:
- eventID
- referenceID
- functionID
- functionName
- transformedContent
- invalidProperties
properties:
functionCallTryNumber:
type: integer
description: The attempt number of the function call that created this event. 1 indexed.
eventID:
type: string
description: Unique ID generated by bem to identify the event.
createdAt:
type: string
format: date-time
description: Timestamp indicating when the event was created.
referenceID:
type: string
description: The unique ID you use internally to refer to this data point, propagated from the original function input.
inboundEmail:
allOf:
- $ref: '#/components/schemas/EventInboundEmail'
description: The inbound email that triggered this event.
metadata:
type: object
properties:
durationFunctionToEventSeconds:
type: number
eventType:
type: string
enum:
- analyze
functionCallID:
type: string
description: Unique identifier of function call that this event is associated with.
functionID:
type: string
description: Unique identifier of function that this event is associated with.
functionName:
type: string
description: Unique name of function that this event is associated with.
functionVersionNum:
type: integer
description: Version number of function that this event is associated with.
callID:
type: string
description: Unique identifier of workflow call that this event is associated with.
workflowID:
type: string
description: Unique identifier of workflow that this event is associated with.
workflowName:
type: string
description: Name of workflow that this event is associated with.
workflowVersionNum:
type: integer
description: Version number of workflow that this event is associated with.
transformationID:
anyOf:
- type: string
- type: 'null'
description: Unique ID for each transformation output generated by bem following Segment's KSUID conventions.
transformedContent:
type: object
unevaluatedProperties: {}
description: The extracted content of the input. The structure of this object is defined by the function's `outputSchema`.
invalidProperties:
type: array
items:
type: string
description: List of properties that were invalid in the input.
s3URL:
anyOf:
- type: string
- type: 'null'
description: Presigned S3 URL of the input file that was analyzed.
fieldBoundingBoxes:
type: object
unevaluatedProperties: {}
description: 'Per-field bounding boxes. A JSON object mapping RFC 6901 JSON Pointer paths (e.g. `"/invoiceNumber"`,
`"/items/0/price"`) to the document regions from which each extracted value was sourced.'
fieldConfidences:
type: object
unevaluatedProperties:
type: number
format: float
description: 'Per-field confidence scores. A JSON object mapping RFC 6901 JSON Pointer paths
to float values in the range [0, 1] indicating the model''s confidence in each extracted field value.'
avgConfidence:
anyOf:
- type: number
format: float
- type: 'null'
description: Average confidence score across all extracted fields, in the range [0, 1].
description: 'Emitted by functions of the legacy `analyze` type (the vision path predecessor of
`extract`). Carries the extracted JSON along with per-field bounding-box metadata
identifying the document regions each value was extracted from.'
title: Analyze Event
SplitItemEvent:
type: object
required:
- eventID
- referenceID
- functionID
- functionName
- outputType
properties:
functionCallTryNumber:
type: integer
description: The attempt number of the function call that created this event. 1 indexed.
eventID:
type: string
description: Unique ID generated by bem to identify the event.
createdAt:
type: string
format: date-time
description: Timestamp indicating when the event was created.
referenceID:
type: string
description: The unique ID you use internally to refer to this data point, propagated from the original function input.
inboundEmail:
allOf:
- $ref: '#/components/schemas/EventInboundEmail'
description: The inbound email that triggered this event.
metadata:
type: object
properties:
durationFunctionToEventSeconds:
type: number
eventType:
type: string
enum:
- split_item
functionCallID:
type: string
description: Unique identifier of function call that this event is associated with.
functionID:
type: string
description: Unique identifier of function that this event is associated with.
functionName:
type: string
description: Unique name of function that this event is associated with.
functionVersionNum:
type: integer
description: Version number of function that this event is associated with.
callID:
type: string
description: Unique identifier of workflow call that this event is associated with.
workflowID:
type: string
description: Unique identifier of workflow that this event is associated with.
workflowName:
type: string
description: Name of workflow that this event is associated with.
workflowVersionNum:
type: integer
description: Version number of workflow that this event is associated with.
outputType:
type: string
enum:
- print_page
- semantic_page
printPageOutput:
type: object
properties:
collectionReferenceID:
type: string
itemCount:
type: integer
itemOffset:
type: integer
# --- truncated at 32 KB (108 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/bem/refs/heads/main/openapi/bem-workflows-api-openapi.yml