> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeroclick.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Book a demo

> A reference flow for finding availability, collecting attendee details, and confirming a free demo booking.

Let an agent check availability, collect the attendee's details, book a time, and return confirmation. This example is loosely based on [ZeroClick's own demo booking flow](https://agents.zeroclick.ai).

<Info>
  This is a reference example, not a required API design or a drop-in implementation. Adapt the endpoints, fields, responses, and fulfillment steps to your product. Only the linked ZeroClick integration requirements are platform contracts.
</Info>

Start with [Overview and setup](/examples/free-actions) for the shared ZeroClick configuration, email policy, request guard, and testing guidance.

## Example choices

* **ZeroClick policy:** `off` is enough if you do not need the agent owner's verified email. Use `requested` to receive it when available, or `required` if identifying the owner is essential to your product.
* **Seller input:** require an attendee `email` to send the calendar invitation, regardless of the ZeroClick policy. A user can book for a colleague, so this address may differ from the agent owner's verified email.
* **Fulfillment:** your calendar integration creates the booking. ZeroClick forwards the request to your API.

You need a calendar integration that can list availability and create bookings. Use a test calendar while implementing the flow. The commands use the placeholder pay URL `https://acme.pay.zeroclick.io`; replace it with yours.

## Build the example

<Steps titleSize="h3">
  <Step title="Describe the action in your catalog">
    Add a service named **Book a demo**, with slug `demo-booking`. Describe who the demo is for, what it covers, how long it takes, and that it costs \$0. Include the email requirement you chose.

    Register the endpoints and their request and response schemas so agents can discover how to complete the action. The core booking flow needs two:

    | Endpoint                 | Purpose                                                |
    | ------------------------ | ------------------------------------------------------ |
    | `GET /demo/availability` | Return available times for a date range and time zone. |
    | `POST /demo/bookings`    | Book a selected time using the attendee's details.     |

    ZeroClick's own flow also supports `GET /demo/bookings/{bookingId}` and `POST /demo/bookings/{bookingId}/cancel` for follow-up actions.

    For the booking body, document these fields:

    | Field                   | Required | Meaning                                                                                                         |
    | ----------------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
    | `start`                 | Yes      | An ISO 8601 timestamp chosen from the availability response.                                                    |
    | `firstName`, `lastName` | Yes      | The attendee's name.                                                                                            |
    | `email`                 | Yes      | The attendee's contact email. In a verified-only adaptation, derive this from the verified buyer email instead. |
    | `company`               | Yes      | The attendee's company.                                                                                         |
    | `timeZone`              | No       | The attendee's time zone, such as `America/New_York`. ZeroClick's demo defaults to `Etc/UTC`.                   |
    | `notes`                 | No       | Questions or context for the demo.                                                                              |

    These fields describe the reference booking flow. Choose the inputs your own scheduling integration needs.
  </Step>

  <Step title="Validate the inputs and complete the action">
    After the guard allows the request, validate the fields, call your calendar provider, and return its confirmed result. The following handler outline uses the `verifyFreeActionRequest` helper from [shared setup](/examples/free-actions#verify-the-request-and-identify-the-agent). `parseBookingInput` and `calendar.createBooking` are application functions you supply, not SDK methods.

    ```ts theme={null}
    export async function POST(request: Request): Promise<Response> {
      const decision = await verifyFreeActionRequest(request, "demo-booking");
      if (decision.action === "deny") return decision.response;

      // Validate required fields, email format, timestamp, and time zone.
      // Return a 400 response for malformed JSON or invalid fields.
      const input = await parseBookingInput(request);
      if (input instanceof Response) return input;

      const booking = await calendar.createBooking({
        ...input,
        idempotencyKey: decision.context.zcRequestId,
      });

      return Response.json(booking, { status: 201 });
    }
    ```

    The `email` in this example is the attendee address supplied to your endpoint. The ZeroClick plan policy neither requires this field nor verifies it. Keep a verified buyer email separate if you also receive one; see [the two email choices](/examples/free-actions#choose-your-email-requirements).

    ZeroClick's demo passes `zcRequestId` to its calendar integration as an idempotency key so a replay of the same forwarded request does not create a duplicate booking. A new agent request can have a new request id; add your own stable operation key if you need deduplication across those requests too.

    Return a clear error if the slot is no longer available or the provider cannot complete the booking. Confirm success only after the provider confirms it. Keep calendar credentials server-side.

    Return the successful response directly, without `withUsage`, `reportUsage`, or a `zc-usage` header. There is no charge to settle.
  </Step>

  <Step title="Test through your pay URL">
    Use a test calendar or a staging integration for booking tests. Fetch your storefront's `/auth.md` and follow its instructions to obtain an agent access token. Then request availability:

    ```sh theme={null}
    curl "https://acme.pay.zeroclick.io/demo/availability?timeZone=America%2FNew_York" \
      --header "Authorization: Bearer $AGENT_ACCESS_TOKEN"
    ```

    Choose a returned start time and save a request as `booking.json`. This illustrates the body; replace `start` with a currently available slot and use your test attendee's details:

    ```json theme={null}
    {
      "start": "2026-10-15T18:00:00.000Z",
      "timeZone": "America/New_York",
      "firstName": "Casey",
      "lastName": "Reed",
      "email": "casey@example.com",
      "company": "Example Co",
      "notes": "We want agents to request quotes through our API."
    }
    ```

    ```sh theme={null}
    curl --request POST "https://acme.pay.zeroclick.io/demo/bookings" \
      --header "Authorization: Bearer $AGENT_ACCESS_TOKEN" \
      --header "Content-Type: application/json" \
      --data-binary @booking.json
    ```

    A booking confirmation should include a booking id, status, and scheduled time. For example, these are fields returned by ZeroClick's calendar integration:

    ```json theme={null}
    {
      "booking_id": "11111111-1111-4111-8111-111111111111",
      "status": "confirmed",
      "scheduled_start": "2026-10-15T18:00:00.000Z",
      "scheduled_end": "2026-10-15T18:30:00.000Z",
      "time_zone": "America/New_York"
    }
    ```

    Run the [shared integration checks](/examples/free-actions#test-the-integration). For this example, also test an unavailable slot, invalid attendee details, and a replay of the same booking request. Each refusal should leave the calendar unchanged, and the replay should return the original booking.
  </Step>

  <Step title="Help agents find and finish the flow">
    Add [agent discovery signals](/website/enable-agent-traffic) to your website, or use the [Buy with AI widget](/website/buy-with-ai-widget) with booking copy such as **Book a demo with your AI** and `data-verb="Book"`.

    Describe the sequence in your service instructions: check availability, ask the user to choose a time, collect the required details, confirm the user's intent to book, submit the booking, and report the confirmed time. Include the email policy so the agent knows whether human verification is needed.

    You can inspect [ZeroClick's agent storefront](https://agents.zeroclick.ai) as a reference. For another free action, keep the same discovery, identity, and email choices, then replace the calendar call with your CRM submission, document delivery, or event registration.
  </Step>
</Steps>
