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

# Configuration & go-live

> ZeroClick dashboard setup, SSM secrets, and the end-to-end verification checklist.

Prices live in your ZeroClick catalog, never in code. The code only declares
quantities against the meter slugs.

## Service + meters (ZeroClick dashboard)

| Setting | Value |
| - | - |
| Service slug | `momentra-events` |
| Meter (index) | `orgs_index` (qty 1 per `POST /api/v1/orgs`) |
| Meter (events) | `events_pull` (qty 1 per events pull) |
| Free routes | `/api/v1/search/businesses`, `/api/v1/search/events`, `/api/v1/orgs/{jobId}`, `/api/v1/report` |

### Free trial / included units

To give agents a free trial, set `includedUnits: 3` on the `orgs_index` meter and
`includedUnits: 50` on the `events_pull` meter price in the ZeroClick dashboard.
ZeroClick owns this accounting — the backend stays stateless per agent (see [Free
and paid](/zeroclick/free-and-paid)).

## Dashboard steps

<Steps>
  <Step title="Create the service">
    Create the service `momentra-events` (or change `zeroClickServiceSlug` to
    match an existing one).
  </Step>

  <Step title="Define the meters">
    `orgs_index` (charged once per `POST /api/v1/orgs`) and `events_pull` (charged
    once per `GET /api/v1/businesses/{id}/events`). `search/*`, `orgs/{jobId}`,
    and `report` are free — no meter.
  </Step>

  <Step title="Set the upstream base URL">
    Set it to the storefront host — **origin only, no path segment**:
    `https://prod.agent.us.api.momentra.org`.
  </Step>

  <Step title="Set included units">
    `includedUnits: 3` on `orgs_index` and `includedUnits: 50` on `events_pull`.
  </Step>
</Steps>

<Warning>
  Do **not** append `/api/v1` to the base URL. ZeroClick's proxy preserves the
  incoming request path verbatim, and every documented path already begins with
  `/api/v1`. If `/api/v1` is baked into the base URL too, requests resolve to
  `/api/v1/api/v1/...` (or, if the base path is dropped, to `/businesses/...` with
  no prefix) — either way API Gateway has no matching route and returns `403
      Missing Authentication Token`. The base URL owns the host; the paths own the
  `/api/v1` prefix.
</Warning>

## Secrets in SSM

The agentic Lambdas read these from SSM Parameter Store (agent account
`018468310169`, `us-east-2`). They are cached at cold start, so after changing a
value force a cold start (bump `SECRET_REFRESH_NONCE` in `src/events-api.ts` and
redeploy, or update a function's config).

### Signing secret — must be JSON keyed by the kid

ZeroClick signs each request with `kid=hsec_…` and the guard resolves the secret
by that kid. A raw string binds only to kid `default` and every request fails
`unknown_kid` → 401. Store it as a `{kid: secret}` JSON object:

```bash theme={null}
aws ssm put-parameter --overwrite --type SecureString \
  --name /momentra/zeroclick/signing-secret \
  --value '{"hsec_<kid>":"zcsec_<signing-secret>"}' --region us-east-2
```

During rotation, hold both kids in the JSON until the old one ages out.

### Usage keys — split read/write

The allowance check (`POST /v1/usage/check`, scope `usage:read`) and async
reports (`POST /v1/usage`, scope `usage:write`) use separate keys. A 4xx here
(e.g. a wrong/placeholder key) is a permanent config error → the guard returns
503 (never fail-open on a 4xx).

```bash theme={null}
aws ssm put-parameter --overwrite --type SecureString \
  --name /momentra/zeroclick/usage-read-key  --value 'zc_<usage:read>'  --region us-east-2
aws ssm put-parameter --overwrite --type SecureString \
  --name /momentra/zeroclick/usage-write-key --value 'zc_<usage:write>' --region us-east-2
```

These paths come from `ZEROCLICK_USAGE_READ_KEY_SSM_PATH` /
`ZEROCLICK_USAGE_WRITE_KEY_SSM_PATH`; if unset the code falls back to the combined
`/momentra/zeroclick/api-key` (a single key carrying both scopes also works).

### Allowance API base URL

Default `https://api.zeroclick.io` (`ZEROCLICK_API_BASE_URL`). The allowance
check sends `{ zcRequestId, serviceSlug, usage }` — `serviceSlug`
(`momentra-events`) is required and read from `ZEROCLICK_SERVICE_SLUG`.

## Verify end to end

<Steps>
  <Step title="Unsigned paid route">
    → `401 {"error":"invalid_zeroclick_signature"}` (the guard rejects it —
    expected).
  </Step>

  <Step title="Signed test for POST /api/v1/orgs">
    → **402** (payment\_required, entitlement working) or **202** (entitled +
    served). Both satisfy the contract.
  </Step>

  <Step title="Interpret failures">
    A `503` means the allowance check got a 4xx (usually a bad usage key); a `401`
    on a signed request means a kid/secret mismatch.
  </Step>
</Steps>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.