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

# Deliver a white paper

> A reference flow for selecting a document and returning a free download, with optional contact collection.

Let an agent find a relevant white paper and retrieve a download URL for its user. The reference flow delivers the document directly, so an email address is optional.

<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:** choose `off` when document delivery needs no verified agent-owner email.
* **Seller input:** accept optional `contactEmail` only if you have a defined use for it, such as sending a copy when requested. Omit the field entirely if you do not need it.
* **Fulfillment:** return a download URL from your document service. A direct download works without any email address.

The [two email choices](/examples/free-actions#choose-your-email-requirements) remain independent in every variant. Changing a ZeroClick plan policy does not add, remove, or verify an email field in your endpoint.

For a finite free allowance, such as five downloads per verified buyer, adapt this flow using [pay-as-you-go included units](/integrate/free-and-identity-endpoints#included-free-units). That variant uses the billing guard and usage reporting instead of the unmetered guard below.

## Build the example

<Steps titleSize="h3">
  <Step title="Describe the action and endpoints">
    Add a service such as `white-paper` and describe its outcome and \$0 cost. Register your endpoint schemas without meter links, following [shared setup](/examples/free-actions). These paths are suggestions for your API:

    | Suggested endpoint                          | Purpose                                               |
    | ------------------------------------------- | ----------------------------------------------------- |
    | `GET /white-papers`                         | List document ids, titles, descriptions, and formats. |
    | `POST /white-papers/{documentId}/downloads` | Return a download URL for the selected document.      |

    These endpoints belong to your upstream API and are called through your pay URL. They are not built-in ZeroClick API operations.
  </Step>

  <Step title="Define the seller inputs">
    This reference design uses the following inputs. Adapt their names and required status to your product:

    | Input          | Required in this example | Purpose                                                                      |
    | -------------- | ------------------------ | ---------------------------------------------------------------------------- |
    | `documentId`   | Yes, in path             | The document selected from your listing.                                     |
    | `contactEmail` | No                       | A user-supplied address, if your workflow offers email delivery.             |
    | `sendCopy`     | No                       | Whether the user wants an emailed copy; defaults to `false` in this example. |
    | `operationId`  | Yes                      | A caller-generated identifier reused for retries, especially email delivery. |

    For example, the request body could be:

    ```json theme={null}
    {
      "sendCopy": false,
      "operationId": "download-guide-001"
    }
    ```
  </Step>

  <Step title="Validate and fulfill the request">
    Use the `verifyFreeActionRequest` helper from [shared setup](/examples/free-actions#verify-the-request-and-identify-the-agent) with service slug `white-paper`. Return a guard denial immediately, then parse and validate your input. Return `400` for malformed or missing fields before creating any records or sending messages.

    Look up the document by id and check that it is available. For direct delivery, return a URL your user can actually open. If it expires, include the expiration in the response and document how to obtain a new one.

    If `sendCopy` is `true`, require `contactEmail` in your input validation before requesting email delivery. This conditional requirement is your application rule and is independent of ZeroClick's **Off** setting. Accepting that address does not verify it.

    Deduplicate email delivery by the verified agent id and `operationId` so retries do not send repeated copies. Report whether the email was queued separately from the download result. Keep storage credentials on your server.

    Return `200 OK` with the download result. If you use signed URLs, include an `expiresAt` timestamp. Do not claim that a queued email was delivered.

    ```json theme={null}
    {
      "documentId": "agent-commerce-guide",
      "title": "A guide to agent commerce",
      "downloadUrl": "https://downloads.example.com/agent-commerce-guide.pdf",
      "contentType": "application/pdf",
      "emailStatus": "not_requested"
    }
    ```

    Return the response without reporting billable usage. Your application supplies the fulfillment logic and error handling; the seller SDK supplies request verification.
  </Step>

  <Step title="Test through your pay URL">
    Use a staging integration. Save the example body as `request.json`, replace its values and the placeholder pay URL below, and get an agent token through your storefront's `/auth.md` recipe.

    ```sh theme={null}
    curl --request POST "https://acme.pay.zeroclick.io/white-papers/agent-commerce-guide/downloads" \
      --header "Authorization: Bearer $AGENT_ACCESS_TOKEN" \
      --header "Content-Type: application/json" \
      --data-binary @request.json
    ```

    Run the [shared integration checks](/examples/free-actions#test-the-integration), then test the cases specific to this action:

    * Request the direct download without `contactEmail`: the result includes a usable URL.
    * Set `sendCopy` to `true` without an address: your API rejects the input even though ZeroClick policy is **Off**.
    * Request an unknown document: return `404` rather than a broken download URL.
    * Repeat an email request with the same `operationId`: only one copy is queued.
    * Open the returned URL from the intended recipient's environment; check expiration behavior if applicable.
  </Step>

  <Step title="Describe the agent's workflow">
    List the available documents, choose one relevant to the user's request, retrieve its URL, and return the title and link. Ask for an email only if the user wants email delivery. If you choose to gate downloads on contact collection, document that as a seller input requirement; requiring the ZeroClick owner's verified email is a separate decision.

    Publish these instructions with your service and add [discovery signals](/website/enable-agent-traffic) on the relevant website page.
  </Step>
</Steps>
