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

# Quickstart

> Add the ZeroClick billing guard to an existing API and serve your first paid agent request.

This guide adds the ZeroClick billing guard to one route of an existing API. When you finish, an unpaid agent request to that route gets a priced `402` challenge, a paid request gets served, and the usage and transaction appear in your dashboard.

<Info>
  You need a store that is set up in the [dashboard](https://dashboard.zeroclick.io). ZeroClick configures your store, services, and plans with you during onboarding. You also need an API that ZeroClick can reach at your store's upstream base URL. This guide uses a service `product-watch` with a meter `requests`; substitute your own slugs.
</Info>

<Steps>
  <Step title="Get your keys">
    Your integration runs on three keys, minted in the dashboard under your store's **Implementation** tab (or **Settings** for individual keys):

    * A **signing secret** (`zcsec_…`) and its key id (`hsec_…`), used to verify that requests really came from ZeroClick. The key id, or `kid`, appears alongside the secret in the dashboard.
    * A **usage read key** (`zc_…`, scope `usage:read`) for allowance checks.
    * A **usage write key** (`zc_…`, scope `usage:write`) for usage reporting.

    A single API key carrying both usage scopes works in place of the two scoped keys. Each secret is shown once when it is created, so store it in your secret manager right away:

    ```sh theme={null}
    ZEROCLICK_SIGNING_SECRET_KID=hsec_k5nq0v7m3d8p
    ZEROCLICK_SIGNING_SECRET=zcsec_…
    ZEROCLICK_API_KEY=zc_…
    ```

    See [keys and secrets](/integrate/keys-and-secrets) for scopes, rotation, and split read/write keys.
  </Step>

  <Step title="Install the SDK">
    <CodeGroup>
      ```sh TypeScript theme={null}
      pnpm add @zeroclickai/sellers
      ```

      ```sh Python theme={null}
      pip install zeroclick-sellers
      ```

      ```sh Go theme={null}
      go get cdn.zeroclick.io/sdks/sellers-go
      ```
    </CodeGroup>

    The TypeScript SDK is ESM and runs anywhere the web-standard `Request`, `Response`, and `fetch` exist, including current Node.js and edge runtimes. The Python SDK supports Python 3.10 and later, with sync and async clients. The Go SDK requires Go 1.24 and imports only the standard library.
  </Step>

  <Step title="Guard a route">
    Configure the client once, then guard the route: verify the signature, check the allowance, do the work, and settle usage on the successful response.

    <CodeGroup>
      ```ts TypeScript theme={null}
      import { createSeller } from "@zeroclickai/sellers";

      const zeroClick = createSeller({
        signingSecrets: {
          [process.env.ZEROCLICK_SIGNING_SECRET_KID!]:
            process.env.ZEROCLICK_SIGNING_SECRET!,
        },
        apiKey: process.env.ZEROCLICK_API_KEY!,
      });

      export async function handle(request: Request): Promise<Response> {
        const decision = await zeroClick.guard(request, {
          serviceSlug: "product-watch",
          usage: [{ meterSlug: "requests", quantity: 1 }],
        });

        if (decision.action === "deny") return decision.response;

        const response = Response.json({
          message: "Hello from the seller",
          zcRequestId: decision.context.zcRequestId,
        });

        return zeroClick.withUsage(response, [
          { serviceSlug: "product-watch", meterSlug: "requests", quantity: 1 },
        ]);
      }
      ```

      ```python Python theme={null}
      import os
      from fastapi import FastAPI, Request
      from fastapi.responses import Response

      from zeroclick_sellers import (
          SyncUsageItem,
          UsageItem,
          ZcResponse,
          create_async_seller,
      )
      from zeroclick_sellers.adapters import zc_request_from_asgi_scope

      zeroclick = create_async_seller(
          signing_secrets={
              os.environ["ZEROCLICK_SIGNING_SECRET_KID"]: os.environ[
                  "ZEROCLICK_SIGNING_SECRET"
              ]
          },
          api_key=os.environ["ZEROCLICK_API_KEY"],
      )
      app = FastAPI()


      def to_fastapi(response: ZcResponse) -> Response:
          return Response(
              content=response.body,
              status_code=response.status,
              headers=dict(response.headers),
          )


      @app.post("/v1/product-watch")
      async def product_watch(request: Request) -> Response:
          zc_request = zc_request_from_asgi_scope(request.scope, await request.body())

          decision = await zeroclick.guard(
              zc_request,
              service_slug="product-watch",
              usage=[UsageItem(meter_slug="requests", quantity=1)],
          )
          if decision.action == "deny":
              return to_fastapi(decision.response)

          result = do_the_work(owner=decision.context.zc_agent_id)

          return to_fastapi(
              zeroclick.with_usage(
                  ZcResponse.json(result),
                  [
                      SyncUsageItem(
                          service_slug="product-watch",
                          meter_slug="requests",
                          quantity=1,
                      )
                  ],
              )
          )
      ```

      ```go Go theme={null}
      package main

      import (
      	"encoding/json"
      	"log"
      	"net/http"
      	"os"

      	sellers "cdn.zeroclick.io/sdks/sellers-go"
      )

      func main() {
      	secrets, err := sellers.SecretsFromEnv() // ZEROCLICK_SIGNING_SECRETS
      	if err != nil {
      		log.Fatal(err)
      	}

      	seller, err := sellers.New(sellers.Config{
      		APIKey:         os.Getenv("ZEROCLICK_API_KEY"),
      		ServiceSlug:    "product-watch",
      		SigningSecrets: secrets,
      		Logger:         log.Default(),
      	})
      	if err != nil {
      		log.Fatal(err)
      	}

      	mux := http.NewServeMux()
      	mux.Handle("/v1/product-watch", seller.Meter(sellers.PerRequest("requests", 1))(
      		http.HandlerFunc(productWatch)))

      	log.Fatal(http.ListenAndServe(":8080", mux))
      }

      func productWatch(w http.ResponseWriter, r *http.Request) {
      	zc, _ := sellers.FromContext(r.Context()) // zc.AgentID, zc.RequestID

      	w.Header().Set("content-type", "application/json")
      	json.NewEncoder(w).Encode(map[string]any{"ok": true, "agent": zc.AgentID})
      }
      ```
    </CodeGroup>

    The guard verifies the signature before it calls the allowance API. Its result is a decision, not an exception. A denial carries the exact response to return: `401` for a bad signature, the `402 payment_required` refusal for a business denial, or `503` under a fail-closed outage policy. In Go, the `Meter` middleware returns the denial and sets the `zc-usage` header for you. In TypeScript and Python, you return `decision.response` and settle usage with `withUsage`.
  </Step>

  <Step title="Verify the integration">
    Deploy the guarded route where ZeroClick can reach it, then open your store's **Implementation** tab in the dashboard and run the API setup verification. ZeroClick sends an unpaid probe to your endpoint and confirms it answers with the priced `402` refusal and reports usage correctly.

    You can also test the guard locally: a plain request with no ZeroClick headers must get `401 {"error":"invalid_zeroclick_signature"}`. Only signed requests from ZeroClick reach your handler.
  </Step>

  <Step title="Serve paid traffic">
    That's the whole integration. Agents now transact with the guarded route through your pay URL: an unpaid call gets one priced `402` challenge, the agent pays with x402 or MPP and retries, and ZeroClick forwards the signed request to your API.

    <Check>
      Each paid request appears under **Transactions** in the dashboard, with the agent, service, meter quantities, and settled amount.
    </Check>
  </Step>
</Steps>

## Next steps

<Columns cols={2}>
  <Card title="The integration contract" icon="plug" href="/integrate/overview">
    Everything your API must verify, check, and return, on one page.
  </Card>

  <Card title="How ZeroClick works" icon="route" href="/concepts/how-zeroclick-works">
    The full request lifecycle: challenge, payment, signed forward, settlement.
  </Card>

  <Card title="Charge up to a maximum" icon="gauge" href="/integrate/charge-up-to-a-maximum">
    Bill work you can't size up front, like output tokens.
  </Card>

  <Card title="SDK reference" icon="package" href="/sdks/overview">
    Configuration and full API surface for each SDK.
  </Card>
</Columns>
