§ Quickstart · 5 minutes

Build your first approval

This is the shortest path to a real Nuvouch loop: your server creates an approval, Nuvouch asks the user, your webhook verifies the callback, and your app executes only after approval.

§ 00 · Fit

Use Nuvouch for approval infrastructure

Nuvouch is for AI agent platforms, payment and fintech platforms, API platforms with dangerous actions, and enterprise workflow tools that need a durable user decision before execution.

§ 01 · Install

Install the SDK

install
npm
npm install @nuvouch/node
.env
server only
NUVOUCH_API_KEY=itg_live_xxxxx
NUVOUCH_CALLBACK_SECRET=nuvouch_live_callback_secret
NUVOUCH_WEBHOOK_URL=https://your-app.example.com/webhooks/nuvouch
§ 02 · Ask

Create an approval

Create first approval
node sdk
import { Nuvouch } from "@nuvouch/node";

const nuvouch = new Nuvouch({
  apiKey: process.env.NUVOUCH_API_KEY,
});

const externalRequestId = "payment_auth_001";

const approval = await nuvouch.approvals.create({
  subject: {
    id: "cus_123",
    label: "Ada Lovelace",
  },
  source: {
    key: "merchant:acct_live_001",
    name: "Stripe Live Account",
  },
  action: {
    type: "payment.authorization",
    title: "Approve payment",
    description: "Allow Billing Agent to charge $84.00",
  },
  amount: {
    value: 84.0,
    currency: "USD",
  },
  details: [
    { label: "Merchant", value: "OpenAI API" },
    { label: "Billing period", value: "May 2026" },
  ],
  actor: {
    type: "ai_agent",
    name: "Billing Agent",
  },
  risk: {
    level: "medium",
    signals: ["automated_action", "usage_threshold_exceeded"],
  },
  decisions: [
    { label: "Approve", value: "approve" },
    { label: "Deny", value: "deny" },
  ],
  externalRequestId,
  metadata: {
    paymentIntentId: "pi_123",
  },
});

console.log(approval.id, approval.status);

Use subject for the user or customer, source for the product/account/provider origin, actor for the agent or system initiating the action, and externalRequestId as your durable retry key.

§ 03 · Decide

Verify the webhook locally

For local development, expose your webhook with a tunnel and set that URL in the integrator console, for example https://your-tunnel.ngrok-free.app/webhooks/nuvouch.

webhook.ts
express-style handler
import { Nuvouch } from "@nuvouch/node";

const nuvouch = new Nuvouch({ apiKey: process.env.NUVOUCH_API_KEY });

app.post(
  "/webhooks/nuvouch",
  express.raw({ type: "application/json" }),
  async (req, res) => {
    const rawBody = req.body.toString("utf8");
    const event = nuvouch.webhooks.verify({
      rawBody,
      signature: req.header("x-nuvouch-signature"),
      secret: process.env.NUVOUCH_CALLBACK_SECRET!,
    });

    if (await hasProcessed(event.deliveryId)) {
      return res.status(200).send("duplicate");
    }

    await saveEvent(event.deliveryId, event);
    res.status(200).send("ok");
  },
);
§ 04 · Verify

Execute only after approval

worker.ts
side effect gate
const event = await nextSavedNuvouchEvent();

if (event.type !== "nuvouch.approval_request.approved") {
  await markBusinessRequestBlocked(event.data.approvalRequest.externalRequestId);
  return;
}

const requestId = event.data.approvalRequest.externalRequestId;
const paymentIntentId = event.data.approvalRequest.metadata?.paymentIntentId;

await runOnce(requestId, async () => {
  await capturePayment(paymentIntentId);
});

After this loop works, continue to getting started for production setup and integration guide for the full payment authorization walkthrough.