Docs/Agentic Commerce (ACP)/Agentic Commerce (ACP)

    Webhooks

    Last updated · MAR 2026·Read as Markdown

    ACP webhooks notify your systems when order events occur. When a checkout completes, a signed HTTP POST is sent to your configured webhook URL with the order details. Useful for syncing ACP orders into your PM tool, your CRM, or your dispatch board.

    1. Log into app.avcodex.com and navigate to your agent.
    2. Go to Publish > Catalog.
    3. Find your API key in the API Keys section.
    4. Click to configure the webhook URL and secret.

    Each API key has its own webhook configuration. You can set:

    • Webhook URL - the HTTPS endpoint that receives events.
    • Webhook Secret - a secret string used to sign payloads for verification.
    Note: Webhook URLs must be publicly accessible HTTPS endpoints. The webhook secret is used to generate HMAC-SHA256 signatures so you can verify that requests are authentic.
    Event Trigger
    order.created An order was created from a completed checkout (manual fulfillment).
    order.fulfilled An order was automatically fulfilled (tool execution succeeded).

    When a checkout with automatic fulfillment products completes, the event type will be order.fulfilled. For manual fulfillment products, the event type will be order.created.

    json
    {
      "event": "order.fulfilled",
      "order_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "checkout_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "application_id": "d4e5f6a7-b8c9-0123-def0-123456789abc",
      "status": "fulfilled",
      "fulfillment_result": [
        { "toolName": "generate_audit_report", "success": true, "output": "Audit complete" }
      ],
      "total": {
        "amount": 25000,
        "currency": "usd"
      },
      "created_at": "2025-01-15T12:05:00.000Z"
    }

    Payload fields#

    Field Type Description
    event string The event type (see table above).
    order_id string (UUID) Unique order identifier.
    checkout_session_id string (UUID) The checkout session that created this order.
    application_id string (UUID) The agent this order belongs to.
    status string Current order status.
    fulfillment_result array or null Results from automatic fulfillment (tool execution).
    total.amount integer Order total in currency minor units.
    total.currency string ISO currency code.
    created_at string (ISO 8601) When the order was created.

    Every webhook request includes these headers:

    Header Description
    Content-Type application/json.
    X-ACP-Event The event type (e.g., order.fulfilled).
    X-ACP-Timestamp Unix timestamp (seconds) when the webhook was sent.
    X-ACP-Signature HMAC-SHA256 signature for payload verification.

    Verify webhook authenticity by computing the HMAC-SHA256 signature and comparing it to the X-ACP-Signature header.

    The signature is computed over the string {timestamp}.{body}, where {timestamp} is the X-ACP-Timestamp header value and {body} is the raw JSON request body.

    Node.js example#

    javascript
    import crypto from "crypto";
    
    function verifyWebhook(req, webhookSecret) {
      const signature = req.headers["x-acp-signature"];
      const timestamp = req.headers["x-acp-timestamp"];
      const body = req.body; // raw string, not parsed JSON
    
      const expected = crypto
        .createHmac("sha256", webhookSecret)
        .update(`${timestamp}.${body}`)
        .digest("hex");
    
      return crypto.timingSafeEqual(
        Buffer.from(signature, "hex"),
        Buffer.from(expected, "hex")
      );
    }

    Python example#

    python
    import hmac
    import hashlib
    
    def verify_webhook(headers, body, webhook_secret):
        signature = headers["X-ACP-Signature"]
        timestamp = headers["X-ACP-Timestamp"]
    
        expected = hmac.new(
            webhook_secret.encode(),
            f"{timestamp}.{body}".encode(),
            hashlib.sha256
        ).hexdigest()
    
        return hmac.compare_digest(signature, expected)
    Note: Always use constant-time comparison (like timingSafeEqual or hmac.compare_digest) when verifying signatures to prevent timing attacks.
    • Timeout: each delivery attempt has a 10-second timeout.
    • Retries: up to 3 delivery attempts (1 initial plus 2 retries) with exponential backoff (1s, 2s delays).
    • Success: a 2xx HTTP response from your endpoint is considered successful delivery.
    • Failure: after all retries fail, the error is recorded on the order. You can check the order status via the API.
    • Respond quickly. Return a 200 response as soon as you receive the webhook. Process the payload asynchronously if needed.
    • Handle duplicates. Webhooks may be delivered more than once. Use the order_id to deduplicate.
    • Verify signatures. Always verify the X-ACP-Signature header before processing the payload.
    • Use HTTPS. Webhook URLs must use HTTPS to protect payload contents in transit.

    *AVCodex · Your AV expertise. Amplified by AI.*

    Was this helpful?
    Edit this page →