API Node & AI Node Behavior
API Node
When the workflow reaches an API node, the system automatically sends a request to the URL you configured — no human action required.
What's in the POST Request Body
In addition to the form fields you specify via bodyMapping, the system always appends the following fields:
| Field | Description |
|---|---|
submittedAt | When the workflow was created |
initiatorId | User ID of the person who submitted the request |
initiatorName | Display name of the submitter |
apiRequestAt | Timestamp of this API call |
subject | Subject of the workflow instance |
responseSchema | A schema hint for external AI services describing the expected response format (see below) |
With bodyMapping: The body includes the system fields above, plus only the form fields listed in bodyMapping.
Without bodyMapping: The body includes the system fields above, plus all form data.
See the exact payload that will be sent
Open the workflow detail page, go to the Flowchart tab and click View Payload on an API node. It shows the complete example request that node will send (URL, body, and the expected response), ready to copy and hand to whoever builds the integration.
How the External Service Should Respond
The system expects the external service to return the following JSON format to decide whether to continue (approve) or reject the workflow:
{
"action": "approve",
"comment": "Processed successfully. Data has been written to the system."
}If action is reject, the workflow is sent back to the previous node and your comment is shown as the reason.
The decision order is as follows — the status code takes precedence over action:
| Situation | Result | Message shown to the user |
|---|---|---|
| Unreachable (wrong URL, service down) | Reject | API call error: connect ECONNREFUSED ... |
| Non-2xx | Reject | API call failed (500) |
2xx with an action that is neither approve nor reject | Reject | Unknown action: "denied" |
2xx with action: "reject" | Reject | your comment |
2xx but responseMapping doesn't match | Reject | API response mapping failed: ... |
| 2xx but this node's required fields are still empty | Reject | Required fields not filled: [...] |
2xx with action: "approve" or no action field | Continue | your comment |
action is matched case-insensitively and trimmed, so "REJECT" and "reject" are equivalent.
That last row is what makes plain REST APIs work: a service that knows nothing about this protocol and simply returns 200 OK is treated as a success, whether its body is plain text or empty. No changes on their side are needed.
action does not count on a non-2xx response
If the status code isn't 2xx, the call is treated as a failure even when the body contains {"action":"approve"}. Return 2xx to let the workflow continue.
A misspelled action is rejected
Values the system cannot interpret — {"action":"rejct"}, {"action":"denied"} — are always treated as a failure and never as an approval. If you don't want to use the action mechanism, omit the field entirely rather than sending a custom value.
What is responseSchema?
responseSchema is automatically appended to the request body to inform an external AI service of the expected JSON response format. If you're integrating with a standard REST API (not an AI), you can safely ignore this field.
If the node has assignedFormFieldIds configured, responseSchema will also include the label, type, and required status of those fields, so the external AI knows which form fields it can fill in. Only fields listed in assignedFormFieldIds will be written back — any other fields returned by the external service are ignored.
Diagnosing a Failed Call
Every API call is recorded in the instance's Progress panel. On failure the message from the table above is shown in red, with the duration and a View response link below it — open it for the full body the external service returned, along with its Content-Type.
When the service is unreachable, the message carries a failure code that tells you which end the problem is on:
ENOTFOUND— the domain could not be resolved, usually a typo in the URLECONNREFUSED— the address is right, but nothing is listening- certificate errors — the service's HTTPS certificate is not valid
All of these mean the request never arrived, rather than the service rejecting your data.
If the service did respond with a non-2xx status, whatever explanation it returned is still kept in full under View response.
WARNING
Records created before 2026-08-17 do not carry this data and show only the original text message.
Writing Back Fields with responseMapping
If responseMapping is configured, the system extracts values from the API response and writes them back to the specified form fields. If the response is missing any configured key, the workflow is rejected — regardless of whether that field is required.
However, responseMapping is not checked when the external service explicitly returns action: "reject" — you have no data to return when rejecting, so the system uses your comment as the rejection reason instead.
AI Node
When the workflow reaches an AI node, the system's built-in AI automatically reads all form data and makes a decision based on the node's instruction.
What the AI Receives
- The node's
instruction(your review criteria) - All current form fields and their values
- The actual content of attachments (images, PDFs, plain text files)
What the AI Does
The AI decides to approve or reject based on the instruction, and returns a review comment.
If the node has assignedFormFieldIds configured, the AI will attempt to fill in values for those fields (e.g., auto-fill a category label or urgency level).
How to write a good instruction
instruction is read by anyone — or any AI — handling this node. It is always included in the POST request body (even if empty). Clear criteria work better than vague descriptions. For example:
- ✅ "If the expense exceeds $50,000 and fewer than three quotes are attached, reject and explain why."
- ❌ "Please review this expense request."