> ## 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.

# Free actions

> Shared setup for free agent actions, with independent choices for ZeroClick email policy and your endpoint inputs.

A free action lets an agent complete a task for its user without paying: book a demo, submit a lead, download a white paper, or register for a webinar. Your API collects the inputs, performs the action, and returns a useful result.

You can think of these as \$0 transactions: the agent completes an action without a payment. The reference examples below use unmetered endpoints: they serve the action without checking a billable allowance or reporting usage. No card or wallet charge, payment record, or trial credit is needed.

## Choose an example

These are reference designs to adapt, not prescribed seller APIs. The endpoint paths, input fields, and response shapes illustrate possible workflows. Your product decides what to collect and how to fulfill the action; the shared ZeroClick integration below applies across them.

| Reference example                                                       | What it demonstrates                                                             |
| ----------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| [Book a demo](/examples/free-actions/book-a-demo)                       | Check availability, collect attendee details, and confirm a booking.             |
| [Capture a lead](/examples/free-actions/capture-a-lead)                 | Submit requirements to a CRM and return a request reference.                     |
| [Deliver a white paper](/examples/free-actions/deliver-a-white-paper)   | Select a document and return a download URL, with or without contact collection. |
| [Register for a webinar](/examples/free-actions/register-for-a-webinar) | Select an event, register an attendee, and return joining instructions.          |

You can also adapt these patterns for a waitlist, a quote request, or another free action your API can fulfill.

## Before you start

You need a store configured in the [dashboard](https://dashboard.zeroclick.io), an upstream API ZeroClick can reach, and a [signing secret and key id](/integrate/keys-and-secrets). ZeroClick configures your store and catalog with you during onboarding.

Configure this shared integration once, then implement the endpoints for your chosen example. The API behind each action—your calendar, CRM, document service, or event platform—is your responsibility.

## Set up ZeroClick

<Steps titleSize="h3">
  <Step title="Choose your email requirements" id="choose-your-email-requirements">
    Make two independent choices:

    | Choice                                                             | Who defines it?                                               |
    | ------------------------------------------------------------------ | ------------------------------------------------------------- |
    | Whether the agent owner's verified email is shared or required     | **ZeroClick**, through the plan's `verifiedEmailPolicy`.      |
    | Whether a request includes a contact, attendee, or recipient email | **You**, through your endpoint's input schema and validation. |

    <Info>
      A plan's email requirement is a ZeroClick concept. It has no effect on which fields your endpoint asks for. **Off** does not prohibit an email input, **Request** does not prompt for one, and **Require** does not verify an address supplied in the request body.
    </Info>

    If you need to enforce limits per verified email, set ZeroClick's email policy to **Require**. After verifying the request, use `zc-buyer-email` as the key for limits enforced by your application—for example, one demo booking per email per day. ZeroClick verifies the email; your API enforces the limit.

    In your store's **Pricing & Plans**, create or edit a **Pay as you go** plan and set **Verified email**:

    | Setting and API value     | ZeroClick behavior                                                                                                                      |
    | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
    | **Off** (`off`)           | Does not share the agent owner's email or require email verification.                                                                   |
    | **Request** (`requested`) | Shares the agent owner's verified email when available. Its absence does not block the call.                                            |
    | **Require** (`required`)  | Requires the agent's human to claim it with a verified email before the call proceeds. Otherwise returns `403 verified_email_required`. |

    You can also set `verifiedEmailPolicy` on an existing plan through the API. For example, to require verification:

    ```sh theme={null}
    curl --request PATCH "https://api.zeroclick.io/v1/plans/$PLAN_ID" \
      --header "Authorization: Bearer $ZEROCLICK_ADMIN_KEY" \
      --header "Content-Type: application/json" \
      --data '{"verifiedEmailPolicy":"required"}'
    ```

    Use an API key with `admin:write`. Set the value to `off` or `requested` for the other choices.

    For the unmetered reference examples, the plan supplies the email policy and the endpoint remains unbilled. Leave these endpoints without meter links, and do not add a paid allowance check to their handlers. ZeroClick advertises endpoints without meter links at \$0 in its discovery spec.

    <Note>
      This policy is per plan, not per endpoint. Without an existing access grant, a pay-as-you-go plan with **Require** gates calls across the storefront, including availability checks. Calls using an existing access grant follow the funding plan's policy. Align the policies of every plan that can fund this workflow; use separate storefronts if you need different entry requirements for different public flows.
    </Note>

    **Request** does not ask the agent to fill in an email field. It shares an already verified email through `zc-buyer-email` when available. If the human claims the agent later, subsequent proxied calls can carry the email; your earlier lead record is not automatically updated.

    Separately, choose what your endpoint accepts. You can require an attendee email with **Off**, offer an optional contact email with **Request**, or accept no email input at all with **Require**. An address submitted by an agent remains unverified unless your own verification process proves ownership.

    For example, a demo booking may accept `attendeeEmail` for a colleague while ZeroClick shares the agent owner's email. Preserve both meanings. If your product only allows users to book for themselves, explicitly enforce that rule in your handler; ZeroClick does not match these addresses for you.

    See [the verified email policy](/concepts/plans-and-pricing#the-verified-email-policy) for the full contract.
  </Step>

  <Step title="Describe your action in the catalog">
    Add a service with a name and slug that describe the action. Register its endpoints and request and response schemas, leaving the free endpoints without meter links. Document the action's outcome, its \$0 cost, and the inputs your API needs.

    Explain the ZeroClick email policy separately from input requirements. For example: “ZeroClick email verification is optional. Booking requires an attendee email for the calendar invitation.” Use the endpoint suggestions on each example page as a starting point.
  </Step>

  <Step title="Verify the request and identify the agent" id="verify-the-request-and-identify-the-agent">
    Install the seller SDK:

    ```sh theme={null}
    pnpm add @zeroclickai/sellers
    ```

    Use `guardIdentity` before parsing the body or performing the action. It verifies the ZeroClick signature and requires an agent credential without making an allowance call. This is the guard ZeroClick uses for its demo endpoints.

    ```ts theme={null}
    import { guardIdentity } from "@zeroclickai/sellers";

    export async function verifyFreeActionRequest(
      request: Request,
      serviceSlug: string,
    ) {
      return guardIdentity(
        request,
        { serviceSlug },
        {
          signingSecrets: {
            [process.env.ZEROCLICK_SIGNING_SECRET_KID!]:
              process.env.ZEROCLICK_SIGNING_SECRET!,
          },
        },
      );
    }
    ```

    Pass the original request, including its unchanged path, query, and body. The standalone guard needs only your signing configuration; there is no usage API key to configure for this flow.

    An agent without a credential receives `401 bearer_required` from the pay URL and follows that storefront's `/auth.md` registration recipe. It retries with `Authorization: Bearer <access token>`. Registration alone is enough for **Off** and **Request**. For **Require**, the human also completes the claim and email verification described in `/auth.md` before retrying.

    `guardIdentity` establishes an agent id; the plan policy enforces email verification. These are separate checks. If your handler does not need an agent id, you can use [`verifyRequest`](/integrate/verify-requests) instead. This changes the handler's identity check, not the plan's email policy.
  </Step>

  <Step title="Handle seller inputs and the verified buyer email">
    Once the guard allows a request, parse and validate your input schema. A required input missing from the body is an application validation error, even when ZeroClick's email policy is **Off**. A valid contact email in the body cannot satisfy ZeroClick's **Require** policy.

    If your plan shares a verified email, read it after request verification:

    ```ts theme={null}
    const verifiedBuyerEmail = request.headers.get("zc-buyer-email");
    ```

    Under **Request**, allow this value to be absent. If your application needs it to fulfill an action, configure **Require** and reject the action if the header is unexpectedly absent. Keep `verifiedBuyerEmail` separate from contact or attendee fields; decide explicitly which address each downstream operation uses.

    Follow the [header trust rules](/resources/headers): `zc-buyer-email` is asserted by ZeroClick over the authenticated channel, but is not itself covered by the request signature. It must not by itself authorize access to existing customer records.

    Call your fulfillment system only after validation. Return its result directly, without `withUsage`, `reportUsage`, or a `zc-usage` header. There is no charge to settle.
  </Step>
</Steps>

## Reduce abuse of free actions

For per-email limits, use **Require** and key your application's counters by `zc-buyer-email` after request verification. Check the limit before performing the action, and update the counter atomically so simultaneous requests cannot bypass it. A submitted contact or attendee email remains a separate input and does not establish a verified identity.

Email verification does not itself rate-limit requests or prove that each email belongs to a different person. Keep retry deduplication and request rate limits appropriate to your API.

For metered free allowances enforced by ZeroClick, see [pay-as-you-go included units](/integrate/free-and-identity-endpoints#included-free-units). That approach uses the billing guard and usage reporting instead of the unmetered flow in these examples.

## Test the integration

Use a staging integration for actions that create records or send invitations. Fetch your storefront's `/auth.md` and follow its instructions to obtain an agent access token. Call your pay URL with `Authorization: Bearer <access token>`.

Test ZeroClick policy and seller validation independently:

| Check                                                               | Expected result                                                                                    |
| ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| **Off**, with an unclaimed agent                                    | The policy allows the call; no verified buyer email is shared.                                     |
| **Request**, with and without a verified human claim                | Both calls proceed; only the verified one carries `zc-buyer-email`.                                |
| **Require**, before and after a verified human claim                | Before claiming, `403 verified_email_required`; after claiming, the call proceeds with the header. |
| Required seller email omitted, with **Off**                         | Your handler rejects the input, such as with `400 invalid_request`.                                |
| Valid seller email supplied, with **Require** and no verified claim | ZeroClick still returns `403 verified_email_required`.                                             |
| Different attendee and verified buyer addresses                     | Your handler applies your own rule for acting on behalf of someone else.                           |

Also check that unsigned requests to your upstream fail, invalid inputs cause no side effects, and retries do not duplicate the action. A new request may have a new `zcRequestId`; use your own stable operation key when you need deduplication across separate agent requests. A successful free call should not ask for a payment credential or consume a paid allowance.

## Help agents discover the action

Add [agent discovery signals](/website/enable-agent-traffic) or the [Buy with AI widget](/website/buy-with-ai-widget) to your website. Describe the sequence in your service instructions: collect inputs, confirm the user's intent, submit the action, and report the result. Each example page supplies a suggested sequence to adapt.
