Export a workflow definition
Returns the workflow as a portable definition: its name, its trigger, and every step with its options.
- Method
- GET
- Path
https://api.returning.ai / v1/ workflow-builder/ data-workflows/ {workflowId}/ export - Permission
- workflowBuilder
- Retries
- Safe to retry: nothing is written.
Authentication#
- Header
Authorization: Bearer <API_KEY>- Permission
- workflowBuilder
Authorization: Bearer <API_KEY> with workflowBuilder, for the community that owns the workflow. Redaction is not optional and has no parameter to turn it off, so an export can be read, kept and re-imported without the document ever holding a working credential.
| Failure | Meaning | Recovery |
|---|---|---|
401 AUTHENTICATION_REQUIRED | No key, or an unknown key | Send a valid key. |
403 API_KEY_PERMISSION_DENIED | No workflowBuilder | Grant the permission. |
404 WORKFLOW_NOT_FOUND | Unknown id, or another community's workflow | Use an id from this community. |
Behaviour#
The document has the same shape an import reads, so it can be posted back to POST / as {definition} to recreate the workflow, here or in another community.
Node credentials in the document are replaced by the redaction marker and listed in redactedPaths. A credential that an import blanked and nobody has filled in yet is written the same way, so an export always shows what is still missing. The trigger's own credentials are removed entirely rather than marked: a webhook trigger's key stays behind as apiKey: {enabled: true} with no value, and an AES key arrives as enabled with an empty key and IV. Import mints or re-collects those.
Request#
Path parameters#
_id.Rule^[0-9a-fA-F]{24}$
Eg65f1a2b3c4d5e6f708192a3b
Headers#
Bearer <API_KEY>.EgBearer <API_KEY>
Watch for
- Redaction covers HTTP auth values, credential-named headers, parameters and body keys, URL query parameters with a credential name, and node-level credentials. The trigger's key material is not exported at all. A secret an author typed inside a raw body template is returned as authored, so treat an export as sensitive even though the named credentials are replaced.
- An empty auth value is "no auth", not a redacted secret: a bearer token stored as
[]stays[]and is not listed inredactedPaths. - Importing this document blanks the redacted node credentials, reports them in
secretsToFill, andPOST /{workflowId}/validatereports each one as aMISSING_SECRETwarning until it is filled in. The warning does not stop a deploy, so fill them before going live. - The trigger's key does not travel, so an import mints a fresh webhook key for the new workflow. An AES key cannot be minted: it arrives enabled but blank, for the author to re-enter.
- The export has no run history, no identifiers from the source community's fields or leaderboards beyond the ids the steps already stored, and no deployment state.
More examples and details
A workflow with one HTTP step whose headers and bearer token are redacted:
{
"kind": "returningai.workflow",
"formatVersion": 1,
"variant": "data_workflows",
"exportedAt": "2026-10-24T11:02:00.000Z",
"workflow": { "name": "VIP bonus", "outgoingWebhookUrl": null },
"trigger": {
"name": "Trade bonus trigger",
"type": "webhook",
"options": { "tokenExchangeEnabled": false, "apiKey": { "enabled": true } }
},
"nodes": [
{
"ref": "node-0",
"name": "Notify receiver",
"type": "http",
"order": 1,
"continueOnFailure": false,
"retryOnFailure": false,
"options": {
"method": "POST",
"url": ["https://receiver.example.com/trade-bonus" ],
"params": {},
"headers": { "X-Api-Key": ["__REDACTED__"] },
"bodyType": "json",
"body": { "member": ["{{trigger.email}}"] },
"auth": { "type": "bearer-token", "token": ["__REDACTED__"] }
}
}
],
"redactedPaths": ["nodes[0].options.headers.X-Api-Key", "nodes[0].options.auth.token"]
}
curl --request GET \
--url 'https://api.returning.ai/v1/workflow-builder/data-workflows/<workflowId>/export' \
--header 'Authorization: Bearer <API_KEY>'
Response#
HTTP 200 with the document at the top level, not wrapped in data: it is a file format, and an import reads it verbatim. redactedPaths rides alongside the document.
kind is returningai.workflow, formatVersion is 1, and variant is data_workflows. All four are required by an import.
The document carries one id space: step references and {{...}} templates are rewritten to the document's own names, trigger for the trigger and each step's ref for the steps, so the same file can be imported into any community without editing a reference. Each reference is paired with the step it named rather than with a position, so a step inserted after the trigger or a step inside a router branch keeps its meaning. An import rewires them onto the ids it mints. Step order is authored order, and ref is the local name a template or reference can use.
To prove an export, import it and compare: create a workflow with {definition}, then read the new workflow back and match step types, order and options, ignoring identifiers.
Eg"returningai.workflow"
Eg1
data_workflows.Eg"data_workflows"
Eg"2026-10-24T11:02:00.000Z"
Eg{"name": "VIP bonus", "outgoingWebhookUrl": null}
RuleNullable
Eg{ ... }
{{...}} templates use the document's own names: trigger and each step's ref.Eg[ ... ]
Eg"node-0"
Eg[ ... ]
{
"kind": "returningai.workflow",
"formatVersion": 1,
"variant": "data_workflows",
"exportedAt": "2026-10-24T11:02:00.000Z",
"workflow": {
"name": "VIP bonus",
"outgoingWebhookUrl": null
},
"trigger": {
"name": "Trade bonus trigger",
"type": "webhook",
"options": {
"tokenExchangeEnabled": false,
"apiKey": {
"enabled": true
}
}
},
"nodes": [
{
"ref": "node-0",
"name": "Notify receiver",
"type": "http",
"order": 1,
"continueOnFailure": false,
"retryOnFailure": false,
"options": {
"method": "POST",
"url": ["https://receiver.example.com/trade-bonus" ],
"params": {},
"headers": {
"X-Api-Key": ["__REDACTED__"]
},
"bodyType": "json",
"body": {
"member": ["{{trigger.email}}"]
},
"auth": {
"type": "bearer-token",
"token": ["__REDACTED__"]
}
}
}
],
"redactedPaths": [
"nodes[0].options.headers.X-Api-Key",
"nodes[0].options.auth.token"
]
}
Errors#
Fix the request04
VALIDATION_FAILEDFix the requestAUTHENTICATION_REQUIREDFix the requestAPI_KEY_REQUIREDFix the requestAPI_KEY_PERMISSION_DENIEDFix the requestworkflowBuilder. Grant the permission.Fix the data01
WORKFLOW_NOT_FOUNDFix the dataRetry with backoff02
RATE_LIMITEDRetry with backoffINTERNAL_ERRORRetry with backoffRetries
Safe to retry: nothing is written. The document contains exportedAt, so two exports of an unchanged workflow differ in that field only.
{
"meta": {
"status": "error",
"statusCode": 400,
"code": "VALIDATION_FAILED",
"errors": [
{
"path": "params.workflowId",
"message": "Id must be a 24 character hex string"
}
],
"requestId": "3f4d0e8b-7a6c-4f1e-9b2d-5a7c8e1f0a3b"
},
"message": "API request rejected error.",
"detail": "The request body is not valid.",
"solution": "Read error detail and try again."
}