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

# Link an account to a creator

> Link a tracked account to a creator.

PUT-to-create with correct REST semantics (review V2R-06): the first
link returns `201 Created` with a `Location` header; re-linking an
account already linked to this creator is an idempotent `200 OK`.
Linking an account already owned by a *different* creator returns
`409`. Returns the link record; `404` if either the creator or the
account does not exist in your organization.



## OpenAPI

````yaml /api-reference/openapi.json put /creators/{creator_id}/accounts/{account_id}
openapi: 3.1.0
info:
  title: CreatorAudit API v2
  summary: Public REST API for tracking creators, accounts, videos, and analytics.
  description: >
    The **CreatorAudit v2 API** tracks Instagram and TikTok creators, accounts,
    and

    their content, and serves the engagement analytics computed from them.


    ### Authentication & scopes


    Send your organization API key as a bearer token on every request:


    ```

    Authorization: Bearer <YOUR_API_KEY>

    ```


    Keys are scoped to a single organization; every response is limited to the
    data

    that organization owns. Missing or invalid credentials return `401`; an
    inactive

    key or subscription returns `403`.


    Each key carries a set of **scopes** — `read`, `write`, and `admin` — and
    keys

    are issued with all three by default. Read endpoints (`GET`) require no
    special

    scope; mutating endpoints (`POST`/`PATCH`/`PUT`/`DELETE`) require the
    `write`

    scope (`admin` implies `write` implies `read`). A key lacking the required
    scope

    gets `403` with `code: INSUFFICIENT_SCOPE`.


    ### Response envelope


    Successful responses are wrapped in a consistent envelope:


    - **Single resource** — `{ "data": { ... } }`

    - **Collection** — `{ "data": [ ... ], "pagination": { ... }, "filters": {
    ... } }`

    - **Collection with metadata** — `{ "data": ..., "meta": { ... } }`


    `pagination` carries `next_cursor`, `has_next`, `limit`, and (when
    requested)

    `total_count`. `filters` echoes the filter/sort that produced the page.


    ### Pagination


    List endpoints use opaque **cursor** pagination. Pass `limit` (1–200) and
    the

    `pagination.next_cursor` from the previous page as `cursor` to fetch the
    next

    page. `pagination.has_next` is `false` on the final page. A cursor is bound
    to

    the exact filter and sort combination it was issued for — reusing it under a

    different filter/sort returns `422`. Pass `include_total=true` to also
    receive

    `pagination.total_count` (adds one COUNT query). List responses also carry
    an

    RFC 8288 `Link` header with `rel="first"` and (when more pages exist)

    `rel="next"`.


    ### Caching


    `GET` responses carry a strong `ETag` and `Cache-Control: private,
    no-cache`.

    Send the value back as `If-None-Match` on a follow-up request; if the

    representation is unchanged the API replies `304 Not Modified` with an empty

    body, saving the re-download.


    ### Rate limits


    Requests are rate limited per API key. Every **authenticated** response
    includes

    `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` (a
    Unix

    timestamp); the unauthenticated `GET /health` and `GET /meta` are not
    limited

    and omit them. Exceeding the limit returns `429` with `code: RATE_LIMITED`
    and a

    `Retry-After` header (seconds to wait).


    ### Account quota


    An organization may set an optional cap on the number of accounts it tracks.
    By

    default there is **no cap** (unlimited). When a cap is set and reached,

    `POST /accounts` returns `403` with `code: QUOTA_EXCEEDED`.


    ### Content negotiation


    The API only produces JSON. A request whose `Accept` header cannot be
    satisfied

    with JSON returns `406` (`code: NOT_ACCEPTABLE`). A write request whose body
    is

    not `application/json` returns `415` (`code: UNSUPPORTED_MEDIA_TYPE`).


    ### Errors


    Errors follow **RFC 9457 Problem Details** (`application/problem+json`):


    ```json

    {
      "type": "urn:creatoraudit:error:not-found",
      "title": "Not Found",
      "status": 404,
      "detail": "Account not found.",
      "code": "NOT_FOUND",
      "instance": "/v2/accounts/{id}",
      "request_id": "8f1c…"
    }

    ```


    The `code` is the stable machine identifier; `type` is an RFC 9457 URN.

    Validation failures (`422`) additionally carry an `errors` array of

    `{ field, message }` entries. The full set of machine `code`s:


    | HTTP | `code` | Meaning |

    | ---- | ------ | ------- |

    | 400 | `BAD_REQUEST` | Malformed request. |

    | 401 | `UNAUTHORIZED` | Missing or invalid API key. |

    | 403 | `FORBIDDEN` | Inactive key/subscription. |

    | 403 | `INSUFFICIENT_SCOPE` | Key lacks the required scope. |

    | 403 | `QUOTA_EXCEEDED` | Account quota reached. |

    | 404 | `NOT_FOUND` | Resource not found in your org. |

    | 406 | `NOT_ACCEPTABLE` | `Accept` not satisfiable as JSON. |

    | 409 | `CONFLICT` | State conflict (e.g. duplicate). |

    | 415 | `UNSUPPORTED_MEDIA_TYPE` | Write body is not JSON. |

    | 422 | `VALIDATION_ERROR` | Request failed validation. |

    | 429 | `RATE_LIMITED` | Rate limit exceeded. |

    | 500 | `INTERNAL_ERROR` | Unexpected server error. |

    | 502 | `UPSTREAM_ERROR` | Upstream provider error. |

    | 503 | `SERVICE_UNAVAILABLE` | Temporarily unavailable; retry. |


    ### Idempotency


    `POST` create endpoints accept an optional `Idempotency-Key` header so a
    retried

    request returns the original result instead of creating a duplicate. On
    success

    a `201` carries a `Location` header pointing at the new resource.


    ### Response headers


    Every response echoes `X-Request-ID` (also surfaced as `request_id` in error

    bodies) so a call can be correlated with its server-side event. Collections
    add

    `Link`; `GET`s add `ETag`/`Cache-Control`; authenticated responses add

    `X-RateLimit-*`; `429`/`503` add `Retry-After`; `201` creates add
    `Location`.
  contact:
    name: CreatorAudit Support
    url: https://creatoraudit.com/
    email: support@creatoraudit.com
  license:
    name: Proprietary — © CreatorAudit
  version: 2.0.0
  x-api-stability: current
servers:
  - url: https://api.creatoraudit.com/v2
    description: Production
security: []
tags:
  - name: Accounts
    description: >-
      Track and manage Instagram/TikTok accounts. Listing, retrieval, creation
      (which begins automated tracking), updates, and removal.
  - name: Videos
    description: >-
      Individually tracked posts/videos, account-discovered videos, and batch
      engagement deltas.
  - name: Creators
    description: >-
      Creators group one or more accounts under a single entity for roll-up
      analytics. Includes account linking and the top-creators leaderboard.
  - name: Analytics
    description: >-
      Daily engagement series for the org, accounts, creators, and individual
      videos, plus per-metric daily breakdowns for accounts, creators, and
      videos.
  - name: Overview
    description: Org-wide headline stats with period-over-period changes.
  - name: Search
    description: Cross-entity search over accounts, creators, and videos.
  - name: System
    description: Unauthenticated liveness and service-health checks.
paths:
  /creators/{creator_id}/accounts/{account_id}:
    put:
      tags:
        - Creators
      summary: Link an account to a creator
      description: |-
        Link a tracked account to a creator.

        PUT-to-create with correct REST semantics (review V2R-06): the first
        link returns `201 Created` with a `Location` header; re-linking an
        account already linked to this creator is an idempotent `200 OK`.
        Linking an account already owned by a *different* creator returns
        `409`. Returns the link record; `404` if either the creator or the
        account does not exist in your organization.
      operationId: link_account
      parameters:
        - name: creator_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
            description: Creator UUID.
            title: Creator Id
          description: Creator UUID.
        - name: account_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
            description: Tracked account UUID.
            title: Account Id
          description: Tracked account UUID.
      responses:
        '200':
          description: Already linked (idempotent re-link).
          content:
            application/json:
              schema: {}
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '201':
          description: Link created.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
            Location:
              schema:
                type: string
              description: URI of the created resource.
        '401':
          description: Unauthorized
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '403':
          description: Forbidden
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '404':
          description: Not Found
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '409':
          description: Conflict
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '422':
          description: Validation Error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '429':
          description: Too Many Requests
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying.
        '500':
          description: Internal Server Error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
        '503':
          description: Service Unavailable
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Correlation id echoed (or minted) for this request.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request quota for the current rate-limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current window.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Unix timestamp when the window resets.
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying.
      security:
        - HTTPBearer: []
components:
  schemas:
    ProblemDetail:
      additionalProperties: true
      properties:
        type:
          title: Type
          type: string
        title:
          title: Title
          type: string
        status:
          title: Status
          type: integer
        detail:
          title: Detail
          type: string
        code:
          title: Code
          type: string
          enum:
            - BAD_REQUEST
            - CONFLICT
            - FORBIDDEN
            - INSUFFICIENT_SCOPE
            - INTERNAL_ERROR
            - NOT_ACCEPTABLE
            - NOT_FOUND
            - QUOTA_EXCEEDED
            - RATE_LIMITED
            - SERVICE_UNAVAILABLE
            - UNAUTHORIZED
            - UNSUPPORTED_MEDIA_TYPE
            - UPSTREAM_ERROR
            - VALIDATION_ERROR
        instance:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Instance
        errors:
          anyOf:
            - items:
                additionalProperties: true
                type: object
              type: array
            - type: 'null'
          default: null
          title: Errors
      required:
        - type
        - title
        - status
        - detail
        - code
      title: ProblemDetail
      type: object
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer

````