n8n
Connect n8n to FinalSay using the community packagen8n-nodes-finalsay (in-repo: finalsay-n8n-nodes/), or using the HTTP Request node with the Agent API.
Community nodes (n8n-nodes-finalsay)
The package adds:
- FinalSay Create Approval —
POST /v1/approvals. Toggles at the bottom (defaults on): use execution id forrequest_idandcorrelation_id(manual fields hidden until toggles are off), and send callback with URL default{{ $execution.resumeUrl }}(Wait → Create → resume). Optional timeout override and callback headers (use headers for non-secret metadata; see Securing the Wait resume URL). - FinalSay Ask & Wait — Same create fields (without a separate callback URL): posts
POST /v1/approvalswithcallback.urlset to the execution resume URL, then pauses until FinalSay delivers the outcome to that URL. Use one item per run. Resume-webhook Authentication options mirror n8n’s Wait node (None / Header / Basic / JWT). Output merges the create response withfinal_result(callback JSON). The node is markedusableAsTool, so n8n also registers derived types for LangChain AI Agent wiring (see below). - FinalSay Get Approval Result —
GET /v1/approvals/:requestId/result(e.g. if you clear the callback URL and poll manually).
npm run build in finalsay-n8n-nodes, then npm link or copy into n8n’s custom nodes path), or from npm when published. See finalsay-n8n-nodes/README.md.
AI Agent tools and HitlTool
n8n auto-derives two extra node types from FinalSay Ask & Wait (same mechanism as built-in send-and-wait integrations such as Gmail):Registered type (package n8n-nodes-finalsay) | Role |
|---|---|
finalSayAskAndWaitTool | Sub-node with a Tool output: connect to the LangChain AI Agent’s ai_tool input so the model can create a FinalSay approval and wait on the resume webhook. |
finalSayAskAndWaitHitlTool | Human-in-the-loop gate between the agent and another tool: Agent → FinalSay HitlTool → downstream tool. Reviewers act in FinalSay; the Hitl UI adds a Message field (merged into approval context when set). |
N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true (n8n ≥ 1.79) so community packages are allowed as AI tools. Restart n8n after installing or upgrading the package.
Shape reference: finalsay-n8n-nodes/examples/ai-agent-finalsay-tool.example.json.
To create approvals only via MCP and handle Wait / resume URLs yourself in the workflow, use the FinalSay MCP adapter tools create_approval or request_human_approval with optional callback — see MCP.
You can still use HTTP Request for full control or unusual payloads.
Human gate before another MCP server
To run a human approval step in n8n before calling a different MCP server (not the FinalSay adapter), wire FinalSay Ask & Wait → (optional IF / Switch onfinal_result) → n8n’s built-in MCP Client Tool. The community package supplies the approval/wait nodes; it does not embed the MCP client—that stays a separate node on the canvas. Reference: finalsay-n8n-nodes/examples/human-gate-before-mcp.example.json and Human review before a different MCP tool in finalsay-n8n-nodes/README.md.
Prerequisites
- Credentials from the web dashboard or mobile app: Agent ID, workspace API key, and your deployment base URL.
- Familiarity with n8n HTTP Request nodes and, for callbacks, Webhook nodes.
Headers for every request
Add these to your HTTP Request node (or expression equivalent):| Header | Value |
|---|---|
X-Agent-Id | Your Agent ID |
X-Api-Key | Your workspace API key |
Content-Type | application/json for POST |
Create an approval
- Add an HTTP Request node.
- Method POST, URL:
{BASE_URL}/v1/approvals - Body: JSON matching Agent API: POST /v1/approvals (
question,context_markdown,options, and optionallytimeout,callback, orrequest_id). Omittimeoutto use the agent’s dashboard defaults.
request_id for polling (the API returns one whether you sent your own or the server generated it).
Get the result
Option A — Callback (recommended for long waits)
- In the create payload, set
callback.urlto a URL n8n exposes (e.g. Webhook node in “Test” or production URL). - Run your workflow; when a human resolves the approval, the service POSTs the final payload to your webhook.
- Parse the JSON in a following node.
Option B — Polling
- After creation, poll GET
{BASE_URL}/v1/approvals/{requestId}/resultwhere{requestId}is therequest_idfrom the create response (or the same value if you setrequest_idin the body yourself). - If the body is
{ "status": "pending" }, wait and repeat (use Wait node or a loop with delay). - When resolved, the response includes the full result object—see Agent API.
Securing the Wait resume URL
When you use Wait → On Webhook Call, n8n gives you{{ $execution.resumeUrl }}. Anyone who obtains that URL could resume the execution unless you protect the Wait node.
Recommended (Wait-compatible): agent-level callback auth
- In the FinalSay web dashboard, open the agent → Settings → Callback webhook authentication.
- Choose a header name (default
X-FinalSay-Callback) and click Generate secret (or Rotate secret). Copy the value once; it is not shown again. - In n8n, on the Wait node, set Authentication to Header Auth (or equivalent) and enter the same header name and value as in the dashboard.
- In FinalSay Create Approval, set Callback URL to
{{ $execution.resumeUrl }}as usual. You can leave Callback headers empty unless you need extra non-secret headers.
callback.headers on create, or MCP tool arguments—so it is not leaked in exports.
If the same header name appears in both Callback headers on the node and agent callback auth, the agent value wins.
Troubleshooting 403 on the resume URL
- Header never sent — Outbound callback auth exists only after you Generate secret in the agent Settings tab. If callback auth is not configured, FinalSay does not add the header; n8n Header Auth on Wait / FinalSay Ask & Wait still expects it → 403.
- Name or value mismatch — Use the same header name as in the dashboard (default
X-FinalSay-Callback) and paste the generated secret into the n8n Header Auth credential’s value. After Rotate secret, update the credential; the previous secret is invalid. - IP allowlist — On FinalSay Ask & Wait, Options → IP(s) Allowlist must either be empty or include the addresses FinalSay uses to call your URL; otherwise n8n returns 403 (IP is not allowed).
- Ignore bots — With Ignore bots enabled, unusual
User-Agentstrings may be rejected.
Tips
- You can omit
request_id; the API assigns a UUID. Add your own stablerequest_idwhen you need idempotent retries or to tie the approval to a workflow run id. - Respect rate limits on create; if you receive
429, slow down. - Idempotency: repeating the same client-supplied
request_idwith the same payload is safe; conflicting payloads return409.