Engineering

Verify Computer Use API Webhooks with HMAC Signatures

Alex Thompson||6 min
Ctrl+H

When you configure a webhook_url for a task run, Coasty sends status updates via Server-Sent Events. These events include a Coasty-Signature header with an HMAC hash of the event payload. You must verify this signature before acting on the run state. This prevents tampered payloads and ensures your downstream systems only see outcomes from the official Coasty Computer Use API.

How webhook signatures work

Coasty signs the raw body of each event using HMAC-SHA256 and sends it in the header Coasty-Signature: t=unix,v1=hex. The t parameter is the Unix timestamp of the signature, v1 is the hex-encoded HMAC hash of the JSON body. You must use the same secret key that you configured in your Coasty dashboard. The signature protects every status change, including queued, running, succeeded, failed, cancelled, and timed_out states.

python
import hmac
import hashlib
import json
from os import getenv

api_key = getenv("COASTY_API_KEY")
secret = api_key.encode()

# Normalize header: Coasty-Signature: t=1234567890,v1=a1b2c3...
header = "Coasty-Signature: t=1234567890,v1=a1b2c3d4e5f6"

def verify_signature(raw_body: bytes, signature_header: str) -> bool:
    """Validate HMAC signature on a Coasty webhook event."""
    # Extract t and v1 components
    parts = signature_header.split(",")
    ts, v1 = [p.split("=")[1] for p in parts]

    mac = hmac.new(secret, raw_body, hashlib.sha256)
    expected = mac.hexdigest()
    return hmac.compare_digest(expected, v1)

# Example: read raw body and header from your web server
# raw_body = request.body
# signature_header = request.headers.get("Coasty-Signature")
# is_valid = verify_signature(raw_body, signature_header)
# if is_valid:
#     event = json.loads(raw_body)
#     run_id = event["run_id"]
#     state = event["state"]
#     print(f"Run {run_id} completed with state {state}")
else:
    print("Signature invalid");

# Example: test against a known payload (replace with real event body)
payload = json.dumps({"run_id":"run_abc123","state":"succeeded"}).encode()
print(verify_signature(payload, header))

Webhook configuration for task runs

You define the webhook_url when you POST /v1/runs to start a task run. The request includes a machine_id and task, and optional parameters like max_steps, deadline_seconds, and on_awaiting_human. The webhook receives events via GET /v1/runs/{id}/events. Coasty bills $0.05 per agent step for task runs, and the signature protects every status change you receive.

Handling awaiting_human events

If your task run hits a situation requiring human input, Coasty sets the state to awaiting_human. The on_awaiting_human parameter determines what happens next: pause, fail, or cancel. When using a webhook, you can pause the run and prompt a human operator before resuming. The signature ensures that only Coasty can trigger that state change.

Always verify the Coasty-Signature header before processing webhook events.

Where this beats brittle automation

Traditional automation relies on brittle selectors and API-only workflows. If a UI element changes or a third-party API alters its response, your scripts break. With the Computer Use API, the agent sees the screen and acts like a human. Webhook signatures let you trust the final state of that agent work, regardless of how it was reached. You can integrate with any downstream system knowing the event is authentic.

Implement HMAC verification for your Coasty Computer Use API webhooks to secure your agent workflows. Once verified, you can trigger downstream actions safely. Build reliable automation that sees the screen and acts like a human. Get your API key at https://coasty.ai/developers .

Want to see this in action?

View Case Studies
Try Coasty Free