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

# Partner workspaces

> For platforms that run TrackRev on behalf of their own customers: provision one workspace per customer and get a key for it.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://app.trackrev.io/api/v1/partner/workspaces" \
    -H "Authorization: Bearer <your partner key>" \
    -H "Content-Type: application/json" \
    -d '{ "external_id": "team_8812", "name": "Acme Marketing" }'
  ```
</RequestExample>

A **platform partner** is a product that uses TrackRev as its link-tracking backend — for example a
social media scheduler that creates a tracked link for every post it publishes. Instead of asking
each of its customers to sign up for TrackRev, the partner provisions a **partner-managed
workspace** per customer and drives it with an ordinary secret key.

* Partner-managed workspaces are on the **unlimited plan**: no link cap, and the analytics, clicks
  and link-performance endpoints are available.
* They have no dashboard organization of their own; everything happens over the API.
  `GET /api/v1/me` reports them with `workspace.partner_managed: true`.

## The partner key

Partner endpoints authenticate with a **partner key**, not a workspace key:

```text theme={null}
pt_live_<8 hex>_<48 hex>
```

Partner keys are issued by TrackRev — contact us to become a partner. Like workspace keys they are
shown once, stored only as a hash, and can be revoked. A partner key only works on
`/api/v1/partner/*`; a workspace key (`lk_…`) is refused there, and a partner key is refused
everywhere else (`401`).

## Get or create a workspace — `POST /api/v1/partner/workspaces`

<ParamField body="external_id" type="string" required>
  Your id for the customer (1–200 characters, matched exactly). One workspace per `external_id`
  per partner — calling again with the same id returns the same workspace.
</ParamField>

<ParamField body="name" type="string" required>
  Workspace name (1–100 characters). Used when the workspace is created; an existing workspace
  keeps its name.
</ParamField>

<ParamField body="rotate_key" type="boolean">
  For an existing workspace: mint a new key and revoke every key **you** previously minted for it
  (keys the workspace's own team created are untouched).
</ParamField>

| Outcome                    | Status | Body                              |
| -------------------------- | ------ | --------------------------------- |
| Created                    | `201`  | `{ workspace, key: "lk_live_…" }` |
| Already exists             | `200`  | `{ workspace, key: null }`        |
| Exists, `rotate_key: true` | `200`  | `{ workspace, key: "lk_live_…" }` |

`workspace` is `{ id, name, slug, partner_external_id }`. `key` is a **secret workspace key**,
labelled `partner:<your partner name>` — use it as `Authorization: Bearer lk_live_…` on every other
endpoint ([links](/developers/endpoints/links), [clicks](/developers/endpoints/clicks),
[webhooks](/developers/webhooks)…). It is shown **once**: store it before doing anything else. If
you lose it, call again with `rotate_key: true`.

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "workspace": {
      "id": "0b6e…",
      "name": "Acme Marketing",
      "slug": "acme-marketing",
      "partner_external_id": "team_8812"
    },
    "key": "lk_live_3f8a92c1_…"
  }
  ```
</ResponseExample>

## Look up a workspace — `GET /api/v1/partner/workspaces/:external_id`

URL-encode the `external_id`. Returns `200 { workspace }`, or `404 not_found` if none of **your**
workspaces has that id. Never returns a key.

```bash theme={null}
curl "https://app.trackrev.io/api/v1/partner/workspaces/team_8812" \
  -H "Authorization: Bearer <your partner key>"
```

## Building on a partner workspace

* Create links with `external_id` set to your post id and an `Idempotency-Key`, so a retried
  publish never creates a second link — see [Links](/developers/endpoints/links).
* One campaign (destination) per piece of content; add a link per account or network with
  `destination_id`. Two links on the same network in one campaign need distinct `external_id`s.
* Destinations must share one own-site domain per workspace. Send `external: true` for
  destinations on platforms the customer doesn't own.
* Read stats for the links you know with `GET /api/v1/links?ids=…` and poll new clicks with
  `GET /api/v1/clicks?link_ids=…&since=…`, or subscribe to `click.created` /
  `sale.created` [webhooks](/developers/webhooks).
* Check `features` on [`GET /api/v1/me`](/developers/endpoints/me) to detect what the deployment
  supports.
