This guide takes you from zero to a signed webhook landing in your terminal. You’ll create a tenant, add a user, and watch a tenant.users.invite event arrive - fully signed.
Prefer to browse first? Jump to the API reference or the webhooks overview.

1. Get your API keys

1

Sign in to the dashboard

Go to app.geldstuck.com and sign in. If you don’t have an account yet, create one - it takes 30 seconds.
2

Create a tenant

Every piece of data in Geldstuck is scoped to a tenant - think of a tenant as a workspace. Click New tenant, give it a name, and hit Create.
3

Copy your keys

You’ll see three secrets. Copy them now - the secret key and webhook secret are shown only once.
GELDSTUCK_PUBLIC_KEY=pk_test_51H...
GELDSTUCK_SECRET_KEY=sk_test_51H...
GELDSTUCK_WEBHOOK_SECRET=whsec_xS...
Treat sk_test_... and whsec_... like database passwords. Never commit them. Store in your secrets manager.

2. Make your first request

Set your base URL and export your keys, then fetch your tenant profile to confirm the keys work.
https://api.geldstuck.com/v1
curl https://api.geldstuck.com/v1/tenants/me \
  -H "x-api-key: $GELDSTUCK_PUBLIC_KEY" \
  -H "x-api-secret: $GELDSTUCK_SECRET_KEY"
You should see a JSON response like:
{
  "tenantId": "tnt_01HX3Z8MQW...",
  "name": "Acme Escrow",
  "status": "active",
  "createdAt": "2026-04-22T09:12:44.000Z"
}

3. Invite a user

Now create a user under your tenant. This triggers the tenant.users.invite webhook - which we’ll catch in the next step.
curl https://api.geldstuck.com/v1/tenants/add-user \
  -H "x-api-key: $GELDSTUCK_PUBLIC_KEY" \
  -H "x-api-secret: $GELDSTUCK_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Ada Lovelace",
    "email": "ada@example.com"
  }'
Response:
{
  "id": "usr_01HX3ZAB...",
  "name": "Ada Lovelace",
  "email": "ada@example.com",
  "tenantId": "tnt_01HX3Z8MQW...",
  "status": "invited",
  "createdAt": "2026-04-22T09:13:02.000Z"
}

4. Receive your first webhook

Webhooks need a public URL we can POST to. For local development, expose your laptop with a tunnel - we recommend ngrok or Cloudflare Tunnel.
1

Start a tunnel to your local server

ngrok http 3000
Copy the https://....ngrok-free.app URL.
2

Register it as a webhook endpoint

In the dashboard, go to Developers → Webhooks → Add endpoint. Paste the tunnel URL with your path, e.g. https://abc123.ngrok-free.app/webhooks, and subscribe to at least tenant.users.invite.
3

Trigger an event

Re-run the add-user call from step 3 - this emits tenant.users.invite to your endpoint.
Your endpoint receives a signed POST:
POST /webhooks HTTP/1.1
Content-Type: application/json
X-Geldstuck-Event: tenant.users.invite
X-Geldstuck-Webhook-Id: evt_01HX3ZC...
Geldstuck-Signature: t=1745311982,v1=b8a7e1c4...

{
  "id": "evt_01HX3ZC...",
  "type": "tenant.users.invite",
  "tenantId": "tnt_01HX3Z8MQW...",
  "data": {
    "userId": "usr_01HX3ZAB...",
    "email": "ada@example.com"
  },
  "createdAt": "2026-04-22T09:13:02.000Z"
}

5. Verify the signature

Never trust a webhook you haven’t verified. An attacker who knows your endpoint URL can forge events unless you check the signature.
import express from "express";
import crypto from "crypto";

const app = express();

app.post(
  "/webhooks",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const header = req.headers["geldstuck-signature"] as string;
    const [tPart, v1Part] = header.split(",");
    const timestamp = Number(tPart.split("=")[1]);
    const received  = v1Part.split("=")[1];

    const expected = crypto
      .createHmac("sha256", process.env.GELDSTUCK_WEBHOOK_SECRET!)
      .update(`${timestamp}.${req.body.toString()}`, "utf8")
      .digest("hex");

    const ok =
      expected.length === received.length &&
      crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));

    if (!ok) return res.status(400).send("Invalid signature");

    const event = JSON.parse(req.body.toString());
    console.log("Received", event.type);
    res.sendStatus(200);
  },
);
That’s the full loop - tenant → API call → signed webhook → verified handler.

What’s next?

KYC walkthrough

Verify your first user with Geldstuck’s hosted identity flow.

Escrow walkthrough

Create an escrow transaction and invite a counterparty.

Webhook events

Full catalog of events you can subscribe to.

API reference

Every endpoint, every parameter.