# Native n8n workflows

Start with the [agent setup guide](https://opencalls.dev/connect/agent?client=n8n), then import the workflow and configure your Open Calls address and secure credential. Both exports are inactive and use `https://YOUR-OPEN-CALLS-HOST.example` until configured. Check account access before enabling a workflow or approving a call.

## Approved call and bounded result

Import `open-calls-call-to-result.workflow.json`. Create a Bearer Auth credential named **Open Calls** with `calls:read` and `calls:write`. Replace every HTTP-node origin with the trusted native installation. Keep TLS checks enabled and redirects disabled; never accept an origin from form input or notification content.

The trigger is manual, without a public form that can spend funds. In **Approved request**, enter the recipient, phone, objective, optional context, language, minutes, attempts and approved integer `maxChargeMicro`. Quote those details through `/api/v1/estimate` first. Obtain approval, persist that request and a unique `idempotencyKey`, then set Boolean `approved` to `true`. Default placeholders and unapproved requests cannot call. A production upstream trigger requires its own authenticated approval and durable request store.

The workflow validates approval and rechecks the quote. A changed maximum stops before creation. It posts the exact body/key, then reads every 20 seconds, at most 45 times. After uncertain creation, reuse the identical body/key. After timeout or restart, resume reads by the saved call ID. Errors, partial results and timeouts never automatically create a second call.

**Grounded result** includes evidence, unresolved items, objective completion, simulation status, event sequence and integer final charge. Pending charge stays null. This node makes no downstream write. Before attaching a sheet/CRM/message action, implement durable processing and destination idempotency. Apply call ID and monotonically increasing event sequence atomically so older observations cannot replace newer ones. A repeated result is not permission to repeat a side effect.

## Verify a notification and inspect the call

Import `open-calls-webhook-result.workflow.json`. This is a **read-only inspection template**, not a durable business-event processor. Its Bearer credential needs only `calls:read`. Configure `OPEN_CALLS_WEBHOOK_SECRET` in a protected self-hosted environment and allow built-in `crypto` with `NODE_FUNCTION_ALLOW_BUILTIN=crypto`. Confirm task runners expose that secret only to trusted workflows. Never print it or put it in node parameters. Environments that cannot supply it securely need a separately configured receiver.

Keep **Raw Body** enabled. The Code node uses `this.helpers.getBinaryDataBuffer(0, 'data')` for n8n binary storage. It rejects absent raw bytes, without a parsed-JSON fallback. It checks body size, singleton headers, canonical key/signature, five-minute clock window, HMAC, matching event ID, known type and valid call UUID. It discards event URLs and fetches only that ID at the configured origin. `webhook.test` requires no call read. Responses are empty; call content is never reflected to the sender.

Configure the receiver's production HTTPS URL on the owner's Developer webhooks page, send a test, then enable delivery after validation. The workflow responds after inspection, never immediately on arrival. Duplicates deliberately repeat only the read. It makes no workflow-static-data deduplication claim. Before adding a business side effect, replace this with transactional unique event storage and an outbox before HTTP 2xx. Handle duplicate/reordered delivery and uncertain acknowledgments; an n8n execution record is not that transaction.

Saved success/error/manual execution data is disabled. Wait state and active execution storage can still contain call content: restrict operators and retention, keeping credentials exclusively in the credential/environment store.

## Errors and acceptance

401: reconnect; 403: obtain scope; 409: reconcile key/version; 422: surface policy; 429: back off; 503: retain identity and reconcile. Never raise limits or change keys to bypass errors. Failed/canceled calls still have final receipts; do not automatically redial.

Accept the package in the actual client: import inactive, confirm origins/credentials, test signature rejection and a test notification, then run local controlled simulations. Check restart/resume, the 45-read bound, revoked credentials, binary storage and duplicates. Real calls need a controlled receiver and explicit budget.

Sources: [Webhook response and raw-body options](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook), [Respond to Webhook](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.respondtowebhook), [binary buffer access](https://github.com/n8n-io/skills/blob/main/skills/n8n-binary-and-data-official/references/BINARY_BASICS.md). These describe n8n capabilities, not completed Open Calls acceptance.

October 18, 2026: The supplied calling workflow accepts standard `ask` requests only. To request human joining through a separately approved API client, use the authenticated owner ID from `GET /api/v1/users/me` as `handoffUserId` in the quote and call, with recording off. The owner handles the actual invitation and private callback acceptance through their account link; this template does not accept invitations automatically. Callback and recipient prompts support English, Hebrew, Spanish, French, German, Portuguese, Arabic and Italian. People speak directly after accepting the verified callback. The eight-language translation beta covers all 56 ordered pairs of different languages when enabled. It calls the starter first, explains in their language and asks spoken permission without a code. After approval, it calls the recipient, explains in their language and introduces both people. Setup uses the interpreter’s voice. The whole session, including setup and ringing, lasts at most ten minutes; an explicitly shorter approved limit still applies. Use `translate` only when the feature is currently enabled and the recipient/owner language pair is configured. MCP clients must check `get_workspace.capabilities.translation`, with `preferred_language` for the recipient and `userLanguage` for the owner’s spoken language (also the report language). REST clients pass `language` and `userLanguage` and require a successful current estimate for the same parameters. A quote does not approve an invitation or establish that anyone connected.
