Skip to main content

Documentation Index

Fetch the complete documentation index at: https://platform.docs.zenoo.com/llms.txt

Use this file to discover all available pages before exploring further.

Hub Client API

A Hub client facilitates an interaction between the Hub and an end user. For a Hub client, a customer journey is a series of pages a.k.a. routes. It renders pages (UI), gathers user input and submits data back to the Hub via a REST API. A Hub client uses the Hub Client API for the following:
  • start a new execution for a given target,
  • start a new execution using a sharable token,
  • submit user input and resume execution,
  • execute a route function,
  • query an execution state and current route,
  • upload files using File cache.

Typical API calls sequence

The workflow execution API sequence is as follows:
  1. start a new execution and get Execution Request resource,
  2. query the corresponding response and get the 1st Route resource to display,
  3. submit the 1st route and get Execution Request resource,
  4. query the corresponding response and get the 2nd Route resource or Validation Error resource or Error resource,
  5. submit the 2nd route, same as (3), until the execution is terminated.
In addition, the workflow execution API enables going back to the previous route and executing a function.

Start new execution

POST /api/gateway/execute/{targetName}

Creates a request to start a new target execution. Add HTTP X-API-KEY header with corresponding api key value for access to restricted targets.
Request:
  • targetName: a target name to specify target to start, format is name:revision or just name (in that case the latest revision is used).
  • payload: an execution input as JSON payload.
Response:
  • 201 Created, a success response has a request URI as a Location header and the body contains the newly created request as Execution Request resource
The corresponding response can be one of the following: An example of a successful response is below:
HTTP/1.1 201 Created
Content-Length: 645
Content-Type: application/json;charset=UTF-8
Location: /api/gateway/request/f3add886-36d3-49eb-8d2b-96862d63dbe4

{
    "uuid": "59bb233b-2d2b-41e7-ad13-f17c14513603",
    "requestURI": "/api/gateway/request/f3add886-36d3-49eb-8d2b-96862d63dbe4",
    "executionURI": "/api/gateway/execution/59bb233b-2d2b-41e7-ad13-f17c14513603"
    "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI2YzBlNjNhMi01MTE1LTRlM2YtOWNjOC1kOTdmYjcxNzFlODIiLCJzdWIiOiJleGVjdXRvciIsImlhdCI6MTU4MjcyNTI3MCwiZXhwIjoxNTgyNzU0MDcwfQ.2QDJai6f4f7fs85CctTN8K3vmL-XGMbFDq0_IF14GkM"
}

Execute exposed function

POST /api/gateway/execute/{componentName}/{functionName}

Creates a request to execute an exposed function. Add HTTP X-API-KEY header with corresponding API key value for access to restricted targets. It returns result of the function if it finishes before timeout. Default timeout is 10s, you can change it by adding HTTP X-SYNC-TIMEOUT header (value is in milliseconds, you can set it to 0 to make the call async).
Request:
  • componentName: a component name in which the function is defined, format is name:revision or just name (in that case the latest revision is used).
  • functionName: a name of the exposed function to execute.
  • payload: an input for function as JSON payload.
Response:

POST /api/gateway/execute/{componentName}/{functionName}/form-data

In addition using JSON as an input, it is possible to execute an exposed function with a form-data as an input with application/x-www-form-urlencoded content-type.

Sending Files as Base64 in Exposed Function Payloads

Exposed functions now support receiving files directly in the JSON payload as base64-encoded strings. The backend will automatically detect base64-encoded file content (such as images or documents), store the file, and replace the payload value with a file descriptor object. This enables seamless file uploads without requiring multipart/form-data.

How it works

  • In your JSON payload, include the file content as a base64-encoded string (for example, an image encoded as base64).
  • The backend will detect if a string is a valid base64-encoded file (minimum length, valid characters, and MIME type check).
  • The file will be stored and the payload value will be replaced with a file descriptor (uuid, fileName, mimeType, size).
  • The exposed function will receive the file descriptor in place of the original base64 string.

Example: Executing an Exposed Function with a Base64 File

POST /api/gateway/execute/my-component/my-function
Content-Type: application/json

{
  "profileImage": "iVBORw0KGgoAAAANSUhEUgAAAAUA..."  // base64-encoded image
}
Backend behavior:
  • The backend detects the base64 string, stores the file, and replaces the value with a file descriptor:
{
  "profileImage": {
    "uuid": "b1c2d3e4-5678-90ab-cdef-1234567890ab",
    "fileName": "profileImage.png",
    "mimeType": "image/png",
    "size": 12345
  }
}

Notes

  • This works for any field in the payload, including nested objects and arrays.
  • Only sufficiently long and valid base64 strings are treated as files; all other strings are left unchanged.
  • The file descriptor can be used in subsequent API calls (e.g., for download or further processing).
  • This feature is available for all exposed functions and route submissions.
See also: File cache API for details on downloading files by descriptor.

Submit route

POST /api/gateway/execution/{uuid}/submit

Creates a request to submit a route for a workflow execution with uuid.
Request:
  • uuid: a route uuid to submit, i.e. the current route uuid.
  • payload: user entered data and file descriptors as JSON payload.
An example request:
POST /api/gateway/execution/59bb233b-2d2b-41e7-ad13-f17c14513603/submit
Host: localhost:8080
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI1MTFiMDQ0MS1kNmQwLTRhOGEtODAwMy0yMmVmNTI3NDA4NDciLCJzdWIiOiJleGVjdXRvciIsImlhdCI6MTU1NzI0NjE4OSwiZXhwIjoxNTU3Mjc0OTg5fQ.2GVAuboArO8k1G48CY1ojFdypO9zm9u2ZubCE7Qa-Co

{
    "uuid": "3a0d231f-12b8-47b3-a495-b9418db294b3",
    "payload": {
        "firstname": "Joe",
        "lastname": "Bloke",
    }
}
Response:
  • 201 Created, a success response has a request URI as a Location header and the body contains the newly created request as Execution Request resource.
The corresponding response can be one of the following:

Go back to previous route

POST /api/gateway/execution/{uuid}/back

Creates a request to go back to the previous route for a workflow execution with uuid.
Request:
  • uuid: a route uuid to go back from, i.e. the current route uuid,
  • payload: user entered data and file descriptors as JSON payload.
An example request:
POST /api/gateway/executor/c973a8e7-eb24-4e55-980f-f2ea0fff680e/back HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI1MTFiMDQ0MS1kNmQwLTRhOGEtODAwMy0yMmVmNTI3NDA4NDciLCJzdWIiOiJleGVjdXRvciIsImlhdCI6MTU1NzI0NjE4OSwiZXhwIjoxNTU3Mjc0OTg5fQ.2GVAuboArO8k1G48CY1ojFdypO9zm9u2ZubCE7Qa-Co

{
    "uuid": "3a0d231f-12b8-47b3-a495-b9418db294b3",
    "payload": {
        "firstname": "Joe"
    }
}
Response:
  • 201 Created, a success response has a request URI as a Location header and the body contains the newly created request as Execution Request resource
The corresponding response can be one of the following:

Execute a route function

POST /api/gataway/execution/{uuid}/function

Creates a request to execute a route function.
Request:
  • name: a route function name
  • payload: input data as JSON payload.
Response:
  • 201 Created, a success response has a request URI as a Location header and the body contains the newly created request as Execution Request resource.
The corresponding response can be one of the following:

Get current route

GET /api/gateway/execution/{uuid}

Query an execution with uuid for the current route. It may take time before the current route is available due to ongoing execution.
Response:
  • 200 OK, a success response with Route resource as a body,
  • 404 Not Found, an executor with uuid not found,
  • 401 Unauthorized, invalid access token,
  • 500 Internal Server Error, execution error.
An example of a successful response:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI1MTFiMDQ0MS1kNmQwLTRhOGEtODAwMy0yMmVmNTI3NDA4NDciLCJzdWIiOiJleGVjdXRvciIsImlhdCI6MTU1NzI0NjE4OSwiZXhwIjoxNTU3Mjc0OTg5fQ.2GVAuboArO8k1G48CY1ojFdypO9zm9u2ZubCE7Qa-Co

{
  "uuid": "89828e1e-c834-42a2-86f1-893209f63ab5",
  "uri": "/product",
  "terminal": false,
  "backEnabled": false,
  "export": {"product1": "Product1", "product2": "Product2"},
  "payload": {"product": "product1"}
)

Get response to Execution Request

GET /api/gateway/request/{uuid}

Query for a response of an Execution request specified by uuid. It may take time before the response is available due to ongoing execution.
Response:

POST /api/gateway/sharable/{token}

Starts an execution corresponding to given sharable token. A sharable token specifies an Execution request, see for details Sharable DSL. Moreover, the POST request body is used as Execution request input. May take time before the response is available due to ongoing execution.
For comprehensive documentation on sharables including payload retrieval API, use cases, and integration patterns, see the Sharables Guide
Response:

Resources

Execution Request

A unique execution request is generated after each execution command submission (POST). The corresponding execution response is queried using the requestURI.
  • uuid: execution UUID,
  • requestURI: request URI,
  • executionURI: execution URI,
  • token: authentication token to query corresponding response and execution.

Route

Route resource represents a route to be rendered by a Hub client. It contains the following fields:
  • uuid: identifies a route for the purpose of resuming a workflow execution,
  • uri: identifies a route for a hub-client, used for client-side routing and rendering a corresponding route view,
  • terminal: marks a route as terminal, set if the corresponding execution terminated,
  • backEnabled: determines if it’s possible to go back to a previous route,
  • export: arbitrary data passed with a route, can be used for setting up a route view, e.g. a list of products,
  • payload: a prior route payload, used to pre-fill route view.
An example Route resource:
{
    "type": "route",
    "uuid": "89828e1e-c834-42a2-86f1-893209f63ab5",
    "uri": "/product",
    "terminal": false,
    "backEnabled": false,
    "export": {"product1": "Product1", "product2": "Product2"}
}

Result

Result resource represents an execution result, like a function execution result. An example Result resource:
{
    "result": "passed"
}

Validation Error

Validation Error resource contains a list of validation errors.
  • errors: a list of validation error
    • field: a field name
    • message: a validation error message
An example Validation Error resource:
{
    "type": "validation-errors",
    "errors": [
        {
            "field": "mobile",
            "message": "Required"
        }
    ]
}

Execution Error

Execution Error resource contains an error message. An example Execution Error resource:
{
    "type": "error",
    "message": "Resume UUID mismatch!"
}

Security

The execution API endpoints are secured using JWT tokens. A new token is generated for every Execution Request. The token is then used to query the corresponding response or current route. The token needs to be included as HTTP Authorization header. The expiration is set to 30 minutes and can be modified using jwt.expiration property.
Authorization: Bearer {token}

Track Frontend Analytics Events

POST /api/gateway/execution/{uuid}/analytics

Sends frontend analytics events to the Hub for tracking user interactions, performance metrics, and errors.
Request:
  • uuid: execution UUID (path parameter)
  • Authorization: JWT token (Bearer token from Execution Request)
  • payload: analytics event as JSON
Event Structure:
  • eventType: string identifying the event type (e.g., "page_load", "button_click", "js_error")
  • properties: arbitrary JSON object containing event-specific data
Note: The executionUuid and timestamp are automatically set by the server. The executionUuid is taken from the URL path parameter, and timestamp is set to the current server time when the event is received.
Example Request:
POST /api/gateway/execution/59bb233b-2d2b-41e7-ad13-f17c14513603/analytics
Host: localhost:8080
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...

{
  "eventType": "page_load",
  "properties": {
    "url": "/product",
    "loadTimeMs": 1234,
    "referrer": "/home"
  }
}
Example Event Types:
Page Load Event:
{
  "eventType": "page_load",
  "properties": {
    "url": "/product",
    "loadTimeMs": 1234,
    "referrer": "/home",
    "viewport": "desktop"
  }
}
Button Click Event:
{
  "eventType": "button_click",
  "properties": {
    "elementId": "submit-btn",
    "label": "Submit",
    "routeUri": "/product"
  }
}
JavaScript Error Event:
{
  "eventType": "js_error",
  "properties": {
    "message": "Cannot read property 'foo' of undefined",
    "stackTrace": "Error: ...\n  at ...",
    "url": "/product",
    "browserInfo": "Chrome/120.0"
  }
}
Response:
  • 202 Accepted: event successfully queued for processing
  • 400 Bad Request: invalid request
  • 401 Unauthorized: invalid or missing JWT token
  • 500 Internal Server Error: server error
Notes:
  • Events are fire-and-forget - the API returns immediately after validation
  • Events are partitioned by execution UUID in Kafka for ordering guarantees
  • The properties field is flexible - frontends can define any structure
  • New event types can be added by the frontend without backend changes
  • Events are used for analytics, monitoring, and debugging