NORNRMandates, approvals and evidence for autonomous agents.
Guide / Make.com
12 minutesHow to add spend controls to Make.com AI agent automations
Gate paid AI steps in Make.com scenarios with a governed wallet, approval threshold and audit trail using NORNR — no custom server required.
1. Why Make.com scenarios need spend controls
Make.com scenarios run autonomously on schedules or webhooks. When a scenario includes an OpenAI, Anthropic or other paid AI module, it can fire dozens or hundreds of times before anyone notices the bill has grown unexpectedly. API rate limits imposed by the AI provider cap total throughput — they do not give you per-scenario budgets, per-run approval thresholds or a signed record of what was requested and why.
NORNR fills that gap. Because Make.com supports arbitrary HTTP requests, you can call the NORNR policy API directly from the scenario, get a decision before the expensive module runs, and branch on that decision with a Router. The scenario keeps its visual, no-code structure; the governance layer runs in the request immediately before the paid step.
2. How the pattern works in Make
Make does not run Python natively, so the agentpay SDK does not apply directly. Instead, you call the NORNR REST API using Make's built-in HTTP — Make a request module. The API accepts JSON and returns a status field you can route on immediately.
The scenario structure is:
- Trigger (webhook, schedule, or any event source)
- HTTP module 1 — Create or reference a wallet (once at scenario setup, or stored in a data store)
- HTTP module 2 — Call NORNR pay endpoint (before every paid AI call)
- Router — branches on
status - Route A (approved) — runs the paid AI module
- Route B (queued) — sends a Slack or email notification and stops the current run
- Route C (rejected) — logs the block and stops
3. Create the governed wallet
In Make, add an HTTP — Make a request module with the following configuration. You can run this once manually or at scenario initialisation; store the returned walletId in a Make Data Store for reuse.
URL: https://nornr.com/api/wallets
Method: POST
Headers: Content-Type: application/json
Authorization: Bearer {{your_nornr_api_key}}
Body (JSON):
{
"owner": "make-scenario-research-agent",
"daily_limit": 40,
"require_approval_above": 15,
"allowed_counterparties": ["openai", "anthropic"]
}
The response includes a walletId. Store this in a Make Data Store key named nornr_wallet_id so subsequent runs can reference it without recreating the wallet.
4. Call the pay endpoint before the paid AI module
Add a second HTTP — Make a request module immediately before your OpenAI or other paid module. Set the body to declare what the scenario is about to spend and why.
URL: https://nornr.com/api/wallets/{{data-store.nornr_wallet_id}}/pay
Method: POST
Headers: Content-Type: application/json
Authorization: Bearer {{your_nornr_api_key}}
Body (JSON):
{
"amount": 8.00,
"to": "openai",
"purpose": "gpt-4o summarisation — incoming lead analysis",
"scenario_run_id": "{{scenario.runId}}"
}
Use Make's variable picker to fill scenario_run_id dynamically. This gives the audit trail a reference you can look up later in the NORNR control room.
5. Route on the decision status
Connect the HTTP response to a Router module. Add three routes with the following filters:
Route A — Label: Approved
Filter: {{http.data.status}} Equal to (text): approved
→ Continue to paid OpenAI / Anthropic module
Route B — Label: Queued (approval required)
Filter: {{http.data.status}} Equal to (text): queued
→ Slack: post "Spend approval required for scenario run {{scenario.runId}}"
→ Stop scenario (no paid module runs)
Route C — Label: Rejected
Filter: {{http.data.status}} Equal to (text): rejected
→ Slack or email: "Spend blocked — {{http.data.reasons}}"
→ Stop scenario
Make evaluates Router routes in order. Put the approved route first so the happy path is the default; routes B and C catch everything that should not proceed.
6. What the NORNR response looks like
The pay endpoint always returns one of three shapes. Your Router filter only needs the status field, but the full payload is worth logging for the audit trail.
// Approved — proceed immediately
{ "status": "approved", "requiresApproval": false, "decisionId": "dec_01hx..." }
// Queued — wait for human review in control room
{ "status": "queued", "requiresApproval": true, "decisionId": "dec_01hx..." }
// Rejected — blocked by policy
{ "status": "rejected", "reasons": ["daily_limit_exceeded"], "decisionId": "dec_01hx..." }
7. Storing the audit trail in Make
After the Router resolves, add a Data Store — Add/replace a record module on every route to persist the decision. Store at minimum: scenario_run_id, decisionId, status, amount, to, and a timestamp from {{now}}.
This gives you a per-run record you can export from Make or query via the NORNR control room. If your organisation uses a data warehouse, pipe the data store to a Google Sheets append or a webhook to your logging endpoint.
8. Handling queued decisions without re-running the scenario
When a spend intent is queued, the human reviewer approves or rejects it in the NORNR control room at /app. You have two options for how Make picks up the resolution:
- Webhook resume: Configure NORNR to POST a webhook to a Make webhook trigger when the decision resolves. A second scenario picks up the approved or rejected state and runs only the paid module if approved.
- Polling: Use a scheduled scenario that checks the decision status endpoint (
GET /api/decisions/{{decisionId}}) at an interval and continues only when status changes fromqueued.
The webhook approach is lower latency and avoids unnecessary polling runs.
9. Common mistakes in Make scenarios
- Placing the HTTP module after the paid step. The point is to gate before money moves. Always position the NORNR module before the OpenAI, Anthropic or other billable module.
- Using a hard-coded wallet ID instead of a Data Store reference. If the wallet is recreated, a hard-coded ID will fail silently and leave the scenario ungoverned.
- Treating queued as an error. Queued is not a failure — it is a hold pending human review. Route it to a notification, not an error handler.
- Not passing
scenario_run_id. Without it, you cannot correlate a control room decision with a specific Make run in your audit log.
10. Featured follow-up paths
- Add a budget to Zapier AI agent actions
- Human approval before a vendor API call
- Audit trail before agent spend moves
- Approved vs queued vs rejected — the core decision model
- Counterparty controls in agent workflows
- Hosted quickstart
The Zapier guide uses the same API pattern with a Code step; the human-approval and audit guides explain the control room mechanics that make queued decisions resolvable.