API documentation

Use your existing automation tool

Keep the n8n, Zapier or Make workflow you already run. Send the step that calls your API through your gateway, and your policy decides it before your API sees it.

Before you start

You change one thing in your workflow: the address the step calls.

A gateway in front of your API

Reserve your gateway and connect your API under Connections → Deployments. Your gateway lives at https://<your-label>.decionisedge.com and forwards to the one API origin you proved you control.

Your ingress key

Reveal the ingress key once in your workspace and keep it in your automation tool's credential store. Every request sends it as AgentSafe-Tenant-Key; your gateway strips it before forwarding.

A step that changes something

Point a POST, PUT, PATCH or DELETE at your gateway, such as a payout, a refund or a deploy. GET, HEAD and OPTIONS pass through and are never decided.

CapabilityStatusWhat it means for your workflow
Hosted gateway in shadow modePrivate betaYour step's request reaches your API as before, and what your policy would have decided is recorded in your workspace.
Hosted gateway enforcementPrivate betaOpened per workspace on a plan that may enforce. BLOCK and ESCALATE stop the request before it reaches your API.
Presence approvals for a held request on a hosted gatewayPlannedToday an ESCALATE on a hosted gateway is held and reported, and nobody can release it. Branch to a person and stop the step.

What your gateway answers

Branch on the agentsafe-execution header where your tool shows headers, and on state in the gateway's own JSON answer otherwise. A forwarded answer is your API's own body and status.

Verdict or stateStatusagentsafe-executionMeaningYour branch
ALLOWYour API's statusFORWARDEDYour policy allowed it and the request reached your API once. The answer is your API's, with agentsafe-decision: ALLOW and agentsafe-dossier-id added.Continue the workflow.
ALLOWYour API's 4xxFAILEDAllowed and sent, and your API refused it. Nothing was done.Handle it as your API's own error.
BLOCK403NOT_FORWARDEDYour policy refused it. Nothing reached your API.Stop. Do not retry the same request.
ESCALATE202HELDA person must decide. The request is held until expires_at, two minutes by default, and nothing reached your API.Stop and notify a person with decision_id and dossier_id. Keep resume_token out of logs and messages.
AUTHORITY_UNAVAILABLE503NOT_FORWARDEDNo decision could be obtained, so nothing was forwarded. Retry-After is set.Retry after Retry-After with the same Idempotency-Key.
EXECUTION_INDETERMINATE502INDETERMINATEThe request was sent and no answer came back. Your API may have acted on it.Do not retry. Check your API for the result first.
ShadowYour API's statusPASSTHROUGHShadow mode: forwarded unchanged, with agentsafe-mode: SHADOW. The verdict is recorded in your workspace, not returned to your step.Continue. Review the recorded decisions before you enforce.
HTTP/1.1 403 Forbidden
agentsafe-state: BLOCK
agentsafe-execution: NOT_FORWARDED

{
  "version": "agent-safe.gateway/1",
  "state": "BLOCK",
  "verdict": "BLOCK",
  "reason_codes": ["<reason code>"],
  "execution": "NOT_FORWARDED",
  "intent_id": "<intent id>",
  "decision_id": "<decision id>",
  "dossier_id": "<dossier id>"
}
Send an Idempotency-Key

Use the trigger's own event or record ID. A retry after 503 AUTHORITY_UNAVAILABLE then carries the same key. Never retry an INDETERMINATE answer: your API may already have acted.

n8n

Point the HTTP Request node that calls your API at your gateway, keep the full response, and add a Switch on the agentsafe-execution header.

1. Change the URL

In the HTTP Request node that calls your API, replace your API's origin with your gateway URL. The path, method and body stay the same: https://<your-label>.decionisedge.com/payouts.

2. Add the ingress key

Use a Custom Auth credential that sends AgentSafe-Tenant-Key. In shadow mode it also sends your API's own Authorization header; remove that once your gateway enforces, because your gateway adds it.

3. Keep every answer

Under Options → Response, turn on Include Response Headers and Status and Never Error, so a 403 or 202 reaches the next node instead of failing this one.

4. Branch

Add a Switch on {{ $json.headers['agentsafe-execution'] }}. FORWARDED and PASSTHROUGH continue; anything else goes to a branch that stops.

HTTP Request node (paste into the n8n canvas)

{
  "nodes": [
    {
      "parameters": {
        "method": "POST",
        "url": "https://<your-label>.decionisedge.com/payouts",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpCustomAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Idempotency-Key",
              "value": "={{ $json.event_id }}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json.payout) }}",
        "options": {
          "response": {
            "response": {
              "fullResponse": true,
              "neverError": true
            }
          }
        }
      },
      "name": "Payout through your gateway",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        0,
        0
      ]
    }
  ],
  "connections": {}
}

Custom Auth credential (shadow mode)

{
  "headers": {
    "AgentSafe-Tenant-Key": "<AGENTSAFE_TENANT_KEY>",
    "Authorization": "<YOUR_API_CREDENTIAL>"
  }
}
WhenThen
FORWARDED or PASSTHROUGHContinue with {{ $json.body }}, your API's answer.
FAILEDYour API refused the request. Handle it as you do today.
NOT_FORWARDED with body.state BLOCKStop. Send body.decision_id and body.dossier_id to the person who owns the step.
HELD (body.state ESCALATE)Stop and notify a person. On a hosted gateway the hold cannot be released yet.
NOT_FORWARDED with body.state AUTHORITY_UNAVAILABLEWait for the Retry-After header, then run again with the same Idempotency-Key.
INDETERMINATEDo not retry. Check your API for the result.
Credential handling

Keep the ingress key in an n8n credential, never in the node, a sticky note or a workflow export that leaves your instance.

Zapier

Replace the action that calls your API with a Webhooks by Zapier Custom Request to your gateway, then add Paths on the gateway's State field.

1. Add a Custom Request

Add a Webhooks by Zapier action, event Custom Request, where your step called your API.

2. Point it at your gateway

Method POST, URL https://<your-label>.decionisedge.com/payouts, Data your mapped JSON body, and the headers below. Data Pass-Through stays off.

3. Branch with Paths

After the request, add Paths. Path A continues only when State does not exist; Path B runs when State exactly matches ESCALATE.

4. Let errors stop the Zap

Leave the step's error handling as it is: a 403 BLOCK or a 5xx answer fails the Custom Request, so the Zap stops before the next step runs.

Webhooks by Zapier · Custom Request

Method:   POST
URL:      https://<your-label>.decionisedge.com/payouts
Data:     {"amount": <mapped amount>, "currency": "<mapped currency>", "recipient": "<mapped recipient>"}
Headers:
  Content-Type        application/json
  AgentSafe-Tenant-Key <AGENTSAFE_TENANT_KEY>
  Idempotency-Key     <mapped trigger ID>
  Authorization       <YOUR_API_CREDENTIAL>   (shadow mode only; remove once your gateway enforces)
Unflatten: yes
Data Pass-Through: no

Paths

Path A · Continue    State (from the Custom Request)  Does not exist
Path B · Hold        State                             (Text) Exactly matches  ESCALATE
                     → notify a person with Decision Id and Dossier Id, then stop
WhenThen
State does not existYour API answered; continue the Zap.
State is ESCALATENotify a person with Decision Id and Dossier Id. The Zap ends on this path.
Step error: 403 BLOCKThe Zap stops. The refusal and its Decision Dossier are in your workspace.
Step error: 503 AUTHORITY_UNAVAILABLEReplay the Zap run later; the same trigger ID keeps the Idempotency-Key.
Step error: 502 INDETERMINATEDo not replay. Check your API for the result first.
Credential handling

Webhooks by Zapier keeps headers in the Zap itself, so anyone who can edit the Zap can read the ingress key. Limit who can edit it, and contact support to replace the key if someone who should not have it could read it.

Make

Point the HTTP module that calls your API at your gateway, keep non-2xx answers as output, and add a Router with filters on the gateway's state.

1. Change the URL

In the HTTP Make a request module that calls your API, set the URL to https://<your-label>.decionisedge.com/payouts. Method and body stay the same.

2. Add the ingress key

Store the ingress key as an API key credential with the header name AgentSafe-Tenant-Key. Keep your API's own credential where it is until your gateway enforces.

3. Keep every answer

Set Parse response to Yes and Evaluate all states as errors to No, so a 403 or a 202 reaches the Router.

4. Branch with a Router

Add a Router with one filter per route below. The fallback route stops the scenario.

HTTP · Make a request

URL:                          https://<your-label>.decionisedge.com/payouts
Method:                       POST
Authentication:               API key · header AgentSafe-Tenant-Key = <AGENTSAFE_TENANT_KEY>
Headers:                      Idempotency-Key = {{1.id}}
                              Authorization   = <YOUR_API_CREDENTIAL>   (shadow mode only)
Body content type:            application/json
Body:                         <your mapped JSON body>
Parse response:               Yes
Evaluate all states as errors: No

Router filters

Continue   data.state  Does not exist  AND  statusCode  Less than  400
Hold       data.state  Equal to        ESCALATE   → notify a person, then stop
Blocked    data.state  Equal to        BLOCK      → record decision_id, then stop
Retry      data.state  Equal to        AUTHORITY_UNAVAILABLE → Break, retry later
Fallback   anything else (including statusCode 502)  → stop and check your API
WhenThen
data.state does not exist and status below 400Your API answered; continue.
data.state is ESCALATENotify a person with data.decision_id, then stop.
data.state is BLOCKStop. Record data.decision_id and data.dossier_id.
data.state is AUTHORITY_UNAVAILABLEUse a Break error handler to retry later with the same Idempotency-Key.
Anything else, including 502Stop and check your API. An INDETERMINATE answer may have acted.
Credential handling

Keep the ingress key in Make's keychain as an API key credential, never in the URL, the body, scenario notes or a blueprint you share.

Write the guardrail

Your policy decides every request your gateway receives. Write it in Policy Writer, in plain English.

Write it in Policy Writer

Under Policies → Draft, open Write and describe the rule, such as: block payouts over 5,000 and send payouts to a new recipient to a person. The proposal joins your draft only when you add it, and becomes policy after review.

Name what it decides

Your gateway names each request by its method: http.post, http.put, http.patch or http.delete, with its path and JSON body. Write rules against those names and the fields in the body your step sends.

One policy per gateway

The Policy field under Deployments names the published policy your gateway uses, or leave it empty for your workspace's default. Every request through that gateway is decided by it.

Approvals

An ESCALATE means a person must decide. Your step receives 202 with execution HELD, and nothing reaches your API.

Today, on a hosted gateway

Branch an ESCALATE to a person with decision_id and dossier_id, and stop the step. The hold expires at expires_at; it cannot be released, because hosted gateways do not yet name a Presence approver.

Presence approvals · Planned

Presence is where the named approver confirms with a passkey. When a hosted gateway can name one, a held request runs once after a fresh ALLOW, and only then.

Shadow first

Every gateway starts in shadow mode. Run your workflow unchanged for a while, then decide whether to enforce.

1. Shadow

Your step's request reaches your API exactly as before, with agentsafe-mode: SHADOW. Keep your API's own credential in the step. Each request is decided and recorded in your workspace with its Decision Dossier.

2. Review

Read what your policy would have blocked or held. Adjust it in Policy Writer until the decisions match what you expect.

3. Enforce · Private beta

Switch your gateway to enforcement under Deployments, give it your API's credential, and remove that credential from your workflow. BLOCK and ESCALATE now stop the request.

Not available yet

What these recipes cannot do today. Plan your workflow around it.

One API per gateway, and it must be yours

A hosted gateway forwards to one HTTPS origin, and only after you prove control of it with /.well-known/agentsafe-upstream or a TXT record. To govern a call to a provider you do not control, call your own API, which then calls the provider.

Requests are named by method

A hosted gateway has no named routes yet. A governed request reaches your policy as http.post, http.put, http.patch or http.delete with its path and body, and one policy decides every request through the gateway.

No approval release on a hosted gateway

An ESCALATE is held until expires_at and then dropped. Resuming it answers 409 PRESENCE_NOT_CONFIGURED, because hosted gateways do not yet name a Presence approver.

No callback when a decision is made

The gateway answers the request that was sent and does not call your workflow back. Holds live in memory for at most five minutes.

No verdict in shadow mode

In shadow, your step receives your API's answer only. Read what your policy would have decided in your workspace, not in the workflow.

Calling Decionis directly instead of through a gateway? The Zapier, Make and n8n connectors evaluate a decision without forwarding anything. Decionis Auto, which runs these steps for you, is Planned.