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

# Submit an AllTrack affiliation for a workspace user

> **POST /writer/by-user/{tenantUserId}/alltrack/affiliation**

<Note>
  This endpoint requires authentication. Include your Bearer token in the Authorization header.
</Note>

## Description

**POST /writer/by-user/{tenantUserId}/alltrack/affiliation**

**Description:**
Applies for AllTrack affiliation on behalf of one workspace user. Royalti
finds the writer linked to the user, or creates one from the legal first
and last name in the request (role `CA`, worldwide territory), then
submits the application exactly as `POST /writer/{id}/alltrack/affiliation`
does. The same checks apply: age 13 or over, no other PRO declared, terms
accepted, and one live application per writer.

Returns `201` with the same body as the GET. If the writer already has a
live application, returns `409` with that application in the body.

Limited to 5 requests per user per hour (`429`, with `Retry-After`).

**Authorization:**

* Required role: `admin` or higher
* API keys: a key scoped to `publishing:affiliation` is accepted. These two
  by-user routes are the only routes that scope reaches.
* Requires the `publisher` capability enabled with its `alltrack` feature on
* Environment kill-switch: `ALLTRACK_AFFILIATION_ENABLED` (503 if off)

**Method:**
POST

## Code Examples

<CodeGroup>
  ```javascript Node.js theme={null}
  const response = await fetch('https://api.royalti.io/writer/by-user/example-id/alltrack/affiliation', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      "firstName": "Ada",
      "middleName": null,
      "lastName": "Obi",
      "email": "ada.obi@example.com",
      "phone": "+2348012345678",
      "dateOfBirth": "1995-06-15",
      "stageName": "Ada O",
      "taxId": null,
      "otherProDeclared": false,
      "tosAcceptedAt": "2026-10-01T10:00:00Z",
      "address": {
        "addressLine1": "12 Marina Road",
        "addressLine2": null,
        "city": "Lagos",
        "stateOrProvince": "Lagos",
        "postalCode": "100001",
        "country": "NG"
      }
    })
  });

  const data = await response.json();
  console.log(data);
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
    'https://api.royalti.io/writer/by-user/example-id/alltrack/affiliation',
    headers={
      'Authorization': f'Bearer {token}'
    },
    json={"firstName":"Ada","middleName":null,"lastName":"Obi","email":"ada.obi@example.com","phone":"+2348012345678","dateOfBirth":"1995-06-15","stageName":"Ada O","taxId":null,"otherProDeclared":false,"tosAcceptedAt":"2026-10-01T10:00:00Z","address":{"addressLine1":"12 Marina Road","addressLine2":null,"city":"Lagos","stateOrProvince":"Lagos","postalCode":"100001","country":"NG"}}
  )

  data = response.json()
  print(data)
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.royalti.io/writer/by-user/example-id/alltrack/affiliation \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"firstName":"Ada","middleName":null,"lastName":"Obi","email":"ada.obi@example.com","phone":"+2348012345678","dateOfBirth":"1995-06-15","stageName":"Ada O","taxId":null,"otherProDeclared":false,"tosAcceptedAt":"2026-10-01T10:00:00Z","address":{"addressLine1":"12 Marina Road","addressLine2":null,"city":"Lagos","stateOrProvince":"Lagos","postalCode":"100001","country":"NG"}}'

  ```
</CodeGroup>


## OpenAPI

````yaml post /writer/by-user/{tenantUserId}/alltrack/affiliation
openapi: 3.0.0
info:
  title: Royalti.io API
  description: "# Royalti API\r\n\r\nThis is the Royalti music royalty management platform API server.\r\n\r\n## Overview\r\n\r\nThe Royalti API provides comprehensive music royalty management services including:\r\n- Music publishing and writer management\r\n- Royalty processing and analytics\r\n- DDEX integration for music industry standards\r\n- File processing and pattern recognition\r\n- Payment processing and distribution\r\n\r\n## Authentication\r\n\r\nThe API uses JWT-based authentication with multiple protection levels:\r\n- Public endpoints for basic operations\r\n- Protected endpoints requiring valid JWT tokens\r\n- Admin endpoints for administrative functions\r\n\r\n## Features\r\n\r\n- Multi-dimensional royalty analytics\r\n- CWR (Collective Works Registration) support\r\n- DDEX integration for music metadata\r\n- Advanced file processing with pattern recognition\r\n- Real-time data processing with queue system"
  version: 2.6.0
  contact:
    name: Royalti.io Support
    email: support@royalti.io
    url: https://royalti.io
  license:
    name: Proprietary
    url: https://royalti.io/terms
servers:
  - url: https://api.royalti.io
    description: Production server
  - url: https://api-dev.royalti.io
    description: Development server
  - url: http://localhost:8084
    description: Local development
security:
  - bearerAuth: []
tags:
  - name: Godmin - Account Erasure
    description: Super admin account-erasure operations
  - name: Accounting
    description: Accounting and financial transaction operations
  - name: Admin Impersonation
    description: Admin user-impersonation endpoints
  - name: Audit
    description: |
      Audit-trail reads. This file documents the work-scoped activity route
      only; the general audit surface (`/audit/entity/{entityType}/{entityId}`,
      `/audit/user/{userId}/activity`, `/audit/high-risk`, `/audit`) predates
      the YAML docs and is not yet described here.
  - name: Automations
    description: |
      Enable, configure, run, and review the four Phase 1 automation
      templates. Mounted under `/ai`, behind `authMiddleware.basicAuth` +
      `loadSubscription`. Deliberately omits the AI chat rate limiter — a
      pure-TS automation run consumes no LLM quota; abuse is bounded by the
      same `workflowGate` wfops throttle the generic Guided Workflow API
      uses. Response envelope is `{ status, message, data }`.
  - name: Billing
    description: |
      Subscription lifecycle (local + Stripe), plans, custom/Stripe invoices,
      usage summaries, the Stripe Customer Portal and Customer Session,
      payment links, and cache/maintenance utilities. All routes require a
      valid tenant session (`bearerAuth`); most additionally require
      `admin` or `owner` role via RBAC — see each endpoint's Authorization
      note. Response envelope is `{ status, message, data }` except where
      noted.
  - name: Capabilities
    description: >-
      Enable, configure, and manage credentials for connections, modules, and
      preferences.
  - name: Catalog Export
    description: >
      Generate catalog exports (BackBeat CWR-workstation import, Too
      Lost/Sonosuite

      distributor formats, and catalog CSV/XLSX exports for assets, products,

      artists, labels, splits, and releases) from a code-defined template

      registry. Admin-only — distinct from the member-accessible generic

      `?export=csv` list-endpoint query param, which remains untouched.
  - name: Catalog Import
    description: |
      Tenant-scoped catalog importer built on the metadata engine: search an
      artist on a configured provider, fetch and merge cross-provider metadata
      into staged `CatalogImportItem` rows, review a read-only diff against
      the tenant's existing catalog, optionally adjust individual staged
      rows, then explicitly apply or reject the batch. Admin-only — every
      route requires the tenant `admin` role or higher.

      **Flow:** `GET /providers` (optional, to see what's active) →
      `GET /search` (resolve an artist to an external id) →
      `POST /fetch` (queues a background job) →
      `GET /job/{jobId}` (poll until complete) →
      `GET /batch/{batchId}` and `GET /batch/{batchId}/diff` (review) →
      `PUT /items/{id}` (optional per-row overrides) →
      `POST /apply` or `POST /reject` (explicit confirm).

      **Review-then-apply, always:** fetch only ever stages
      `CatalogImportItem` rows — it never writes to `Asset`/`Product`. The
      only tenant-catalog write path is `POST /apply`, which is always an
      explicit, reviewer-initiated call.

      **Idempotency:** re-running the same import is safe. Staged rows are
      deduplicated against already-pending/imported rows by ISRC/UPC before
      insert, and `POST /apply` only ever touches `status: pending` rows
      scoped to the batch/items and tenant supplied — re-applying an
      already-applied batch or a batch with no matching pending rows is a
      no-op (`imported: 0, failed: 0`).
  - name: Currencies
    description: |
      Global currency reference data, per-tenant currency enablement, and
      exchange rates used to convert royalty data between currencies for
      reporting. All routes are mounted behind the platform's standard
      `basicAuth` + RBAC stack, so every endpoint requires a valid bearer
      token even where no `require*` role gate is applied in code. Response
      envelope is `{ success, data }` for currency endpoints and
      `{ status, data }` for exchange-rate endpoints (the two controllers
      predate a shared convention).
  - name: CWR Export
    description: |
      CISAC Common Works Registration (CWR) file generation for a tenant's
      publisher. Builds an async export job against the tenant's works and
      writers, persists the rendered file to Cloud Storage, and exposes job
      status + a download endpoint for the resulting file. All endpoints
      require the `publisher` capability enabled. Mounted at `/cwr`.
  - name: CWR Acknowledgment
    description: |
      Upload and parse CWR acknowledgment (ACK) files returned by a
      performing rights society after a registration submission, and
      inspect/update per-work registration status derived from them.
  - name: DDEX
    description: DDEX operations (ERN/MEAD, messages, delivery, providers)
  - name: DMP Import
    description: |
      Imports a tenant's catalog (writers, works, work-writer relationships,
      artists, recordings, cross-references, and acknowledgements) from a
      django-music-publisher (DMP) works JSON export, with an optional
      acknowledgements CSV export layered on top. Mounted at `/dmp`.
      Import is best-effort and per-record: a failed row is captured in
      that phase's `errors[]` array rather than aborting the whole run, so
      a "completed" response can still contain 0 created rows if every
      record errored — check `result.*.errors` before treating a response
      as fully successful.
  - name: Downloads
    description: >-
      Generate and manage data downloads (royalty reports, accounting exports,
      etc.)
  - name: Label
    description: Label management operations
  - name: LabelGrid
    description: LabelGrid distribution settings and credentials (LabelGrid plan WP-08)
  - name: PRO Credentials
    description: >
      CRUD for `TenantPROCredentials` — one credential set per (tenant,

      society) pair, used by the CWR submission pipeline to deliver

      registration files to a PRO over SFTP, API, or EMAIL. Mounted at

      `/pro-credentials`. All routes require `admin` and an active

      `publisher` capability enabled (enforced router-wide via `router.use()`,
      not

      per-route).


      **Credentials are never returned by the API.** The model's `toJSON()`

      strips `credentialsEncrypted` (ciphertext) and `decryptedCredentials`

      (plaintext, populated only in-process for the connection-test

      endpoint) from every serialized response — list/get/create/update

      responses include the account metadata (`societyCode`, `accountId`,

      `submissionMethod`, `endpointConfig`, `isActive`, `lastUsedAt`) but

      never the credential payload itself, masked or otherwise. Write

      requests still accept plaintext `credentials` in the body (over TLS);

      they are encrypted at rest (pgcrypto-backed) before the row is

      persisted.
  - name: Publisher Bulk Operations
    description: |
      Admin-only bulk variants of the single-statement statement/PDF flows
      in `publishers.yaml`: many-file statement import in one call, batch
      posting statements to the ledger, and rendering many writer/publisher
      statement PDFs into one zip. Own controller
      (`publisherBulkController.ts`), deliberately kept separate from
      `publisherStatementReconciliationController`/`publisherRoyaltyController`
      to avoid touching either under active development on the same PR base.
  - name: Publishing Ledger Bridge
    description: |
      Bridges a publisher statement's matched WRITER shares into the
      accounting ledger as `publishing_royalty` transactions
      (`publishingLedgerBridge.ts`), and the reversal that voids them. This
      is the only path in the codebase that can write or reverse
      `sourceFactTable='PublisherStatements'` ledger transactions — never
      automatic on ingest, always an explicit admin action.
  - name: Publisher-Writer Agreements
    description: |
      Manage `PublisherWriterAgreement` records — the contractual
      relationship between a `Publisher` and a `CWRWriter`, including its
      territory grants, status lifecycle (draft → pending → active →
      expired/terminated), and validity dates. Territory conflicts are
      checked against a writer/publisher pair's OTHER active agreements
      on every create/update/add-territory call.

      All endpoints require the `publisher` capability enabled for the tenant
      (`requireCapability('publisher')`). Unlike most routers in this API, this
      controller does NOT use the shared `asyncWrapper`/centralized error
      handler — every method catches its own errors and writes the JSON
      response directly, so error bodies here are `{ message, error? }`,
      not the `{ status, message }` shape used elsewhere. Role
      requirements come entirely from the global RBAC route table
      (`cwr.permissions.ts`): reads need `user` or higher, writes need
      `admin` or higher — there is no route-level `requireUser`/
      `requireAdmin` call in this router's own file.
  - name: Publishers
    description: |
      Core Publisher CRUD (name, IPI numbers, publisher type, settings) plus the
      `/publishers/me` singleton lookup and the `/publishers-with-user-data`
      convenience list. `POST`/`PUT`/`DELETE` require `admin`; reads require
      only `user`.
  - name: Publisher Territories
    description: |
      Per-publisher territory rows (`PublisherTerritory`) carrying PR/MR/SR
      share splits, inclusion/exclusion, and CWR 2.2+ formula/assignment/license
      fields. Distinct from the `territories` JSONB column on `Publisher` itself
      — these endpoints manage the normalized `PublisherTerritories` table.
  - name: Publisher Agreements
    description: |
      Per-publisher agreement rows (`PublisherAgreement`) — original,
      sub-publishing, administration, or collection agreements with territory
      and right-type terms.
  - name: Publisher CWR Export
    description: |
      Generates a CWR registration file (text/plain) for a single publisher's
      exportable works. One publisher per call — a CWR file carries a single
      sender/publisher chain, so batch `publisherIds` requests are rejected.
  - name: Publisher Statements
    description: |
      Publisher royalty statement generation, listing, detail, status
      transitions, and PDF export (`PublisherStatement`). Statement status
      follows a locked state machine: `draft → pending → approved → paid`
      (with `pending → draft` and `approved → pending` as the only backward
      transitions).
  - name: Statement Reconciliation
    description: |
      Phase 6 reconciliation surface built on top of Publisher Statements:
      PRO-file ingestion (BMI/ASCAP/MLC/MANUAL), line-level work matching
      (manual + fuzzy auto-match), variance detection against expected
      royalties, variance-flag comment threads, manual statement adjustments
      (H-05, locked once a statement is `approved`/`paid`), and emailing the
      rendered statement PDF to recipients.
  - name: Sub-Publishing
    description: |
      Sub-publishing agreements between an original publisher and a
      sub-publisher (`SubPublishingAgreement`), territory-conflict checking,
      and agreement discussion threads (H-07, backed by the polymorphic
      `DisputeMessage` model with `subjectType: sub_publishing_agreement`).
  - name: Recoupment Ledger
    description: |
      Read-only running-balance ledger (`RecoupmentLedger`) for a
      sub-publishing agreement's advance/recoupment activity.
  - name: Publishing Analytics
    description: >
      Tenant-scoped aggregation endpoints over `PublisherStatementLine` and

      `RecoupmentLedger` (WP-09, locks the G-ANALYTICS response-shape

      contract). Every aggregation returns the same uniform envelope:

      `{ dimension, rows: [{ key, label, ...metrics }], totals, currency, meta?
      }`.

      All support optional `periodStart`/`periodEnd` (ISO date, inclusive)

      filtering — see each endpoint for period semantics (statement-period

      overlap vs. ledger event-date).
  - name: Publishing Bootstrap
    description: |
      Scan → review → apply pipeline that bootstraps skeleton CWR works from
      the recording catalog. Scans stage proposals only; the diff is
      read-only and recomputed live; POST /apply is the single CWR write
      path. Ownership data (shares/publishers/agreements) is never seeded.
  - name: Publishing Claims
    description: |
      Tenant-wide inbox for `WriterClaim` disputes over CWR work ownership,
      share splits, registration conflicts, or metadata. Mounted at
      `/publishing`. Per-work claim endpoints (file a claim, list a work's
      claims) live on the `/work/works/{workId}/claims` routes instead, to
      keep work-scoped CRUD together — this file documents only the
      tenant-wide inbox surface (`/publishing/claims*`).

      All routes require the `publisher` capability enabled. Resolve/transition
      and bulk-resolve require `admin`; list/get/message/evidence routes
      accept any authenticated tenant user — finer-grained authorization
      (claimant-only actions such as withdraw) is enforced inside the
      service layer, not by RBAC middleware.
  - name: Source Creator
    description: |
      AI-assisted wizard for onboarding a new royalty data source: file
      analysis, AI column-mapping suggestions, BigQuery SQL generation,
      sandbox testing, and draft-source persistence. Available on every
      plan tier — most routes require an `admin` role or higher.
  - name: Webhook Configuration
    description: Tenant-settings CRUD used to configure outbound webhook delivery
  - name: Payment Webhooks
    description: Payment processor webhook endpoints
  - name: Billing Webhooks
    description: Stripe billing and subscription webhooks
  - name: Branding
    description: |
      Per-tenant brand tokens (primary/accent colours, font, logo, logo mark)
      used to theme the tenant's workspace UI and emails. Both reading and
      updating brand tokens require an admin role.
  - name: Custom Domains
    description: |
      Custom workspace domains (e.g. `app.yourlabel.com`) that resolve to a
      tenant's Royalti workspace. Domains are provisioned with automatic SSL
      and validated via a DNS TXT record or an HTTP file challenge. Adding a
      domain requires an admin role; removing it requires the tenant owner.
      A tenant may have at most one active custom domain at a time.
  - name: Email Domains
    description: |
      The tenant's custom email sending domain, used so outbound
      transactional and royalty emails are sent from the tenant's own
      domain instead of the shared `royalti.io` sender. Domain ownership is
      proven with DNS records (DKIM, SPF, and a return-path record) that
      must be added before the domain is verified. Viewing the configuration
      requires an admin role; registering, deleting, or triggering
      verification requires the tenant owner.
  - name: Email Settings
    description: |
      The tenant's email sending configuration: custom email domain status
      plus sender address/name. Email branding (from-name, reply-to, logo,
      colours, footer) is a separate surface — `GET`/`PUT
      /capabilities/email-branding` — and is not part of these responses.
      Any tenant member can view settings; updating them requires an admin
      role or higher.
  - name: Email Templates
    description: |
      Read-only catalogue of the transactional email templates Royalti can
      send (welcome, password reset, invite, payment notifications, etc.),
      with tenant-branded HTML/text preview rendering and a test-send
      endpoint for confirming how a template looks with the tenant's
      current branding. All endpoints in this cluster require an admin role.
  - name: Works & CWR Registrations
    description: >
      Musical works (`CWRWork`) are the composition-level entities behind

      publishing: title, ISWC, writer splits, and their links to society

      registrations, recordings (masters), and ownership claims. All routes

      in this group are mounted at `/work` and require an active `publisher`

      capability enabled for the tenant (`requireCapability('publisher')`), plus
      a valid session

      (`requireUser` for reads, `requireAdmin` for writes unless noted

      otherwise). Role hierarchy: `guest < user < admin < owner`; `requireAdmin`

      allows `admin` and above.


      Registrations (`WorkRegistration`) track a work's submission to a

      performing-rights society (PRO) — ASCAP, BMI, PRS, etc. — including the

      NWR (New Work Registration) CWR transaction pipeline shipped 2026-07-05

      (PR #485): a registration is created in `pending` status, explicitly

      queued for PRO submission (`queuedAt` set), picked up by the

      `proSubmissionService` worker, and may land in `submitted`,

      `registered`, `rejected`, or `conflict`. Only `pending` rows can be

      (re)queued — a row that has left `pending` is never re-armed.

      Registration conflicts represent a competing claim from a society or

      third party against a specific registration and are tracked

      separately from work-scoped ownership claims (`WriterClaim`).
  - name: Writers
    description: |
      Manage CWR (Common Works Registration) writers — the composers,
      authors, arrangers, and translators credited on a tenant's musical
      works — and their associations with individual works. Writers are
      distinct from `TenantUser` accounts; a writer may optionally be
      linked to a `TenantUser` via `tenantUserId` (`userData` in
      responses) to pull in platform account details.

      All endpoints require the `publisher` capability enabled for the tenant
      (`requireCapability('publisher')`) in addition to the stated role. Reads
      require the `user` role or higher; writes (create/update/delete and
      work associations) require `admin` or higher, enforced both by the
      global RBAC route table (`cwr.permissions.ts`) and, for this router,
      duplicated at the route level via `requireUser`/`requireAdmin`.
paths:
  /writer/by-user/{tenantUserId}/alltrack/affiliation:
    post:
      tags:
        - Writers
        - AllTrack
      summary: Submit an AllTrack affiliation for a workspace user
      description: >-
        **POST /writer/by-user/{tenantUserId}/alltrack/affiliation**


        **Description:**

        Applies for AllTrack affiliation on behalf of one workspace user.
        Royalti

        finds the writer linked to the user, or creates one from the legal first

        and last name in the request (role `CA`, worldwide territory), then

        submits the application exactly as `POST
        /writer/{id}/alltrack/affiliation`

        does. The same checks apply: age 13 or over, no other PRO declared,
        terms

        accepted, and one live application per writer.


        Returns `201` with the same body as the GET. If the writer already has a

        live application, returns `409` with that application in the body.


        Limited to 5 requests per user per hour (`429`, with `Retry-After`).


        **Authorization:**

        - Required role: `admin` or higher

        - API keys: a key scoped to `publishing:affiliation` is accepted. These
        two
          by-user routes are the only routes that scope reaches.
        - Requires the `publisher` capability enabled with its `alltrack`
        feature on

        - Environment kill-switch: `ALLTRACK_AFFILIATION_ENABLED` (503 if off)


        **Method:**

        POST
      parameters:
        - name: tenantUserId
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The workspace user (TenantUser) id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - firstName
                - lastName
                - email
                - phone
                - dateOfBirth
                - address
                - otherProDeclared
                - tosAcceptedAt
              properties:
                firstName:
                  type: string
                  example: Ada
                  maxLength: 45
                  description: Legal first name. Also used for a new writer.
                middleName:
                  type: string
                  example: null
                  nullable: true
                  maxLength: 45
                lastName:
                  type: string
                  example: Obi
                  maxLength: 45
                  description: Legal last name. Also used for a new writer.
                email:
                  type: string
                  example: ada.obi@example.com
                  format: email
                phone:
                  type: string
                  example: '+2348012345678'
                  description: Full international number, including the country code
                dateOfBirth:
                  type: string
                  example: '1995-06-15'
                  format: date
                stageName:
                  type: string
                  example: Ada O
                  nullable: true
                taxId:
                  type: string
                  example: null
                  nullable: true
                otherProDeclared:
                  type: boolean
                  example: false
                  enum:
                    - false
                tosAcceptedAt:
                  type: string
                  example: '2026-10-01T10:00:00Z'
                  format: date-time
                address:
                  type: object
                  required:
                    - addressLine1
                    - city
                    - postalCode
                    - country
                  properties:
                    addressLine1:
                      type: string
                      example: 12 Marina Road
                    addressLine2:
                      type: string
                      example: null
                      nullable: true
                    city:
                      type: string
                      example: Lagos
                    stateOrProvince:
                      type: string
                      example: Lagos
                      nullable: true
                    postalCode:
                      type: string
                      example: '100001'
                    country:
                      type: string
                      example: NG
                      description: Two-letter ISO country code
      responses:
        '201':
          description: Application submitted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AffiliationByUserResponse'
        '400':
          description: >-
            Validation error (under 13, another PRO declared, terms not
            accepted, unreadable phone number)
        '401':
          description: Missing/invalid authentication
        '403':
          description: >-
            Insufficient role or API key scope, or the publisher capability or
            its `alltrack` feature is off
        '404':
          description: The user is not a member of this workspace (`TENANT_USER_NOT_FOUND`)
        '409':
          description: >
            The writer already has a live application (`AFFILIATION_EXISTS`,
            body

            includes `writer` and `affiliation`), or more than one writer is

            linked to this user (`MULTIPLE_WRITERS_FOR_USER`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AffiliationByUserConflict'
        '429':
          description: >-
            More than 5 applications for this user in the last hour
            (`AFFILIATION_RATE_LIMITED`)
        '503':
          description: AllTrack affiliation service is currently disabled
      security:
        - bearerAuth: []
components:
  schemas:
    AffiliationByUserResponse:
      type: object
      required:
        - writer
        - affiliation
      properties:
        writer:
          allOf:
            - $ref: '#/components/schemas/AffiliationByUserWriter'
          nullable: true
        affiliation:
          allOf:
            - $ref: '#/components/schemas/AffiliationByUserRecord'
          nullable: true
    AffiliationByUserConflict:
      type: object
      properties:
        status:
          type: string
          enum:
            - error
        code:
          type: string
          enum:
            - AFFILIATION_EXISTS
            - MULTIPLE_WRITERS_FOR_USER
        message:
          type: string
        writer:
          $ref: '#/components/schemas/AffiliationByUserWriter'
        affiliation:
          $ref: '#/components/schemas/AffiliationByUserRecord'
    AffiliationByUserWriter:
      type: object
      properties:
        id:
          type: string
          format: uuid
        firstName:
          type: string
        lastName:
          type: string
        ipiNameNumber:
          type: string
          nullable: true
        affiliatedPRO:
          type: string
          nullable: true
    AffiliationByUserRecord:
      type: object
      properties:
        id:
          type: string
          format: uuid
        writerId:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - draft
            - submitting
            - pending
            - active
            - rejected
            - failed
        ipiNameNumber:
          type: string
          nullable: true
        alltrackAccountId:
          type: string
          nullable: true
        statusReason:
          type: string
          nullable: true
        tosAcceptedAt:
          type: string
          format: date-time
          nullable: true
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        JWT Authorization header using the Bearer scheme. Format: "Bearer
        {token}"

````

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