Two HTTP calls. One webhook
Your canvas keeps the logic. Momentum answers one question: may this step continue, must a person look, or must this case stop? Use this if the agent lives in n8n, Zapier, Make, Agentforce, Flowise, Dify, or any tool that can POST JSON. Code agents use the Python or Node.js SDK instead.
POST /v1/emit-event
Send what happened. Policy decides continue, pause, or block.
POST /v1/request-approval
Always pauses. The next node runs only after Approve on Feed.
Webhook POST
Momentum calls your URL when a reviewer acts. Route on decision_code.
How it looks on the canvas
A complete agent on a canvas — the same shape as n8n. Trigger, set IDs, POST emit-event, then honor continue / paused / blocked. If paused, request approval, wait for Feed, and route on the reviewer's decision. continue and APPROVE reuse one Disburse loan node.
Before you start
Three things from Momentum. Then you are ready to POST.
- On Feed click Add Agent. Choose No-code agent. In your builder, add a POST webhook, turn the workflow on, and paste the production URL. Click Test, then Connect & apply governance. Copy the agent_id.
- Create a live key on API Key (fe_live_…). It is shown once.
- Store the key as a header credential in your builder — never in a node that logs the full request.
Headers
Put these on every call to Momentum.
HTTP headers
Authorization: Bearer fe_live_paste_your_key_here
Content-Type: application/jsonBase URL: https://forceequals-momentum-api.onrender.com
Quick start
Same agent_id, case_id, and execution_id on both calls. execution_id is unique per run (n8n: {{ $execution.id }}). case_id is the business item — one loan, one ticket.
POST https://forceequals-momentum-api.onrender.com/v1/emit-event
{
"agent_id": "loan-agent",
"execution_id": "exec_1001",
"case_id": "loan_1001",
"version": 1,
"event_type": "loan.risk.calculated",
"event_details": {
"loan_amount": 1500000,
"risk_score": 0.42
}
}POST https://forceequals-momentum-api.onrender.com/v1/request-approval
{
"agent_id": "loan-agent",
"execution_id": "exec_1001",
"case_id": "loan_1001",
"version": 1,
"title": "Approve disbursement",
"context": { "amount": 1500000 }
}What each call does
| Call | When to use it |
|---|---|
| POST /v1/emit-event | Report a fact. Policy decides continue, pause, or block. |
| POST /v1/request-approval | Ask a human on Feed. Always pauses until they resolve it. |
| Webhook POST | Momentum wakes your canvas after Approve, Reject, or Request change. |
Branch on the result
Unlike the SDK, your canvas does not wait inside the HTTP node. Switch on status. Never put payout, send, or write on the default branch.
| status | What you do |
|---|---|
| continue | Next node. Skip irreversible actions if you still need request-approval. |
| paused | Park this run. Wait on the webhook you registered. |
| blocked | Stop this case. Do not wait for a human. |
Typical responses
{ "status": "continue", "case_id": "loan_1001" }
{ "status": "paused", "approval_id": "apr_ab12cd34", "case_id": "loan_1001" }
{ "status": "blocked", "reason": "Amount exceeds organization limit" }Review on Feed
- Open Momentum → Feed while the run is paused.
- Approve POSTs your webhook and you continue. Reject closes this case. Request change stops this run — resubmit with the same case_id, a new execution_id, and version + 1.
Webhook body after Feed
{
"event": "approval.resolved",
"approval_id": "apr_ab12cd34",
"execution_id": "exec_1001",
"case_id": "loan_1001",
"version": 1,
"status": "approved",
"decision_code": "APPROVE",
"reason": "",
"can_resubmit": false
}| decision_code | What you do |
|---|---|
| APPROVE | Resume. Wire this into the same Disburse / merge / send node as continue — one action block, two incoming wires. |
| DENY | Stop. A later request is a new case. |
| REQUEST_CHANGES | Stop this run. Resubmit the same case with updated values. |
Every decision is also stored on History. If your builder cannot receive webhooks, poll GET https://forceequals-momentum-api.onrender.com/v1/approvals/apr_… with the same Bearer header.
n8n, Zapier, Make, Agentforce
Same contract on every canvas. Only the node names change.
| Builder | What to add |
|---|---|
| n8n | Webhook (POST, Production URL, workflow Active) → HTTP Request (emit-event) → Switch on status → Wait on the webhook → Switch on decision_code. Header Auth: Authorization = Bearer fe_live_…. |
| Zapier | Catch Hook as the resume URL. Webhooks POST with the Bearer header. Paths on status. Turn the Zap on before you Test in Momentum. |
| Make | Custom webhook + HTTP module + Router. Enable the scenario before Test. |
| Agentforce / others | Named Credential or HTTP tool against https://forceequals-momentum-api.onrender.com. Park when paused; continue only after APPROVE. |
If something fails
| What you see | What to do |
|---|---|
| Test button fails | Workflow must be Active. URL must be POST and reachable (not localhost). In n8n use the Production URL. |
| 401 from emit-event | Header is Bearer fe_live_… with a space after Bearer. Generate a new key if the secret was lost. |
| Nothing on Feed | agent_id in the JSON must match Connect Agent. A silent continue will not create a card — pause or request-approval will. |
| Approve does not resume | The Wait URL is not the URL you Tested. Re-test, or poll GET /v1/approvals/{id}. |
Built the agent in code instead? Use the Python or Node.jsguide. To put this org's policies into Cursor, Claude, or Codex — without emitting events — connect on the MCP tab.