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

# Partners

> Give each of your clients API access to their own visitors' journeys

If you resell Maverick to your own customers, you can expose visitor journey data
to each of them through the API — without any client being able to see another
client's data.

## How partner accounts are structured

You have one Maverick account. Each of your clients is a **tracked domain** on that
account, with an optional **client reference** (`clientRef`) — your own label for
that client.

Every visitor identified across all your clients' sites lives under your one
account. What separates them is the domain they were seen on.

## Attribution on every record

People and events both carry the client they belong to:

```json theme={null}
{
  "eventType": "click",
  "timestamp": "2026-07-24T18:10:00Z",
  "url": "https://acme.com/product",
  "domain": "acme.com",
  "clientRef": "ACME-1"
}
```

Filter to one client with either `domain` or `client_ref`:

```bash theme={null}
curl -H "X-API-Key: mk_live_..." \
  "https://api-v1.maverickintelligence.co/v1/people?client_ref=ACME-1"
```

`domain` matches subdomains too — `acme.com` includes `app.acme.com`. If a client
has several domains registered under one `clientRef`, `client_ref` covers them all.

## Giving a client direct access

Rather than relaying data through your own product, you can issue each client an
API key **scoped to their domain only**. In the dashboard, go to
**Partner → Domains** and select **Enable API** on a client's domain.

The key is shown once. It behaves like any other API key, with one difference:
it can only ever read that one client's data.

* `/v1/people` returns only that client's visitors.
* `/v1/people/{id}/events` returns only events from that client's domain.
* Another client's person ID returns `404`, not an empty result — a scoped key
  cannot confirm that visitors outside its scope exist.
* Passing `?domain=` for someone else's domain returns nothing. The scope is a
  ceiling, not a default.

Each scoped key gets its own hourly rate limit, so one client's traffic never
consumes another's.

**Rotating and revoking.** Selecting *Rotate key* issues a new key and stops the
old one working immediately. *Revoke key* removes API access while leaving
tracking untouched.

## Reading a journey

A journey is the ordered stream of everything a visitor did:

```bash theme={null}
curl -H "X-API-Key: mk_live_..." \
  "https://api-v1.maverickintelligence.co/v1/people/{id}/events?limit=100"
```

Two things to build for:

**Journeys vary enormously.** One visitor has three events; another has several
thousand. Always page with `cursor` rather than assuming you got everything in one
response.

**Event shape is open-ended.** `eventId`, `sessionId`, `eventType`, `timestamp` and
`url` are always present. Everything else depends on the event type, and new event
types and fields appear as the tracking pixel evolves — without an API version
change. Treat `eventType` as an open set and ignore fields you do not recognise
rather than rejecting the payload.

Narrow to one kind of step with `event_type`:

```bash theme={null}
curl -H "X-API-Key: mk_live_..." \
  "https://api-v1.maverickintelligence.co/v1/people/{id}/events?event_type=form_submission"
```

## Getting journeys pushed instead of polled

If you'd rather receive activity than fetch it, subscribe to the
**`person.activity`** event on your partner webhook (Partner → Partner Webhook).

This event is **opt-in**. It is far higher volume than `person.identified` — one
engaged visitor fires dozens of events — so it is off by default and you must
switch it on deliberately.

Deliveries are **batched per visitor**: you get one call carrying that person's
new events as an array, not one call per event.

```json theme={null}
{
  "webhookId": "wh_a1b2c3d4e5f6a7b8",
  "event": "person.activity",
  "timestamp": "2026-07-24T18:10:04Z",
  "domain": "acme.com",
  "clientRef": "ACME-1",
  "data": {
    "person": { "id": "p_...", "email": "visitor@example.com" },
    "events": [
      { "eventType": "page_view", "timestamp": "2026-07-24T18:09:00Z", "url": "https://acme.com/" },
      { "eventType": "click", "timestamp": "2026-07-24T18:10:00Z", "url": "https://acme.com/", "clickElement": "Product" }
    ],
    "eventCount": 2,
    "truncated": false
  }
}
```

Events arrive **oldest-first**, so a journey reads forwards. If a visitor is
active enough to exceed the per-delivery cap, `truncated` is `true` — page the
API for the complete journey rather than assuming the batch is whole.

Payloads are signed with HMAC-SHA256 exactly like every other webhook event.
