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

# External references

> Bind existing clients and durably deduplicate client, exercise and programme creation within your integration.

An external reference is an opaque ID from your system. Its namespace consists
of the authenticated company, the stable OAuth client ID and the resource type.
The same ID can exist in another company, another integration or another resource
type. Rotating a client secret preserves this namespace. Creating a replacement
OAuth client creates a separate namespace; it does not transfer references.

References have no 24-hour expiry. Durable unique indexes allow at most one
resource per external ID and one external ID per resource in each namespace.
The server derives ownership from the verified OAuth token. Callers cannot set
company IDs, source IDs or internal import metadata to claim another namespace.

## Bind or edit an existing client

First find the client through the company-scoped client resources. Use this
operation to bind a client that is already linked to your company:

```bash theme={null}
curl -X PUT \
  'https://api.fitsociety.io/public/v1/clients/66f7b8b1e13c8d25f4d3d90c/external-reference' \
  -H "Authorization: Bearer $FITSOCIETY_ACCESS_TOKEN" \
  -H 'Idempotency-Key: member-123-reference-r1' \
  -H 'Content-Type: application/json' \
  -d '{"externalId":"member-123","revision":1}'
```

This requires `clients:write`. `externalId` must be a nonblank string of at most
200 characters without control characters; surrounding whitespace is trimmed.
The first binding requires `revision: 1`. Revisions must be JSON integers from
1 through 9007199254740991.

To edit the ID, send the same client path with a strictly greater revision and a
new idempotency key for that logical update:

```bash theme={null}
curl -X PUT \
  'https://api.fitsociety.io/public/v1/clients/66f7b8b1e13c8d25f4d3d90c/external-reference' \
  -H "Authorization: Bearer $FITSOCIETY_ACCESS_TOKEN" \
  -H 'Idempotency-Key: member-456-reference-r2' \
  -H 'Content-Type: application/json' \
  -d '{"externalId":"member-456","revision":2}'
```

An identical `externalId` and revision replays successfully. A stale revision,
a different ID with the same revision, or an ID already bound to another client
returns `409`. The binding's client cannot be changed by this operation.
Editing replaces the old ID, so update your local register and stop retrying
creation or lookup with the old ID. This operation does not change app access,
modify the global client profile or take over a manually managed relationship.

## Read and look up your reference

These reads require `clients:read`:

```bash theme={null}
curl \
  'https://api.fitsociety.io/public/v1/clients/66f7b8b1e13c8d25f4d3d90c/external-reference' \
  -H "Authorization: Bearer $FITSOCIETY_ACCESS_TOKEN"

curl --get 'https://api.fitsociety.io/public/v1/clients' \
  -H "Authorization: Bearer $FITSOCIETY_ACCESS_TOKEN" \
  --data-urlencode 'externalId=member-456' \
  --data-urlencode 'limit=1'
```

The dedicated read returns `data.externalReference`, or `null` if your source
has no binding. Client detail and list items expose the same optional object:

```json theme={null}
{
  "externalId": "member-456",
  "revision": 2
}
```

The exact `externalId` filter applies before counting and pagination and combines
with the existing email, search and status filters. Other integrations' IDs never
appear in your output or match this filter. Company relationship visibility
continues to apply; a reference does not grant access to an unavailable client.

## Durably deduplicate creation

Pass an optional **string** `externalReference` to the existing create resource.
Creation chooses initial revision 1; the explicit client binding operation uses
the `{externalId, revision}` object instead.

```bash theme={null}
curl -X POST 'https://api.fitsociety.io/public/v1/clients' \
  -H "Authorization: Bearer $FITSOCIETY_ACCESS_TOKEN" \
  -H 'Idempotency-Key: member-123-create-attempt-1' \
  -H 'Content-Type: application/json' \
  -d '{"firstName":"Jane","lastName":"Doe","email":"jane@example.com","inviteByEmail":false,"externalReference":"member-123"}'
```

The normal assigned-coach configuration and create validation still apply.
An existing global account can be linked to a new company relationship without
changing its profile. For a client already linked to your company, use the
explicit reference PUT above.

Referenced creation also supports these Workout V2 resources with their existing
write scopes, required fields, consent checks and company resource checks:

* `POST /public/v1/workout/exercises`
* `POST /public/v1/workout/clients/{clientId}/exercises`
* `POST /public/v1/workout/plans`
* `POST /public/v1/workout/plans/create-and-assign/{clientId}`

```bash theme={null}
curl -X POST 'https://api.fitsociety.io/public/v1/workout/exercises' \
  -H "Authorization: Bearer $FITSOCIETY_ACCESS_TOKEN" \
  -H 'Idempotency-Key: exercise-squat-create-attempt-1' \
  -H 'Content-Type: application/json' \
  -d '{"name":[{"lang":"en","value":"Back squat"}],"primaryMuscle":"Quads","visibility":"Company","externalReference":"exercise-squat"}'
```

Referenced workout creation accepts `application/json` only. Multipart requests
and uploaded files are rejected; use the ordinary media workflow separately.
The external reference does not relax exercise classification or programme
validation. See the API reference for complete programme, day, set, superset,
rest, tempo and calendar definitions.

The resource and reference commit in one MongoDB transaction. A failed mapping
cannot leave an orphan client, exercise or plan. Client mails, webhooks and default
measurement assignment start only after commit. An opted-in OAuth client also
persists the new relationship's required external app-access policy inside that
transaction; see [External client access](/public-api/client-access).

An identical create request with the same external reference returns the same
resource, including after the HTTP idempotency record expires. Changed creation
content or reuse through a different endpoint or client path returns `409`.
Object-key order does not matter; array order and supplied field values do.
A replay does not recreate assignments, reset workout performance or send another
invitation. Use the normal read endpoint when you need the resource's current
profile or plan state after later edits.

Successful referenced creates add this receipt alongside the existing resource ID
in `data`:

```json theme={null}
{
  "externalReference": {
    "externalId": "exercise-squat",
    "revision": 1
  }
}
```

Every write still requires an `Idempotency-Key`. Keep the same key when retrying
one HTTP operation; after its retention window, the durable reference remains the
resource-level recovery mechanism. Keep your own step register for client,
exercise, plan, assignment and access-entitlement synchronization. Resource
creation alone does not confirm that app or client-AI access is effective.


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