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

# Quickstart

> Receive your first Fit Pro Tracker webhook in about 10 minutes.

This guide walks through subscribing to your first webhook event, firing a test payload from the FPT admin, and verifying the signature. By the end you'll have a working endpoint that confirms `contact.status_changed` events end-to-end.

<Note>
  You need a Fit Pro Tracker account with **organization admin** access (or location admin if you're scoping to a single location). If you don't have that yet, contact your account owner.
</Note>

## 1. Stand up a temporary endpoint

For initial testing we recommend [webhook.site](https://webhook.site) — it gives you a unique URL that captures incoming POSTs with their full payload and headers. Perfect for verifying delivery before you write your real handler.

<Steps>
  <Step title="Open webhook.site">
    Open [webhook.site](https://webhook.site) in a new tab. You'll be auto-assigned a unique URL like `https://webhook.site/8a3f...`.
  </Step>

  <Step title="Copy your unique URL">
    Keep this tab open — incoming requests will appear here in real time.
  </Step>
</Steps>

## 2. Register the subscription in FPT

<Steps>
  <Step title="Open Webhook Endpoints in the FPT admin">
    Navigate to **Settings → Webhook Endpoints**.
  </Step>

  <Step title="Click Add Endpoint">
    A dialog appears with three fields:

    * **URL** — paste your webhook.site URL
    * **Events** — check the events you want. For this quickstart, pick `contact.status_changed` (fires when a Lead converts to a Member, etc.). You can check all four — the others (`contact.created`, `contact.sub_group_changed`, `contact.deleted`) follow the same shape.
    * **PII categories** — leave at default for the quickstart
  </Step>

  <Step title="Save">
    The endpoint is now active. FPT will start delivering matching events within seconds of the next status change at your location.
  </Step>

  <Step title="Grab your signing secret">
    The signing secret was returned in the Save response. Save it now — you'll need it for signature verification later. You won't be able to view it again; you can rotate it if lost.
  </Step>
</Steps>

## 3. Trigger an event

The fastest way to fire a real event right now: click the **paper-plane (Send test event)** icon on your new endpoint's row in the FPT admin. A dialog opens with radio buttons for each event type your subscription is subscribed to, plus a **live payload preview** showing exactly what will be POSTed.

<Steps>
  <Step title="Pick an event type">
    Select `contact.status_changed` to see the typed-event shape (the most informative).
  </Step>

  <Step title="Click Send test event">
    FPT signs and POSTs a synthetic payload to your webhook.site URL using your real signing secret. Within \~1 second you'll see the request land on webhook.site.
  </Step>
</Steps>

Test events are clearly marked so your handler can filter them:

* `X-FPT-Test-Event: true` header
* `_test: true` flag inside `data`
* `contactId: -1` (synthetic, never collides with a real contact)

You can also trigger a **real** event by moving any test contact between lifecycle groups (Lead → Member) in the FPT admin. That fires `contact.status_changed` against the same endpoint.

## 4. Inspect what you got

On webhook.site you'll see a request with these key bits:

```http theme={null}
POST / HTTP/1.1
Content-Type: application/json
User-Agent: FitProTracker-Webhook/1.0 (test)
X-FPT-Event-Id: 9f1c7e2a8c4d4b1b9e3f5a6d7c8b9a0e
X-FPT-Test-Event: true
X-FPT-Signature: t=1717023600,v1=a3f...
```

```json theme={null}
{
  "eventId":        "9f1c7e2a8c4d4b1b9e3f5a6d7c8b9a0e",
  "eventType":      "contact.status_changed",
  "eventTimestamp": "2026-06-10T23:45:00Z",
  "locationId":     1234,
  "organizationId": 5678,
  "apiVersion":     "2026-05-29",
  "data": {
    "contactId":          9876,
    "firstName":          "Test",
    "lastName":           "Webhook",
    "fullName":           "Test Webhook",
    "email":              "test@webhook.fitprotracker.com",
    "phone":              "+15555550100",
    "isActive":           true,
    "contactGroupId":     3,
    "subGroupId":         null,
    "subGroupName":       null,
    "previousStatusId":   1,
    "newStatusId":        3,
    "previousStatusName": "Leads",
    "newStatusName":      "Members",
    "_test":              true
  }
}
```

That's the full envelope. The shape is consistent across every event type — only the `eventType` and `data` fields vary by event. Identity fields (firstName, lastName, email, phone, etc.) are included in every typed event so you can act on a single payload without round-tripping for state.

## 5. Verify the signature

Now do this for real — using a small script. We provide samples in three languages on the [Signature verification](/webhooks/signing) page; the one-liner concept:

```javascript theme={null}
const expected = hmac_sha256(secret, `${timestamp}.${rawBody}`);
if (expected !== signature) throw new Error("invalid signature");
```

If the signature checks out, you have a verified, idempotency-keyable, partner-ready event handler. 🎉

## Next steps

<CardGroup cols={2}>
  <Card title="The envelope shape in full" icon="envelope" href="/webhooks/envelope">
    Every field, every type, every quirk.
  </Card>

  <Card title="Idempotency contract" icon="arrows-rotate" href="/webhooks/delivery">
    Why you must dedupe by EventId.
  </Card>

  <Card title="HMAC verification, in code" icon="shield" href="/webhooks/signing">
    Production-ready samples in JS, Python, C#.
  </Card>

  <Card title="Event catalog" icon="list-check" href="/events/overview">
    What each event means and what's in its `data`.
  </Card>
</CardGroup>
