openapi: 3.0.1
info:
  title: ArelHub API
  description: Customer and integrator endpoints for the ArelHub platform.
  version: v1
paths:
  /v1/tendlc/brands:
    get:
      tags:
        - 10DLC Registration
      summary: List all 10DLC brand registrations for the authenticated account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TenDlcBrand'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TenDlcBrand'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TenDlcBrand'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - 10DLC Registration
      summary: Register a 10DLC brand for the authenticated account.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterTenDlcBrandRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/RegisterTenDlcBrandRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/RegisterTenDlcBrandRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            application/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            text/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/tendlc/brands/{brandId}':
    get:
      tags:
        - 10DLC Registration
      summary: Get a specific 10DLC brand owned by the authenticated account.
      parameters:
        - name: brandId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            application/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            text/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    delete:
      tags:
        - 10DLC Registration
      summary: Delete a Draft brand that has not been submitted to TCR.
      parameters:
        - name: brandId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/tendlc/brand:
    get:
      tags:
        - 10DLC Registration
      summary: "Legacy singular brand lookup — returns the oldest brand for the account.\r\nPrefer `GET brands` for multi-brand accounts."
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            application/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            text/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - 10DLC Registration
      summary: Register a 10DLC brand for the authenticated account.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterTenDlcBrandRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/RegisterTenDlcBrandRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/RegisterTenDlcBrandRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            application/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            text/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/tendlc/brands/{brandId}/profile':
    put:
      tags:
        - 10DLC Registration
      summary: Update TCR profile fields on a Draft or Failed brand before (re)submission.
      parameters:
        - name: brandId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateTenDlcBrandProfileRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateTenDlcBrandProfileRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateTenDlcBrandProfileRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            application/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            text/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/tendlc/brands/{brandId}/identity':
    put:
      tags:
        - 10DLC Registration
      summary: 'Update legal name, EIN, and brand type on a Draft or Failed brand before submission.'
      parameters:
        - name: brandId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateTenDlcBrandIdentityRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateTenDlcBrandIdentityRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateTenDlcBrandIdentityRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            application/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            text/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/tendlc/brand/profile:
    put:
      tags:
        - 10DLC Registration
      summary: Legacy profile update — targets the oldest brand for the account.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateTenDlcBrandProfileRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateTenDlcBrandProfileRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateTenDlcBrandProfileRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            application/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
            text/json:
              schema:
                $ref: '#/components/schemas/TenDlcBrand'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/tendlc/brands/{brandId}/submit':
    post:
      tags:
        - 10DLC Registration
      summary: Submit a 10DLC brand to The Campaign Registry (TCR).
      parameters:
        - name: brandId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/tendlc/brand/submit:
    post:
      tags:
        - 10DLC Registration
      summary: Legacy submit — targets the oldest brand for the account.
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/tendlc/brands/{brandId}/resubmit':
    post:
      tags:
        - 10DLC Registration
      summary: Resubmit an existing 10DLC brand to TCR after profile changes.
      parameters:
        - name: brandId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/tendlc/brand/resubmit:
    post:
      tags:
        - 10DLC Registration
      summary: Legacy resubmit — targets the oldest brand for the account.
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/tendlc/brands/{brandId}/sync':
    post:
      tags:
        - 10DLC Registration
      summary: Force an immediate TCR sync for a specific brand.
      parameters:
        - name: brandId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/tendlc/brand/sync:
    post:
      tags:
        - 10DLC Registration
      summary: Legacy sync — targets the oldest brand for the account.
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/tendlc/campaigns:
    get:
      tags:
        - 10DLC Registration
      summary: List all 10DLC campaigns for the authenticated account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TenDlcCampaign'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TenDlcCampaign'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TenDlcCampaign'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - 10DLC Registration
      summary: Create a new 10DLC campaign linked to a brand owned by the account.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTenDlcCampaignRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateTenDlcCampaignRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateTenDlcCampaignRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/TenDlcCampaign'
            application/json:
              schema:
                $ref: '#/components/schemas/TenDlcCampaign'
            text/json:
              schema:
                $ref: '#/components/schemas/TenDlcCampaign'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/tendlc/campaigns/{id}/submit':
    post:
      tags:
        - 10DLC Registration
      summary: Submit a 10DLC campaign to The Campaign Registry.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/tendlc/campaigns/{id}/sync':
    post:
      tags:
        - 10DLC Registration
      summary: Force an immediate TCR sync for a specific campaign.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/me/brands/{brandId}/tcr':
    get:
      tags:
        - 10DLC Registration
      summary: Returns sanitized TCR status details for a specific brand owned by the authenticated account.
      parameters:
        - name: brandId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/UserBrandTcrStatus'
            application/json:
              schema:
                $ref: '#/components/schemas/UserBrandTcrStatus'
            text/json:
              schema:
                $ref: '#/components/schemas/UserBrandTcrStatus'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/me/campaigns/{campaignId}/mno-status':
    get:
      tags:
        - 10DLC Registration
      summary: Returns per-MNO status for a specific campaign owned by the authenticated account.
      parameters:
        - name: campaignId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TcrCampaignMnoStatus'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TcrCampaignMnoStatus'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TcrCampaignMnoStatus'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/accounts/{accountId}/templates/{templateId}':
    get:
      tags:
        - Account Templates
      summary: "Returns the raw `BodyTemplate` and `DefaultVariables` for a template that belongs to\r\naccountId. Use this to perform variable substitution client-side."
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: templateId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
        - api-key: [ ]
  '/v1/accounts/{accountId}/templates/{templateId}/render':
    post:
      tags:
        - Account Templates
      summary: "Render a saved template for the given account with provided variables.\r\nReturns the rendered body string. Only templates belonging to accountId are accessible."
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: templateId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RenderTemplateRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/RenderTemplateRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/RenderTemplateRequest'
      responses:
        '200':
          description: Success
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
        - api-key: [ ]
  /v1/accounts:
    get:
      tags:
        - Accounts
      summary: Returns all accounts visible to the authenticated user.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Account'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Account'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Account'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - Accounts
      summary: Creates a new account owned by the authenticated user.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAccountRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateAccountRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateAccountRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Account'
            application/json:
              schema:
                $ref: '#/components/schemas/Account'
            text/json:
              schema:
                $ref: '#/components/schemas/Account'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/accounts/{accountId}':
    get:
      tags:
        - Accounts
      summary: 'Returns a single account by ID, scoped to the authenticated user.'
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Account'
            application/json:
              schema:
                $ref: '#/components/schemas/Account'
            text/json:
              schema:
                $ref: '#/components/schemas/Account'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    put:
      tags:
        - Accounts
      summary: 'Updates the name, address, and contact details of an account.'
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateAccountRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateAccountRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateAccountRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Account'
            application/json:
              schema:
                $ref: '#/components/schemas/Account'
            text/json:
              schema:
                $ref: '#/components/schemas/Account'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    delete:
      tags:
        - Accounts
      summary: Deletes an account owned by the specified user.
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: userId
          in: query
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/accounts/{accountId}/address':
    put:
      tags:
        - Accounts
      summary: Update account address
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateAccountAddressRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateAccountAddressRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateAccountAddressRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Account'
            application/json:
              schema:
                $ref: '#/components/schemas/Account'
            text/json:
              schema:
                $ref: '#/components/schemas/Account'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/accounts/{accountId}/contact':
    put:
      tags:
        - Accounts
      summary: Update account contact information
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateAccountContactRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateAccountContactRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateAccountContactRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Account'
            application/json:
              schema:
                $ref: '#/components/schemas/Account'
            text/json:
              schema:
                $ref: '#/components/schemas/Account'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/api-keys:
    get:
      tags:
        - API Keys
      summary: List all API keys for the authenticated user's account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ApiKey'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ApiKey'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ApiKey'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - API Keys
      summary: Create a new API key for the user's account. The raw key is returned once.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateApiKeyRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateApiKeyRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateApiKeyRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ApiKey'
            application/json:
              schema:
                $ref: '#/components/schemas/ApiKey'
            text/json:
              schema:
                $ref: '#/components/schemas/ApiKey'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/api-keys/{apiKeyId}':
    get:
      tags:
        - API Keys
      summary: Get a specific API key by ID (must belong to user's account).
      parameters:
        - name: apiKeyId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ApiKey'
            application/json:
              schema:
                $ref: '#/components/schemas/ApiKey'
            text/json:
              schema:
                $ref: '#/components/schemas/ApiKey'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    delete:
      tags:
        - API Keys
      summary: Soft-delete an API key.
      parameters:
        - name: apiKeyId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/api-keys/{apiKeyId}/rotate':
    post:
      tags:
        - API Keys
      summary: Rotate an API key. Returns the new raw key (shown once).
      parameters:
        - name: apiKeyId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ApiKey'
            application/json:
              schema:
                $ref: '#/components/schemas/ApiKey'
            text/json:
              schema:
                $ref: '#/components/schemas/ApiKey'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/api-keys/{apiKeyId}/revoke':
    post:
      tags:
        - API Keys
      summary: Revoke an API key.
      parameters:
        - name: apiKeyId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/api-keys/{apiKeyId}/usage':
    get:
      tags:
        - API Keys
      summary: Get usage statistics for an API key.
      parameters:
        - name: apiKeyId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ApiKeyUsage'
            application/json:
              schema:
                $ref: '#/components/schemas/ApiKeyUsage'
            text/json:
              schema:
                $ref: '#/components/schemas/ApiKeyUsage'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/api-keys/usage/analytics:
    get:
      tags:
        - API Keys
      summary: Get account-level API usage analytics across all user API keys.
      parameters:
        - name: windowHours
          in: query
          schema:
            type: integer
            format: int32
            default: 24
        - name: topEndpoints
          in: query
          schema:
            type: integer
            format: int32
            default: 5
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ApiKeyUsageAnalytics'
            application/json:
              schema:
                $ref: '#/components/schemas/ApiKeyUsageAnalytics'
            text/json:
              schema:
                $ref: '#/components/schemas/ApiKeyUsageAnalytics'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /health:
    get:
      tags:
        - ArelHub.Api
      responses:
        '200':
          description: Success
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/auth/me:
    get:
      tags:
        - Authentication
      summary: 'Returns the authenticated caller''s resolved identity, account, and permission claims.'
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
        - api-key: [ ]
  /v1/auth/login:
    post:
      tags:
        - Authentication
      summary: "Authenticate a user with email and password.\r\nRecords all login attempts (success and failure) for security tracking.\r\nEnforces account lockout after 5 failed attempts within 15 minutes."
      requestBody:
        description: Login credentials (email and password)
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserLoginRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UserLoginRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UserLoginRequest'
      responses:
        '200':
          description: Success
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/auth/external-login:
    post:
      tags:
        - Authentication
      summary: Completes external OAuth2 login and issues local ArelHub user tokens.
      requestBody:
        description: OAuth2 callback data and PKCE verifier.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExternalUserLoginRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/ExternalUserLoginRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/ExternalUserLoginRequest'
      responses:
        '200':
          description: Success
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/auth/logout:
    post:
      tags:
        - Authentication
      summary: Logout the current user. Revokes the current token and terminates the session.
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/profile:
    get:
      tags:
        - Authentication
      summary: Get the authenticated user's profile information
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/UserLoginResult'
            application/json:
              schema:
                $ref: '#/components/schemas/UserLoginResult'
            text/json:
              schema:
                $ref: '#/components/schemas/UserLoginResult'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    put:
      tags:
        - Authentication
      summary: Update the authenticated user's profile information (first name and last name only)
      requestBody:
        description: Profile update request with first and last name
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateUserProfileRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateUserProfileRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateUserProfileRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/UserLoginResult'
            application/json:
              schema:
                $ref: '#/components/schemas/UserLoginResult'
            text/json:
              schema:
                $ref: '#/components/schemas/UserLoginResult'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/change-password:
    post:
      tags:
        - Authentication
      summary: Change the authenticated user's password.
      requestBody:
        description: Current and new password values
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChangeUserPasswordRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/ChangeUserPasswordRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/ChangeUserPasswordRequest'
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/forgot-password:
    post:
      tags:
        - Authentication
      summary: "Initiates password reset flow by sending a reset link to the user email when the account exists.\r\nAlways returns success to avoid account enumeration."
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ForgotUserPasswordRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/ForgotUserPasswordRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/ForgotUserPasswordRequest'
      responses:
        '200':
          description: Success
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/auth/reset-password:
    post:
      tags:
        - Authentication
      summary: Resets password using a signed reset token from the forgot password email.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResetUserPasswordRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/ResetUserPasswordRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/ResetUserPasswordRequest'
      responses:
        '200':
          description: Success
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/billing/subscription:
    get:
      tags:
        - Billing
      summary: Get the authenticated user's active subscription.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/AccountSubscription'
            application/json:
              schema:
                $ref: '#/components/schemas/AccountSubscription'
            text/json:
              schema:
                $ref: '#/components/schemas/AccountSubscription'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/plans:
    get:
      tags:
        - Billing
      summary: Get available subscription plans.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionPlan'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionPlan'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionPlan'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/events:
    get:
      tags:
        - Billing
      summary: Get billing events for the authenticated account within a date window.
      parameters:
        - name: from
          in: query
          schema:
            type: string
            format: date-time
        - name: to
          in: query
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BillingEvent'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BillingEvent'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BillingEvent'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/outstanding-summary:
    get:
      tags:
        - Billing
      summary: Get the open invoice total and payments applied against it.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/OutstandingInvoiceSummary'
            application/json:
              schema:
                $ref: '#/components/schemas/OutstandingInvoiceSummary'
            text/json:
              schema:
                $ref: '#/components/schemas/OutstandingInvoiceSummary'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/current-cycle:
    get:
      tags:
        - Billing
      summary: Current billing cycle ledger and open (unbilled) balance for the authenticated account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/BillingCycle'
            application/json:
              schema:
                $ref: '#/components/schemas/BillingCycle'
            text/json:
              schema:
                $ref: '#/components/schemas/BillingCycle'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/charge-open-balance:
    post:
      tags:
        - Billing
      summary: Invoice unbilled open balance for the active cycle and charge the linked card.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Invoice'
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
            text/json:
              schema:
                $ref: '#/components/schemas/Invoice'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/subscription/change:
    post:
      tags:
        - Billing
      summary: Change the authenticated user's subscription plan.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssignPlanRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/AssignPlanRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/AssignPlanRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/AccountSubscription'
            application/json:
              schema:
                $ref: '#/components/schemas/AccountSubscription'
            text/json:
              schema:
                $ref: '#/components/schemas/AccountSubscription'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/subscription/cancel:
    post:
      tags:
        - Billing
      summary: Cancel the authenticated user's subscription.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/AccountSubscription'
            application/json:
              schema:
                $ref: '#/components/schemas/AccountSubscription'
            text/json:
              schema:
                $ref: '#/components/schemas/AccountSubscription'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/payments/manual:
    post:
      tags:
        - Billing
      summary: Create a one-time manual payment against the authenticated account.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateManualPaymentRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateManualPaymentRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateManualPaymentRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ManualPaymentResult'
            application/json:
              schema:
                $ref: '#/components/schemas/ManualPaymentResult'
            text/json:
              schema:
                $ref: '#/components/schemas/ManualPaymentResult'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/subscription/preview-change:
    get:
      tags:
        - Billing
      summary: Preview the effects of a plan change for the authenticated user.
      parameters:
        - name: newPlanId
          in: query
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/PlanChangePreview'
            application/json:
              schema:
                $ref: '#/components/schemas/PlanChangePreview'
            text/json:
              schema:
                $ref: '#/components/schemas/PlanChangePreview'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/message-costs:
    get:
      tags:
        - Billing
      summary: "Get the authenticated account's message cost summary for a date range.\r\nDefaults to the last 30 days."
      parameters:
        - name: from
          in: query
          schema:
            type: string
            format: date-time
        - name: to
          in: query
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/MessageCostSummary'
            application/json:
              schema:
                $ref: '#/components/schemas/MessageCostSummary'
            text/json:
              schema:
                $ref: '#/components/schemas/MessageCostSummary'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/billing/message-costs/channels:
    get:
      tags:
        - Billing
      summary: "Get per-channel cost breakdown for the authenticated account.\r\nReturns total attempts, carrier cost, and customer charge grouped by channel type.\r\nDefaults to the last 30 days."
      parameters:
        - name: from
          in: query
          schema:
            type: string
            format: date-time
        - name: to
          in: query
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ChannelCostBreakdown'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ChannelCostBreakdown'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ChannelCostBreakdown'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/billing/message-costs/detail:
    get:
      tags:
        - Billing
      summary: "Get paginated per-message cost detail for the authenticated account.\r\nDefaults to the last 30 days, 50 per page."
      parameters:
        - name: from
          in: query
          schema:
            type: string
            format: date-time
        - name: to
          in: query
          schema:
            type: string
            format: date-time
        - name: page
          in: query
          schema:
            type: integer
            format: int32
            default: 1
        - name: pageSize
          in: query
          schema:
            type: integer
            format: int32
            default: 50
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/MessageCostDetail'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/MessageCostDetail'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/MessageCostDetail'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/billing/payment-methods:
    get:
      tags:
        - Billing
      summary: Retrieves all saved payment methods for the current user's account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PaymentMethod'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PaymentMethod'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PaymentMethod'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - Billing
      summary: Attaches a new payment method to the account (requires step-up authentication).
      requestBody:
        description: Request with Stripe payment method ID and optional default flag.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SavePaymentMethodRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/SavePaymentMethodRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/SavePaymentMethodRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/PaymentMethod'
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentMethod'
            text/json:
              schema:
                $ref: '#/components/schemas/PaymentMethod'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/payment-methods/setup-intent:
    post:
      tags:
        - Billing
      summary: Creates a Stripe SetupIntent for adding a new payment method.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SetupIntent'
            application/json:
              schema:
                $ref: '#/components/schemas/SetupIntent'
            text/json:
              schema:
                $ref: '#/components/schemas/SetupIntent'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/billing/payment-methods/{paymentMethodId}/set-default':
    post:
      tags:
        - Billing
      summary: Sets a payment method as the default for the account (requires step-up authentication).
      parameters:
        - name: paymentMethodId
          in: path
          description: ID of the payment method.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/billing/payment-methods/{paymentMethodId}':
    delete:
      tags:
        - Billing
      summary: Deletes a payment method from the account (requires step-up authentication).
      parameters:
        - name: paymentMethodId
          in: path
          description: ID of the payment method to delete.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/receipts:
    get:
      tags:
        - Billing
      summary: Returns all receipts for the authenticated account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Receipt'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Receipt'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Receipt'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/billing/receipts/{receiptId}/download':
    get:
      tags:
        - Billing
      summary: Downloads a receipt as a PDF attachment.
      parameters:
        - name: receiptId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/messages/{messageId}/carrier-events':
    post:
      tags:
        - Carrier Webhooks
      summary: Processes an inbound carrier delivery event for a message.
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CarrierEventRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CarrierEventRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CarrierEventRequest'
      responses:
        '202':
          description: Accepted
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  '/v1/webhooks/messages/provider/{providerKey}/{providerMessageId}/carrier-events':
    post:
      tags:
        - Carrier Webhooks
      summary: Processes an inbound provider-scoped carrier delivery event identified by provider key and message ID.
      parameters:
        - name: providerKey
          in: path
          required: true
          schema:
            type: string
        - name: providerMessageId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CarrierEventRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CarrierEventRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CarrierEventRequest'
      responses:
        '202':
          description: Accepted
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  '/v1/subaccounts/{subaccountId}/preferences':
    get:
      tags:
        - Channel Consent
      summary: Returns per-channel opt-out status for the authenticated recipient.
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ChannelPreferenceStatus'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ChannelPreferenceStatus'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ChannelPreferenceStatus'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/subaccounts/{subaccountId}/opt-outs':
    get:
      tags:
        - Channel Consent
      summary: List all opt-out records for a subaccount.
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ChannelOptOut'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ChannelOptOut'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ChannelOptOut'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/subaccounts/{subaccountId}/opt-out':
    post:
      tags:
        - Channel Consent
      summary: Opt out of a channel for a subaccount (on behalf of a recipient).
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChannelOptOutRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/ChannelOptOutRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/ChannelOptOutRequest'
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/subaccounts/{subaccountId}/opt-in':
    post:
      tags:
        - Channel Consent
      summary: Opt back in to a channel for a subaccount.
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChannelOptInRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/ChannelOptInRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/ChannelOptInRequest'
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/subaccounts/{subaccountId}/routing-policy':
    get:
      tags:
        - Channel Routing
      summary: Get the channel routing policy for a subaccount.
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ChannelRoutingPolicy'
            application/json:
              schema:
                $ref: '#/components/schemas/ChannelRoutingPolicy'
            text/json:
              schema:
                $ref: '#/components/schemas/ChannelRoutingPolicy'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    put:
      tags:
        - Channel Routing
      summary: "Create or update the channel routing policy for a subaccount.\r\nSets the preferred channel type and ordered fallback chain used at runtime dispatch."
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpsertChannelRoutingPolicyRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpsertChannelRoutingPolicyRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpsertChannelRoutingPolicyRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ChannelRoutingPolicy'
            application/json:
              schema:
                $ref: '#/components/schemas/ChannelRoutingPolicy'
            text/json:
              schema:
                $ref: '#/components/schemas/ChannelRoutingPolicy'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/subaccounts/{subaccountId}/routing-policy/preview':
    get:
      tags:
        - Channel Routing
      summary: "Preview the effective channel route that would be resolved for a given channel type and subaccount.\r\nReturns the ordered list of channels (primary + fallbacks) that dispatch would attempt."
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: requestedChannelType
          in: query
          schema:
            $ref: '#/components/schemas/ChannelTypeEntity'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ChannelRoutePreview'
            application/json:
              schema:
                $ref: '#/components/schemas/ChannelRoutePreview'
            text/json:
              schema:
                $ref: '#/components/schemas/ChannelRoutePreview'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/email-otp/issue:
    post:
      tags:
        - Email OTP
      summary: Issue a new email OTP challenge for the authenticated user.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IssueRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/IssueRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/IssueRequest'
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/email-otp/verify:
    post:
      tags:
        - Email OTP
      summary: Verify an email OTP challenge for the authenticated user.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/VerifyRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/VerifyRequest'
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/invoices:
    get:
      tags:
        - Invoices
      summary: Lists all invoices for the authenticated account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Invoice'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Invoice'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Invoice'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/billing/invoices/{invoiceId}':
    get:
      tags:
        - Invoices
      summary: 'Returns a single invoice by ID, verifying it belongs to the authenticated account.'
      parameters:
        - name: invoiceId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Invoice'
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
            text/json:
              schema:
                $ref: '#/components/schemas/Invoice'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/billing/invoices/{invoiceId}/download':
    get:
      tags:
        - Invoices
      summary: Generates and downloads the specified invoice as a PDF attachment.
      parameters:
        - name: invoiceId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/{userId}/login-history':
    get:
      tags:
        - Login History
      summary: Get paginated login history for the authenticated user
      parameters:
        - name: userId
          in: path
          description: User ID to fetch history for
          required: true
          schema:
            type: string
            format: uuid
        - name: pageNumber
          in: query
          description: 'Page number for pagination (default: 1)'
          schema:
            type: integer
            format: int32
            default: 1
        - name: pageSize
          in: query
          description: 'Number of items per page (default: 50)'
          schema:
            type: integer
            format: int32
            default: 50
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/{userId}/login-history/failed':
    get:
      tags:
        - Login History
      summary: Get failed login attempts only
      parameters:
        - name: userId
          in: path
          description: User ID to fetch failed attempts for
          required: true
          schema:
            type: string
            format: uuid
        - name: pageNumber
          in: query
          description: 'Page number for pagination (default: 1)'
          schema:
            type: integer
            format: int32
            default: 1
        - name: pageSize
          in: query
          description: 'Number of items per page (default: 50)'
          schema:
            type: integer
            format: int32
            default: 50
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/{userId}/login-history/successful':
    get:
      tags:
        - Login History
      summary: Get successful login attempts only
      parameters:
        - name: userId
          in: path
          description: User ID to fetch successful attempts for
          required: true
          schema:
            type: string
            format: uuid
        - name: pageNumber
          in: query
          description: 'Page number for pagination (default: 1)'
          schema:
            type: integer
            format: int32
            default: 1
        - name: pageSize
          in: query
          description: 'Number of items per page (default: 50)'
          schema:
            type: integer
            format: int32
            default: 50
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/{userId}/login-history/stats':
    get:
      tags:
        - Login History
      summary: Get login history statistics for the authenticated user
      parameters:
        - name: userId
          in: path
          description: User ID to fetch statistics for
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/LoginStatistics'
            application/json:
              schema:
                $ref: '#/components/schemas/LoginStatistics'
            text/json:
              schema:
                $ref: '#/components/schemas/LoginStatistics'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/{userId}/activity-timeline':
    get:
      tags:
        - Login History
      summary: Get a merged account activity timeline containing audit events and login events.
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: pageNumber
          in: query
          schema:
            type: integer
            format: int32
            default: 1
        - name: pageSize
          in: query
          schema:
            type: integer
            format: int32
            default: 25
        - name: lookbackDays
          in: query
          schema:
            type: integer
            format: int32
            default: 30
        - name: searchTerm
          in: query
          schema:
            type: string
        - name: activityType
          in: query
          schema:
            type: string
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/AccountActivityTimeline'
            application/json:
              schema:
                $ref: '#/components/schemas/AccountActivityTimeline'
            text/json:
              schema:
                $ref: '#/components/schemas/AccountActivityTimeline'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/{userId}/login-history/by-date-range':
    get:
      tags:
        - Login History
      summary: Get login history filtered by date range
      parameters:
        - name: userId
          in: path
          description: User ID to fetch history for
          required: true
          schema:
            type: string
            format: uuid
        - name: startDate
          in: query
          description: Start of date range (inclusive)
          schema:
            type: string
            format: date-time
        - name: endDate
          in: query
          description: End of date range (exclusive)
          schema:
            type: string
            format: date-time
        - name: pageNumber
          in: query
          description: 'Page number for pagination (default: 1)'
          schema:
            type: integer
            format: int32
            default: 1
        - name: pageSize
          in: query
          description: 'Number of items per page (default: 50)'
          schema:
            type: integer
            format: int32
            default: 50
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/UserLoginHistoryPagedResponse'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/{userId}/login-history/is-locked':
    get:
      tags:
        - Login History
      summary: Check if account is locked due to failed login attempts
      parameters:
        - name: userId
          in: path
          description: User ID to check lockout status for
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/accounts/{accountId}/messages/{messageId}/risk':
    get:
      tags:
        - Messages
      summary: 'Returns the latest risk decision for a message, with a customer-safe explanation.'
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: messageId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/MessageRiskResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/MessageRiskResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/MessageRiskResponse'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/accounts/{accountId}/messages':
    post:
      tags:
        - Messages
      summary: Submits a new message for dispatch under the specified account.
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMessageRequest'
            examples:
              sms-transactional:
                summary: SMS transactional
                description: Simple SMS dispatch with E.164 destination.
                value:
                  channel: SMS
                  destination: '+15551234567'
                  body: Your OTP is 123456
                  messageType: Transactional
                  actor: user-api
              email-transactional:
                summary: Email transactional
                description: Email message using the same unified submit contract.
                value:
                  channel: Email
                  destination: ops@arelhub.com
                  body: Daily report is ready.
                  messageType: Transactional
                  actor: user-api
              whatsapp-template:
                summary: WhatsApp
                description: WhatsApp send request. Template resolution occurs server-side via approved channel templates.
                value:
                  channel: WhatsApp
                  destination: '+15557654321'
                  body: 'Order #9421 shipped'
                  messageType: Transactional
                  actor: user-api
              slack-internal:
                summary: Slack internal
                description: Slack channel dispatch through the same lifecycle path.
                value:
                  channel: Slack
                  destination: '#alerts'
                  body: Payment webhook backlog exceeded threshold
                  messageType: System
                  actor: staff-api
              rcs-transactional:
                summary: RCS transactional
                description: RCS dispatch through the unified submit contract using an E.164 destination.
                value:
                  channel: RCS
                  destination: '+15559876543'
                  body: Your verification code is 842991
                  messageType: Transactional
                  actor: user-api
              inapppush-segment:
                summary: In-App Push segment
                description: Firebase segment fan-out using topic targets.
                value:
                  channel: InAppPush
                  destination: ''
                  body: Scheduled maintenance starts in 10 minutes.
                  messageType: System
                  actor: system-worker
                  pushTopics:
                    - segment:oncall
                    - segment:priority-tenants
                  pushUserIds:
                    - user-8f5e1f2a
          text/json:
            schema:
              $ref: '#/components/schemas/CreateMessageRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateMessageRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Message'
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
            text/json:
              schema:
                $ref: '#/components/schemas/Message'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too Many Requests
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
        - api-key: [ ]
    get:
      tags:
        - Messages
      summary: Lists messages for an account with optional server-side filtering.
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Page
          in: query
          schema:
            type: integer
            format: int32
        - name: PageSize
          in: query
          schema:
            type: integer
            format: int32
        - name: Sort
          in: query
          schema:
            type: string
        - name: Direction
          in: query
          schema:
            type: string
        - name: MessageState
          in: query
          schema:
            $ref: '#/components/schemas/MessageStateEntity'
        - name: ChannelType
          in: query
          schema:
            $ref: '#/components/schemas/ChannelTypeEntity'
        - name: Destination
          in: query
          schema:
            type: string
        - name: AccountName
          in: query
          schema:
            type: string
        - name: SubaccountName
          in: query
          schema:
            type: string
        - name: IncludeDeleted
          in: query
          schema:
            type: boolean
        - name: CreatedFrom
          in: query
          schema:
            type: string
            format: date-time
        - name: CreatedTo
          in: query
          schema:
            type: string
            format: date-time
        - name: Search
          in: query
          schema:
            type: string
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
        - api-key: [ ]
  '/v1/accounts/{accountId}/messages/{messageId}':
    get:
      tags:
        - Messages
      summary: Returns a single message by ID for the specified account.
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: messageId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
        - api-key: [ ]
  '/v1/accounts/{accountId}/messages/{messageId}/transition':
    post:
      tags:
        - Messages
      summary: Applies a customer-permitted state transition to an existing message.
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: messageId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AccountTransitionRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/AccountTransitionRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/AccountTransitionRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Message'
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
            text/json:
              schema:
                $ref: '#/components/schemas/Message'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
        - api-key: [ ]
  /v1/messages/segments/preview:
    post:
      tags:
        - Messages
      summary: 'Calculates segment count, encoding, and estimated cost for a message body without sending it.'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SegmentPreviewRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/SegmentPreviewRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/SegmentPreviewRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SegmentPreviewResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/SegmentPreviewResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/SegmentPreviewResponse'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  '/v1/subaccounts/{subaccountId}/messages':
    post:
      tags:
        - Messages
      summary: Submits a new message for dispatch under the specified subaccount.
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMessageRequest'
            examples:
              sms-transactional:
                summary: SMS transactional
                description: Simple SMS dispatch with E.164 destination.
                value:
                  channel: SMS
                  destination: '+15551234567'
                  body: Your OTP is 123456
                  messageType: Transactional
                  actor: user-api
              email-transactional:
                summary: Email transactional
                description: Email message using the same unified submit contract.
                value:
                  channel: Email
                  destination: ops@arelhub.com
                  body: Daily report is ready.
                  messageType: Transactional
                  actor: user-api
              whatsapp-template:
                summary: WhatsApp
                description: WhatsApp send request. Template resolution occurs server-side via approved channel templates.
                value:
                  channel: WhatsApp
                  destination: '+15557654321'
                  body: 'Order #9421 shipped'
                  messageType: Transactional
                  actor: user-api
              slack-internal:
                summary: Slack internal
                description: Slack channel dispatch through the same lifecycle path.
                value:
                  channel: Slack
                  destination: '#alerts'
                  body: Payment webhook backlog exceeded threshold
                  messageType: System
                  actor: staff-api
              rcs-transactional:
                summary: RCS transactional
                description: RCS dispatch through the unified submit contract using an E.164 destination.
                value:
                  channel: RCS
                  destination: '+15559876543'
                  body: Your verification code is 842991
                  messageType: Transactional
                  actor: user-api
              inapppush-segment:
                summary: In-App Push segment
                description: Firebase segment fan-out using topic targets.
                value:
                  channel: InAppPush
                  destination: ''
                  body: Scheduled maintenance starts in 10 minutes.
                  messageType: System
                  actor: system-worker
                  pushTopics:
                    - segment:oncall
                    - segment:priority-tenants
                  pushUserIds:
                    - user-8f5e1f2a
          text/json:
            schema:
              $ref: '#/components/schemas/CreateMessageRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateMessageRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Message'
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
            text/json:
              schema:
                $ref: '#/components/schemas/Message'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too Many Requests
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
        - api-key: [ ]
    get:
      tags:
        - Messages
      summary: Lists messages for a subaccount with optional server-side filtering.
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Page
          in: query
          schema:
            type: integer
            format: int32
        - name: PageSize
          in: query
          schema:
            type: integer
            format: int32
        - name: Sort
          in: query
          schema:
            type: string
        - name: Direction
          in: query
          schema:
            type: string
        - name: MessageState
          in: query
          schema:
            $ref: '#/components/schemas/MessageStateEntity'
        - name: ChannelType
          in: query
          schema:
            $ref: '#/components/schemas/ChannelTypeEntity'
        - name: Destination
          in: query
          schema:
            type: string
        - name: AccountName
          in: query
          schema:
            type: string
        - name: SubaccountName
          in: query
          schema:
            type: string
        - name: IncludeDeleted
          in: query
          schema:
            type: boolean
        - name: CreatedFrom
          in: query
          schema:
            type: string
            format: date-time
        - name: CreatedTo
          in: query
          schema:
            type: string
            format: date-time
        - name: Search
          in: query
          schema:
            type: string
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
        - api-key: [ ]
  '/v1/subaccounts/{subaccountId}/messages/{messageId}':
    get:
      tags:
        - Messages
      summary: Returns a single message by ID for the specified subaccount.
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: messageId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
        - api-key: [ ]
  /v1/preferences/notifications:
    get:
      tags:
        - Notification Preferences
      summary: Returns the notification preferences for the authenticated user.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/UserNotificationPreferences'
            application/json:
              schema:
                $ref: '#/components/schemas/UserNotificationPreferences'
            text/json:
              schema:
                $ref: '#/components/schemas/UserNotificationPreferences'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    put:
      tags:
        - Notification Preferences
      summary: Updates the notification preferences for the authenticated user.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserNotificationPreferences'
          text/json:
            schema:
              $ref: '#/components/schemas/UserNotificationPreferences'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UserNotificationPreferences'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/UserNotificationPreferences'
            application/json:
              schema:
                $ref: '#/components/schemas/UserNotificationPreferences'
            text/json:
              schema:
                $ref: '#/components/schemas/UserNotificationPreferences'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/number-pools:
    get:
      tags:
        - Number Pools
      summary: List all number pools for the authenticated account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/NumberPool'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/NumberPool'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/NumberPool'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - Number Pools
      summary: Create a new number pool.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateNumberPoolRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateNumberPoolRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateNumberPoolRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/NumberPool'
            application/json:
              schema:
                $ref: '#/components/schemas/NumberPool'
            text/json:
              schema:
                $ref: '#/components/schemas/NumberPool'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/number-pools/{id}/numbers/{phoneNumberId}':
    post:
      tags:
        - Number Pools
      summary: Add a phone number to a pool.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: phoneNumberId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    delete:
      tags:
        - Number Pools
      summary: Remove a phone number from a pool.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: phoneNumberId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/number-pools/{id}':
    delete:
      tags:
        - Number Pools
      summary: Delete a number pool. All numbers in the pool will be unassigned first.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/authorize:
    post:
      tags:
        - OAuth2 Authentication
      summary: "Gets authorization URL for OAuth2 provider.\r\nClient should redirect user to this URL for provider login."
      requestBody:
        description: Provider ID and redirect URI
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AuthorizeProviderRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/AuthorizeProviderRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/AuthorizeProviderRequest'
      responses:
        '200':
          description: Authorization URL generated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthorizeProviderResponse'
        '400':
          description: Invalid provider or request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Provider not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/auth/callback:
    post:
      tags:
        - OAuth2 Authentication
      summary: "Handles OAuth2 provider callback.\r\nCalled by provider after user authorizes. Exchanges code for tokens and user info."
      requestBody:
        description: Callback data from OAuth2 provider
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OAuth2CallbackRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/OAuth2CallbackRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/OAuth2CallbackRequest'
      responses:
        '200':
          description: Callback handled successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2CallbackResponse'
        '400':
          description: Invalid callback or user auth failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/auth/link:
    post:
      tags:
        - OAuth2 Authentication
      summary: "Links an external provider to authenticated user's account.\r\nAllows multi-provider authentication for same user."
      requestBody:
        description: Provider link request
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LinkProviderRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/LinkProviderRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/LinkProviderRequest'
      responses:
        '200':
          description: Provider linked successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalIdentityResponse'
        '400':
          description: Invalid request or duplicate provider
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: User not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Provider not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/unlink:
    post:
      tags:
        - OAuth2 Authentication
      summary: Unlinks an external provider from authenticated user's account.
      requestBody:
        description: Provider unlink request
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UnlinkProviderRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UnlinkProviderRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UnlinkProviderRequest'
      responses:
        '204':
          description: Provider unlinked successfully
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: User not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Identity not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/identities:
    get:
      tags:
        - OAuth2 Authentication
      summary: Gets all external provider identities linked to authenticated user.
      responses:
        '200':
          description: Identities retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserIdentitiesResponse'
        '401':
          description: User not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/identities/primary:
    get:
      tags:
        - OAuth2 Authentication
      summary: Gets the user's primary (preferred) authentication method.
      responses:
        '200':
          description: Primary identity retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalIdentityResponse'
        '401':
          description: User not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: No primary identity set
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - OAuth2 Authentication
      summary: Sets an external identity as the user's primary authentication method.
      requestBody:
        description: Identity to set as primary
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetPrimaryIdentityRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/SetPrimaryIdentityRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/SetPrimaryIdentityRequest'
      responses:
        '204':
          description: Primary identity set successfully
        '400':
          description: Invalid request or unlinked identity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: User not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Identity not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/providers:
    get:
      tags:
        - OAuth2 Authentication
      summary: Gets all OAuth2 providers.
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ExternalAuthProviderResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - OAuth2 Authentication
      summary: Creates a new OAuth2 provider.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateProviderRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateProviderRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateProviderRequest'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAuthProviderResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/providers/public:
    get:
      tags:
        - OAuth2 Authentication
      summary: "Gets active OAuth2 providers for public login discovery.\r\nReturns only non-sensitive fields needed by client login UIs."
      parameters:
        - name: providerType
          in: query
          schema:
            type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PublicExternalAuthProviderResponse'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  '/v1/auth/providers/{providerId}':
    put:
      tags:
        - OAuth2 Authentication
      summary: Updates an OAuth2 provider.
      parameters:
        - name: providerId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateProviderRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateProviderRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateProviderRequest'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAuthProviderResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    delete:
      tags:
        - OAuth2 Authentication
      summary: Deletes an OAuth2 provider.
      parameters:
        - name: providerId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/providers/{providerId}/activate':
    post:
      tags:
        - OAuth2 Authentication
      summary: Activates an OAuth2 provider.
      parameters:
        - name: providerId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/providers/{providerId}/deactivate':
    post:
      tags:
        - OAuth2 Authentication
      summary: Deactivates an OAuth2 provider.
      parameters:
        - name: providerId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/mfa/methods/{providerId}':
    get:
      tags:
        - OAuth2MFA
      summary: Gets available MFA methods for a provider.
      parameters:
        - name: providerId
          in: path
          description: Provider ID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Methods retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/auth/mfa/challenge:
    post:
      tags:
        - OAuth2MFA
      summary: Initiates an MFA challenge for delegation verification.
      requestBody:
        description: Challenge initiation request
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InitiateMFAChallengeRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/InitiateMFAChallengeRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/InitiateMFAChallengeRequest'
      responses:
        '200':
          description: Challenge initiated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2MFAChallengeInit'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Delegation not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/mfa/challenge/verify:
    post:
      tags:
        - OAuth2MFA
      summary: Verifies an MFA challenge with the provided code.
      requestBody:
        description: Challenge verification request
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyMFAChallengeRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/VerifyMFAChallengeRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/VerifyMFAChallengeRequest'
      responses:
        '200':
          description: Verification processed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2MFAChallengeVerify'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Challenge not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/mfa/required/{providerId}':
    get:
      tags:
        - OAuth2MFA
      summary: Checks if MFA is required for a provider.
      parameters:
        - name: providerId
          in: path
          description: Provider ID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Check completed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MFARequiredResponse'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  '/v1/auth/mfa/config/{providerId}':
    get:
      tags:
        - OAuth2MFA
      summary: "Gets the MFA configuration for a provider.\r\nStaff only endpoint."
      parameters:
        - name: providerId
          in: path
          description: Provider ID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Configuration retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2MFAConfig'
        '404':
          description: Provider not found or MFA not configured
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - OAuth2MFA
      summary: "Creates or updates MFA configuration for a provider.\r\nStaff only endpoint."
      parameters:
        - name: providerId
          in: path
          description: Provider ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        description: MFA configuration request
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrUpdateMFAConfigRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateOrUpdateMFAConfigRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateOrUpdateMFAConfigRequest'
      responses:
        '200':
          description: Configuration created/updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2MFAConfig'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/onboarding:
    get:
      tags:
        - Onboarding
      summary: Returns the onboarding status and checklist for the authenticated user's account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/AccountOnboardingStatus'
            application/json:
              schema:
                $ref: '#/components/schemas/AccountOnboardingStatus'
            text/json:
              schema:
                $ref: '#/components/schemas/AccountOnboardingStatus'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/onboarding/resend-email-verification:
    post:
      tags:
        - Onboarding
      summary: Resends the email confirmation link to the authenticated user's registered address.
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/webhooks/config:
    get:
      tags:
        - Payment Webhooks
      summary: Get webhook configuration for the authenticated account
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/WebhookConfig'
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookConfig'
            text/json:
              schema:
                $ref: '#/components/schemas/WebhookConfig'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - Payment Webhooks
      summary: Configure payment webhook URL and generate secret
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConfigureWebhookRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/ConfigureWebhookRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/ConfigureWebhookRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/WebhookConfig'
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookConfig'
            text/json:
              schema:
                $ref: '#/components/schemas/WebhookConfig'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/webhooks/enable:
    post:
      tags:
        - Payment Webhooks
      summary: Enable payment webhooks
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/webhooks/disable:
    post:
      tags:
        - Payment Webhooks
      summary: Disable payment webhooks
      responses:
        '204':
          description: No Content
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/billing/webhooks/regenerate-secret:
    post:
      tags:
        - Payment Webhooks
      summary: Regenerate webhook secret
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/WebhookSecret'
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookSecret'
            text/json:
              schema:
                $ref: '#/components/schemas/WebhookSecret'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/phone-numbers/search:
    get:
      tags:
        - Phone Numbers
      summary: Search available phone numbers.
      parameters:
        - name: areaCode
          in: query
          schema:
            type: string
        - name: regionCode
          in: query
          schema:
            type: string
        - name: countryCode
          in: query
          schema:
            type: string
        - name: type
          in: query
          schema:
            $ref: '#/components/schemas/PhoneNumberTypeEntity'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AvailableNumber'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AvailableNumber'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AvailableNumber'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '502':
          description: Server Error
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/phone-numbers/purchase:
    post:
      tags:
        - Phone Numbers
      summary: Purchase a phone number and provision it to the account.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PurchasePhoneNumberRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/PurchasePhoneNumberRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/PurchasePhoneNumberRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProvisionedPhoneNumber'
            application/json:
              schema:
                $ref: '#/components/schemas/ProvisionedPhoneNumber'
            text/json:
              schema:
                $ref: '#/components/schemas/ProvisionedPhoneNumber'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/phone-numbers:
    get:
      tags:
        - Phone Numbers
      summary: List all provisioned numbers for the authenticated account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProvisionedPhoneNumber'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProvisionedPhoneNumber'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProvisionedPhoneNumber'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/phone-numbers/{id}/assign':
    post:
      tags:
        - Phone Numbers
      summary: Assign a phone number to a subaccount.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssignPhoneNumberRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/AssignPhoneNumberRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/AssignPhoneNumberRequest'
      responses:
        '204':
          description: No Content
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/phone-numbers/{id}/unassign':
    post:
      tags:
        - Phone Numbers
      summary: Remove subaccount assignment from a phone number.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/phone-numbers/{id}/set-default':
    post:
      tags:
        - Phone Numbers
      summary: Set a phone number as the default for account or subaccount.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/phone-numbers/{id}':
    delete:
      tags:
        - Phone Numbers
      summary: Release (delete) a phone number. This action is irreversible.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/plans:
    get:
      tags:
        - Plans
      summary: Get active subscription plans. Anonymous — used by the public pricing page.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionPlan'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionPlan'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubscriptionPlan'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/privacy/export:
    post:
      tags:
        - Privacy
      summary: "Request a data export (DSAR - Data Subject Access Request)\r\nUser can download all their personal data within 30 days (GDPR requirement)"
      description: "POST /v1/privacy/export\r\nReturns: 201 Created with request details"
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/DataSubjectRequest'
            application/json:
              schema:
                $ref: '#/components/schemas/DataSubjectRequest'
            text/json:
              schema:
                $ref: '#/components/schemas/DataSubjectRequest'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/privacy/erasure:
    post:
      tags:
        - Privacy
      summary: "Request account erasure/anonymization (Right to be Forgotten - GDPR Article 17)\r\nUser's personal data will be anonymized while preserving billing/audit records"
      description: "POST /v1/privacy/erasure\r\nReturns: 201 Created with request details"
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/DataSubjectRequest'
            application/json:
              schema:
                $ref: '#/components/schemas/DataSubjectRequest'
            text/json:
              schema:
                $ref: '#/components/schemas/DataSubjectRequest'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/privacy/requests/{requestId}':
    get:
      tags:
        - Privacy
      summary: "Get a specific privacy request by ID\r\nUser can only access their own requests"
      description: "GET /v1/privacy/requests/{requestId}\r\nReturns: 200 OK with request details, or 404 Not Found"
      parameters:
        - name: requestId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/DataSubjectRequest'
            application/json:
              schema:
                $ref: '#/components/schemas/DataSubjectRequest'
            text/json:
              schema:
                $ref: '#/components/schemas/DataSubjectRequest'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/privacy/requests:
    get:
      tags:
        - Privacy
      summary: Get all privacy requests for the current user
      description: "GET /v1/privacy/requests\r\nReturns: 200 OK with list of user's requests"
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DataSubjectRequest'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DataSubjectRequest'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DataSubjectRequest'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/privacy/requests/{requestId}/download':
    get:
      tags:
        - Privacy
      summary: "Download data export file\r\nUser can only download their own exports, and only within 7 days of generation"
      description: "GET /v1/privacy/requests/{requestId}/download\r\nReturns: 200 OK with JSON export file, or 404/410 if expired"
      parameters:
        - name: requestId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/privacy/consent/{category}':
    post:
      tags:
        - Privacy
      summary: Grant consent for a data processing category
      description: "POST /v1/privacy/consent/{category}\r\nCategories: Marketing, Analytics, Profiling, ThirdPartySharing\r\nReturns: 201 Created with consent record"
      parameters:
        - name: category
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/ConsentCategoryEntity'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ConsentRecord'
            application/json:
              schema:
                $ref: '#/components/schemas/ConsentRecord'
            text/json:
              schema:
                $ref: '#/components/schemas/ConsentRecord'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    delete:
      tags:
        - Privacy
      summary: "Revoke consent for a data processing category\r\nUser has the right to withdraw consent at any time (GDPR Article 7.3)"
      description: "DELETE /v1/privacy/consent/{category}\r\nReturns: 204 No Content on success"
      parameters:
        - name: category
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/ConsentCategoryEntity'
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    get:
      tags:
        - Privacy
      summary: Get current (most recent) consent status for a category
      description: "GET /v1/privacy/consent/{category}\r\nReturns: 200 OK with consent record, or 404 if no consent exists"
      parameters:
        - name: category
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/ConsentCategoryEntity'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ConsentRecord'
            application/json:
              schema:
                $ref: '#/components/schemas/ConsentRecord'
            text/json:
              schema:
                $ref: '#/components/schemas/ConsentRecord'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/privacy/consents:
    get:
      tags:
        - Privacy
      summary: Get all consent records for the current user (full audit trail)
      description: "GET /v1/privacy/consents\r\nReturns: 200 OK with list of all consent records"
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ConsentRecord'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ConsentRecord'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ConsentRecord'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/provider-discovery/discover:
    post:
      tags:
        - Provider Discovery
      summary: Discovers a provider by email domain.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DiscoverProviderRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/DiscoverProviderRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/DiscoverProviderRequest'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DiscoverProviderResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  '/v1/provider-discovery/health/{providerId}':
    get:
      tags:
        - Provider Discovery
      summary: Gets provider health status.
      parameters:
        - name: providerId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProviderHealthStatus'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/provider-discovery/health:
    get:
      tags:
        - Provider Discovery
      summary: Gets health status for all providers.
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProviderHealthStatus'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/provider-discovery/health/unhealthy:
    get:
      tags:
        - Provider Discovery
      summary: Gets unhealthy providers (Degraded or Unavailable).
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProviderHealthStatus'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/provider-discovery/rules:
    get:
      tags:
        - Provider Discovery
      summary: Gets all discovery rules (staff only).
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProviderDiscoveryRule'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - Provider Discovery
      summary: Adds a discovery rule (staff only).
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddProviderDiscoveryRuleRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/AddProviderDiscoveryRuleRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/AddProviderDiscoveryRuleRequest'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProviderDiscoveryRule'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/provider-discovery/health/{providerId}/check':
    post:
      tags:
        - Provider Discovery
      summary: Manually checks a provider's health.
      parameters:
        - name: providerId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProviderHealthStatus'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /openapi/public.json:
    get:
      tags:
        - PublicOpenApi
      summary: Returns the public OpenAPI document as JSON.
      responses:
        '200':
          description: Success
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /openapi/public.yaml:
    get:
      tags:
        - PublicOpenApi
      summary: Returns the public OpenAPI document as YAML.
      responses:
        '200':
          description: Success
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/quota:
    get:
      tags:
        - Quota
      summary: Get the authenticated user's account quota and current usage.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/AccountQuota'
            application/json:
              schema:
                $ref: '#/components/schemas/AccountQuota'
            text/json:
              schema:
                $ref: '#/components/schemas/AccountQuota'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/quota/subaccounts:
    get:
      tags:
        - Quota
      summary: Get all subaccount quotas for the authenticated user's account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubaccountQuota'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubaccountQuota'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubaccountQuota'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/quota/subaccounts/{subaccountId}':
    get:
      tags:
        - Quota
      summary: Get quota and usage for a specific subaccount owned by the authenticated user.
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SubaccountQuota'
            application/json:
              schema:
                $ref: '#/components/schemas/SubaccountQuota'
            text/json:
              schema:
                $ref: '#/components/schemas/SubaccountQuota'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    put:
      tags:
        - Quota
      summary: "Set or update quota limits for a subaccount owned by the authenticated user.\r\nUse 0 to set a limit to unlimited. Omit (null) to keep current value."
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateQuotaRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateQuotaRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateQuotaRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SubaccountQuota'
            application/json:
              schema:
                $ref: '#/components/schemas/SubaccountQuota'
            text/json:
              schema:
                $ref: '#/components/schemas/SubaccountQuota'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/realtime-metrics:
    get:
      tags:
        - Realtime Metrics
      summary: Returns the current metrics snapshot for all of the caller's accounts.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RealtimeMetrics'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RealtimeMetrics'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RealtimeMetrics'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  '/v1/realtime-metrics/account/{accountId}':
    get:
      tags:
        - Realtime Metrics
      summary: Returns the current metrics snapshot for a specific account.
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/RealtimeMetrics'
            application/json:
              schema:
                $ref: '#/components/schemas/RealtimeMetrics'
            text/json:
              schema:
                $ref: '#/components/schemas/RealtimeMetrics'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  '/v1/realtime-metrics/subaccount/{subaccountId}':
    get:
      tags:
        - Realtime Metrics
      summary: Returns the current metrics snapshot for a specific subaccount.
      parameters:
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/RealtimeMetrics'
            application/json:
              schema:
                $ref: '#/components/schemas/RealtimeMetrics'
            text/json:
              schema:
                $ref: '#/components/schemas/RealtimeMetrics'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/realtime-metrics/history:
    get:
      tags:
        - Realtime Metrics
      summary: Returns historical metrics snapshots with optional account/subaccount and time-range filters.
      parameters:
        - name: accountId
          in: query
          schema:
            type: string
            format: uuid
        - name: subaccountId
          in: query
          schema:
            type: string
            format: uuid
        - name: fromUtc
          in: query
          schema:
            type: string
            format: date-time
        - name: toUtc
          in: query
          schema:
            type: string
            format: date-time
        - name: limit
          in: query
          schema:
            type: integer
            format: int32
            default: 100
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RealtimeMetrics'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RealtimeMetrics'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RealtimeMetrics'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/realtime-metrics/health:
    get:
      tags:
        - Realtime Metrics
      summary: Returns the health status of the real-time metrics system.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/RealtimeMetricsHealth'
            application/json:
              schema:
                $ref: '#/components/schemas/RealtimeMetricsHealth'
            text/json:
              schema:
                $ref: '#/components/schemas/RealtimeMetricsHealth'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/register/payment-config:
    get:
      tags:
        - Registration
      summary: Returns the public Stripe publishable key needed to render the payment UI during signup.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/PublicRegistrationPaymentConfig'
            application/json:
              schema:
                $ref: '#/components/schemas/PublicRegistrationPaymentConfig'
            text/json:
              schema:
                $ref: '#/components/schemas/PublicRegistrationPaymentConfig'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/register/payment-diagnostics:
    get:
      tags:
        - Registration
      summary: Retrieves Stripe key diagnostics for the local development environment.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/PublicRegistrationPaymentDiagnostics'
            application/json:
              schema:
                $ref: '#/components/schemas/PublicRegistrationPaymentDiagnostics'
            text/json:
              schema:
                $ref: '#/components/schemas/PublicRegistrationPaymentDiagnostics'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/register/setup-intent:
    post:
      tags:
        - Registration
      summary: Creates a Stripe setup intent for the public registration flow.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SetupIntent'
            application/json:
              schema:
                $ref: '#/components/schemas/SetupIntent'
            text/json:
              schema:
                $ref: '#/components/schemas/SetupIntent'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/register:
    post:
      tags:
        - Registration
      summary: Registers a new account and owner using the public onboarding flow.
      requestBody:
        description: 'The account registration details including selected plan, owner profile, and payment method.'
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAccountWithOwnerRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateAccountWithOwnerRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateAccountWithOwnerRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/PublicRegistrationResult'
            application/json:
              schema:
                $ref: '#/components/schemas/PublicRegistrationResult'
            text/json:
              schema:
                $ref: '#/components/schemas/PublicRegistrationResult'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/confirm-email:
    get:
      tags:
        - Registration
      summary: Confirms a user's email address using the token sent in their registration email.
      parameters:
        - name: token
          in: query
          description: The confirmation token embedded in the email link.
          schema:
            type: string
      responses:
        '200':
          description: Success
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  '/v1/risk/signals/messages/{messageId}':
    get:
      tags:
        - Risk Signals
      summary: Retrieve risk signals attributed to one of your messages.
      description: "Returns the individual risk signals that the adaptive risk engine captured while\r\nevaluating this message. Each signal has a type, score contribution, confidence,\r\nhuman-readable reason, and source provider.\r\n            \r\nOnly signals belonging to messages owned by the authenticated account are accessible;\r\nrequests for other accounts' messages return 404.\r\n            \r\nUse the optional `?signalType=` query parameter to filter results to a single type\r\n(e.g., `?signalType=UrlSafety`). Returns an empty list when the message was not\r\nevaluated or the evaluation produced no signals.\r\n            \r\n**Real-time updates:** connect to the SignalR hub at\r\n`/hubs/user-risk-signals` to receive `ReceiveMessageSignals` events\r\nthe moment the risk engine evaluates a new message for your account."
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: signalType
          in: query
          schema:
            $ref: '#/components/schemas/RiskSignalTypeEntity'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RiskSignal'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RiskSignal'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RiskSignal'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/risk/signals/messages/{messageId}/summary':
    get:
      tags:
        - Risk Signals
      summary: Retrieve the aggregated risk signal summary for one of your messages.
      description: "Returns pre-aggregated statistics for all signals captured during the message's\r\nlatest risk evaluation:\r\n- Total signals collected\r\n- Maximum individual score contribution\r\n- Average confidence across signals\r\n- Per signal-type counts\r\n- Per provider counts\r\n- Up to five highest-contributing signals\r\n            \r\nUseful as a quick-read risk profile without fetching every individual signal.\r\nReturns a zeroed summary when the message has no evaluation record.\r\n            \r\nOnly signals belonging to messages owned by the authenticated account are accessible;\r\nrequests for other accounts' messages return 404."
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/RiskSignalSummary'
            application/json:
              schema:
                $ref: '#/components/schemas/RiskSignalSummary'
            text/json:
              schema:
                $ref: '#/components/schemas/RiskSignalSummary'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/risk/signals/messages/{messageId}/export':
    get:
      tags:
        - Risk Signals
      summary: Export risk signals for one of your messages as CSV or JSON.
      description: "Downloads all risk signals for the requested message as a file attachment.\r\n            \r\nSupported formats:\r\n- `format=csv` (default) — RFC 4180 CSV with a header row. Content-Type: `text/csv`.\r\n- `format=json` — Pretty-printed JSON array. Content-Type: `application/json`.\r\n            \r\nUse the optional `?signalType=` parameter to restrict the export to a single signal type.\r\n            \r\nThe response includes a `Content-Disposition: attachment` header with a filename\r\nthat embeds the message ID and a UTC timestamp, for example:\r\n`risk-signals-<messageId>-20260622T120000Z.csv`.\r\n            \r\nOnly signals belonging to messages owned by the authenticated account are accessible;\r\nrequests for other accounts' messages return 404."
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: format
          in: query
          schema:
            type: string
            default: csv
        - name: signalType
          in: query
          schema:
            $ref: '#/components/schemas/RiskSignalTypeEntity'
      responses:
        '200':
          description: Success
        '400':
          description: Bad Request
          content:
            text/csv:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/csv:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/csv:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/stripe-connect/onboard:
    post:
      tags:
        - Stripe Connect
      summary: Create a Stripe Connected Account and get onboarding URL
      description: "This endpoint:\r\n1. Creates a Stripe Express Connected Account\r\n2. Returns an onboarding URL for the Account admin to complete verification\r\n3. Once verified, the Account can charge their Subaccounts"
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/OnboardingResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/OnboardingResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/OnboardingResponse'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/stripe-connect/status:
    get:
      tags:
        - Stripe Connect
      summary: Check Stripe Connect onboarding status
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/OnboardingStatusResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/OnboardingStatusResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/OnboardingStatusResponse'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/webhooks/stripe/connect:
    post:
      tags:
        - Stripe Webhooks
      summary: Handles inbound Stripe connected-account webhook events.
      responses:
        '200':
          description: Success
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/webhooks/stripe:
    post:
      tags:
        - Stripe Webhooks
      summary: 'Stripe webhook endpoint. Verifies signature, then dispatches event.'
      responses:
        '200':
          description: Success
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  '/v1/subaccounts/{subaccountId}/manual-charge':
    post:
      tags:
        - Subaccount Charges
      summary: Creates a manual one-time charge against a Subaccount.
      parameters:
        - name: subaccountId
          in: path
          description: ID of the subaccount to charge.
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        description: 'Charge details including amount, currency, and payment method.'
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSubaccountChargeRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateSubaccountChargeRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateSubaccountChargeRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SubaccountChargeResult'
            application/json:
              schema:
                $ref: '#/components/schemas/SubaccountChargeResult'
            text/json:
              schema:
                $ref: '#/components/schemas/SubaccountChargeResult'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '402':
          description: Client Error
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '409':
          description: Conflict
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/subaccounts/{subaccountId}/payments':
    get:
      tags:
        - Subaccount Charges
      summary: Retrieves payment history for a Subaccount.
      parameters:
        - name: subaccountId
          in: path
          description: ID of the subaccount.
          required: true
          schema:
            type: string
            format: uuid
        - name: take
          in: query
          description: 'Number of payments to return (1-500, default 50).'
          schema:
            type: integer
            format: int32
            default: 50
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubaccountPaymentEvent'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubaccountPaymentEvent'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubaccountPaymentEvent'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/subaccounts/{subaccountId}/payment-methods':
    get:
      tags:
        - Subaccount Payment Methods
      summary: List the available payment methods for a subaccount.
      parameters:
        - name: subaccountId
          in: path
          description: Identifier of the subaccount whose payment methods are being listed.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PaymentMethod'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PaymentMethod'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PaymentMethod'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/subaccounts/{subaccountId}/payment-methods/setup-intent':
    post:
      tags:
        - Subaccount Payment Methods
      summary: Create a Stripe setup intent for adding a new payment method to a subaccount.
      parameters:
        - name: subaccountId
          in: path
          description: Identifier of the subaccount for which the setup intent is created.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SubaccountSetupIntent'
            application/json:
              schema:
                $ref: '#/components/schemas/SubaccountSetupIntent'
            text/json:
              schema:
                $ref: '#/components/schemas/SubaccountSetupIntent'
        '409':
          description: Conflict
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/subaccounts/{subaccountId}':
    post:
      tags:
        - Subaccount Payment Methods
      summary: Attach a confirmed Stripe payment method to a subaccount.
      parameters:
        - name: subaccountId
          in: path
          description: Identifier of the subaccount receiving the payment method.
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        description: Card or payment method details including the Stripe payment method identifier.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AttachSubaccountPaymentMethodRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/AttachSubaccountPaymentMethodRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/AttachSubaccountPaymentMethodRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/PaymentMethod'
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentMethod'
            text/json:
              schema:
                $ref: '#/components/schemas/PaymentMethod'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '409':
          description: Conflict
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/subaccounts/{subaccountId}/{paymentMethodId}/default':
    post:
      tags:
        - Subaccount Payment Methods
      summary: Set a payment method as the default for the subaccount.
      parameters:
        - name: subaccountId
          in: path
          description: Identifier of the subaccount whose default payment method is being updated.
          required: true
          schema:
            type: string
            format: uuid
        - name: paymentMethodId
          in: path
          description: Identifier of the payment method to mark as default.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/subaccounts/{subaccountId}/{paymentMethodId}':
    delete:
      tags:
        - Subaccount Payment Methods
      summary: Delete a payment method from a subaccount.
      parameters:
        - name: subaccountId
          in: path
          description: Identifier of the subaccount whose payment method is being removed.
          required: true
          schema:
            type: string
            format: uuid
        - name: paymentMethodId
          in: path
          description: Identifier of the payment method to delete.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/accounts/{accountId}/subaccounts':
    get:
      tags:
        - Subaccounts
      summary: Lists all subaccounts belonging to the caller's account.
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Subaccount'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Subaccount'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Subaccount'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - Subaccounts
      summary: Creates a new subaccount under the caller's account.
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSubaccountRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateSubaccountRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateSubaccountRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Subaccount'
            application/json:
              schema:
                $ref: '#/components/schemas/Subaccount'
            text/json:
              schema:
                $ref: '#/components/schemas/Subaccount'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/accounts/{accountId}/subaccounts/{subaccountId}':
    get:
      tags:
        - Subaccounts
      summary: Returns a single subaccount by ID.
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Subaccount'
            application/json:
              schema:
                $ref: '#/components/schemas/Subaccount'
            text/json:
              schema:
                $ref: '#/components/schemas/Subaccount'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    put:
      tags:
        - Subaccounts
      summary: Updates the name or settings of an existing subaccount.
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateSubaccountRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateSubaccountRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateSubaccountRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Subaccount'
            application/json:
              schema:
                $ref: '#/components/schemas/Subaccount'
            text/json:
              schema:
                $ref: '#/components/schemas/Subaccount'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    delete:
      tags:
        - Subaccounts
      summary: Deletes a subaccount from the caller's account.
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: subaccountId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/support/cases:
    post:
      tags:
        - Support Cases
      summary: Creates a new support case for the authenticated account.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSupportCaseRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateSupportCaseRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateSupportCaseRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SupportCase'
            application/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
            text/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SupportCase'
            application/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
            text/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    get:
      tags:
        - Support Cases
      summary: Lists all support cases for the authenticated account with pagination.
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            format: int32
            default: 1
        - name: pageSize
          in: query
          schema:
            type: integer
            format: int32
            default: 50
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SupportCaseListResult'
            application/json:
              schema:
                $ref: '#/components/schemas/SupportCaseListResult'
            text/json:
              schema:
                $ref: '#/components/schemas/SupportCaseListResult'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/support/cases/{id}':
    get:
      tags:
        - Support Cases
      summary: 'Returns a single support case by ID, scoped to the authenticated account.'
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SupportCase'
            application/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
            text/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/support/cases/by-reference/{referenceNumber}':
    get:
      tags:
        - Support Cases
      summary: Returns a support case by its human-readable reference number.
      parameters:
        - name: referenceNumber
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SupportCase'
            application/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
            text/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/support/cases/{id}/comments':
    post:
      tags:
        - Support Cases
      summary: Appends a user comment to an existing support case.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddSupportCaseCommentRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/AddSupportCaseCommentRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/AddSupportCaseCommentRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SupportCase'
            application/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
            text/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/support/cases/{id}/reopen':
    post:
      tags:
        - Support Cases
      summary: Reopens a closed support case with optional notes.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReopenSupportCaseRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/ReopenSupportCaseRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/ReopenSupportCaseRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/SupportCase'
            application/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
            text/json:
              schema:
                $ref: '#/components/schemas/SupportCase'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/webhooks/tcr:
    post:
      tags:
        - TCR Webhooks
      summary: Receives and processes a TCR webhook payload after signature verification.
      responses:
        '200':
          description: Success
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/templates:
    get:
      tags:
        - Templates
      summary: List all templates for the authenticated user's account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/MessageTemplate'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/MessageTemplate'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/MessageTemplate'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - Templates
      summary: Create a new message template.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMessageTemplateRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateMessageTemplateRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateMessageTemplateRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/MessageTemplate'
            application/json:
              schema:
                $ref: '#/components/schemas/MessageTemplate'
            text/json:
              schema:
                $ref: '#/components/schemas/MessageTemplate'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/templates/{templateId}':
    get:
      tags:
        - Templates
      summary: Get a specific template by ID (must belong to user's account).
      parameters:
        - name: templateId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/MessageTemplate'
            application/json:
              schema:
                $ref: '#/components/schemas/MessageTemplate'
            text/json:
              schema:
                $ref: '#/components/schemas/MessageTemplate'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    put:
      tags:
        - Templates
      summary: Update an existing template.
      parameters:
        - name: templateId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateMessageTemplateRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateMessageTemplateRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateMessageTemplateRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/MessageTemplate'
            application/json:
              schema:
                $ref: '#/components/schemas/MessageTemplate'
            text/json:
              schema:
                $ref: '#/components/schemas/MessageTemplate'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    delete:
      tags:
        - Templates
      summary: Soft-delete a template.
      parameters:
        - name: templateId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/templates/{templateId}/render':
    post:
      tags:
        - Templates
      summary: Render a saved template with provided variables.
      parameters:
        - name: templateId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RenderTemplateRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/RenderTemplateRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/RenderTemplateRequest'
      responses:
        '200':
          description: Success
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/templates/preview:
    post:
      tags:
        - Templates
      summary: Preview a template body without saving. Useful for live preview in the UI.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemplatePreviewRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/TemplatePreviewRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/TemplatePreviewRequest'
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/token/refresh:
    post:
      tags:
        - Token Management
      summary: Refresh access token using a refresh token
      requestBody:
        description: Refresh token request
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefreshTokenRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/RefreshTokenRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/RefreshTokenRequest'
      responses:
        '200':
          description: Success
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
  /v1/auth/token/revoke:
    post:
      tags:
        - Token Management
      summary: Revoke the current refresh token (logout)
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RevokeTokenRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/RevokeTokenRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/RevokeTokenRequest'
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/token/sessions:
    get:
      tags:
        - Token Management
      summary: Get active sessions for the current user
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/auth/token/sessions/{sessionId}':
    delete:
      tags:
        - Token Management
      summary: Terminate a specific session
      parameters:
        - name: sessionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/auth/token/sessions/terminate-others:
    post:
      tags:
        - Token Management
      summary: Terminate all other sessions (logout everywhere else)
      responses:
        '200':
          description: Success
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/webhooks:
    get:
      tags:
        - Webhooks
      summary: List all webhooks for the authenticated user's account.
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/WebhookEndpoint'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/WebhookEndpoint'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/WebhookEndpoint'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    post:
      tags:
        - Webhooks
      summary: Create a new webhook endpoint. The signing secret is returned once.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWebhookEndpointRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/CreateWebhookEndpointRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/CreateWebhookEndpointRequest'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
            text/json:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/webhooks/{webhookId}':
    get:
      tags:
        - Webhooks
      summary: Get a specific webhook by ID (must belong to user's account).
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
            text/json:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    put:
      tags:
        - Webhooks
      summary: 'Update a webhook endpoint (URL, label, events, active status).'
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateWebhookEndpointRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateWebhookEndpointRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateWebhookEndpointRequest'
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
            text/json:
              schema:
                $ref: '#/components/schemas/WebhookEndpoint'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
    delete:
      tags:
        - Webhooks
      summary: Soft-delete a webhook endpoint.
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/webhooks/{webhookId}/rotate-secret':
    post:
      tags:
        - Webhooks
      summary: Rotate the signing secret. Returns the new secret (shown once).
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/webhooks/{webhookId}/test':
    post:
      tags:
        - Webhooks
      summary: Send a test webhook payload to the endpoint.
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/WebhookDeliveryLog'
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookDeliveryLog'
            text/json:
              schema:
                $ref: '#/components/schemas/WebhookDeliveryLog'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/webhooks/{webhookId}/deliveries':
    get:
      tags:
        - Webhooks
      summary: Get delivery logs for a webhook endpoint (paginated).
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: page
          in: query
          schema:
            type: integer
            format: int32
            default: 1
        - name: pageSize
          in: query
          schema:
            type: integer
            format: int32
            default: 20
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/WebhookDeliveryLog'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/WebhookDeliveryLog'
            text/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/WebhookDeliveryLog'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  '/v1/webhooks/{webhookId}/deliveries/{deliveryLogId}/replay':
    post:
      tags:
        - Webhooks
      summary: "Replay a specific delivery log as a safe test dispatch for diagnostics.\r\nIncludes ownership checks and short cooldown idempotency guardrails."
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: deliveryLogId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Success
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/WebhookDeliveryLog'
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookDeliveryLog'
            text/json:
              schema:
                $ref: '#/components/schemas/WebhookDeliveryLog'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '409':
          description: Conflict
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: Unauthorized — missing or invalid credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '403':
          description: Forbidden — insufficient permissions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
      security:
        - jwt: [ ]
  /v1/webhooks/whatsapp:
    get:
      tags:
        - WhatsApp Webhooks
      summary: "Handles Meta's webhook verification challenge (GET request).\r\nMeta sends: ?hub.mode=subscribe&hub.challenge=CHALLENGE_TOKEN&hub.verify_token=VERIFY_TOKEN\r\nWe must echo back the challenge if the verify token matches."
      parameters:
        - name: hub.mode
          in: query
          schema:
            type: string
        - name: hub.challenge
          in: query
          schema:
            type: string
        - name: hub.verify_token
          in: query
          schema:
            type: string
      responses:
        '200':
          description: Success
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
    post:
      tags:
        - WhatsApp Webhooks
      summary: "Receives delivery receipt and message status events from Meta's WhatsApp Business Platform.\r\n            \r\nExpected webhook payload structure:\r\n{\r\n  \"object\": \"whatsapp_business_account\",\r\n  \"entry\": [{\r\n    \"id\": \"ACCOUNT_ID\",\r\n    \"changes\": [{\r\n      \"value\": {\r\n        \"messaging_product\": \"whatsapp\",\r\n        \"statuses\": [{\r\n          \"id\": \"wamid.xxxxx\",\r\n          \"status\": \"delivered|sent|read|failed\",\r\n          \"recipient_id\": \"+16175551234\",\r\n          \"timestamp\": \"1671794240\"\r\n        }]\r\n      },\r\n      \"field\": \"messages\"\r\n    }]\r\n  }]\r\n}"
      requestBody:
        content:
          application/json:
            schema: { }
          text/json:
            schema: { }
          application/*+json:
            schema: { }
      responses:
        '200':
          description: Success
        '422':
          description: Validation error — request body failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too many requests — rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
components:
  schemas:
    Account:
      title: Account
      type: object
      properties:
        accountId:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        name:
          type: string
          nullable: true
        streetAddress1:
          type: string
          nullable: true
        streetAddress2:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        stateOrProvince:
          type: string
          nullable: true
        postalCode:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
        emailAddress:
          type: string
          nullable: true
        phoneNumber:
          type: string
          nullable: true
        status:
          $ref: '#/components/schemas/AccountStatusEntity'
        createdAt:
          type: string
          format: date-time
        stripeConnectedAccountId:
          type: string
          nullable: true
        isStripeOnboardingComplete:
          type: boolean
        stripeOnboardingCompletedAt:
          type: string
          format: date-time
          nullable: true
        platformFeeBps:
          type: integer
          format: int32
        outboundDispatchEnabled:
          type: boolean
        outboundDispatchHeldAt:
          type: string
          format: date-time
          nullable: true
        outboundDispatchHeldBy:
          type: string
          nullable: true
        outboundDispatchHoldReason:
          type: string
          nullable: true
      additionalProperties: false
      description: Public Account payload returned by the API.
    AccountActivityTimeline:
      title: AccountActivityTimeline
      type: object
      properties:
        userId:
          type: string
          format: uuid
        windowStartUtc:
          type: string
          format: date-time
        windowEndUtc:
          type: string
          format: date-time
        searchTerm:
          type: string
          nullable: true
        activityType:
          type: string
          nullable: true
        pageNumber:
          type: integer
          format: int32
        pageSize:
          type: integer
          format: int32
        totalCount:
          type: integer
          format: int32
        items:
          type: array
          items:
            $ref: '#/components/schemas/AccountActivityTimelineItem'
          nullable: true
      additionalProperties: false
      description: Public AccountActivityTimeline payload returned by the API.
    AccountActivityTimelineItem:
      title: AccountActivityTimelineItem
      type: object
      properties:
        source:
          type: string
          nullable: true
        activityType:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        success:
          type: boolean
        timestampUtc:
          type: string
          format: date-time
        tableName:
          type: string
          nullable: true
        entityId:
          type: string
          format: uuid
          nullable: true
        ipAddress:
          type: string
          nullable: true
        userAgent:
          type: string
          nullable: true
        failureReason:
          type: string
          nullable: true
        notes:
          type: string
          nullable: true
      additionalProperties: false
      description: Public AccountActivityTimelineItem payload returned by the API.
    AccountEntity:
      type: object
      properties:
        accountId:
          type: string
          format: uuid
          readOnly: true
        userId:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          nullable: true
          readOnly: true
        emailAddress:
          type: string
          nullable: true
          readOnly: true
        phoneNumber:
          type: string
          nullable: true
          readOnly: true
        teamSize:
          type: string
          nullable: true
          readOnly: true
        streetAddress1:
          type: string
          nullable: true
          readOnly: true
        streetAddress2:
          type: string
          nullable: true
          readOnly: true
        city:
          type: string
          nullable: true
          readOnly: true
        stateOrProvince:
          type: string
          nullable: true
          readOnly: true
        postalCode:
          type: string
          nullable: true
          readOnly: true
        country:
          type: string
          nullable: true
          readOnly: true
        stripeConnectedAccountId:
          type: string
          nullable: true
          readOnly: true
        isStripeOnboardingComplete:
          type: boolean
          readOnly: true
        stripeOnboardingCompletedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        paymentWebhookUrl:
          type: string
          nullable: true
          readOnly: true
        paymentWebhookSecret:
          type: string
          nullable: true
          readOnly: true
        paymentWebhooksEnabled:
          type: boolean
          readOnly: true
        platformFeeBps:
          type: integer
          format: int32
          readOnly: true
        outboundDispatchEnabled:
          type: boolean
          readOnly: true
        outboundDispatchHeldAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        outboundDispatchHeldBy:
          type: string
          nullable: true
          readOnly: true
        outboundDispatchHoldReason:
          type: string
          nullable: true
          readOnly: true
        status:
          $ref: '#/components/schemas/AccountStatusEntity'
        isDeleted:
          type: boolean
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        owner:
          $ref: '#/components/schemas/UserEntity'
        isOutboundDispatchHeld:
          type: boolean
          readOnly: true
        users:
          type: array
          items:
            $ref: '#/components/schemas/UserEntity'
          nullable: true
          readOnly: true
        messages:
          type: array
          items:
            $ref: '#/components/schemas/MessageEntity'
          nullable: true
          readOnly: true
        subaccounts:
          type: array
          items:
            $ref: '#/components/schemas/SubaccountEntity'
          nullable: true
          readOnly: true
        apiKeys:
          type: array
          items:
            $ref: '#/components/schemas/ApiKeyEntity'
          nullable: true
          readOnly: true
        channels:
          type: array
          items:
            $ref: '#/components/schemas/ChannelEntity'
          nullable: true
          readOnly: true
      additionalProperties: false
      x-internal: true
    AccountOnboardingStatus:
      title: AccountOnboardingStatus
      type: object
      properties:
        accountId:
          type: string
          format: uuid
        accountName:
          type: string
          nullable: true
        ownerEmail:
          type: string
          nullable: true
        accountStatus:
          $ref: '#/components/schemas/AccountStatusEntity'
        checklistCreatedAt:
          type: string
          format: date-time
        emailVerified:
          type: boolean
        emailVerifiedAt:
          type: string
          format: date-time
          nullable: true
        paymentMethodAttached:
          type: boolean
        paymentMethodAttachedAt:
          type: string
          format: date-time
          nullable: true
        requiresStaffReview:
          type: boolean
        staffReviewApproved:
          type: boolean
        staffReviewedAt:
          type: string
          format: date-time
          nullable: true
        isReadyForActivation:
          type: boolean
        completedAt:
          type: string
          format: date-time
          nullable: true
        nudgeCount:
          type: integer
          format: int32
        lastNudgeAt:
          type: string
          format: date-time
          nullable: true
        blockers:
          type: array
          items:
            type: string
          nullable: true
      additionalProperties: false
      description: Public AccountOnboardingStatus payload returned by the API.
    AccountQuota:
      title: AccountQuota
      type: object
      properties:
        accountQuotaId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        dailyLimit:
          type: integer
          format: int32
          nullable: true
        monthlyLimit:
          type: integer
          format: int32
          nullable: true
        ratePerSecond:
          type: integer
          format: int32
          nullable: true
        ratePerMinute:
          type: integer
          format: int32
          nullable: true
        dailyUsed:
          type: integer
          format: int32
        monthlyUsed:
          type: integer
          format: int32
        dailyRemaining:
          type: integer
          format: int32
          nullable: true
        monthlyRemaining:
          type: integer
          format: int32
          nullable: true
        lastDailyReset:
          type: string
          format: date-time
        lastMonthlyReset:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
      description: Public AccountQuota payload returned by the API.
    AccountStatusEntity:
      enum:
        - Active
        - Suspended
        - Closed
        - Archived
        - PendingVerification
      type: string
      x-internal: true
    AccountSubscription:
      title: AccountSubscription
      type: object
      properties:
        subscriptionId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        planId:
          type: string
          format: uuid
        planName:
          type: string
          nullable: true
        cycle:
          $ref: '#/components/schemas/BillingCycleEntity'
        status:
          $ref: '#/components/schemas/SubscriptionStatusEntity'
        startDate:
          type: string
          format: date-time
        currentPeriodStart:
          type: string
          format: date-time
        currentPeriodEnd:
          type: string
          format: date-time
        cancelledAt:
          type: string
          format: date-time
          nullable: true
        cancelEffectiveDate:
          type: string
          format: date-time
          nullable: true
        externalSubscriptionId:
          type: string
          nullable: true
        externalCustomerId:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
      description: Public AccountSubscription payload returned by the API.
    AccountTransitionRequest:
      type: object
      properties:
        transition:
          type: string
          nullable: true
        reason:
          type: string
          nullable: true
        actor:
          type: string
          nullable: true
      additionalProperties: false
    AddProviderDiscoveryRuleRequest:
      type: object
      properties:
        emailDomain:
          type: string
          nullable: true
        providerId:
          type: string
          format: uuid
        priority:
          type: integer
          format: int32
          nullable: true
      additionalProperties: false
    AddSupportCaseCommentRequest:
      type: object
      properties:
        body:
          type: string
          nullable: true
        isInternal:
          type: boolean
      additionalProperties: false
    ApiKey:
      title: ApiKey
      type: object
      properties:
        apiKeyId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
          nullable: true
        label:
          type: string
          nullable: true
        permissions:
          $ref: '#/components/schemas/ApiKeyRightsEntity'
        createdAt:
          type: string
          format: date-time
        expiresAt:
          type: string
          format: date-time
          nullable: true
        isRevoked:
          type: boolean
        isActive:
          type: boolean
        lastUsedAt:
          type: string
          format: date-time
          nullable: true
        usageCount:
          type: integer
          format: int64
        keyValue:
          type: string
          nullable: true
      additionalProperties: false
      description: Public ApiKey payload returned by the API.
    ApiKeyEndpointUsage:
      title: ApiKeyEndpointUsage
      type: object
      properties:
        method:
          type: string
          nullable: true
        endpoint:
          type: string
          nullable: true
        requestCount:
          type: integer
          format: int64
        errorCount:
          type: integer
          format: int64
        errorRatePercent:
          type: number
          format: double
        averageResponseTimeMs:
          type: number
          format: double
      additionalProperties: false
      description: Public ApiKeyEndpointUsage payload returned by the API.
    ApiKeyEntity:
      type: object
      properties:
        apiKeyId:
          type: string
          format: uuid
          readOnly: true
        accountId:
          type: string
          format: uuid
          readOnly: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        label:
          type: string
          nullable: true
          readOnly: true
        keyHash:
          type: string
          nullable: true
          readOnly: true
        permissions:
          $ref: '#/components/schemas/ApiKeyRightsEntity'
        isRevoked:
          type: boolean
          readOnly: true
        expiresAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        isDeleted:
          type: boolean
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        lastUsedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        usageCount:
          type: integer
          format: int64
          readOnly: true
        account:
          $ref: '#/components/schemas/AccountEntity'
        subaccount:
          $ref: '#/components/schemas/SubaccountEntity'
      additionalProperties: false
      x-internal: true
    ApiKeyRightsEntity:
      enum:
        - None
        - ReadAccounts
        - ManageAccounts
        - ReadSubaccounts
        - ManageSubaccounts
        - ReadMessages
        - CreateMessages
        - TransitionMessages
        - DeleteMessages
        - ManageTemplates
        - FullAccess
      type: string
      x-internal: true
    ApiKeyUsage:
      title: ApiKeyUsage
      type: object
      properties:
        apiKeyId:
          type: string
          format: uuid
        totalRequests:
          type: integer
          format: int64
        lastUsedAt:
          type: string
          format: date-time
          nullable: true
        requestsLastMinute:
          type: integer
          format: int32
        requestsLastHour:
          type: integer
          format: int32
        requestsLastDay:
          type: integer
          format: int32
      additionalProperties: false
      description: Public ApiKeyUsage payload returned by the API.
    ApiKeyUsageAnalytics:
      title: ApiKeyUsageAnalytics
      type: object
      properties:
        windowStartUtc:
          type: string
          format: date-time
        windowEndUtc:
          type: string
          format: date-time
        windowHours:
          type: integer
          format: int32
        totalRequests:
          type: integer
          format: int64
        errorRequests:
          type: integer
          format: int64
        errorRatePercent:
          type: number
          format: double
        averageResponseTimeMs:
          type: number
          format: double
        trend:
          type: array
          items:
            $ref: '#/components/schemas/ApiKeyUsageTrendPoint'
          nullable: true
        topEndpoints:
          type: array
          items:
            $ref: '#/components/schemas/ApiKeyEndpointUsage'
          nullable: true
        anomalies:
          type: array
          items:
            $ref: '#/components/schemas/ApiKeyUsageAnomaly'
          nullable: true
      additionalProperties: false
      description: Public ApiKeyUsageAnalytics payload returned by the API.
    ApiKeyUsageAnomaly:
      title: ApiKeyUsageAnomaly
      type: object
      properties:
        type:
          type: string
          nullable: true
        severity:
          type: string
          nullable: true
        summary:
          type: string
          nullable: true
        observedAtUtc:
          type: string
          format: date-time
      additionalProperties: false
      description: Public ApiKeyUsageAnomaly payload returned by the API.
    ApiKeyUsageTrendPoint:
      title: ApiKeyUsageTrendPoint
      type: object
      properties:
        bucketStartUtc:
          type: string
          format: date-time
        bucketEndUtc:
          type: string
          format: date-time
        requestCount:
          type: integer
          format: int64
        errorCount:
          type: integer
          format: int64
        errorRatePercent:
          type: number
          format: double
      additionalProperties: false
      description: Public ApiKeyUsageTrendPoint payload returned by the API.
    AssignPhoneNumberRequest:
      type: object
      properties:
        subaccountId:
          type: string
          format: uuid
      additionalProperties: false
    AssignPlanRequest:
      type: object
      properties:
        planId:
          type: string
          format: uuid
        cycle:
          $ref: '#/components/schemas/BillingCycleEntity'
        externalCustomerId:
          type: string
          nullable: true
        externalSubscriptionId:
          type: string
          nullable: true
      additionalProperties: false
    AttachSubaccountPaymentMethodRequest:
      type: object
      properties:
        stripePaymentMethodId:
          type: string
          description: Stripe payment method identifier for the card or wallet instrument being attached.
          nullable: true
        setAsDefault:
          type: boolean
          description: Whether the attached payment method should become the subaccount's default payment method.
      additionalProperties: false
      description: Body for attaching a previously confirmed Stripe payment method to a subaccount.
    AuditTypeEntity:
      enum:
        - Transition
        - Duplicate
        - Event
      type: string
      x-internal: true
    AuthorizeProviderRequest:
      type: object
      properties:
        providerId:
          type: string
          description: Provider ID to authorize with.
          format: uuid
        redirectUri:
          type: string
          description: "Redirect URI after user authorizes.\r\nMust match provider's registered redirect URIs."
          nullable: true
        codeChallenge:
          type: string
          description: "PKCE code challenge (SHA256(code_verifier)).\r\nUsed for secure code exchange."
          nullable: true
      additionalProperties: false
      description: Request to get authorization URL for OAuth2 provider.
    AuthorizeProviderResponse:
      type: object
      properties:
        authorizationUrl:
          type: string
          description: Authorization URL to redirect user to.
          nullable: true
        state:
          type: string
          description: "CSRF protection state (random unique value).\r\nMust be stored and verified after callback."
          nullable: true
      additionalProperties: false
      description: Response containing authorization URL.
    AvailableNumber:
      title: AvailableNumber
      type: object
      properties:
        e164Number:
          type: string
          nullable: true
        numberType:
          $ref: '#/components/schemas/PhoneNumberTypeEntity'
        capabilities:
          $ref: '#/components/schemas/PhoneNumberCapabilityEntity'
        monthlyFeeCents:
          type: integer
          format: int32
        regionCode:
          type: string
          nullable: true
        areaCode:
          type: string
          nullable: true
        countryCode:
          type: string
          nullable: true
      additionalProperties: false
      description: Public AvailableNumber payload returned by the API.
    BillingCycle:
      title: BillingCycle
      type: object
      properties:
        accountId:
          type: string
          format: uuid
        subscriptionId:
          type: string
          format: uuid
          nullable: true
        periodStart:
          type: string
          format: date-time
          nullable: true
        periodEnd:
          type: string
          format: date-time
          nullable: true
        planName:
          type: string
          nullable: true
        externalCustomerId:
          type: string
          nullable: true
        unbilledChargesUsd:
          type: number
          format: double
        unbilledCreditsUsd:
          type: number
          format: double
        openBalanceUsd:
          type: number
          format: double
        unbilledEventCount:
          type: integer
          format: int32
        eventCount:
          type: integer
          format: int32
        hasStripeCustomer:
          type: boolean
        canChargeOpenBalance:
          type: boolean
        events:
          type: array
          items:
            $ref: '#/components/schemas/BillingEvent'
          nullable: true
      additionalProperties: false
      description: Public BillingCycle payload returned by the API.
    BillingCycleEntity:
      enum:
        - Monthly
        - Annual
      type: string
      x-internal: true
    BillingEvent:
      title: BillingEvent
      type: object
      properties:
        billingEventId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
          nullable: true
        referenceId:
          type: string
          format: uuid
          nullable: true
        invoiceId:
          type: string
          format: uuid
          nullable: true
        eventType:
          $ref: '#/components/schemas/BillingEventTypeEntity'
        description:
          type: string
          nullable: true
        quantity:
          type: integer
          format: int32
        unitPriceUsd:
          type: number
          format: double
        totalUsd:
          type: number
          format: double
        occurredAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public BillingEvent payload returned by the API.
    BillingEventTypeEntity:
      enum:
        - SubscriptionFee
        - MessageUsage
        - OverageFee
        - AutoPay
        - Refund
        - BrandFee
        - PhoneNumberRental
        - InboundSms
        - PhoneNumberSetup
        - ManualPay
        - CampaignFee
        - CampaignMonthlyFee
        - StandardVettingFee
        - EnhancedVettingFee
        - PoliticalVettingFee
        - BrandAppealFee
        - VettingAppealFee
        - BrandResubmitFee
        - CampaignResubmitFee
        - NumberConnectivityFee
      type: string
      x-internal: true
    BrandStatusEntity:
      enum:
        - Draft
        - Submitted
        - Pending
        - Verified
        - Failed
      type: string
      x-internal: true
    CarrierEventRequest:
      type: object
      properties:
        event:
          $ref: '#/components/schemas/CarrierMessageEventEntity'
        reason:
          type: string
          nullable: true
      additionalProperties: false
    CarrierMessageEventEntity:
      enum:
        - Accepted
        - Delivered
        - Failed
        - Rejected
      type: string
      x-internal: true
    ChangeUserPasswordRequest:
      required:
        - currentPassword
        - newPassword
      type: object
      properties:
        currentPassword:
          minLength: 1
          type: string
        newPassword:
          maxLength: 128
          minLength: 12
          pattern: '^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{12,}$'
          type: string
      additionalProperties: false
    ChannelAccountEntity:
      type: object
      properties:
        channelAccountId:
          type: string
          format: uuid
          readOnly: true
        channelId:
          type: string
          format: uuid
          readOnly: true
        encryptedConfiguration:
          type: string
          nullable: true
          readOnly: true
        externalAccountId:
          type: string
          nullable: true
          readOnly: true
        senderIdentity:
          type: string
          nullable: true
          readOnly: true
        isVerified:
          type: boolean
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        verifiedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        updatedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        channel:
          $ref: '#/components/schemas/ChannelEntity'
      additionalProperties: false
      x-internal: true
    ChannelCostBreakdown:
      title: ChannelCostBreakdown
      type: object
      properties:
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        totalAttempts:
          type: integer
          format: int32
        totalCarrierCostUsd:
          type: number
          format: double
        totalCustomerChargeUsd:
          type: number
          format: double
      additionalProperties: false
      description: Public ChannelCostBreakdown payload returned by the API.
    ChannelEntity:
      type: object
      properties:
        channelId:
          type: string
          format: uuid
          readOnly: true
        accountId:
          type: string
          format: uuid
          readOnly: true
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        provider:
          type: string
          nullable: true
          readOnly: true
        isEnabled:
          type: boolean
          readOnly: true
        priority:
          type: integer
          format: int32
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        updatedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        account:
          $ref: '#/components/schemas/AccountEntity'
        channelAccount:
          $ref: '#/components/schemas/ChannelAccountEntity'
        templates:
          type: array
          items:
            $ref: '#/components/schemas/ChannelTemplateEntity'
          nullable: true
          readOnly: true
      additionalProperties: false
      x-internal: true
    ChannelOptInRequest:
      required:
        - channelType
        - subaccountId
      type: object
      properties:
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        subaccountId:
          type: string
          format: uuid
      additionalProperties: false
    ChannelOptOut:
      title: ChannelOptOut
      type: object
      properties:
        channelOptOutId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        recipientId:
          type: string
          nullable: true
        reason:
          type: string
          nullable: true
        actor:
          type: string
          nullable: true
        optedOutAt:
          type: string
          format: date-time
        optedInAt:
          type: string
          format: date-time
          nullable: true
        isOptedOut:
          type: boolean
      additionalProperties: false
      description: Public ChannelOptOut payload returned by the API.
    ChannelOptOutRequest:
      required:
        - channelType
        - subaccountId
      type: object
      properties:
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        subaccountId:
          type: string
          format: uuid
        reason:
          type: string
          nullable: true
      additionalProperties: false
    ChannelPreferenceStatus:
      title: ChannelPreferenceStatus
      type: object
      properties:
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        isOptedOut:
          type: boolean
      additionalProperties: false
      description: Public ChannelPreferenceStatus payload returned by the API.
    ChannelRoutePreview:
      title: ChannelRoutePreview
      type: object
      properties:
        subaccountId:
          type: string
          format: uuid
        requestedChannelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        orderedRoute:
          type: array
          items:
            $ref: '#/components/schemas/ChannelTypeEntity'
          nullable: true
      additionalProperties: false
      description: Public ChannelRoutePreview payload returned by the API.
    ChannelRoutingPolicy:
      title: ChannelRoutingPolicy
      type: object
      properties:
        channelRoutingPolicyId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
        preferredChannelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        fallbackChain:
          type: array
          items:
            $ref: '#/components/schemas/ChannelTypeEntity'
          nullable: true
        isEnabled:
          type: boolean
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
      description: Public ChannelRoutingPolicy payload returned by the API.
    ChannelTemplateEntity:
      type: object
      properties:
        channelTemplateId:
          type: string
          format: uuid
          readOnly: true
        channelId:
          type: string
          format: uuid
          readOnly: true
        messageTemplateId:
          type: string
          format: uuid
          readOnly: true
        bodyTemplate:
          type: string
          nullable: true
          readOnly: true
        subjectTemplate:
          type: string
          nullable: true
          readOnly: true
        providerTemplateId:
          type: string
          nullable: true
          readOnly: true
        isApproved:
          type: boolean
          readOnly: true
        approvedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        updatedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        channel:
          $ref: '#/components/schemas/ChannelEntity'
        messageTemplate:
          $ref: '#/components/schemas/MessageTemplateEntity'
      additionalProperties: false
      x-internal: true
    ChannelTypeEntity:
      enum:
        - Unknown
        - Sms
        - Email
        - WhatsApp
        - Slack
        - InAppPush
        - Rcs
      type: string
      x-internal: true
    ConfigureWebhookRequest:
      type: object
      properties:
        webhookUrl:
          type: string
          description: The absolute URL where payment provider webhooks should be delivered.
          nullable: true
      additionalProperties: false
      description: Request to configure webhook
    ConsentCategoryEntity:
      enum:
        - Marketing
        - Analytics
        - Profiling
        - ThirdPartySharing
      type: string
      x-internal: true
    ConsentRecord:
      title: ConsentRecord
      type: object
      properties:
        consentId:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        category:
          $ref: '#/components/schemas/ConsentCategoryEntity'
        isGranted:
          type: boolean
        consentVersion:
          type: string
          nullable: true
        ipAddress:
          type: string
          nullable: true
        userAgent:
          type: string
          nullable: true
        grantedAt:
          type: string
          format: date-time
        revokedAt:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
      description: Public ConsentRecord payload returned by the API.
    ContentFormatEntity:
      enum:
        - Unknown
        - Sms
        - Mms
      type: string
      x-internal: true
    CreateAccountRequest:
      type: object
      properties:
        name:
          type: string
          nullable: true
      additionalProperties: false
    CreateAccountWithOwnerRequest:
      required:
        - accountName
        - ownerEmail
        - ownerFirstName
        - ownerLastName
        - ownerPassword
        - ownerRole
        - planName
        - primaryMessagingUseCase
      type: object
      properties:
        accountName:
          maxLength: 100
          minLength: 0
          type: string
        streetAddress1:
          maxLength: 100
          minLength: 0
          type: string
          nullable: true
        streetAddress2:
          maxLength: 100
          minLength: 0
          type: string
          nullable: true
        city:
          maxLength: 100
          minLength: 0
          type: string
          nullable: true
        stateOrProvince:
          maxLength: 100
          minLength: 0
          type: string
          nullable: true
        postalCode:
          maxLength: 20
          minLength: 0
          type: string
          nullable: true
        country:
          maxLength: 100
          minLength: 0
          type: string
          nullable: true
        emailAddress:
          maxLength: 320
          minLength: 0
          type: string
          format: email
          nullable: true
        phoneNumber:
          maxLength: 50
          minLength: 0
          type: string
          nullable: true
        planName:
          maxLength: 100
          minLength: 0
          type: string
        teamSize:
          maxLength: 50
          minLength: 0
          type: string
          nullable: true
        primaryMessagingUseCase:
          maxLength: 1000
          minLength: 10
          type: string
        stripePaymentMethodId:
          maxLength: 100
          minLength: 0
          type: string
          nullable: true
        ownerFirstName:
          maxLength: 100
          minLength: 0
          type: string
        ownerLastName:
          maxLength: 100
          minLength: 0
          type: string
        ownerEmail:
          maxLength: 320
          minLength: 0
          type: string
          format: email
        ownerPassword:
          maxLength: 128
          minLength: 12
          pattern: '^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{12,}$'
          type: string
        ownerRole:
          $ref: '#/components/schemas/UserRoleEntity'
        captchaToken:
          maxLength: 2048
          minLength: 0
          type: string
          nullable: true
      additionalProperties: false
    CreateApiKeyRequest:
      type: object
      properties:
        accountId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
          nullable: true
        label:
          type: string
          nullable: true
        permissions:
          $ref: '#/components/schemas/ApiKeyRightsEntity'
      additionalProperties: false
    CreateManualPaymentRequest:
      type: object
      properties:
        amountUsd:
          type: number
          format: double
        description:
          type: string
          nullable: true
      additionalProperties: false
    CreateMessageRequest:
      required:
        - actor
        - channelType
        - messageType
      type: object
      properties:
        accountId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
          nullable: true
        account:
          $ref: '#/components/schemas/AccountEntity'
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        destination:
          type: string
          nullable: true
        body:
          type: string
          nullable: true
        templateId:
          type: string
          format: uuid
          nullable: true
        templateVariables:
          type: object
          additionalProperties:
            type: string
          nullable: true
        pushTopics:
          type: array
          items:
            type: string
          nullable: true
        pushUserIds:
          type: array
          items:
            type: string
          nullable: true
        messageType:
          $ref: '#/components/schemas/MessageTypeEntity'
        actor:
          minLength: 1
          type: string
        reason:
          type: string
          nullable: true
      additionalProperties: false
    CreateMessageTemplateRequest:
      required:
        - bodyTemplate
        - channelType
        - name
      type: object
      properties:
        name:
          maxLength: 200
          minLength: 1
          type: string
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        bodyTemplate:
          maxLength: 2000
          minLength: 1
          type: string
        defaultVariables:
          type: object
          additionalProperties:
            type: string
          nullable: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
      additionalProperties: false
    CreateNumberPoolRequest:
      type: object
      properties:
        name:
          type: string
          nullable: true
        strategy:
          $ref: '#/components/schemas/PoolSelectionStrategyEntity'
        subaccountId:
          type: string
          format: uuid
          nullable: true
      additionalProperties: false
    CreateOrUpdateMFAConfigRequest:
      type: object
      properties:
        requireMFA:
          type: boolean
          description: Whether MFA is required for the provider.
        allowedMethods:
          type: array
          items:
            type: string
          description: Allowed MFA methods for the provider.
          nullable: true
        challengeTimeoutSeconds:
          type: integer
          description: Optional challenge timeout in seconds.
          format: int32
          nullable: true
        maxAttempts:
          type: integer
          description: Optional maximum number of verification attempts.
          format: int32
          nullable: true
      additionalProperties: false
      description: Request to create or update MFA configuration.
    CreateProviderRequest:
      type: object
      properties:
        providerType:
          type: string
          nullable: true
        displayName:
          type: string
          nullable: true
        clientId:
          type: string
          nullable: true
        clientSecret:
          type: string
          nullable: true
        redirectUri:
          type: string
          nullable: true
        tenantId:
          type: string
          nullable: true
        scopes:
          type: array
          items:
            type: string
          nullable: true
      additionalProperties: false
    CreateSubaccountChargeRequest:
      type: object
      properties:
        amountMinor:
          type: integer
          description: 'Amount to charge in minor currency units (e.g., cents).'
          format: int64
        currency:
          type: string
          description: 'Currency code (e.g., USD).'
          nullable: true
        idempotencyKey:
          type: string
          description: Idempotency key to prevent duplicate charges.
          nullable: true
        stripePaymentMethodId:
          type: string
          description: 'Optional Stripe payment method ID; if not provided, default is used.'
          nullable: true
        description:
          type: string
          description: Optional charge description.
          nullable: true
        statementDescriptorSuffix:
          type: string
          description: Optional statement descriptor suffix for the Stripe charge.
          nullable: true
        metadata:
          type: object
          additionalProperties:
            type: string
          description: Optional metadata key-value pairs.
          nullable: true
      additionalProperties: false
      description: Body for a user-initiated manual charge of a Subaccount.
    CreateSubaccountRequest:
      type: object
      properties:
        accountId:
          type: string
          format: uuid
        name:
          type: string
          nullable: true
        slug:
          type: string
          nullable: true
        createdBy:
          type: string
          nullable: true
      additionalProperties: false
    CreateSupportCaseRequest:
      type: object
      properties:
        category:
          $ref: '#/components/schemas/SupportCaseCategoryEntity'
        severity:
          $ref: '#/components/schemas/SupportCaseSeverityEntity'
        subject:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
        relatedMessageId:
          type: string
          format: uuid
          nullable: true
        relatedWebhookEndpointId:
          type: string
          format: uuid
          nullable: true
        relatedRequestId:
          type: string
          nullable: true
        relatedComplianceIncidentId:
          type: string
          format: uuid
          nullable: true
        metadataJson:
          type: string
          nullable: true
        preferredContactMethod:
          $ref: '#/components/schemas/SupportContactMethodEntity'
        source:
          $ref: '#/components/schemas/SupportCaseSourceEntity'
      additionalProperties: false
    CreateTenDlcCampaignRequest:
      type: object
      properties:
        brandId:
          type: string
          format: uuid
        useCase:
          $ref: '#/components/schemas/TenDlcUseCaseEntity'
        subUseCases:
          type: array
          items:
            type: string
          nullable: true
        carrierName:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        messageFlow:
          type: string
          nullable: true
        sampleMessage1:
          type: string
          nullable: true
        sampleMessage2:
          type: string
          nullable: true
        sampleMessage3:
          type: string
          nullable: true
        sampleMessage4:
          type: string
          nullable: true
        sampleMessage5:
          type: string
          nullable: true
        embeddedLink:
          type: boolean
        embeddedPhone:
          type: boolean
        ageGated:
          type: boolean
        directLending:
          type: boolean
        affiliateMarketing:
          type: boolean
        subscriberOptin:
          type: boolean
        subscriberOptout:
          type: boolean
        subscriberHelp:
          type: boolean
      additionalProperties: false
    CreateWebhookEndpointRequest:
      required:
        - label
        - subscribedEvents
        - url
      type: object
      properties:
        url:
          minLength: 1
          type: string
          format: uri
        label:
          maxLength: 200
          minLength: 1
          type: string
        subscribedEvents:
          $ref: '#/components/schemas/WebhookEventTypeEntity'
        subaccountId:
          type: string
          format: uuid
          nullable: true
      additionalProperties: false
    DataSubjectRequest:
      title: DataSubjectRequest
      type: object
      properties:
        requestId:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        requestType:
          $ref: '#/components/schemas/DataSubjectRequestTypeEntity'
        status:
          $ref: '#/components/schemas/DataSubjectRequestStatusEntity'
        exportFormat:
          $ref: '#/components/schemas/ExportFormatEntity'
        exportFileUrl:
          type: string
          nullable: true
        exportExpiresAt:
          type: string
          format: date-time
          nullable: true
        failureReason:
          type: string
          nullable: true
        requestedAt:
          type: string
          format: date-time
        completedAt:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
      description: Public DataSubjectRequest payload returned by the API.
    DataSubjectRequestStatusEntity:
      enum:
        - Pending
        - InProgress
        - Completed
        - Failed
      type: string
      x-internal: true
    DataSubjectRequestTypeEntity:
      enum:
        - Export
        - Erasure
      type: string
      x-internal: true
    DiscoverProviderRequest:
      type: object
      properties:
        email:
          type: string
          description: The user's email address used to resolve a matching provider configuration.
          nullable: true
      additionalProperties: false
      description: Request to discover a provider.
    DiscoverProviderResponse:
      type: object
      properties:
        providerId:
          type: string
          format: uuid
          nullable: true
        providerName:
          type: string
          nullable: true
        found:
          type: boolean
      additionalProperties: false
    EmailOtpPurposeEntity:
      enum:
        - Login
        - StepUp
        - EmailVerification
      type: string
      x-internal: true
    ExportFormatEntity:
      enum:
        - CSV
        - Excel
        - PDF
        - JSON
      type: string
      x-internal: true
    ExternalAuthProviderResponse:
      type: object
      properties:
        providerId:
          type: string
          format: uuid
        providerType:
          type: string
          nullable: true
        displayName:
          type: string
          nullable: true
        isActive:
          type: boolean
        createdAt:
          type: string
          format: date-time
        config:
          nullable: true
      additionalProperties: false
    ExternalIdentityResponse:
      type: object
      properties:
        identityId:
          type: string
          description: Unique ID of the external identity record.
          format: uuid
        userId:
          type: string
          description: ArelHub user ID associated with this external identity.
          format: uuid
        providerType:
          type: string
          description: 'Provider type such as Google, Microsoft, or OIDC.'
          nullable: true
        providerDisplayName:
          type: string
          description: Human-friendly display name of the provider.
          nullable: true
        externalSubject:
          type: string
          description: Subject identifier returned by the external provider.
          nullable: true
        email:
          type: string
          description: The email address associated with the external identity if available.
          nullable: true
        displayName:
          type: string
          description: The display name retrieved from the provider profile.
          nullable: true
        profilePictureUrl:
          type: string
          description: Optional URL to the provider profile picture.
          nullable: true
        isPrimaryIdentity:
          type: boolean
          description: True when this is the primary identity for the user.
        isActive:
          type: boolean
          description: True when the external identity is active.
        linkedAt:
          type: string
          description: Timestamp when the identity was first linked.
          format: date-time
        unlinkedAt:
          type: string
          description: 'Timestamp when the identity was unlinked, if applicable.'
          format: date-time
          nullable: true
      additionalProperties: false
      description: Response DTO for external identity information.
    ExternalUserLoginRequest:
      type: object
      properties:
        code:
          type: string
          nullable: true
        state:
          type: string
          nullable: true
        codeVerifier:
          type: string
          nullable: true
        providerType:
          type: string
          nullable: true
        error:
          type: string
          nullable: true
        errorDescription:
          type: string
          nullable: true
      additionalProperties: false
    ForgotUserPasswordRequest:
      required:
        - email
      type: object
      properties:
        email:
          minLength: 1
          type: string
          format: email
      additionalProperties: false
    InitiateMFAChallengeRequest:
      type: object
      properties:
        delegationId:
          type: string
          description: The delegation associated with the MFA challenge.
          format: uuid
        method:
          type: string
          description: Requested MFA method for challenge delivery.
          nullable: true
      additionalProperties: false
      description: Request to initiate an MFA challenge.
    Invoice:
      title: Invoice
      type: object
      properties:
        invoiceId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        invoiceNumber:
          type: string
          nullable: true
        periodStart:
          type: string
          format: date-time
        periodEnd:
          type: string
          format: date-time
        subtotalUsd:
          type: number
          format: double
        taxUsd:
          type: number
          format: double
        totalUsd:
          type: number
          format: double
        taxRate:
          type: number
          format: double
          nullable: true
        taxJurisdiction:
          type: string
          nullable: true
        status:
          $ref: '#/components/schemas/InvoiceStatusEntity'
        paidAt:
          type: string
          format: date-time
          nullable: true
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
          nullable: true
        emailedAt:
          type: string
          format: date-time
          nullable: true
        emailStatus:
          $ref: '#/components/schemas/InvoiceEmailStatusEntity'
      additionalProperties: false
      description: Public Invoice payload returned by the API.
    InvoiceEmailStatusEntity:
      enum:
        - NotSent
        - Sent
        - Failed
      type: string
      x-internal: true
    InvoiceStatusEntity:
      enum:
        - Draft
        - Issued
        - PartiallyPaid
        - Paid
        - Overdue
        - Voided
      type: string
      x-internal: true
    IssueRequest:
      type: object
      properties:
        purpose:
          $ref: '#/components/schemas/EmailOtpPurposeEntity'
      additionalProperties: false
      description: Request to issue a new email OTP challenge for the current user.
    LinkProviderRequest:
      type: object
      properties:
        providerId:
          type: string
          format: uuid
        code:
          type: string
          nullable: true
        codeVerifier:
          type: string
          nullable: true
        redirectUri:
          type: string
          nullable: true
      additionalProperties: false
    LoginStatistics:
      type: object
      properties:
        totalAttempts:
          type: integer
          format: int32
        successfulLogins:
          type: integer
          format: int32
        failedLogins:
          type: integer
          format: int32
        lastSuccessfulLogin:
          type: string
          format: date-time
          nullable: true
        lastFailedLogin:
          type: string
          format: date-time
          nullable: true
        recentFailedAttempts:
          type: integer
          format: int32
        isAccountLocked:
          type: boolean
        timeUntilUnlock:
          $ref: '#/components/schemas/TimeSpan'
      additionalProperties: false
    MFARequiredResponse:
      type: object
      properties:
        isRequired:
          type: boolean
          description: True when MFA is required for the provider.
      additionalProperties: false
      description: Response indicating if MFA is required.
    ManualPaymentResult:
      title: ManualPaymentResult
      type: object
      properties:
        accountId:
          type: string
          format: uuid
        amountUsd:
          type: number
          format: double
        currency:
          type: string
          nullable: true
        stripePaymentId:
          type: string
          nullable: true
        paymentRecordedEventId:
          type: string
          format: uuid
        processedAt:
          type: string
          format: date-time
        description:
          type: string
          nullable: true
      additionalProperties: false
      description: Public ManualPaymentResult payload returned by the API.
    Message:
      title: Message
      type: object
      properties:
        messageId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        account:
          $ref: '#/components/schemas/Account'
        subaccountId:
          type: string
          format: uuid
          nullable: true
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        destination:
          type: string
          nullable: true
        body:
          type: string
          nullable: true
        messageType:
          $ref: '#/components/schemas/MessageTypeEntity'
        currentState:
          $ref: '#/components/schemas/MessageStateEntity'
        createdAt:
          type: string
          format: date-time
        rowVersion:
          type: string
          format: byte
          nullable: true
        latestVersion:
          $ref: '#/components/schemas/MessageVersion'
        versions:
          type: array
          items:
            $ref: '#/components/schemas/MessageVersion'
          nullable: true
        pushTopics:
          type: array
          items:
            type: string
          nullable: true
        pushUserIds:
          type: array
          items:
            type: string
          nullable: true
        adaptiveRiskParticipated:
          type: boolean
        adaptiveRiskExplanationBucket:
          type: string
          nullable: true
        channelHistory:
          type: array
          items:
            $ref: '#/components/schemas/MessageChannel'
          nullable: true
        messageTemplateId:
          type: string
          format: uuid
          nullable: true
      additionalProperties: false
      description: Public Message payload returned by the API.
    MessageChannel:
      title: MessageChannel
      type: object
      properties:
        messageChannelId:
          type: string
          format: uuid
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        providerName:
          type: string
          nullable: true
        attemptCount:
          type: integer
          format: int32
        wasFallback:
          type: boolean
        providerMessageId:
          type: string
          nullable: true
        providerStatus:
          type: string
          nullable: true
        deliveryStatus:
          $ref: '#/components/schemas/MessageChannelDeliveryStatusEntity'
        createdAt:
          type: string
          format: date-time
        sentAt:
          type: string
          format: date-time
          nullable: true
        deliveredAt:
          type: string
          format: date-time
          nullable: true
        failedAt:
          type: string
          format: date-time
          nullable: true
        failureReason:
          type: string
          nullable: true
        errorCategory:
          $ref: '#/components/schemas/SendErrorCategoryEntity'
      additionalProperties: false
      description: Public MessageChannel payload returned by the API.
    MessageChannelDeliveryStatusEntity:
      enum:
        - Pending
        - Sent
        - Delivered
        - Failed
        - Undelivered
      type: string
      x-internal: true
    MessageChannelEntity:
      type: object
      properties:
        messageChannelId:
          type: string
          format: uuid
          readOnly: true
        messageId:
          type: string
          format: uuid
          readOnly: true
        channelId:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        providerName:
          type: string
          nullable: true
          readOnly: true
        attemptCount:
          type: integer
          format: int32
          readOnly: true
        wasFallback:
          type: boolean
          readOnly: true
        providerMessageId:
          type: string
          nullable: true
          readOnly: true
        providerStatus:
          type: string
          nullable: true
          readOnly: true
        deliveryStatus:
          $ref: '#/components/schemas/MessageChannelDeliveryStatusEntity'
        createdAt:
          type: string
          format: date-time
          readOnly: true
        sentAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        deliveredAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        failedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        failureReason:
          type: string
          nullable: true
          readOnly: true
        message:
          $ref: '#/components/schemas/MessageEntity'
        channel:
          $ref: '#/components/schemas/ChannelEntity'
      additionalProperties: false
      x-internal: true
    MessageCostDetail:
      title: MessageCostDetail
      type: object
      properties:
        messageCostId:
          type: string
          format: uuid
        messageId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
          nullable: true
        subaccountName:
          type: string
          nullable: true
        carrierName:
          type: string
          nullable: true
        customerChargeUsd:
          type: number
          format: double
        createdAt:
          type: string
          format: date-time
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        attemptNumber:
          type: integer
          format: int32
      additionalProperties: false
      description: Public MessageCostDetail payload returned by the API.
    MessageCostSummary:
      title: MessageCostSummary
      type: object
      properties:
        totalMessages:
          type: integer
          format: int32
        totalCarrierCostUsd:
          type: number
          format: double
        totalCustomerChargeUsd:
          type: number
          format: double
        totalMarginUsd:
          type: number
          format: double
        marginPercent:
          type: number
          format: double
        periodStart:
          type: string
          format: date-time
        periodEnd:
          type: string
          format: date-time
      additionalProperties: false
      description: Public MessageCostSummary payload returned by the API.
    MessageEntity:
      type: object
      properties:
        messageId:
          type: string
          format: uuid
          readOnly: true
        accountId:
          type: string
          format: uuid
          readOnly: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        destination:
          type: string
          nullable: true
          readOnly: true
        messageType:
          $ref: '#/components/schemas/MessageTypeEntity'
        contentFormat:
          $ref: '#/components/schemas/ContentFormatEntity'
        body:
          type: string
          nullable: true
          readOnly: true
        contentHash:
          type: string
          format: byte
          nullable: true
          readOnly: true
        pushTopicsJson:
          type: string
          nullable: true
          readOnly: true
        pushUserIdsJson:
          type: string
          nullable: true
          readOnly: true
        messageTemplateId:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        templateVariablesJson:
          type: string
          nullable: true
          readOnly: true
        status:
          $ref: '#/components/schemas/MessageStatusEntity'
        isDeleted:
          type: boolean
          readOnly: true
        rowVersion:
          type: string
          format: byte
          nullable: true
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        account:
          $ref: '#/components/schemas/AccountEntity'
        subaccount:
          $ref: '#/components/schemas/SubaccountEntity'
        channelHistory:
          type: array
          items:
            $ref: '#/components/schemas/MessageChannelEntity'
          nullable: true
          readOnly: true
        dispatchChannelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        dispatchAttemptNumber:
          type: integer
          format: int32
          readOnly: true
        pushTopics:
          type: array
          items:
            type: string
          nullable: true
          readOnly: true
        pushUserIds:
          type: array
          items:
            type: string
          nullable: true
          readOnly: true
        renderedBodyOverride:
          type: string
          nullable: true
          readOnly: true
        effectiveBody:
          type: string
          nullable: true
          readOnly: true
        templateVariables:
          type: object
          additionalProperties:
            type: string
          nullable: true
          readOnly: true
        currentState:
          $ref: '#/components/schemas/MessageStateEntity'
        versions:
          type: array
          items:
            $ref: '#/components/schemas/MessageVersionEntity'
          nullable: true
          readOnly: true
      additionalProperties: false
      x-internal: true
    MessageRiskResponse:
      type: object
      properties:
        outcome:
          type: string
          nullable: true
        explanation:
          type: string
          nullable: true
        isShadowDecision:
          type: boolean
        evaluatedAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Risk decision summary returned to authenticated account owners.
    MessageStateAudit:
      title: MessageStateAudit
      type: object
      properties:
        fromState:
          $ref: '#/components/schemas/MessageStateEntity'
        toState:
          $ref: '#/components/schemas/MessageStateEntity'
        reason:
          type: string
          nullable: true
        actor:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
        auditType:
          $ref: '#/components/schemas/AuditTypeEntity'
        versionNumber:
          type: integer
          format: int32
      additionalProperties: false
      description: Public MessageStateAudit payload returned by the API.
    MessageStateAuditEntity:
      type: object
      properties:
        fromState:
          $ref: '#/components/schemas/MessageStateEntity'
        toState:
          $ref: '#/components/schemas/MessageStateEntity'
        reason:
          type: string
          nullable: true
          readOnly: true
        actor:
          type: string
          nullable: true
          readOnly: true
        auditType:
          $ref: '#/components/schemas/AuditTypeEntity'
        versionNumber:
          type: integer
          format: int32
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
      additionalProperties: false
      x-internal: true
    MessageStateEntity:
      enum:
        - Created
        - Validated
        - ContextResolved
        - ComplianceEvaluated
        - Queued
        - Submitted
        - Accepted
        - Delivered
        - HeldForReview
        - RejectedValidation
        - RejectedContext
        - RejectedCompliance
        - RejectedUpstream
        - FailedDelivery
        - SuspendedCustomer
        - SuspendedCampaign
        - DeadLettered
        - Deleted
        - DispatchHeld
      type: string
      x-internal: true
    MessageStatusEntity:
      enum:
        - Active
        - Archived
      type: string
      x-internal: true
    MessageTemplate:
      title: MessageTemplate
      type: object
      properties:
        messageTemplateId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
          nullable: true
        name:
          type: string
          nullable: true
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        bodyTemplate:
          type: string
          nullable: true
        defaultVariables:
          type: object
          additionalProperties:
            type: string
          nullable: true
        variables:
          type: array
          items:
            type: string
          nullable: true
        isActive:
          type: boolean
        isDeleted:
          type: boolean
        createdBy:
          type: string
          format: uuid
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
      description: Public MessageTemplate payload returned by the API.
    MessageTemplateEntity:
      type: object
      properties:
        messageTemplateId:
          type: string
          format: uuid
          readOnly: true
        accountId:
          type: string
          format: uuid
          readOnly: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        name:
          type: string
          nullable: true
          readOnly: true
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        bodyTemplate:
          type: string
          nullable: true
          readOnly: true
        defaultVariables:
          type: string
          nullable: true
          readOnly: true
        isActive:
          type: boolean
          readOnly: true
        isDeleted:
          type: boolean
          readOnly: true
        createdBy:
          type: string
          format: uuid
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        updatedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        account:
          $ref: '#/components/schemas/AccountEntity'
        subaccount:
          $ref: '#/components/schemas/SubaccountEntity'
        channelTemplates:
          type: array
          items:
            $ref: '#/components/schemas/ChannelTemplateEntity'
          nullable: true
          readOnly: true
      additionalProperties: false
      x-internal: true
    MessageTypeEntity:
      enum:
        - Transactional
        - Marketing
        - Compliance
        - System
        - Other
      type: string
      x-internal: true
    MessageVersion:
      title: MessageVersion
      type: object
      properties:
        messageState:
          $ref: '#/components/schemas/MessageStateEntity'
        tryCount:
          type: integer
          format: int32
        createdAt:
          type: string
          format: date-time
        nextRetryAt:
          type: string
          format: date-time
          nullable: true
        versionNumber:
          type: integer
          format: int32
        audits:
          type: array
          items:
            $ref: '#/components/schemas/MessageStateAudit'
          nullable: true
      additionalProperties: false
      description: Public MessageVersion payload returned by the API.
    MessageVersionEntity:
      type: object
      properties:
        messageState:
          $ref: '#/components/schemas/MessageStateEntity'
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        versionNumber:
          type: integer
          format: int32
          readOnly: true
        sequenceNumber:
          type: integer
          format: int32
          readOnly: true
        tryCount:
          type: integer
          format: int32
          readOnly: true
        nextRetryAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        audits:
          type: array
          items:
            $ref: '#/components/schemas/MessageStateAuditEntity'
          nullable: true
          readOnly: true
      additionalProperties: false
      x-internal: true
    NumberPool:
      title: NumberPool
      type: object
      properties:
        poolId:
          type: string
          format: uuid
        name:
          type: string
          nullable: true
        strategy:
          $ref: '#/components/schemas/PoolSelectionStrategyEntity'
        isActive:
          type: boolean
        numberCount:
          type: integer
          format: int32
        subaccountId:
          type: string
          format: uuid
          nullable: true
        createdAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public NumberPool payload returned by the API.
    OAuth2CallbackRequest:
      type: object
      properties:
        code:
          type: string
          description: Authorization code from OAuth2 provider.
          nullable: true
        state:
          type: string
          description: CSRF protection state (must match the one sent in authorize request).
          nullable: true
        codeVerifier:
          type: string
          description: PKCE code verifier (43-128 characters).
          nullable: true
        providerType:
          type: string
          description: 'Provider type ("Google", "Microsoft", "OIDC").'
          nullable: true
        error:
          type: string
          description: Error code if authorization failed.
          nullable: true
        errorDescription:
          type: string
          description: Error description if authorization failed.
          nullable: true
      additionalProperties: false
      description: Request to handle OAuth2 provider callback.
    OAuth2CallbackResponse:
      type: object
      properties:
        isSuccess:
          type: boolean
          description: Whether callback was successfully processed.
        userId:
          type: string
          description: Authenticated user ID (if successful).
          format: uuid
          nullable: true
        isNewUser:
          type: boolean
          description: Whether this is a new user (first-time OAuth login).
        identity:
          $ref: '#/components/schemas/ExternalIdentityResponse'
        errorMessage:
          type: string
          description: Error message if callback failed.
          nullable: true
      additionalProperties: false
      description: Response after handling OAuth2 callback.
    OAuth2MFAChallengeInit:
      title: OAuth2MFAChallengeInit
      type: object
      properties:
        challengeId:
          type: string
          format: uuid
        delegationId:
          type: string
          format: uuid
        method:
          type: string
          nullable: true
        expiresAt:
          type: string
          format: date-time
        timeoutSeconds:
          type: integer
          format: int32
      additionalProperties: false
      description: Public OAuth2MFAChallengeInit payload returned by the API.
    OAuth2MFAChallengeVerify:
      title: OAuth2MFAChallengeVerify
      type: object
      properties:
        challengeId:
          type: string
          format: uuid
        isVerified:
          type: boolean
        isExpired:
          type: boolean
        attemptCount:
          type: integer
          format: int32
        maxAttempts:
          type: integer
          format: int32
        errorMessage:
          type: string
          nullable: true
      additionalProperties: false
      description: Public OAuth2MFAChallengeVerify payload returned by the API.
    OAuth2MFAConfig:
      title: OAuth2MFAConfig
      type: object
      properties:
        configId:
          type: string
          format: uuid
        providerId:
          type: string
          format: uuid
        requireMFA:
          type: boolean
        allowedMethods:
          type: array
          items:
            type: string
          nullable: true
        challengeTimeoutSeconds:
          type: integer
          format: int32
        maxAttempts:
          type: integer
          format: int32
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
      description: Public OAuth2MFAConfig payload returned by the API.
    OnboardingResponse:
      type: object
      properties:
        connectedAccountId:
          type: string
          description: Stripe Connect account identifier created for the account.
          nullable: true
        onboardingUrl:
          type: string
          description: URL to the Stripe Express onboarding flow for this connected account.
          nullable: true
      additionalProperties: false
      description: Response for onboarding creation
    OnboardingStatusResponse:
      type: object
      properties:
        isComplete:
          type: boolean
          description: True when Stripe reports charges_enabled on the Connected Account.
        hasConnectedAccount:
          type: boolean
          description: True once a Stripe Connected Account exists for this Account.
        chargesEnabled:
          type: boolean
          description: Whether Stripe reports charges_enabled on the Connected Account.
        payoutsEnabled:
          type: boolean
          description: Whether payouts are enabled on the Connected Account.
        detailsSubmitted:
          type: boolean
          description: True once Stripe has accepted the Express onboarding submission (verification may still be pending).
      additionalProperties: false
      description: Response for onboarding status check
    OutstandingInvoiceSummary:
      title: OutstandingInvoiceSummary
      type: object
      properties:
        openInvoiceCount:
          type: integer
          format: int32
        openInvoiceGrossUsd:
          type: number
          format: double
        appliedPaymentsUsd:
          type: number
          format: double
        netOutstandingUsd:
          type: number
          format: double
      additionalProperties: false
      description: Public OutstandingInvoiceSummary payload returned by the API.
    PaymentMethod:
      title: PaymentMethod
      type: object
      properties:
        paymentMethodId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
          nullable: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
        namespace:
          $ref: '#/components/schemas/StripeNamespaceEntity'
        cardBrand:
          type: string
          nullable: true
        last4:
          type: string
          nullable: true
        expirationMonth:
          type: integer
          format: int32
        expirationYear:
          type: integer
          format: int32
        isDefault:
          type: boolean
        isExpired:
          type: boolean
        createdAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public PaymentMethod payload returned by the API.
    PhoneNumberCapabilityEntity:
      enum:
        - None
        - Sms
        - Mms
        - Voice
      type: string
      x-internal: true
    PhoneNumberStatusEntity:
      enum:
        - Active
        - Suspended
        - Porting
        - Released
      type: string
      x-internal: true
    PhoneNumberTypeEntity:
      enum:
        - LongCode
        - TollFree
        - ShortCode
      type: string
      x-internal: true
    PlanChangePreview:
      title: PlanChangePreview
      type: object
      properties:
        currentPlanName:
          type: string
          nullable: true
        newPlanName:
          type: string
          nullable: true
        currentMonthlyPrice:
          type: number
          format: double
        newMonthlyPrice:
          type: number
          format: double
        unusedCreditUsd:
          type: number
          format: double
        newPlanChargeUsd:
          type: number
          format: double
        netAmountUsd:
          type: number
          format: double
        remainingDays:
          type: integer
          format: int32
        effectiveDate:
          type: string
          format: date-time
        nextBillingDate:
          type: string
          format: date-time
        isUpgrade:
          type: boolean
        isDueNow:
          type: boolean
      additionalProperties: false
      description: Public PlanChangePreview payload returned by the API.
    PoolSelectionStrategyEntity:
      enum:
        - RoundRobin
        - Random
        - LeastUsed
      type: string
      x-internal: true
    ProblemDetails:
      type: object
      properties:
        type:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        status:
          type: integer
          format: int32
          nullable: true
        detail:
          type: string
          nullable: true
        instance:
          type: string
          nullable: true
      additionalProperties: { }
    ProviderDiscoveryRule:
      title: ProviderDiscoveryRule
      type: object
      properties:
        ruleId:
          type: string
          format: uuid
        emailDomain:
          type: string
          nullable: true
        providerId:
          type: string
          format: uuid
        priority:
          type: integer
          format: int32
        isActive:
          type: boolean
        createdAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public ProviderDiscoveryRule payload returned by the API.
    ProviderHealthStatus:
      title: ProviderHealthStatus
      type: object
      properties:
        statusId:
          type: string
          format: uuid
        providerId:
          type: string
          format: uuid
        status:
          type: string
          nullable: true
        responseTimeMs:
          type: integer
          format: int32
        errorMessage:
          type: string
          nullable: true
        failureCount:
          type: integer
          format: int32
        successCount:
          type: integer
          format: int32
        lastCheckedAt:
          type: string
          format: date-time
        isAvailable:
          type: boolean
        isDegraded:
          type: boolean
      additionalProperties: false
      description: Public ProviderHealthStatus payload returned by the API.
    ProvisionedPhoneNumber:
      title: ProvisionedPhoneNumber
      type: object
      properties:
        phoneNumberId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        e164Number:
          type: string
          nullable: true
        numberType:
          $ref: '#/components/schemas/PhoneNumberTypeEntity'
        status:
          $ref: '#/components/schemas/PhoneNumberStatusEntity'
        capabilities:
          $ref: '#/components/schemas/PhoneNumberCapabilityEntity'
        isDefault:
          type: boolean
        isPooled:
          type: boolean
        poolId:
          type: string
          format: uuid
          nullable: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
        subaccountName:
          type: string
          nullable: true
        monthlyFeeCents:
          type: integer
          format: int32
        purchasedAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public ProvisionedPhoneNumber payload returned by the API.
    PublicExternalAuthProviderResponse:
      type: object
      properties:
        providerId:
          type: string
          description: Unique provider identifier.
          format: uuid
        providerType:
          type: string
          description: Provider type identifier.
          nullable: true
        displayName:
          type: string
          description: Display name shown to end users.
          nullable: true
      additionalProperties: false
      description: Public metadata for an external authentication provider.
    PublicRegistrationPaymentConfig:
      type: object
      properties:
        publishableKey:
          type: string
          description: Stripe publishable key for client-side card element initialisation.
          nullable: true
      additionalProperties: false
      description: Public-facing configuration needed to initialise Stripe.js on the registration page.
    PublicRegistrationPaymentDiagnostics:
      type: object
      properties:
        environment:
          type: string
          description: 'ASP.NET Core environment name (Development, Staging, Production).'
          nullable: true
        hasPublishableKey:
          type: boolean
          description: Indicates whether a publishable key is configured.
        publishableKeyPrefix:
          type: string
          description: Leading characters of the publishable key for sanity checking.
          nullable: true
        publishableKeyMode:
          type: string
          description: Whether the publishable key is in test or live mode.
          nullable: true
        hasSecretKey:
          type: boolean
          description: Indicates whether a secret key is configured.
        secretKeyPrefix:
          type: string
          description: Leading characters of the secret key for sanity checking.
          nullable: true
        secretKeyMode:
          type: string
          description: Whether the secret key is in test or live mode.
          nullable: true
        keyModeMatch:
          type: boolean
          description: True when both keys are in the same mode (both test or both live).
        currency:
          type: string
          description: Configured currency code.
          nullable: true
      additionalProperties: false
      description: Development-only Stripe key diagnostics returned by the payment-diagnostics endpoint.
    PublicRegistrationResult:
      type: object
      properties:
        accountId:
          type: string
          description: Newly created account ID.
          format: uuid
        ownerUserId:
          type: string
          description: User ID of the account owner.
          format: uuid
        ownerEmail:
          type: string
          description: Email address of the account owner.
          nullable: true
        accountName:
          type: string
          description: Display name of the registered account.
          nullable: true
        message:
          type: string
          description: Human-readable confirmation message.
          nullable: true
      additionalProperties: false
      description: Response returned after a successful public account registration.
    PurchasePhoneNumberRequest:
      type: object
      properties:
        e164Number:
          type: string
          nullable: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
        countryCode:
          type: string
          nullable: true
      additionalProperties: false
    QuotaUnitEntity:
      enum:
        - PerMessage
        - PerSegment
      type: string
      x-internal: true
    RealtimeMetrics:
      title: RealtimeMetrics
      type: object
      properties:
        realtimeMetricId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
          nullable: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
        snapshotTimeUtc:
          type: string
          format: date-time
        messagesSent:
          type: integer
          format: int32
        messagesDelivered:
          type: integer
          format: int32
        messagesFailed:
          type: integer
          format: int32
        messagesPending:
          type: integer
          format: int32
        deliveryRate:
          type: number
          format: double
        activeConnections:
          type: integer
          format: int32
        queueDepth:
          type: integer
          format: int32
        averageLatencyMs:
          type: number
          format: double
        throughputPerSecond:
          type: integer
          format: int64
      additionalProperties: false
      description: Public RealtimeMetrics payload returned by the API.
    RealtimeMetricsHealth:
      title: RealtimeMetricsHealth
      type: object
      properties:
        isHealthy:
          type: boolean
        lastUpdateUtc:
          type: string
          format: date-time
        totalMetricsTracked:
          type: integer
          format: int32
        activeAccounts:
          type: integer
          format: int32
        activeSubaccounts:
          type: integer
          format: int32
        status:
          type: string
          nullable: true
      additionalProperties: false
      description: Public RealtimeMetricsHealth payload returned by the API.
    Receipt:
      title: Receipt
      type: object
      properties:
        receiptId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        invoiceId:
          type: string
          format: uuid
        receiptNumber:
          type: string
          nullable: true
        externalPaymentId:
          type: string
          nullable: true
        amountUsd:
          type: number
          format: double
        taxUsd:
          type: number
          format: double
        totalUsd:
          type: number
          format: double
        paidAt:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public Receipt payload returned by the API.
    RefreshTokenEntity:
      type: object
      properties:
        refreshTokenId:
          type: string
          format: uuid
          readOnly: true
        userId:
          type: string
          format: uuid
        token:
          type: string
          nullable: true
        expiresAt:
          type: string
          format: date-time
        revoked:
          type: boolean
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        revokedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        tokenFamilyId:
          type: string
          format: uuid
          readOnly: true
        replacedByTokenId:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        user:
          $ref: '#/components/schemas/UserEntity'
        isActive:
          type: boolean
          readOnly: true
      additionalProperties: false
      x-internal: true
    RefreshTokenRequest:
      type: object
      properties:
        refreshToken:
          type: string
          description: The refresh token to exchange for new access and refresh tokens.
          nullable: true
      additionalProperties: false
      description: Request to refresh tokens
    RegisterTenDlcBrandRequest:
      type: object
      properties:
        legalName:
          type: string
          nullable: true
        ein:
          type: string
          nullable: true
        brandType:
          $ref: '#/components/schemas/TenDlcBrandTypeEntity'
        phone:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        website:
          type: string
          nullable: true
        street:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        state:
          type: string
          nullable: true
        postalCode:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
        vertical:
          $ref: '#/components/schemas/TenDlcVerticalEntity'
        stockSymbol:
          type: string
          nullable: true
        stockExchange:
          type: string
          nullable: true
        altBusinessId:
          type: string
          nullable: true
        altBusinessIdType:
          type: string
          nullable: true
      additionalProperties: false
    RenderTemplateRequest:
      type: object
      properties:
        variables:
          type: object
          additionalProperties:
            type: string
          nullable: true
      additionalProperties: false
    ReopenSupportCaseRequest:
      type: object
      properties:
        notes:
          type: string
          nullable: true
      additionalProperties: false
    ResetUserPasswordRequest:
      required:
        - newPassword
        - token
      type: object
      properties:
        token:
          minLength: 1
          type: string
        newPassword:
          maxLength: 128
          minLength: 12
          pattern: '^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{12,}$'
          type: string
      additionalProperties: false
    RevokeTokenRequest:
      type: object
      properties:
        refreshToken:
          type: string
          description: 'Optional refresh token to revoke; if omitted, the current user''s tokens are revoked.'
          nullable: true
      additionalProperties: false
      description: Request to revoke a token
    RiskSignal:
      title: RiskSignal
      type: object
      properties:
        riskSignalId:
          type: string
          format: uuid
        adaptiveRiskEvaluationId:
          type: string
          format: uuid
        signalType:
          type: string
          nullable: true
        scoreContribution:
          type: number
          format: double
        confidence:
          type: number
          format: double
        reason:
          type: string
          nullable: true
        rawData:
          type: string
          nullable: true
        sourceProvider:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public RiskSignal payload returned by the API.
    RiskSignalSummary:
      title: RiskSignalSummary
      type: object
      properties:
        totalSignalsCollected:
          type: integer
          format: int32
        maxScoreContribution:
          type: number
          format: double
        averageConfidence:
          type: number
          format: double
        signalCountByType:
          type: object
          additionalProperties:
            type: integer
            format: int32
          nullable: true
        signalCountByProvider:
          type: object
          additionalProperties:
            type: integer
            format: int32
          nullable: true
        highestContributingSignals:
          type: array
          items:
            $ref: '#/components/schemas/RiskSignal'
          nullable: true
      additionalProperties: false
      description: Public RiskSignalSummary payload returned by the API.
    RiskSignalTypeEntity:
      enum:
        - ContentToxicity
        - SenderReputation
        - DomainReputation
        - UrlSafety
        - SpammerPattern
        - HeaderAnomaly
        - RecipientComplaintHistory
        - MessageFormatAnomaly
        - AuthenticationFailure
        - GeographicAnomaly
        - TemporalAnomaly
      type: string
      x-internal: true
    SavePaymentMethodRequest:
      type: object
      properties:
        stripePaymentMethodId:
          type: string
          nullable: true
        setAsDefault:
          type: boolean
      additionalProperties: false
    SegmentPreviewRequest:
      type: object
      properties:
        body:
          type: string
          description: Message body to evaluate.
          nullable: true
        mediaType:
          $ref: '#/components/schemas/ContentFormatEntity'
        smartEncoding:
          type: boolean
          description: 'When true, smart-encoding normalization is applied before calculating segments.'
          nullable: true
      additionalProperties: false
      description: Request body for the segment preview endpoint.
    SegmentPreviewResponse:
      type: object
      properties:
        encoding:
          type: string
          description: 'Detected or applied encoding (e.g. GSM7, UCS2).'
          nullable: true
        charCount:
          type: integer
          description: Total character count in the evaluated body.
          format: int32
        segmentCount:
          type: integer
          description: Number of SMS segments the body will occupy.
          format: int32
        estimatedCarrierCostUsd:
          type: number
          description: Estimated carrier cost in USD for the calculated segment count.
          format: double
        estimatedCustomerChargeUsd:
          type: number
          description: Estimated customer charge in USD based on the active subscription plan; null when no plan is active.
          format: double
          nullable: true
        normalizedBody:
          type: string
          description: Smart-encoding normalized body; null when smart encoding was not requested.
          nullable: true
      additionalProperties: false
      description: Segment analysis result returned by the preview endpoint.
    SendErrorCategoryEntity:
      enum:
        - None
        - RecipientValidation
        - Consent
        - ChannelConfiguration
        - ProviderError
        - QuotaExceeded
        - Platform
      type: string
      x-internal: true
    SetPrimaryIdentityRequest:
      type: object
      properties:
        userId:
          type: string
          format: uuid
        identityId:
          type: string
          format: uuid
      additionalProperties: false
    SetupIntent:
      title: SetupIntent
      type: object
      properties:
        setupIntentId:
          type: string
          nullable: true
        clientSecret:
          type: string
          nullable: true
        status:
          type: string
          nullable: true
        publishableKey:
          type: string
          nullable: true
      additionalProperties: false
      description: Public SetupIntent payload returned by the API.
    StepUpAction:
      enum:
        - ChangePassword
        - ChangeEmail
        - PaymentMethod
        - RevokeSession
        - ApiKey
        - BillingChange
      type: string
    StripeNamespaceEntity:
      enum:
        - Platform
        - Connected
      type: string
      x-internal: true
    Subaccount:
      title: Subaccount
      type: object
      properties:
        subaccountId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        name:
          type: string
          nullable: true
        slug:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
        createdBy:
          type: string
          nullable: true
        status:
          $ref: '#/components/schemas/SubaccountStatusEntity'
        isolationRules:
          type: string
          nullable: true
        isDeleted:
          type: boolean
        stripeCustomerId:
          type: string
          nullable: true
        defaultPaymentMethodId:
          type: string
          format: uuid
          nullable: true
      additionalProperties: false
      description: Public Subaccount payload returned by the API.
    SubaccountChargeResult:
      type: object
      properties:
        subaccountPaymentEventId:
          type: string
          format: uuid
        paymentIntentId:
          type: string
          nullable: true
        status:
          $ref: '#/components/schemas/SubaccountPaymentEventStatusEntity'
        amountMinor:
          type: integer
          format: int64
        currency:
          type: string
          nullable: true
        applicationFeeAmountMinor:
          type: integer
          format: int64
        failureCode:
          type: string
          nullable: true
        failureMessage:
          type: string
          nullable: true
        refundId:
          type: string
          nullable: true
      additionalProperties: false
    SubaccountEntity:
      type: object
      properties:
        subaccountId:
          type: string
          format: uuid
          readOnly: true
        accountId:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          nullable: true
        stripeCustomerId:
          type: string
          nullable: true
          readOnly: true
        billingEmail:
          type: string
          nullable: true
          readOnly: true
        defaultPaymentMethodId:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        slug:
          type: string
          nullable: true
        isolationRules:
          type: string
          nullable: true
          readOnly: true
        status:
          $ref: '#/components/schemas/SubaccountStatusEntity'
        isDeleted:
          type: boolean
          readOnly: true
        createdBy:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        account:
          $ref: '#/components/schemas/AccountEntity'
        users:
          type: array
          items:
            $ref: '#/components/schemas/UserEntity'
          nullable: true
          readOnly: true
        messages:
          type: array
          items:
            $ref: '#/components/schemas/MessageEntity'
          nullable: true
          readOnly: true
        apiKeys:
          type: array
          items:
            $ref: '#/components/schemas/ApiKeyEntity'
          nullable: true
          readOnly: true
      additionalProperties: false
      x-internal: true
    SubaccountPaymentEvent:
      title: SubaccountPaymentEvent
      type: object
      properties:
        subaccountPaymentEventId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        stripePaymentIntentId:
          type: string
          nullable: true
        connectedAccountId:
          type: string
          nullable: true
        amountMinor:
          type: integer
          format: int64
        currency:
          type: string
          nullable: true
        applicationFeeAmountMinor:
          type: integer
          format: int64
        status:
          $ref: '#/components/schemas/SubaccountPaymentEventStatusEntity'
        failureCode:
          type: string
          nullable: true
        failureMessage:
          type: string
          nullable: true
        occurredAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public SubaccountPaymentEvent payload returned by the API.
    SubaccountPaymentEventStatusEntity:
      enum:
        - Pending
        - Succeeded
        - Failed
        - Refunded
        - PartiallyRefunded
      type: string
      x-internal: true
    SubaccountQuota:
      title: SubaccountQuota
      type: object
      properties:
        subaccountQuotaId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
        dailyLimit:
          type: integer
          format: int32
          nullable: true
        monthlyLimit:
          type: integer
          format: int32
          nullable: true
        ratePerSecond:
          type: integer
          format: int32
          nullable: true
        ratePerMinute:
          type: integer
          format: int32
          nullable: true
        dailyUsed:
          type: integer
          format: int32
        monthlyUsed:
          type: integer
          format: int32
        dailyRemaining:
          type: integer
          format: int32
          nullable: true
        monthlyRemaining:
          type: integer
          format: int32
          nullable: true
        lastDailyReset:
          type: string
          format: date-time
        lastMonthlyReset:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
      description: Public SubaccountQuota payload returned by the API.
    SubaccountSetupIntent:
      title: SubaccountSetupIntent
      type: object
      properties:
        setupIntentId:
          type: string
          nullable: true
        clientSecret:
          type: string
          nullable: true
        status:
          type: string
          nullable: true
        connectedAccountId:
          type: string
          nullable: true
        stripeCustomerId:
          type: string
          nullable: true
      additionalProperties: false
      description: Public SubaccountSetupIntent payload returned by the API.
    SubaccountStatusEntity:
      enum:
        - Active
        - Suspended
        - Closed
        - Archived
      type: string
      x-internal: true
    SubscriptionPlan:
      title: SubscriptionPlan
      type: object
      properties:
        planId:
          type: string
          format: uuid
        name:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        monthlyPriceUsd:
          type: number
          format: double
        annualPriceUsd:
          type: number
          format: double
          nullable: true
        smsBaseMessagePriceUsd:
          type: number
          format: double
          nullable: true
        inboundSmsRate:
          type: number
          format: double
          nullable: true
        smsOveragePerMessageUsd:
          type: number
          format: double
          nullable: true
        mmsBaseMessagePriceUsd:
          type: number
          format: double
          nullable: true
        inboundMmsRate:
          type: number
          format: double
          nullable: true
        mmsOveragePerMessageUsd:
          type: number
          format: double
          nullable: true
        carrierSurchargePassThrough:
          type: boolean
        platformFeePercent:
          type: number
          format: double
        phoneNumberSetupRate:
          type: number
          format: double
          nullable: true
        phoneNumberMonthlyRate:
          type: number
          format: double
          nullable: true
        tenDlcBrandRegistrationFee:
          type: number
          format: double
          nullable: true
        tenDlcCampaignRegistrationFee:
          type: number
          format: double
          nullable: true
        tenDlcLowVolumeCampaignRegistrationFee:
          type: number
          format: double
          nullable: true
        tenDlcSpecialCampaignRegistrationFee:
          type: number
          format: double
          nullable: true
        tenDlcPoliticalCampaignRegistrationFee:
          type: number
          format: double
          nullable: true
        tenDlcSoleProprietorCampaignRegistrationFee:
          type: number
          format: double
          nullable: true
        tenDlcCampaignMonthlyMaintenanceFee:
          type: number
          format: double
          nullable: true
        tenDlcLowVolumeCampaignMonthlyMaintenanceFee:
          type: number
          format: double
          nullable: true
        tenDlcSpecialCampaignMonthlyMaintenanceFee:
          type: number
          format: double
          nullable: true
        tenDlcPoliticalCampaignMonthlyMaintenanceFee:
          type: number
          format: double
          nullable: true
        tenDlcSoleProprietorCampaignMonthlyMaintenanceFee:
          type: number
          format: double
          nullable: true
        tenDlcStandardVettingFee:
          type: number
          format: double
          nullable: true
        tenDlcEnhancedVettingFee:
          type: number
          format: double
          nullable: true
        tenDlcPoliticalVettingFee:
          type: number
          format: double
          nullable: true
        tenDlcBrandAppealFee:
          type: number
          format: double
          nullable: true
        tenDlcVettingAppealFee:
          type: number
          format: double
          nullable: true
        tenDlcBrandResubmitFee:
          type: number
          format: double
          nullable: true
        tenDlcCampaignResubmitFee:
          type: number
          format: double
          nullable: true
        tenDlcNumberConnectivityFee:
          type: number
          format: double
          nullable: true
        ratePerSecond:
          type: integer
          format: int32
          nullable: true
        ratePerMinute:
          type: integer
          format: int32
          nullable: true
        dailyMessageLimit:
          type: integer
          format: int32
          nullable: true
        monthlyMessageLimit:
          type: integer
          format: int32
          nullable: true
        maxSubaccounts:
          type: integer
          format: int32
          nullable: true
        quotaUnit:
          $ref: '#/components/schemas/QuotaUnitEntity'
        isActive:
          type: boolean
        sortOrder:
          type: integer
          format: int32
        updatedAt:
          type: string
          format: date-time
          nullable: true
        createdAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public SubscriptionPlan payload returned by the API.
    SubscriptionStatusEntity:
      enum:
        - Active
        - PastDue
        - Cancelled
        - Expired
        - Trialing
      type: string
      x-internal: true
    SupportCase:
      title: SupportCase
      type: object
      properties:
        id:
          type: string
          format: uuid
        referenceNumber:
          type: string
          nullable: true
        accountId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
          nullable: true
        createdByUserId:
          type: string
          format: uuid
        contactEmail:
          type: string
          nullable: true
        category:
          $ref: '#/components/schemas/SupportCaseCategoryEntity'
        severity:
          $ref: '#/components/schemas/SupportCaseSeverityEntity'
        status:
          $ref: '#/components/schemas/SupportCaseStatusEntity'
        source:
          $ref: '#/components/schemas/SupportCaseSourceEntity'
        subject:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        preferredContactMethod:
          $ref: '#/components/schemas/SupportContactMethodEntity'
        correlationKey:
          type: string
          nullable: true
        relatedMessageId:
          type: string
          format: uuid
          nullable: true
        relatedWebhookEndpointId:
          type: string
          format: uuid
          nullable: true
        relatedRequestId:
          type: string
          nullable: true
        relatedComplianceIncidentId:
          type: string
          format: uuid
          nullable: true
        metadataJson:
          type: string
          nullable: true
        assignedToStaffId:
          type: string
          format: uuid
          nullable: true
        assignedAt:
          type: string
          format: date-time
          nullable: true
        firstRespondedAt:
          type: string
          format: date-time
          nullable: true
        resolvedByStaffId:
          type: string
          format: uuid
          nullable: true
        resolvedAt:
          type: string
          format: date-time
          nullable: true
        resolutionNotes:
          type: string
          nullable: true
        reopenCount:
          type: integer
          format: int32
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        closedAt:
          type: string
          format: date-time
          nullable: true
        wasDeduped:
          type: boolean
        comments:
          type: array
          items:
            $ref: '#/components/schemas/SupportCaseComment'
          nullable: true
        statusHistory:
          type: array
          items:
            $ref: '#/components/schemas/SupportCaseStatusHistory'
          nullable: true
      additionalProperties: false
      description: Public SupportCase payload returned by the API.
    SupportCaseCategoryEntity:
      enum:
        - AccountAccess
        - Billing
        - MessagingDelivery
        - WebhooksIntegrations
        - PhoneNumbersTenDlc
        - ApiDeveloper
        - SecurityPrivacy
        - Other
      type: string
      x-internal: true
    SupportCaseComment:
      title: SupportCaseComment
      type: object
      properties:
        id:
          type: string
          format: uuid
        supportCaseId:
          type: string
          format: uuid
        authorType:
          $ref: '#/components/schemas/SupportCommentAuthorTypeEntity'
        authorUserId:
          type: string
          format: uuid
          nullable: true
        authorStaffId:
          type: string
          format: uuid
          nullable: true
        body:
          type: string
          nullable: true
        isInternal:
          type: boolean
        createdAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public SupportCaseComment payload returned by the API.
    SupportCaseListResult:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/SupportCase'
          nullable: true
        totalCount:
          type: integer
          format: int32
        page:
          type: integer
          format: int32
        pageSize:
          type: integer
          format: int32
      additionalProperties: false
    SupportCaseSeverityEntity:
      enum:
        - Low
        - Medium
        - High
        - Critical
      type: string
      x-internal: true
    SupportCaseSourceEntity:
      enum:
        - UserDashboard
        - Api
        - StaffCreated
      type: string
      x-internal: true
    SupportCaseStatusEntity:
      enum:
        - Open
        - Assigned
        - WaitingOnCustomer
        - Escalated
        - Resolved
        - Closed
        - Reopened
      type: string
      x-internal: true
    SupportCaseStatusHistory:
      title: SupportCaseStatusHistory
      type: object
      properties:
        id:
          type: string
          format: uuid
        supportCaseId:
          type: string
          format: uuid
        fromStatus:
          $ref: '#/components/schemas/SupportCaseStatusEntity'
        toStatus:
          $ref: '#/components/schemas/SupportCaseStatusEntity'
        changedByType:
          $ref: '#/components/schemas/SupportCommentAuthorTypeEntity'
        changedById:
          type: string
          format: uuid
          nullable: true
        notes:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public SupportCaseStatusHistory payload returned by the API.
    SupportCommentAuthorTypeEntity:
      enum:
        - User
        - Staff
        - System
      type: string
      x-internal: true
    SupportContactMethodEntity:
      enum:
        - Email
      type: string
      x-internal: true
    TcrCampaignMnoStatus:
      title: TcrCampaignMnoStatus
      type: object
      properties:
        mno:
          type: string
          nullable: true
        operationStatus:
          type: string
          nullable: true
        tpmLimit:
          type: integer
          format: int32
          nullable: true
        brandTier:
          type: string
          nullable: true
        qualified:
          type: boolean
          nullable: true
      additionalProperties: false
      description: Public TcrCampaignMnoStatus payload returned by the API.
    TcrStatusEntity:
      enum:
        - NotSubmitted
        - Pending
        - Approved
        - Failed
        - Suspended
      type: string
      x-internal: true
    TemplatePreviewRequest:
      required:
        - bodyTemplate
      type: object
      properties:
        bodyTemplate:
          maxLength: 2000
          minLength: 1
          type: string
        variables:
          type: object
          additionalProperties:
            type: string
          nullable: true
      additionalProperties: false
    TenDlcBrand:
      title: TenDlcBrand
      type: object
      properties:
        brandId:
          type: string
          format: uuid
        legalName:
          type: string
          nullable: true
        ein:
          type: string
          nullable: true
        brandType:
          $ref: '#/components/schemas/TenDlcBrandTypeEntity'
        status:
          $ref: '#/components/schemas/BrandStatusEntity'
        failureReason:
          type: string
          nullable: true
        submittedAt:
          type: string
          format: date-time
          nullable: true
        verifiedAt:
          type: string
          format: date-time
          nullable: true
        createdAt:
          type: string
          format: date-time
        tcrBrandId:
          type: string
          nullable: true
        tcrStatus:
          $ref: '#/components/schemas/TcrStatusEntity'
        tcrIdentityStatus:
          type: string
          nullable: true
        tcrVettingScore:
          type: integer
          format: int32
          nullable: true
        tcrVettingClass:
          type: string
          nullable: true
        tcrFailureCode:
          type: string
          nullable: true
        tcrFailureReason:
          type: string
          nullable: true
        tcrSubmittedAt:
          type: string
          format: date-time
          nullable: true
        tcrLastSyncedAt:
          type: string
          format: date-time
          nullable: true
        isLiveTcrData:
          type: boolean
        phone:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        website:
          type: string
          nullable: true
        street:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        state:
          type: string
          nullable: true
        postalCode:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
        vertical:
          $ref: '#/components/schemas/TenDlcVerticalEntity'
        stockSymbol:
          type: string
          nullable: true
        stockExchange:
          type: string
          nullable: true
        altBusinessId:
          type: string
          nullable: true
        altBusinessIdType:
          type: string
          nullable: true
        accountId:
          type: string
          format: uuid
          nullable: true
      additionalProperties: false
      description: Public TenDlcBrand payload returned by the API.
    TenDlcBrandTypeEntity:
      enum:
        - PrivateProfit
        - PublicProfit
        - NonProfit
        - Government
        - SoleProprietor
      type: string
      x-internal: true
    TenDlcCampaign:
      title: TenDlcCampaign
      type: object
      properties:
        campaignId:
          type: string
          format: uuid
        brandId:
          type: string
          format: uuid
        useCase:
          $ref: '#/components/schemas/TenDlcUseCaseEntity'
        description:
          type: string
          nullable: true
        status:
          $ref: '#/components/schemas/TenDlcCampaignStatusEntity'
        failureReason:
          type: string
          nullable: true
        submittedAt:
          type: string
          format: date-time
          nullable: true
        activatedAt:
          type: string
          format: date-time
          nullable: true
        createdAt:
          type: string
          format: date-time
        tcrCampaignId:
          type: string
          nullable: true
        tcrStatus:
          $ref: '#/components/schemas/TcrStatusEntity'
        tcrFailureCode:
          type: string
          nullable: true
        tcrFailureReason:
          type: string
          nullable: true
        tcrSubmittedAt:
          type: string
          format: date-time
          nullable: true
        tcrLastSyncedAt:
          type: string
          format: date-time
          nullable: true
        vettingScore:
          type: integer
          format: int32
          nullable: true
        throughputLimitPerMinute:
          type: integer
          format: int32
          nullable: true
        isLiveTcrData:
          type: boolean
        subUseCases:
          type: array
          items:
            type: string
          nullable: true
        carrierName:
          type: string
          nullable: true
        carrierCampaignId:
          type: string
          nullable: true
        messageFlow:
          type: string
          nullable: true
        sampleMessage1:
          type: string
          nullable: true
        sampleMessage2:
          type: string
          nullable: true
        sampleMessage3:
          type: string
          nullable: true
        sampleMessage4:
          type: string
          nullable: true
        sampleMessage5:
          type: string
          nullable: true
        embeddedLink:
          type: boolean
        embeddedPhone:
          type: boolean
        ageGated:
          type: boolean
        directLending:
          type: boolean
        affiliateMarketing:
          type: boolean
        subscriberOptin:
          type: boolean
        subscriberOptout:
          type: boolean
        subscriberHelp:
          type: boolean
        updatedAt:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
      description: Public TenDlcCampaign payload returned by the API.
    TenDlcCampaignStatusEntity:
      enum:
        - Draft
        - Submitted
        - Active
        - Suspended
        - Deactivated
      type: string
      x-internal: true
    TenDlcUseCaseEntity:
      enum:
        - Marketing
        - Transactional
        - OTP
        - Mixed
        - CustomerCare
        - TwoFactorAuthentication
        - AccountNotification
        - AgentsFranchises
        - CarrierExempt
        - Charity
        - DeliveryNotification
        - Emergency
        - FraudAlert
        - HigherEducation
        - K12Education
        - LowVolume
        - MachineToMachine
        - Political
        - PollingVoting
        - Proxy
        - PublicSafetyRestricted
        - PublicServiceAnnouncement
        - SecurityAlert
        - Social
        - SoleProprietor
        - Sweepstake
        - Trial
        - UcaasHigh
        - UcaasLow
      type: string
      x-internal: true
    TenDlcVerticalEntity:
      enum:
        - Agriculture
        - Communication
        - Construction
        - Education
        - Energy
        - Entertainment
        - Financial
        - Gambling
        - Government
        - Healthcare
        - Hospitality
        - HumanResources
        - Insurance
        - Legal
        - Manufacturing
        - NonProfit
        - ProfessionalServices
        - RealEstate
        - Retail
        - Technology
        - Transportation
        - Other
      type: string
      x-internal: true
    TimeSpan:
      type: object
      properties:
        ticks:
          type: integer
          format: int64
        days:
          type: integer
          format: int32
          readOnly: true
        hours:
          type: integer
          format: int32
          readOnly: true
        milliseconds:
          type: integer
          format: int32
          readOnly: true
        microseconds:
          type: integer
          format: int32
          readOnly: true
        nanoseconds:
          type: integer
          format: int32
          readOnly: true
        minutes:
          type: integer
          format: int32
          readOnly: true
        seconds:
          type: integer
          format: int32
          readOnly: true
        totalDays:
          type: number
          format: double
          readOnly: true
        totalHours:
          type: number
          format: double
          readOnly: true
        totalMilliseconds:
          type: number
          format: double
          readOnly: true
        totalMicroseconds:
          type: number
          format: double
          readOnly: true
        totalNanoseconds:
          type: number
          format: double
          readOnly: true
        totalMinutes:
          type: number
          format: double
          readOnly: true
        totalSeconds:
          type: number
          format: double
          readOnly: true
      additionalProperties: false
    UnlinkProviderRequest:
      type: object
      properties:
        identityId:
          type: string
          description: External identity ID to unlink.
          format: uuid
        password:
          type: string
          description: User's password for verification (security check).
          nullable: true
      additionalProperties: false
      description: Request to unlink an external provider from account.
    UpdateAccountAddressRequest:
      type: object
      properties:
        streetAddress1:
          type: string
          nullable: true
        streetAddress2:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        stateOrProvince:
          type: string
          nullable: true
        postalCode:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
      additionalProperties: false
    UpdateAccountContactRequest:
      type: object
      properties:
        emailAddress:
          type: string
          nullable: true
        phoneNumber:
          type: string
          nullable: true
      additionalProperties: false
    UpdateAccountRequest:
      type: object
      properties:
        name:
          type: string
          nullable: true
        streetAddress1:
          type: string
          nullable: true
        streetAddress2:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        stateOrProvince:
          type: string
          nullable: true
        postalCode:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
        phoneNumber:
          type: string
          nullable: true
        emailAddress:
          type: string
          nullable: true
        status:
          $ref: '#/components/schemas/AccountStatusEntity'
      additionalProperties: false
    UpdateMessageTemplateRequest:
      type: object
      properties:
        name:
          maxLength: 200
          type: string
          nullable: true
        channelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        bodyTemplate:
          maxLength: 2000
          type: string
          nullable: true
        defaultVariables:
          type: object
          additionalProperties:
            type: string
          nullable: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
        updateSubaccountScope:
          type: boolean
        isActive:
          type: boolean
          nullable: true
      additionalProperties: false
    UpdateQuotaRequest:
      type: object
      properties:
        dailyLimit:
          type: integer
          format: int32
          nullable: true
        monthlyLimit:
          type: integer
          format: int32
          nullable: true
        ratePerSecond:
          type: integer
          format: int32
          nullable: true
        ratePerMinute:
          type: integer
          format: int32
          nullable: true
      additionalProperties: false
    UpdateSubaccountRequest:
      type: object
      properties:
        name:
          type: string
          nullable: true
        slug:
          type: string
          nullable: true
        status:
          $ref: '#/components/schemas/SubaccountStatusEntity'
      additionalProperties: false
    UpdateTenDlcBrandIdentityRequest:
      type: object
      properties:
        legalName:
          type: string
          nullable: true
        ein:
          type: string
          nullable: true
        brandType:
          $ref: '#/components/schemas/TenDlcBrandTypeEntity'
      additionalProperties: false
    UpdateTenDlcBrandProfileRequest:
      type: object
      properties:
        phone:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        website:
          type: string
          nullable: true
        street:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        state:
          type: string
          nullable: true
        postalCode:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
        vertical:
          $ref: '#/components/schemas/TenDlcVerticalEntity'
        stockSymbol:
          type: string
          nullable: true
        stockExchange:
          type: string
          nullable: true
        altBusinessId:
          type: string
          nullable: true
        altBusinessIdType:
          type: string
          nullable: true
      additionalProperties: false
    UpdateUserProfileRequest:
      required:
        - emailAddress
        - firstName
        - lastName
      type: object
      properties:
        firstName:
          maxLength: 100
          minLength: 1
          type: string
        lastName:
          maxLength: 100
          minLength: 1
          type: string
        emailAddress:
          maxLength: 256
          minLength: 0
          type: string
          format: email
        phoneNumber:
          maxLength: 20
          minLength: 0
          type: string
          format: tel
          nullable: true
      additionalProperties: false
    UpdateWebhookEndpointRequest:
      type: object
      properties:
        url:
          type: string
          format: uri
          nullable: true
        label:
          maxLength: 200
          type: string
          nullable: true
        subscribedEvents:
          $ref: '#/components/schemas/WebhookEventTypeEntity'
        isActive:
          type: boolean
          nullable: true
      additionalProperties: false
    UpsertChannelRoutingPolicyRequest:
      type: object
      properties:
        preferredChannelType:
          $ref: '#/components/schemas/ChannelTypeEntity'
        fallbackChain:
          type: array
          items:
            $ref: '#/components/schemas/ChannelTypeEntity'
          nullable: true
        isEnabled:
          type: boolean
      additionalProperties: false
    UserBrandTcrStatus:
      title: UserBrandTcrStatus
      type: object
      properties:
        brandId:
          type: string
          description: ID of the brand.
          format: uuid
        tcrBrandId:
          type: string
          description: TCR Registry brand ID.
          nullable: true
        tcrStatus:
          type: string
          description: 'Brand status from TCR (Pending, Active, Rejected, etc.).'
          nullable: true
        tcrIdentityStatus:
          type: string
          description: Identity verification status.
          nullable: true
        tcrVettingScore:
          type: integer
          description: TCR vetting score (0-100).
          format: int32
          nullable: true
        tcrVettingClass:
          type: string
          description: TCR vetting class.
          nullable: true
        tcrFailureCode:
          type: string
          description: Failure code if status is Rejected.
          nullable: true
        tcrFailureReason:
          type: string
          description: Failure reason if status is Rejected.
          nullable: true
        tcrSubmittedAt:
          type: string
          description: UTC timestamp when brand was submitted to TCR.
          format: date-time
          nullable: true
        tcrLastSyncedAt:
          type: string
          description: UTC timestamp of last sync with TCR.
          format: date-time
          nullable: true
      additionalProperties: false
      description: TCR brand status DTO for user view.
    UserEntity:
      type: object
      properties:
        userId:
          type: string
          format: uuid
          readOnly: true
        accountId:
          type: string
          format: uuid
          nullable: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
        firstName:
          type: string
          nullable: true
        lastName:
          type: string
          nullable: true
        emailAddress:
          type: string
          nullable: true
        passwordHash:
          type: string
          nullable: true
        role:
          $ref: '#/components/schemas/UserRoleEntity'
        emailConfirmationToken:
          type: string
          nullable: true
          readOnly: true
        emailConfirmedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        isEmailConfirmed:
          type: boolean
          readOnly: true
        isActive:
          type: boolean
          readOnly: true
        isDeleted:
          type: boolean
          readOnly: true
        rowVersion:
          type: string
          format: byte
          nullable: true
          readOnly: true
        isAnonymized:
          type: boolean
          readOnly: true
        anonymizedAt:
          type: string
          format: date-time
          nullable: true
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        account:
          $ref: '#/components/schemas/AccountEntity'
        subaccount:
          $ref: '#/components/schemas/SubaccountEntity'
        ownedAccounts:
          type: array
          items:
            $ref: '#/components/schemas/AccountEntity'
          nullable: true
        refreshTokens:
          type: array
          items:
            $ref: '#/components/schemas/RefreshTokenEntity'
          nullable: true
        userLoginLogs:
          type: array
          items:
            $ref: '#/components/schemas/UserLoginLogEntity'
          nullable: true
      additionalProperties: false
      x-internal: true
    UserIdentitiesResponse:
      type: object
      properties:
        identities:
          type: array
          items:
            $ref: '#/components/schemas/ExternalIdentityResponse'
          description: The set of external identities associated with a user.
          nullable: true
      additionalProperties: false
      description: Response containing list of user's external identities.
    UserLoginHistory:
      type: object
      properties:
        userLoginLogId:
          type: integer
          format: int32
        userId:
          type: string
          format: uuid
        loggedInAt:
          type: string
          format: date-time
        wasSuccessful:
          type: boolean
        ipAddress:
          type: string
          nullable: true
        userAgent:
          type: string
          nullable: true
        failureReason:
          type: string
          nullable: true
      additionalProperties: false
    UserLoginHistoryPagedResponse:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/UserLoginHistory'
          nullable: true
        pageNumber:
          type: integer
          format: int32
        pageSize:
          type: integer
          format: int32
        totalCount:
          type: integer
          format: int32
        totalPages:
          type: integer
          format: int32
          readOnly: true
        hasNextPage:
          type: boolean
          readOnly: true
        hasPreviousPage:
          type: boolean
          readOnly: true
      additionalProperties: false
    UserLoginLogEntity:
      type: object
      properties:
        userLoginLogId:
          type: integer
          format: int32
          readOnly: true
        userId:
          type: string
          format: uuid
          readOnly: true
        refreshTokenId:
          type: string
          format: uuid
          nullable: true
          readOnly: true
        loggedInAt:
          type: string
          format: date-time
          readOnly: true
        wasSuccessful:
          type: boolean
          readOnly: true
        failureReason:
          type: string
          nullable: true
          readOnly: true
        ipAddress:
          type: string
          nullable: true
          readOnly: true
        userAgent:
          type: string
          nullable: true
          readOnly: true
        tokenVersion:
          type: integer
          format: int32
          nullable: true
          readOnly: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        user:
          $ref: '#/components/schemas/UserEntity'
        refreshToken:
          $ref: '#/components/schemas/RefreshTokenEntity'
      additionalProperties: false
      x-internal: true
    UserLoginRequest:
      required:
        - email
        - password
      type: object
      properties:
        email:
          minLength: 1
          type: string
          format: email
        password:
          maxLength: 256
          minLength: 6
          type: string
        captchaToken:
          type: string
          nullable: true
      additionalProperties: false
    UserLoginResult:
      type: object
      properties:
        success:
          type: boolean
        accessToken:
          type: string
          nullable: true
        refreshToken:
          type: string
          nullable: true
        userId:
          type: string
          format: uuid
          nullable: true
        firstName:
          type: string
          nullable: true
        lastName:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        role:
          type: string
          nullable: true
        accountId:
          type: string
          format: uuid
          nullable: true
        subaccountId:
          type: string
          format: uuid
          nullable: true
        errorCode:
          type: string
          nullable: true
        errorMessage:
          type: string
          nullable: true
        externalEmail:
          type: string
          nullable: true
        failedAttemptCount:
          type: integer
          format: int32
        maxFailedAttempts:
          type: integer
          format: int32
        remainingAttempts:
          type: integer
          format: int32
          readOnly: true
        isAccountLocked:
          type: boolean
        secondsUntilUnlock:
          type: number
          format: double
          nullable: true
        lockoutTimeMessage:
          type: string
          nullable: true
          readOnly: true
      additionalProperties: false
    UserNotificationPreferences:
      title: UserNotificationPreferences
      type: object
      properties:
        emailNotifications:
          type: boolean
        failedLoginAlerts:
          type: boolean
        billingThresholdAlerts:
          type: boolean
        webhookFailureAlerts:
          type: boolean
        quotaThresholdAlerts:
          type: boolean
        securityUpdates:
          type: boolean
      additionalProperties: false
      description: Public UserNotificationPreferences payload returned by the API.
    UserRoleEntity:
      enum:
        - Admin
        - Manager
        - Associate
      type: string
      x-internal: true
    VerifyMFAChallengeRequest:
      type: object
      properties:
        challengeId:
          type: string
          description: The unique challenge identifier.
          format: uuid
        code:
          type: string
          description: One-time code supplied by the user for verification.
          nullable: true
      additionalProperties: false
      description: Request to verify an MFA challenge.
    VerifyRequest:
      type: object
      properties:
        challengeId:
          type: string
          format: uuid
        code:
          type: string
          nullable: true
        action:
          $ref: '#/components/schemas/StepUpAction'
      additionalProperties: false
      description: Request to verify an email OTP challenge and optionally complete a step-up action.
    WebhookConfig:
      title: WebhookConfig
      type: object
      properties:
        webhookUrl:
          type: string
          description: The configured endpoint for incoming webhook delivery.
          nullable: true
        webhookSecret:
          type: string
          description: The current secret used to validate webhook payload signatures.
          nullable: true
        isEnabled:
          type: boolean
          description: Indicates whether the webhook delivery is enabled.
      additionalProperties: false
      description: Webhook configuration response
    WebhookDeliveryLog:
      title: WebhookDeliveryLog
      type: object
      properties:
        webhookDeliveryLogId:
          type: string
          format: uuid
        webhookEndpointId:
          type: string
          format: uuid
        eventType:
          $ref: '#/components/schemas/WebhookEventTypeEntity'
        httpStatusCode:
          type: integer
          format: int32
          nullable: true
        responseTimeMs:
          type: integer
          format: int64
          nullable: true
        attemptNumber:
          type: integer
          format: int32
        success:
          type: boolean
        errorMessage:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
      additionalProperties: false
      description: Public WebhookDeliveryLog payload returned by the API.
    WebhookEndpoint:
      title: WebhookEndpoint
      type: object
      properties:
        webhookEndpointId:
          type: string
          format: uuid
        accountId:
          type: string
          format: uuid
        subaccountId:
          type: string
          format: uuid
          nullable: true
        url:
          type: string
          nullable: true
        label:
          type: string
          nullable: true
        subscribedEvents:
          $ref: '#/components/schemas/WebhookEventTypeEntity'
        isActive:
          type: boolean
        isDeleted:
          type: boolean
        consecutiveFailures:
          type: integer
          format: int32
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
          nullable: true
        secret:
          type: string
          nullable: true
      additionalProperties: false
      description: Public WebhookEndpoint payload returned by the API.
    WebhookEventTypeEntity:
      enum:
        - None
        - MessageAccepted
        - MessageDelivered
        - MessageFailed
        - MessageRejected
        - MessageDeadLettered
        - AllMessageEvents
        - AccountUpdated
        - SubaccountUpdated
        - All
      type: string
      x-internal: true
    WebhookSecret:
      title: WebhookSecret
      type: object
      properties:
        webhookSecret:
          type: string
          description: Webhook signing secret used to verify incoming payloads.
          nullable: true
      additionalProperties: false
      description: Represents a generated webhook signing secret.
  securitySchemes:
    jwt:
      type: http
      description: JWT Authorization header using the Bearer scheme.
      scheme: bearer
      bearerFormat: JWT
    api-key:
      type: apiKey
      description: API Key authentication using the X-Api-Key header.
      name: X-Api-Key
      in: header
tags:
  - name: PublicOpenApi
    description: Serves the curated public OpenAPI contract without exposing Swagger UI or private documents.
  - name: Accounts
    description: Customer-facing CRUD endpoints for the authenticated user's accounts.
  - name: ApiKeys
    description: "Self-service API key management (JWT-authenticated).\r\nUsers can create, rotate, revoke, and delete their own API keys."
  - name: Auth
    description: 'Provides endpoints for user authentication including login, logout, and profile management.'
  - name: Billing
    description: "Self-service billing and subscription management (JWT-authenticated).\r\nUsers can view their subscription, change plans, and manage billing events."
  - name: ChannelConsent
    description: "Self-service opt-out management per channel.\r\nAllows authenticated users to opt out or back in to messaging for their subaccounts."
  - name: ChannelRouting
    description: "Self-service channel routing policy management for authenticated account users.\r\nAllows account admins to configure per-subaccount channel routing preferences and fallback chains."
  - name: UserEmailOtp
    description: "Step-up Email OTP endpoints for the currently authenticated user.\r\nIssue sends a one-time code to the user's email; Verify confirms it. The\r\ncaller is responsible for binding a successful verification to the actual\r\nsensitive action it is gating."
  - name: UserInvoices
    description: "Self-service invoice management (JWT-authenticated).\r\nUsers can view and download their own invoices."
  - name: LoginHistory
    description: "Provides endpoints for viewing login history and security statistics.\r\nAll endpoints require authentication and can only access the authenticated user's own data."
  - name: MessageCost
    description: "Self-service message cost reporting (JWT-authenticated).\r\nUsers can view their message cost summary, per-channel breakdown, and per-message detail."
  - name: MessageRisk
    description: "Risk transparency endpoint.\r\nReturns a customer-safe view of the latest risk decision for a message they own.\r\nReason codes are bucketed into human-readable explanations to avoid leaking internal signals."
  - name: Messages
    description: "Self-service message submission and lifecycle management (JWT-authenticated).\r\nUsers can submit messages, view their status, and advance them through the standard lifecycle."
  - name: MessageSegments
    description: Customer-facing endpoint for SMS segment calculation and cost preview.
  - name: NotificationPreferences
    description: ''
  - name: NumberPools
    description: "Self-service number pool management (JWT-authenticated).\r\nUsers can create, update, delete, and manage their own number pools."
  - name: OAuth2
    description: "API endpoints for OAuth2 external authentication.\r\nSupports provider authorization, callback handling, and identity management."
  - name: OAuth2MFA
    description: "API endpoints for OAuth2 Multi-Factor Authentication.\r\nManages MFA configuration, challenge initiation, and verification."
  - name: Onboarding
    description: "Self-service onboarding and email verification (JWT-authenticated).\r\nUsers can view their onboarding status and resend email verification links."
  - name: UserPaymentMethods
    description: User endpoint for managing payment methods
  - name: PaymentWebhooks
    description: "Self-service payment webhook management (JWT-authenticated).\r\nUsers can configure webhook URLs, enable/disable webhooks, and regenerate secrets."
  - name: PhoneNumbers
    description: "Self-service phone number management (JWT-authenticated).\r\nUsers can search, purchase, assign, and release phone numbers."
  - name: Plans
    description: "Self-service subscription plan management (anonymous).\r\nUsers can view available subscription plans without authentication."
  - name: UserPrivacy
    description: "Self-service privacy and data subject request management (JWT-authenticated).\r\nUsers can request data exports, account erasure, and manage consent preferences."
  - name: ProviderDiscovery
    description: "Self-service provider discovery and health monitoring (JWT-authenticated).\r\nUsers can discover providers by email domain and view provider health status."
  - name: Quota
    description: "Self-service quota management (JWT-authenticated).\r\nUsers can view and manage their own account and subaccount quota usage."
  - name: RealtimeMetrics
    description: "Self-service real-time metrics retrieval (JWT-authenticated).\r\nUsers can view current and historical metrics for their accounts and subaccounts."
  - name: Receipts
    description: "Self-service receipt management (JWT-authenticated).\r\nUsers can view and download receipts for their accounts."
  - name: Registration
    description: Self-service account registration and onboarding.
  - name: RiskSignals
    description: "Self-service risk signal retrieval (JWT-authenticated).\r\nUsers can view detailed and aggregated risk signals for their messages."
  - name: StripeConnect
    description: "Stripe Connect onboarding for Accounts to charge their Subaccounts\r\nStripe Connect - Platform Payments"
  - name: StripeConnectedWebhook
    description: "Receives webhook events from Stripe's connected-account event stream\r\n(events carry a top-level `account` field). Registered in Stripe\r\nDashboard with a SEPARATE signing secret distinct from the platform\r\nwebhook endpoint."
  - name: StripeWebhook
    description: "Receives webhook events from Stripe for payment lifecycle events.\r\nNo auth — verified via HMAC-SHA256 signature."
  - name: SubaccountCharges
    description: "Self-service subaccount charge management (JWT-authenticated).\r\nUsers can create manual charges and view payment history for their subaccounts."
  - name: SubaccountMessages
    description: Customer-facing endpoints for submitting and retrieving messages under a specific subaccount.
  - name: MeSubaccountPaymentMethods
    description: 'Payment method management for a subaccount, scoped to the parent account''s Stripe connected account.'
  - name: Subaccounts
    description: Customer-facing endpoints for managing subaccounts within an account.
  - name: SupportCases
    description: "Self-service support case management (JWT-authenticated).\r\nUsers can create, view, and manage support cases for their accounts."
  - name: TcrWebhook
    description: 'Initialises the controller with TCR webhook service, options, and logger.'
  - name: TemplatesAccount
    description: "Account-scoped template operations accessible via API key or user JWT.\r\nIntended for programmatic integrations (e.g. the simulator, customer code)."
  - name: TemplatesUser
    description: "Self-service message template management (JWT-authenticated).\r\nUsers can create, update, delete, and render message templates for their accounts and subaccounts"
  - name: TenDlc
    description: Self-service 10DLC registration and campaign management (JWT-authenticated).
  - name: Token
    description: "Self-service token management (JWT-authenticated).\r\nUsers can refresh access tokens, revoke refresh tokens, and manage active sessions for their accounts."
  - name: Webhooks
    description: "User self-service webhook management (JWT-authenticated).\r\nUsers can create, update, delete, test, and view delivery logs for their own webhooks."
  - name: CarrierWebhook
    description: "Self-service carrier webhook handling (anonymous).\r\nUsers can configure carrier webhooks to receive delivery events for their messages."
  - name: ProviderMessageWebhook
    description: Initialises the controller with a logger and webhook service.
  - name: WhatsAppWebhook
    description: "Receives and processes webhook events from Meta's WhatsApp Business Platform.\r\nHandles message delivery status callbacks and subscription verification.\r\n            \r\nWebhook flow:\r\n1. GET /v1/webhooks/whatsapp (Meta verification handshake)\r\n2. POST /v1/webhooks/whatsapp (delivery receipt events)"