Provider API Contract
This page documents the complete HTTP API specification that a custom node provider must implement.
Required Endpoints
GET /manifest
Returns the list of available nodes in the provider.
Response:
{
"nodes": [
{
"type": "my-custom-node",
"name": "My Custom Node",
"category": "Custom Nodes",
"timeoutMs": 600000,
"inputSchema": {
"field1": {
"type": "string",
"required": true,
"description": "Field description"
},
"field2": {
"type": "number",
"default": 10,
"description": "Optional numeric field"
}
},
"outputSchema": {
"resultado": { "type": "string" },
"timestamp": { "type": "string" }
}
}
]
}
In the example above,
timeoutMs: 600000sets a 10-minute timeout for this node. If omitted, the default is 30 minutes.
Node Fields
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Unique node identifier |
name | string | Yes | Name displayed in the palette |
category | string | No | Category in the palette (default: "Custom Nodes") |
inputSchema | object | No | Schema for input fields |
outputSchema | object | No | Schema for output data |
timeoutMs | number | No | Execution timeout in milliseconds (default: 18000000 = 30 minutes) |
Input Schema
Each field in inputSchema can have:
| Property | Type | Description |
|---|---|---|
type | string | Type: string, number, boolean, object, array, any |
required | boolean | Whether the field is required |
default | any | Default value |
description | string | Description displayed as a tooltip |
enum | string[] | List of allowed values (renders as a dropdown) |
items | object | Item schema (for type: array) |
Output Schema
The outputSchema defines the data the node produces after execution. Each field has:
| Property | Type | Description |
|---|---|---|
type | string | Data type |
Outputs are accessible via expressions: {{ steps.myNode.outputs.result }}
For files, you can declare type: "fileRef" in outputSchema to improve autocomplete and visualization. This is optional: files sent in artifacts with type: "file" are also saved and exposed as fileRef when the execution runs.
POST /execute
Executes a node with the provided data.
Request:
{
"nodeType": "my-custom-node",
"inputs": {
"field1": "field value",
"field2": 42
},
"runId": "run_abc123",
"nodeId": "node_xyz789"
}
| Field | Type | Description |
|---|---|---|
nodeType | string | Type of node to execute |
inputs | object | Input field values |
runId | string | Current execution ID |
nodeId | string | Node ID in the flow |
Response (Success):
{
"status": "success",
"logs": [
"Processing field1: field value",
"Result calculated successfully"
],
"outputs": {
"result": "processed data",
"timestamp": "2024-01-15T10:30:00Z"
},
"artifacts": []
}
Response (Failure):
{
"status": "failed",
"logs": [
"Processing field1: field value",
"ERROR: Invalid field"
],
"outputs": {},
"error": {
"message": "Detailed error description"
},
"artifacts": []
}
Response Fields
| Field | Type | Required | Description |
|---|---|---|---|
status | string | Yes | "success" or "failed" |
logs | string[] | No | Log messages (displayed in the details view) |
outputs | object | No | Data produced by the node |
error | object | No | Error details (when failed) |
error.message | string | — | Human-readable error message |
artifacts | array | No | Generated files (screenshots, etc.) |
Artifacts
The artifacts field allows the node to return generated files during execution. QANode accepts two artifact types:
| Type | Use |
|---|---|
screenshot | Visual execution evidence |
file | Files that can be used by other nodes |
Each artifact can be sent as inline base64:
{
"artifacts": [
{
"type": "screenshot",
"name": "resultado.png",
"base64": "iVBORw0KGgoAAAANSUhEUg..."
},
{
"type": "file",
"name": "report.pdf",
"mimeType": "application/pdf",
"key": "report",
"base64": "JVBERi0xLjQKJeLj..."
}
]
}
| Field | Type | Description |
|---|---|---|
type | string | Type: screenshot or file |
name | string | File name |
base64 | string | Base64-encoded content |
mimeType | string | Optional. If missing, QANode tries to infer it from the content and file name |
key / outputKey | string | Optional. Output name created for file artifacts |
Artifacts are automatically saved to QANode's storage and are available in the execution results.
Files as fileRef
When a file artifact has base64, QANode saves the content and creates a fileRef in the outputs.
If the artifact includes key or outputKey:
{
"outputs": {
"report": {
"source": "runArtifact",
"path": "runs/run_abc123/files/report.pdf",
"name": "report.pdf",
"mimeType": "application/pdf",
"sizeBytes": 18452
}
}
}
If there is only one file and no key was provided, QANode uses outputs.fileRef.
{
"outputs": {
"fileRef": {
"source": "runArtifact",
"path": "runs/run_abc123/files/report.pdf",
"name": "report.pdf",
"mimeType": "application/pdf",
"sizeBytes": 18452
}
}
}
If several files have no key, they are grouped in outputs.files.
For files the user should pass to another node, prefer setting
key/outputKeyon the artifact. This makes the variables panel clearer.
Optional Endpoint
GET /health
Checks whether the provider is running. Used during the connection test.
Response:
{
"ok": true,
"nodeCount": 5
}
Authentication
If the provider requires authentication, configure the Token when registering the provider in QANode. The token will be sent as the Authorization: Bearer {token} header on all requests.
Required Field Validation
QANode validates fields marked as required: true in the inputSchema before calling /execute. If a required field is empty, the execution fails without calling the provider.
Timeouts
| Endpoint | Timeout |
|---|---|
GET /manifest | 5 seconds |
POST /execute | 30 minutes (default) — configurable via timeoutMs in the manifest |
The /execute timeout can be customized per node through the timeoutMs field in the manifest. This is useful for nodes that perform long-running operations such as data processing, scraping, or integration with external systems.
{
"nodes": [
{
"type": "processar-lote",
"name": "Processar Lote",
"timeoutMs": 1800000,
"inputSchema": { ... }
}
]
}
In the example above, the node will have a 30-minute timeout (1,800,000ms). If timeoutMs is not defined, the default is 30 minutes (300,000ms).
If the provider does not respond within the timeout, the request is aborted and the node is marked as failed.
Global Flow Timeout
Regardless of each node's individual timeout, QANode enforces a global 24-hour timeout per flow execution. If a flow (or suite) exceeds 24 hours of total execution time, it will be automatically stopped and marked as failed.
Headers Sent by QANode
Content-Type: application/json
Authorization: Bearer {token} (if configured)
Best Practices
- Unique type names: Use prefixes to avoid conflicts (e.g.,
my-company-validator) - Descriptive logs: Include logs that help diagnose issues
- Error handling: Always return
status: "failed"with a clearerror.message - Typed inputs: Define a complete
inputSchemaso QANode generates appropriate forms - Output Schema: Define
outputSchemaso QANode shows available fields in autocomplete - Idempotency: If possible, implement
/executein an idempotent manner - Timeout: Use
timeoutMsin the manifest for nodes that need more than 30 minutes. Also implement internal timeouts to prevent operations from hanging
