Webhooks
Receive execution events and start governed work from external systems.
Guest Machines supports two different webhook directions. Outbound webhooks notify your system about platform events. Inbound webhooks let an external system start a configured flow.
Outbound webhooks
Create a webhook for the events your integration actually consumes. Your endpoint should return a successful response quickly and move expensive processing to a queue.
Webhooks are created in the console by an organization admin or owner, which is why they are absent from the API reference: an API key has no role, so it cannot create one however it is scoped. The delivery contract below is what your integration builds against.
Design the receiver to tolerate duplicate delivery, delayed delivery, and events arriving close together.
Delivery headers
Every delivery is signed. Guest Machines sends a JSON body with these headers:
| Header | Contents |
|---|---|
X-GuestMachines-Signature | Comma-separated scheme=value elements; today, sha256=… |
X-GuestMachines-Timestamp | Unix seconds, and part of the signed message |
X-GuestMachines-Event | The event name, such as run.completed |
X-GuestMachines-Delivery-Id | Unique per delivery attempt; also present in the body |
Use X-GuestMachines-Delivery-Id as the deduplication key.
Verify the signature
The signing secret is shown once when you create the webhook, and again when you rotate it. Store it in a secret manager.
The signed message is the timestamp, a literal ., then the exact raw request body. Compute HMAC-SHA256(secret, "{timestamp}.{body}") and hex-encode it.
Parse the signature header rather than comparing it whole. It is a comma-separated list of scheme=value elements: find the one whose scheme is sha256, compare its value in constant time, and ignore any element whose scheme you do not recognize. A receiver written this way keeps working when a new algorithm is added alongside the current one.
import hashlib
import hmac
def is_signed_by_guest_machines(secret, body_bytes, timestamp, signature_header):
expected = hmac.new(
secret.encode(),
f"{timestamp}.".encode() + body_bytes,
hashlib.sha256,
).hexdigest()
for element in signature_header.split(","):
scheme, _, value = element.strip().partition("=")
if scheme == "sha256" and hmac.compare_digest(value, expected):
return True
return FalseSign against the raw bytes you received. Re-serializing the parsed JSON changes key order and whitespace, and the signature will not match. Reject deliveries whose timestamp is far outside your clock tolerance, and reject unsigned requests outright rather than falling back to trusting them.
Rotating a secret invalidates the old one immediately, so update the receiver before rotating.
Stability
This signing scheme is stable. Future algorithms will be added as further elements in X-GuestMachines-Signature rather than replacing sha256, so a receiver that selects the scheme it knows keeps verifying without changes. This commitment covers webhook delivery only; it says nothing about the stability of the HTTP API, which is governed by the API reference.
Inbound webhooks
An inbound webhook exposes a trigger URL for a specific automation. Treat the trigger token as a secret. Rotate it if it is disclosed and update the sending system immediately.
Validate and constrain payloads before they reach expensive agent execution. A public trigger should not become an unbounded prompt relay.
Operational checklist
- Use HTTPS.
- Verify the signature on every delivery, and reject anything unsigned.
- Store received delivery IDs.
- Respond before doing expensive work.
- Retry only transient failures.
- Monitor repeated delivery failures.
- Never log credentials or full sensitive payloads.