Suede AI Agent StudioDocsStart buildingOpen workspace
Navigation menu

Developers4 min readUpdated

Trigger agents from any app with signed webhooks

Quick answer

Add a Webhook node to an Agent Studio flow and launch it, and the agent gets a URL at /api/agents/{id-or-slug}/webhook. Sign each POST with HMAC-SHA256 over {timestamp}.{raw body} using the secret shown at launch, send it in x-suede-webhook-signature with x-suede-webhook-timestamp, and the JSON body becomes the run's input.

What you'll have

  • A webhook-triggered agent with its signing secret saved where your sender reads it
  • Working signing code in Node or Python that Agent Studio accepts on the first try
  • A clear read on every response code, so failures are obvious in your logs
On this page
  1. How do webhook triggers work in Agent Studio?
  2. How do I sign a webhook request?
  3. What headers and limits does the webhook endpoint enforce?
  4. What does each webhook response mean?
  5. How do I rotate a lost or leaked webhook secret?
  6. Questions

How do webhook triggers work in Agent Studio?#

A Webhook node turns an agent into a listener. Your backend, a serverless function or any automation step that runs code POSTs JSON to the agent's webhook URL, Agent Studio checks the signature, and the flow runs with that JSON as its input. A plain JSON object passes through as-is; any other JSON value arrives wrapped as { body: {value} }.

Set up a webhook-triggered agent

0 of 5 done

  1. Step 1: Add a Webhook node

    Open the builder, drop a Webhook node at the start of the flow and wire it to the steps that should run. The optional note field is for your own reference.
    Open the builder
  2. Step 2: Dry-run the flow

    Run it with a sample payload so every downstream step sees the shape it will get in production. Dry runs are free.
  3. Step 3: Launch and save the secret

    Click Launch. The launch response shows the signing secret once; store it in the secret store of whatever will send the webhook.
    Read the launch guide
  4. Step 4: Sign and send a test

    Use the Node or Python sample below with your agent's id or slug and confirm a 200 with a runId.
  5. Step 5: Watch the run

    Open Workspace to see the run, its outputs and its cost.
    Open Workspace

How do I sign a webhook request?#

Take the current time in Unix milliseconds, join it to the exact raw body with a period, and compute an HMAC-SHA256 of that string keyed by your webhook secret. Send the hex digest prefixed with sha256=. Sign the bytes you send: serialize the JSON once and post that same string.

Sign and send a webhook (Node.js 18+)typescript
import { createHmac } from "node:crypto";

const secret = process.env.SUEDE_WEBHOOK_SECRET!; // shown once at launch
const url = "https://agents.suedeai.ai/api/agents/<id-or-slug>/webhook";

export async function sendToAgent(payload: Record<string, unknown>): Promise<unknown> {
  const timestamp = Date.now().toString();          // Unix ms, decimal string
  const rawBody = JSON.stringify(payload);          // sign exactly what you send
  const signature =
    "sha256=" + createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");

  const res = await fetch(url, {
    method: "POST",
    headers: {
      "content-type": "application/json",
      "x-suede-webhook-timestamp": timestamp,
      "x-suede-webhook-signature": signature,
    },
    body: rawBody,
  });
  if (!res.ok) throw new Error(`Agent webhook failed: ${res.status}`);
  return res.json(); // { runId, status, totalCostUsdc, outputs }
}

await sendToAgent({ event: "lead.created", email: "ana@example.com" });
Sign and send a webhook (Python 3)python
import hashlib, hmac, json, os, time, urllib.request

secret = os.environ["SUEDE_WEBHOOK_SECRET"].encode()
url = "https://agents.suedeai.ai/api/agents/<id-or-slug>/webhook"

timestamp = str(int(time.time() * 1000))
raw_body = json.dumps({"event": "lead.created", "email": "ana@example.com"})
digest = hmac.new(secret, f"{timestamp}.{raw_body}".encode(), hashlib.sha256).hexdigest()

req = urllib.request.Request(url, data=raw_body.encode(), method="POST", headers={
    "content-type": "application/json",
    "x-suede-webhook-timestamp": timestamp,
    "x-suede-webhook-signature": "sha256=" + digest,
})
print(urllib.request.urlopen(req).read().decode())

What headers and limits does the webhook endpoint enforce?#

Webhook request rules
RuleValue
EndpointPOST /api/agents/{id-or-slug}/webhook
Content typeapplication/json (a charset suffix is fine)
Signature headerx-suede-webhook-signature: sha256={hex}
Timestamp headerx-suede-webhook-timestamp, Unix milliseconds as a decimal string
Signed string{timestamp}.{raw body}, HMAC-SHA256 keyed by your secret
Freshness window5 minutes either side of the server clock
Body size256 KB maximum
Rate limitsPer source IP and per agent, each with a Retry-After on 429

What does each webhook response mean?#

Webhook responses
StatusMeaningWhat to do
200The run started and finished; body has runId, status, totalCostUsdc, outputsRead status for done or error
401Bad signature, stale timestamp or unknown agentCheck the secret, clock and raw body
413Body over 256 KBSend a reference such as a URL instead of the full payload
415Content type is not JSONSet content-type: application/json
429Rate limitedWait for Retry-After, then resend with a fresh timestamp

A bad signature, a stale timestamp and an unknown agent all return the same 401 on purpose, so nobody probing the endpoint learns which agents exist. If a signature fails, compare the exact bytes you signed with the bytes you sent: re-serializing JSON after signing is the usual cause.

How do I rotate a lost or leaked webhook secret?#

Signed in as the owner, call POST /api/agents/{id}/webhook/rotate to replace the secret atomically and receive the new one once. Relaunching an agent never rotates the secret, so the services already sending to it keep working through every update.

Wire your first event

Drop a Webhook node on the canvas, launch, and send a signed test in under ten minutes.

Questions buyers ask#

What do I sign for an Agent Studio webhook?

The string {timestamp}.{raw body}, where the timestamp is Unix milliseconds and the body is the exact bytes you POST. Use HMAC-SHA256 with your webhook secret and send sha256={hex} in x-suede-webhook-signature.

Can I find my webhook secret again after launch?

No, it is shown once in the launch response. Save it right away; if it is lost, the owner rotates it with POST /api/agents/{id}/webhook/rotate and gets a fresh one.

Can Stripe or GitHub post straight to my agent's webhook?

Send them through a step that signs with your Agent Studio secret, such as a serverless function or your backend. It receives the provider's event, signs it the Agent Studio way and forwards it in a few lines of code.

How big can a webhook payload be?

Up to 256 KB of JSON. For larger data, send a link or an id and let the agent fetch the rest with an HTTP Request node.

Why am I getting a 401 with the right secret?

Usually the body you signed differs from the body you sent, or the sender's clock is more than 5 minutes off. Serialize once, sign that string, send that string, and sync the clock.

Was this page helpful?

Good work starts with a clear flow.

Give an agent a job. Connect the steps. See how the work becomes a service someone else can call.

Input
Reason
Output

A workflow you can inspect

Make the steps visible.

Start with a template or describe the job. Connect inputs, reasoning, and output on the canvas.

Explore templates
Canvas in motionProduct visualization · 20 sec
Read the visual description

A stylized organization chart opens into a workflow canvas. Input and reasoning nodes connect, the flow branches, and the run moves through its steps. The film ends with Suede AI Agent Studio. Music only; no spoken narration.