Webhook triggers
Start an agent or a workflow from another system with a signed HTTP request.
A webhook trigger gives an agent or a workflow its own URL. When your system calls that URL with a valid signature, AgentWorks starts a run and passes the request body to it as input. No API key is involved: the signature is the proof.
Use a webhook trigger when an event in another system should start work — a new order, a form that was submitted, a ticket that changed status. To drive work from your own code and read results back, use the API with a key instead.
Create the trigger
Create the trigger in the app (see Schedules and triggers). You get two values, shown once:
- the Webhook URL,
https://api.agent-works.ai/triggers/fire/webhook/{trigger_id} - the Signing secret
Store the secret as a secret in the calling system.
Sign the request
Every request carries two headers:
| Header | Value |
|---|---|
X-Webhook-Timestamp | The current time as Unix seconds. |
X-Webhook-Signature | Base64 of HMAC-SHA256 over {timestamp}.{body}, keyed with the signing secret. |
Sign the exact bytes you send as the body. A request whose timestamp is more than 5 minutes away from the current time is refused, so a captured request cannot be replayed later.
import base64, hashlib, hmac, json, time, urllib.request
url = "https://api.agent-works.ai/triggers/fire/webhook/TRIGGER_ID"
secret = "YOUR_SIGNING_SECRET"
body = json.dumps({"order_id": "SO-10432", "customer": "Berg Wholesale"}).encode()
timestamp = str(int(time.time()))
signature = base64.b64encode(
hmac.new(secret.encode(), f"{timestamp}.".encode() + body, hashlib.sha256).digest()
).decode()
request = urllib.request.Request(
url,
data=body,
method="POST",
headers={
"Content-Type": "application/json",
"X-Webhook-Timestamp": timestamp,
"X-Webhook-Signature": signature,
},
)
print(urllib.request.urlopen(request).status) # 202
What comes back
A valid request answers 202 Accepted straight away; the run starts in the background.
{ "status": "accepted", "trigger_id": "…" }
The JSON you sent is the input of the run. Follow what happened under View fire history on the trigger, or in the agent's or workflow's results.
| Status | Meaning |
|---|---|
202 | Accepted. The run is starting. |
401 | The signature or the timestamp is missing, wrong or too old. |
402 | The workspace balance or a spending limit does not allow the run. |
404 | The trigger does not exist or is switched off. |
429 | More than 30 requests in a minute for this endpoint. |
Good to know
- Send JSON. A body that is not JSON is passed on as raw text, cut to 1,000 characters.
- The limit is 30 requests per minute. If your source can burst above that, queue on your side.
- If an action in the run needs approval, a person decides it in the app. See Runs and approvals.
- Rotate the secret by creating a new trigger and switching the caller over.