QANode Logo

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: 600000 sets a 10-minute timeout for this node. If omitted, the default is 30 minutes.

Node Fields

FieldTypeRequiredDescription
typestringYesUnique node identifier
namestringYesName displayed in the palette
categorystringNoCategory in the palette (default: "Custom Nodes")
inputSchemaobjectNoSchema for input fields
outputSchemaobjectNoSchema for output data
timeoutMsnumberNoExecution timeout in milliseconds (default: 18000000 = 30 minutes)

Input Schema

Each field in inputSchema can have:

PropertyTypeDescription
typestringType: string, number, boolean, object, array, any
requiredbooleanWhether the field is required
defaultanyDefault value
descriptionstringDescription displayed as a tooltip
enumstring[]List of allowed values (renders as a dropdown)
itemsobjectItem schema (for type: array)

Output Schema

The outputSchema defines the data the node produces after execution. Each field has:

PropertyTypeDescription
typestringData 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"
}
FieldTypeDescription
nodeTypestringType of node to execute
inputsobjectInput field values
runIdstringCurrent execution ID
nodeIdstringNode 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

FieldTypeRequiredDescription
statusstringYes"success" or "failed"
logsstring[]NoLog messages (displayed in the details view)
outputsobjectNoData produced by the node
errorobjectNoError details (when failed)
error.messagestringHuman-readable error message
artifactsarrayNoGenerated files (screenshots, etc.)

Artifacts

The artifacts field allows the node to return generated files during execution. QANode accepts two artifact types:

TypeUse
screenshotVisual execution evidence
fileFiles 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..."
    }
  ]
}
FieldTypeDescription
typestringType: screenshot or file
namestringFile name
base64stringBase64-encoded content
mimeTypestringOptional. If missing, QANode tries to infer it from the content and file name
key / outputKeystringOptional. 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/outputKey on 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

EndpointTimeout
GET /manifest5 seconds
POST /execute30 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

  1. Unique type names: Use prefixes to avoid conflicts (e.g., my-company-validator)
  2. Descriptive logs: Include logs that help diagnose issues
  3. Error handling: Always return status: "failed" with a clear error.message
  4. Typed inputs: Define a complete inputSchema so QANode generates appropriate forms
  5. Output Schema: Define outputSchema so QANode shows available fields in autocomplete
  6. Idempotency: If possible, implement /execute in an idempotent manner
  7. Timeout: Use timeoutMs in the manifest for nodes that need more than 30 minutes. Also implement internal timeouts to prevent operations from hanging