Run a real approval in minutes.
Forsig pauses a risky AI-agent action, asks a human for a decision, and returns a structured result your code can branch on.
Quickstart
Create an API key in the Developer portal, set it locally, then run one of the examples. The first run should use test or shadow mode.
export FORSIG_API_KEY=fsk_test_xxx
export FORSIG_BASE_URL=https://www.forsig.com
node examples/refund-agent-node/index.mjs
No secrets: send only what a reviewer needs. Do not include API keys, passwords, full payment details, or unnecessary customer records.
Shadow mode and active mode
Use shadow mode to learn where approvals would trigger without blocking your agent. Switch selected workflows to active mode when you are ready to pause execution.
{
"mode": "shadow",
"status": "shadow_logged",
"wouldHaveEscalated": true
}
Node.js
import { Forsig } from "@forsig/sdk";
const forsig = new Forsig({ apiKey: process.env.FORSIG_API_KEY });
const decision = await forsig.escalate({
agent: "refund-agent",
action: "stripe.refund",
risk: "refund_over_limit",
context: { amount: 500, customer: "VIP customer #123" },
waitForDecision: true
});
if (decision.status === "approved") {
await issueRefund();
}
Python
from forsig import Forsig
import os
forsig = Forsig(api_key=os.environ["FORSIG_API_KEY"])
decision = forsig.escalate(
agent="refund-agent",
action="stripe.refund",
risk="refund_over_limit",
context={"amount": 500, "customer": "VIP customer #123"},
wait_for_decision=True,
)
if decision.status == "approved":
issue_refund()
cURL
curl https://www.forsig.com/api/v1/escalations \
-H "Authorization: Bearer $FORSIG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent": "refund-agent",
"action": "stripe.refund",
"risk": "refund_over_limit",
"context": { "amount": 500, "customer": "VIP customer #123" },
"waitForDecision": true
}'
Framework examples
Refunds
Place Forsig before the payment API call. If approved, continue. If rejected or timed out, stop.
Deployments
Escalate production migrations, data updates, and release actions before they run.
Tool spend
Require approval before paid exports, purchases, or external tool calls spend money.
async function approvalNode(state) {
const decision = await forsig.escalate({
agent: "support-agent",
action: state.action,
risk: state.risk,
context: state.reviewContext,
waitForDecision: true
});
return { ...state, forsigDecision: decision };
}
Webhook signing
When a callback URL is set, Forsig posts the resolved decision with a signature header. Verify the raw body before trusting the event.
import { createHmac, timingSafeEqual } from "node:crypto";
function verifyForsigWebhook(rawBody, signature, secret) {
const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(signature || "");
const b = Buffer.from(expected);
return a.length === b.length && timingSafeEqual(a, b);
}
Security model
Forsig stores reviewer identity, action descriptions, risk reasons, signed decisions, and timestamps. It never needs API keys, passwords, full payment records, or private agent memory.