openapi: 3.0.3
info:
  title: Abundera API
  version: 1.0.0
  description: 'Abundera AI wealth management platform API.


    ## Authentication


    Four authentication methods are supported:


    1. **Session cookie** (`abundera_session`) — Set after WebAuthn login. Used by the browser dashboard.

    2. **API key** (`Authorization: Bearer abnd_live_...`) — Created via Settings > API Keys. Requires Pro plan or higher.
    Scoped per-key with optional IP allowlist.

    3. **SSH public key** — Registered via Settings > SSH Keys. Supports ssh-rsa, ssh-ed25519, and ECDSA. Requires Pro plan
    or higher.

    4. **mTLS client certificate** — Uploaded via Settings > Certificates. PEM format, X.509 v3. Requires Pro plan or higher.


    ## Rate Limiting


    All endpoints are rate limited. Limits vary by endpoint category. Rate limit headers are returned on 429 responses:

    - `X-RateLimit-Limit` — Max requests per window

    - `X-RateLimit-Remaining` — Remaining requests

    - `Retry-After` — Seconds until window resets


    ## Base URL


    All API paths are prefixed with `/v1/`. Example: `GET https://abundera.ai/v1/auth/me`'
  contact:
    name: Abundera Engineering
    email: security@abundera.ai
    url: https://abundera.ai
  termsOfService: https://abundera.ai/terms.html
  license:
    name: Proprietary
    url: https://abundera.ai/terms.html
  x-logo:
    url: https://abundera.ai/img/logo.svg
    altText: Abundera logo
    backgroundColor: '#0f172a'
externalDocs:
  description: Abundera compliance & security documentation
  url: https://abundera.ai/compliance/
servers:
- url: https://abundera.ai/v1
  description: Production API (all endpoints via /v1 prefix)
tags:
- name: .well-known
- name: affiliate
- name: api
  description: Public API endpoints (waitlist signup, notifications)
- name: auth
  description: Authentication, registration, MFA, sessions, and account management
  externalDocs:
    description: Security architecture
    url: https://abundera.ai/security/
- name: billing
  description: 'Stripe billing: checkout, subscription status, portal, pause/resume, refunds'
  externalDocs:
    description: Pricing & plans
    url: https://abundera.ai/pricing/
- name: financial
  description: 'Financial data CRUD: income, properties, businesses, taxes, contributions, loans'
  externalDocs:
    description: Trust & compliance
    url: https://abundera.ai/trust/
- name: integrations
  description: 'Third-party integrations: Google, Microsoft, IMAP, calendar, email'
- name: leads
- name: mail
- name: me
- name: plaid
  description: 'Plaid integration: account linking, transactions, webhooks'
- name: products
- name: scim
- name: track
- name: videos
- name: webhooks
  description: User-managed outbound webhooks (CRUD)
x-tagGroups:
- name: Authentication & Account
  tags:
  - auth
- name: Wealth Data
  tags:
  - financial
  - plaid
- name: Admin & Platform
  tags:
  - billing
- name: Infrastructure
  tags:
  - api
  - integrations
  - webhooks
security:
- bearerAuth: []
- apiKeyAuth: []
paths:
  /.well-known/abundera-capabilities.json:
    get:
      summary: RFC 8615 well-known URI. Self-declares the scopes + webhook event
      tags:
      - .well-known
      responses:
        '200':
          description: Successful response
          headers: &id001
            X-Request-ID:
              description: Unique request ID for support reference
              schema:
                type: string
                example: req_a1b2c3d4e5
            X-API-Version:
              description: Current API version
              schema:
                type: string
                example: '1'
            X-Content-Type-Options:
              description: Prevents MIME type sniffing
              schema:
                type: string
                enum:
                - nosniff
            X-Frame-Options:
              description: Prevents clickjacking
              schema:
                type: string
                enum:
                - DENY
            Strict-Transport-Security:
              description: HSTS enforcement with preload
              schema:
                type: string
                example: max-age=31536000; includeSubDomains; preload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'GET /.well-known/abundera-capabilities.json  —  core (abundera.ai) catalog. RFC 8615 well-known URI. Self-declares
        the scopes + webhook event types for the "core" Abundera product. Aggregated by /v1/products


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_.well_known_abundera_capabilities.json
    options:
      tags:
      - .well-known
      summary: core (abundera.ai) catalog
      description: 'RFC 8615 well-known URI. Self-declares the scopes + webhook event

        types for the "core" Abundera product. Aggregated by /v1/products

        alongside each external product''s equivalent document so the

        federated /account/api-keys/ + /account/webhooks/ UIs have a single

        merged view.

        Schema shape + ETag + cache semantics match the pattern documented

        in ADR 077 (see also the sibling files in pro.qr.abundera.ai and

        sign.abundera.ai).'
      security:
      - bearerAuth: []
      responses:
        '200':
          description: OK
        '401':
          description: Authentication required
        '429':
          description: Rate limited
  /affiliate/accept-terms:
    post:
      summary: Create accept term
      tags:
      - affiliate
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /v1/affiliate/accept-terms — record acceptance of the affiliate program ToS. Required before activation.
        Stores an audit event with the terms version + IP hash + timestamp.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ftc_disclosure_acked:
                  description: Field read by the handler.
                version:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_affiliate_accept_terms
  /affiliate/apply:
    post:
      summary: Create apply (apply)
      tags:
      - affiliate
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /v1/affiliate/apply — creator self-serve application. Auth-gated. Idempotent on user_id (one affiliate
        per hub user). Status starts at pending_verification — Stripe Connect + tax form unlock active.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_affiliate_apply
  /affiliate/cohort-progress:
    get:
      summary: '@openapi /affiliate/cohort-progress: get:'
      tags:
      - affiliate
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /affiliate/cohort-progress: get:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_affiliate_cohort_progress
  /affiliate/commissions:
    get:
      summary: '@openapi /affiliate/commissions: get:'
      tags:
      - affiliate
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /affiliate/commissions: get:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_affiliate_commissions
  /affiliate/dashboard:
    get:
      summary: '@openapi /affiliate/dashboard: get:'
      tags:
      - affiliate
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /affiliate/dashboard: get:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_affiliate_dashboard
  /affiliate/links:
    get:
      summary: '@openapi /affiliate/links: get:'
      tags:
      - affiliate
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /affiliate/links: get:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_affiliate_links
    post:
      summary: '@openapi /affiliate/links: get:'
      tags:
      - affiliate
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /affiliate/links: get:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                landing_path:
                  description: Field read by the handler.
                slug:
                  description: Field read by the handler.
                target_property:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_affiliate_links
  /affiliate/onboard/dashboard-link:
    post:
      summary: Create dashboard link
      tags:
      - affiliate
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /v1/affiliate/onboard/dashboard-link — return a Stripe Express dashboard login link. Affiliate uses
        this to manage payout method, view transfers, and download tax forms.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_affiliate_onboard_dashboard_link
  /affiliate/onboard/stripe:
    get:
      summary: '@openapi /affiliate/onboard/stripe: post:'
      tags:
      - affiliate
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /affiliate/onboard/stripe: post:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_affiliate_onboard_stripe
    post:
      summary: '@openapi /affiliate/onboard/stripe: post:'
      tags:
      - affiliate
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /affiliate/onboard/stripe: post:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_affiliate_onboard_stripe
  /affiliate/sales-rep-apply:
    post:
      summary: Create sales rep apply
      tags:
      - affiliate
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /v1/affiliate/sales-rep-apply — apply as a sales rep. Creates an affiliate row with type=''sales_rep'',
        status=''pending_verification'' and rule_sales_rep_v1. Activation is gated on the user signing the Sales Rep


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_affiliate_sales_rep_apply
  /affiliate/tax-form:
    get:
      summary: '@openapi /affiliate/tax-form: post:'
      tags:
      - affiliate
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /affiliate/tax-form: post:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_affiliate_tax_form
    post:
      summary: '@openapi /affiliate/tax-form: post:'
      tags:
      - affiliate
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /affiliate/tax-form: post:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                form_type:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_affiliate_tax_form
  /affiliate/visit:
    post:
      summary: Create visit (visit)
      tags:
      - affiliate
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /v1/affiliate/visit — record an inbound referral visit. Public endpoint. Called by site/js/affiliate-track.js
        on every property. Body: { slug, landing_url }


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                landing_url:
                  description: Field read by the handler.
                slug:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_affiliate_visit
  /analysis/chat:
    post:
      summary: Create chat (chat)
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /v1/analysis/chat — RAG-based financial chat Question → financial context → LLM → response Supports
        optional conversationId for persistence + escalation detection


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                question:
                  type: string
                conversationId:
                  type: string
      operationId: post_analysis_chat
  /analysis/chat/conversations:
    get:
      summary: '@openapi /analysis/chat/conversations: get:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /analysis/chat/conversations: get:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_analysis_chat_conversations
    post:
      summary: '@openapi /analysis/chat/conversations: get:'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /analysis/chat/conversations: get:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_analysis_chat_conversations
  /analysis/chat/escalate:
    post:
      summary: Create escalate
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /v1/analysis/chat/escalate — request human support


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                conversationId:
                  type: string
                reason:
                  type: string
                  example: No longer needed
      operationId: post_analysis_chat_escalate
  /analysis/chat/ws-ticket:
    post:
      summary: Create ws ticket
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /v1/analysis/chat/ws-ticket — issue one-time JWT for WebSocket upgrade


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                conversationId:
                  type: string
      operationId: post_analysis_chat_ws_ticket
  /analysis/chat/{conversationId}/messages:
    get:
      summary: '@openapi /analysis/chat/{conversationId}/messages: get:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: '@openapi /analysis/chat/{conversationId}/messages: get:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      parameters:
      - name: conversationId
        in: path
        required: true
        schema:
          type: string
      operationId: get_analysis_chat_conversationId_messages
  /analysis/findings:
    get:
      summary: '@openapi /analysis/findings: get:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /analysis/findings: get:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_analysis_findings
    post:
      summary: '@openapi /analysis/findings: get:'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '@openapi /analysis/findings: get:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                findingId:
                  type: string
                action:
                  type: string
                  enum:
                  - dismiss
                  - snooze
                  - reopen
                  example: dismiss
                snoozeDays:
                  type: string
      operationId: post_analysis_findings
  /analysis/run:
    post:
      summary: Create run (run)
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /v1/analysis/run — On-demand analysis engine execution


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                categories:
                  description: Field read by the handler.
                engineIds:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_analysis_run
  /api/client-error:
    post:
      summary: Create client error
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '405':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/client-error Receiver for browser-side error reports and form telemetry events. Used by site/js/lib/error-reporter.js
        (uncaught exceptions) and


        **Rate limit:** 30 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                kind:
                  description: Field read by the handler.
                message:
                  description: Field read by the handler.
                page:
                  description: Field read by the handler.
                source:
                  description: Field read by the handler.
                stack:
                  description: Field read by the handler.
                userAgent:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_api_client_error
  /api/compliance-status:
    get:
      summary: Retrieve compliance statu
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  checks:
                    type: string
                  failing:
                    type: string
                  generated_at:
                    type: string
                    format: date-time
                  level:
                    type: string
                  message:
                    type: string
                  passing:
                    type: string
                  total:
                    type: number
                  warnings:
                    type: string
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/compliance-status — Public endpoint returning live compliance check results No auth required.
        Returns cached results from shard-provisioner hourly checks. KV key: "compliance:latest" (set by runComplianceChecks
        in shard-provisioner)


        **Rate limit:** 30 per minute'
      security: []
      operationId: get_api_compliance_status
  /api/contact:
    post:
      summary: 'Cloudflare Pages Function: Contact Form Abundera.ai Receives contact form submissions, verifies Turn'
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'Cloudflare Pages Function: Contact Form Abundera.ai Receives contact form submissions, verifies Turnstile,
        sends email notification.


        **Turnstile verification** required


        **Rate limit:** 30 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_api_contact
  /api/documents:
    get:
      summary: 'CRUD /api/documents — User document uploads GET: list documents, POST: upload a document Files store'
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/documents — User document uploads GET: list documents, POST: upload a document Files stored
        in R2 (DOCUMENTS_BUCKET), metadata in D1 (user_documents)


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_documents
    post:
      summary: 'CRUD /api/documents — User document uploads GET: list documents, POST: upload a document Files store'
      tags:
      - api
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/documents — User document uploads GET: list documents, POST: upload a document Files stored
        in R2 (DOCUMENTS_BUCKET), metadata in D1 (user_documents)


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_api_documents
  /api/documents/{id}:
    delete:
      summary: Delete document
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 30 per minute
      description: 'GET /api/documents/:id — Download/view a document DELETE /api/documents/:id — Delete a document


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Re-authentication required** for write operations


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      parameters:
      - &id002
        name: id
        in: path
        required: true
        schema:
          type: string
      operationId: delete_api_documents_id
    get:
      summary: Retrieve document
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  docId:
                    type: string
                  level:
                    type: string
                  type:
                    type: string
                  uploadDate:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 30 per minute
      description: 'GET /api/documents/:id — Download/view a document DELETE /api/documents/:id — Delete a document


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Re-authentication required** for write operations


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      parameters:
      - *id002
      operationId: get_api_documents_id
  /api/errors:
    post:
      summary: Create error (errors)
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/errors — Client-side error reporting (no auth required) Logs frontend errors to LOGS_DB for
        monitoring


        **Rate limit:** 30 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                message:
                  type: string
                source:
                  type: string
                lineno:
                  type: string
                colno:
                  type: string
                stack:
                  type: string
                page:
                  type: integer
                  example: 1
                userAgent:
                  type: string
      operationId: post_api_errors
  /api/financial/accounts:
    get:
      summary: Fetch accounts from Plaid, with Capital One balance fallback
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  accounts:
                    type: string
                  cached:
                    type: string
                  connections:
                    type: array
                    items:
                      type: object
                  created_at:
                    type: string
                    format: date-time
                  id:
                    type: string
                    format: uuid
                  institution_id:
                    type: string
                    format: uuid
                  institution_name:
                    type: string
                  last_synced_at:
                    type: string
                    format: date-time
                  level:
                    type: string
                  link_type:
                    type: string
                  message:
                    type: string
                  products:
                    type: string
                  success:
                    type: boolean
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/financial/accounts — Fetch all linked accounts for the authenticated user PUT /api/financial/accounts
        — Save account nickname Decrypts tokens, calls Plaid /accounts/get for each connection


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_accounts
    put:
      summary: Fetch accounts from Plaid, with Capital One balance fallback
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/financial/accounts — Fetch all linked accounts for the authenticated user PUT /api/financial/accounts
        — Save account nickname Decrypts tokens, calls Plaid /accounts/get for each connection


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                accountId:
                  type: string
                nickname:
                  type: string
      operationId: put_api_financial_accounts
  /api/financial/affiliations:
    delete:
      summary: 'CRUD /api/financial/affiliations — Memberships and affiliations GET: list all, POST: create, PUT: up'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/affiliations — Memberships and affiliations GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_affiliations
    get:
      summary: 'CRUD /api/financial/affiliations — Memberships and affiliations GET: list all, POST: create, PUT: up'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  affiliations:
                    type: array
                    items:
                      $ref: '#/components/schemas/Affiliations'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/affiliations — Memberships and affiliations GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_affiliations
    post:
      summary: 'CRUD /api/financial/affiliations — Memberships and affiliations GET: list all, POST: create, PUT: up'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/affiliations — Memberships and affiliations GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                type:
                  type: string
                  enum: &id003
                  - professional
                  - social
                  - religious
                  - alumni
                  - charitable
                  - political
                  - fraternal
                  - military
                  - veteran
                  - first_responder
                  - union
                  - government
                  - license
                  - other
                  example: professional
                role:
                  type: string
                  example: member
                membership_number:
                  type: string
                  example: MEM-12345
                join_date:
                  type: string
                  format: date
                annual_dues:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 250
                status:
                  type: string
                  enum: &id004
                  - active
                  - retired
                  - veteran
                  - honorable_discharge
                  - reserve
                  example: active
                service_branch:
                  type: string
                  enum: &id005
                  - army
                  - navy
                  - air_force
                  - marines
                  - coast_guard
                  - space_force
                  - national_guard
                  example: army
                rank:
                  type: string
                service_start:
                  type: string
                  format: date
                service_end:
                  type: string
                  format: date
                benefits:
                  type: array
                  items:
                    type: string
                id_number:
                  type: string
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - type
      operationId: post_api_financial_affiliations
    put:
      summary: 'CRUD /api/financial/affiliations — Memberships and affiliations GET: list all, POST: create, PUT: up'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/affiliations — Memberships and affiliations GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                type:
                  type: string
                  enum: *id003
                  example: professional
                role:
                  type: string
                  example: member
                membership_number:
                  type: string
                  example: MEM-12345
                join_date:
                  type: string
                  format: date
                annual_dues:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 250
                status:
                  type: string
                  enum: *id004
                  example: active
                service_branch:
                  type: string
                  enum: *id005
                  example: army
                rank:
                  type: string
                service_start:
                  type: string
                  format: date
                service_end:
                  type: string
                  format: date
                benefits:
                  type: array
                  items:
                    type: string
                id_number:
                  type: string
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - type
      operationId: put_api_financial_affiliations
  /api/financial/alert-preferences:
    delete:
      summary: 'CRUD /api/financial/alert-preferences — Engine alert & notification preferences GET: list all, POST:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/alert-preferences — Engine alert & notification preferences GET: list all, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_alert_preferences
    get:
      summary: 'CRUD /api/financial/alert-preferences — Engine alert & notification preferences GET: list all, POST:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  alert_preferences:
                    type: array
                    items:
                      $ref: '#/components/schemas/AlertPreferences'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/alert-preferences — Engine alert & notification preferences GET: list all, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_alert_preferences
    post:
      summary: 'CRUD /api/financial/alert-preferences — Engine alert & notification preferences GET: list all, POST:'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/alert-preferences — Engine alert & notification preferences GET: list all, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                engine_id:
                  type: string
                  maxLength: 100
                category:
                  type: string
                  maxLength: 100
                  example: income
                channel:
                  type: string
                  enum: &id006
                  - in_app
                  - email
                  - sms
                  - push
                  - webhook
                  maxLength: 50
                  example: in_app
                frequency:
                  type: string
                  enum: &id007
                  - realtime
                  - daily
                  - weekly
                  - monthly
                  - never
                  maxLength: 50
                  example: realtime
                threshold_amount:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                is_enabled:
                  type: string
                details:
                  type: object
              required:
              - category
      operationId: post_api_financial_alert_preferences
    put:
      summary: 'CRUD /api/financial/alert-preferences — Engine alert & notification preferences GET: list all, POST:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/alert-preferences — Engine alert & notification preferences GET: list all, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                engine_id:
                  type: string
                  maxLength: 100
                category:
                  type: string
                  maxLength: 100
                  example: income
                channel:
                  type: string
                  enum: *id006
                  maxLength: 50
                  example: in_app
                frequency:
                  type: string
                  enum: *id007
                  maxLength: 50
                  example: realtime
                threshold_amount:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                is_enabled:
                  type: string
                details:
                  type: object
              required:
              - category
      operationId: put_api_financial_alert_preferences
  /api/financial/assets:
    delete:
      summary: 'CRUD /api/financial/assets — Unified asset management GET: list (optional ?category=, ?parent_id=), '
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/assets — Unified asset management GET: list (optional ?category=, ?parent_id=), POST:
        create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_assets
    get:
      summary: 'CRUD /api/financial/assets — Unified asset management GET: list (optional ?category=, ?parent_id=), '
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  assets:
                    type: array
                    items:
                      $ref: '#/components/schemas/Assets'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/assets — Unified asset management GET: list (optional ?category=, ?parent_id=), POST:
        create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_assets
    post:
      summary: 'CRUD /api/financial/assets — Unified asset management GET: list (optional ?category=, ?parent_id=), '
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/assets — Unified asset management GET: list (optional ?category=, ?parent_id=), POST:
        create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                parent_id:
                  type: string
                  format: uuid
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                category:
                  type: string
                  enum: &id008
                  - real_estate
                  - financial
                  - holding
                  - vehicle
                  - boat
                  - collectible
                  - equipment
                  - crypto
                  - other
                  example: real_estate
                type:
                  type: string
                  maxLength: 50
                  example: checking
                purchase_price:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 250000
                current_value:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 350000
                purchase_date:
                  type: string
                  format: date
                ownership:
                  type: string
                  example: owned
                location:
                  type: string
                  maxLength: 500
                  example: Las Vegas, NV
                identifier_label:
                  type: string
                identifier_value:
                  type: string
                details:
                  type: object
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - category
              - type
      operationId: post_api_financial_assets
    put:
      summary: 'CRUD /api/financial/assets — Unified asset management GET: list (optional ?category=, ?parent_id=), '
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/assets — Unified asset management GET: list (optional ?category=, ?parent_id=), POST:
        create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                parent_id:
                  type: string
                  format: uuid
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                category:
                  type: string
                  enum: *id008
                  example: real_estate
                type:
                  type: string
                  maxLength: 50
                  example: checking
                purchase_price:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 250000
                current_value:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 350000
                purchase_date:
                  type: string
                  format: date
                ownership:
                  type: string
                  example: owned
                location:
                  type: string
                  maxLength: 500
                  example: Las Vegas, NV
                identifier_label:
                  type: string
                identifier_value:
                  type: string
                details:
                  type: object
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - category
              - type
      operationId: put_api_financial_assets
  /api/financial/beneficiaries:
    delete:
      summary: 'CRUD /api/financial/beneficiaries — Beneficiary designations GET: list, POST: create, PUT: update, D'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/beneficiaries — Beneficiary designations GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_beneficiaries
    get:
      summary: 'CRUD /api/financial/beneficiaries — Beneficiary designations GET: list, POST: create, PUT: update, D'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  beneficiary_designations:
                    type: array
                    items:
                      $ref: '#/components/schemas/BeneficiaryDesignations'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/beneficiaries — Beneficiary designations GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_beneficiaries
    post:
      summary: 'CRUD /api/financial/beneficiaries — Beneficiary designations GET: list, POST: create, PUT: update, D'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/beneficiaries — Beneficiary designations GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                asset_type:
                  type: string
                  enum: &id009
                  - life_insurance
                  - retirement_401k
                  - retirement_ira
                  - bank_account
                  - brokerage
                  - annuity
                  - trust
                  - real_estate
                  example: life_insurance
                asset_id:
                  type: string
                  format: uuid
                asset_description:
                  type: string
                  maxLength: 500
                  example: Fidelity 401k
                beneficiary_type:
                  type: string
                  enum: &id010
                  - primary
                  - contingent
                  example: primary
                beneficiary_family_member_id:
                  type: string
                  format: uuid
                beneficiary_entity_id:
                  type: string
                  format: uuid
                beneficiary_name:
                  type: string
                  maxLength: 200
                  example: Jane Smith
                percentage:
                  type: number
                  minimum: 0
                  maximum: 100
                  example: 100
                last_verified_date:
                  type: string
                  format: date
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - asset_type
              - beneficiary_type
      operationId: post_api_financial_beneficiaries
    put:
      summary: 'CRUD /api/financial/beneficiaries — Beneficiary designations GET: list, POST: create, PUT: update, D'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/beneficiaries — Beneficiary designations GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                asset_type:
                  type: string
                  enum: *id009
                  example: life_insurance
                asset_id:
                  type: string
                  format: uuid
                asset_description:
                  type: string
                  maxLength: 500
                  example: Fidelity 401k
                beneficiary_type:
                  type: string
                  enum: *id010
                  example: primary
                beneficiary_family_member_id:
                  type: string
                  format: uuid
                beneficiary_entity_id:
                  type: string
                  format: uuid
                beneficiary_name:
                  type: string
                  maxLength: 200
                  example: Jane Smith
                percentage:
                  type: number
                  minimum: 0
                  maximum: 100
                  example: 100
                last_verified_date:
                  type: string
                  format: date
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - asset_type
              - beneficiary_type
      operationId: put_api_financial_beneficiaries
  /api/financial/budget:
    delete:
      summary: 'CRUD /api/financial/budget — Budget category management GET: list all, POST: create, PUT: update, DE'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/budget — Budget category management GET: list all, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_budget
    get:
      summary: 'CRUD /api/financial/budget — Budget category management GET: list all, POST: create, PUT: update, DE'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  budget_categories:
                    type: array
                    items:
                      $ref: '#/components/schemas/BudgetCategories'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/budget — Budget category management GET: list all, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_budget
    post:
      summary: 'CRUD /api/financial/budget — Budget category management GET: list all, POST: create, PUT: update, DE'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/budget — Budget category management GET: list all, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 100
                  example: John Smith
                type:
                  type: string
                  enum: &id011
                  - needs
                  - wants
                  - savings
                  example: needs
                monthly_limit:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                color:
                  type: string
                  maxLength: 9
                notes:
                  type: string
                  maxLength: 500
                  example: Important details
              required:
              - name
              - type
              - monthly_limit
      operationId: post_api_financial_budget
    put:
      summary: 'CRUD /api/financial/budget — Budget category management GET: list all, POST: create, PUT: update, DE'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/budget — Budget category management GET: list all, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 100
                  example: John Smith
                type:
                  type: string
                  enum: *id011
                  example: needs
                monthly_limit:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                color:
                  type: string
                  maxLength: 9
                notes:
                  type: string
                  maxLength: 500
                  example: Important details
              required:
              - name
              - type
              - monthly_limit
      operationId: put_api_financial_budget
  /api/financial/cash-flows:
    delete:
      summary: 'CRUD /api/financial/cash-flows — Unified income & expense tracking GET: list (optional ?direction=in'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/cash-flows — Unified income & expense tracking GET: list (optional ?direction=inflow|outflow),
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_cash_flows
    get:
      summary: 'CRUD /api/financial/cash-flows — Unified income & expense tracking GET: list (optional ?direction=in'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  cash_flows:
                    type: array
                    items:
                      $ref: '#/components/schemas/CashFlows'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/cash-flows — Unified income & expense tracking GET: list (optional ?direction=inflow|outflow),
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_cash_flows
    post:
      summary: 'CRUD /api/financial/cash-flows — Unified income & expense tracking GET: list (optional ?direction=in'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/cash-flows — Unified income & expense tracking GET: list (optional ?direction=inflow|outflow),
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                direction:
                  type: string
                  enum: &id012
                  - inflow
                  - outflow
                  example: inflow
                type:
                  type: string
                  maxLength: 50
                  example: checking
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 50000
                frequency:
                  type: string
                  enum: &id013
                  - weekly
                  - biweekly
                  - monthly
                  - quarterly
                  - semi-annually
                  - annually
                  - one_time
                  - one-time
                  example: weekly
                linked_entity_id:
                  type: string
                  format: uuid
                linked_asset_id:
                  type: string
                  format: uuid
                family_member_id:
                  type: string
                  format: uuid
                  maxLength: 36
                category:
                  type: string
                  example: income
                details:
                  type: object
                start_date:
                  type: string
                  format: date
                  example: '2026-01-01'
                end_date:
                  type: string
                  format: date
                  example: '2026-12-31'
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
                is_active:
                  type: string
              required:
              - name
              - direction
              - type
              - amount
              - frequency
      operationId: post_api_financial_cash_flows
    put:
      summary: 'CRUD /api/financial/cash-flows — Unified income & expense tracking GET: list (optional ?direction=in'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/cash-flows — Unified income & expense tracking GET: list (optional ?direction=inflow|outflow),
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                direction:
                  type: string
                  enum: *id012
                  example: inflow
                type:
                  type: string
                  maxLength: 50
                  example: checking
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 50000
                frequency:
                  type: string
                  enum: *id013
                  example: weekly
                linked_entity_id:
                  type: string
                  format: uuid
                linked_asset_id:
                  type: string
                  format: uuid
                family_member_id:
                  type: string
                  format: uuid
                  maxLength: 36
                category:
                  type: string
                  example: income
                details:
                  type: object
                start_date:
                  type: string
                  format: date
                  example: '2026-01-01'
                end_date:
                  type: string
                  format: date
                  example: '2026-12-31'
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
                is_active:
                  type: string
              required:
              - name
              - direction
              - type
              - amount
              - frequency
      operationId: put_api_financial_cash_flows
  /api/financial/contacts:
    delete:
      summary: 'CRUD /api/financial/contacts — Personal contact network GET: list all (with optional ?category= filt'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/contacts — Personal contact network GET: list all (with optional ?category= filter),
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_contacts
    get:
      summary: 'CRUD /api/financial/contacts — Personal contact network GET: list all (with optional ?category= filt'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  contacts:
                    type: array
                    items:
                      $ref: '#/components/schemas/ContactsNetwork'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/contacts — Personal contact network GET: list all (with optional ?category= filter),
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_contacts
    post:
      summary: 'CRUD /api/financial/contacts — Personal contact network GET: list all (with optional ?category= filt'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/contacts — Personal contact network GET: list all (with optional ?category= filter),
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                full_name:
                  type: string
                  maxLength: 200
                  example: John Smith
                relationship:
                  type: string
                  maxLength: 50
                  example: spouse
                category:
                  type: string
                  enum: &id014
                  - family
                  - professional
                  - service_provider
                  - emergency
                  example: family
                email:
                  type: string
                  example: user@example.com
                phone:
                  type: string
                  example: '+15551234567'
                company:
                  type: string
                  example: Acme Corp
                title:
                  type: string
                  example: Software Engineer
                is_emergency_contact:
                  type: boolean
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - full_name
              - relationship
              - category
      operationId: post_api_financial_contacts
    put:
      summary: 'CRUD /api/financial/contacts — Personal contact network GET: list all (with optional ?category= filt'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/contacts — Personal contact network GET: list all (with optional ?category= filter),
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                full_name:
                  type: string
                  maxLength: 200
                  example: John Smith
                relationship:
                  type: string
                  maxLength: 50
                  example: spouse
                category:
                  type: string
                  enum: *id014
                  example: family
                email:
                  type: string
                  example: user@example.com
                phone:
                  type: string
                  example: '+15551234567'
                company:
                  type: string
                  example: Acme Corp
                title:
                  type: string
                  example: Software Engineer
                is_emergency_contact:
                  type: boolean
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - full_name
              - relationship
              - category
      operationId: put_api_financial_contacts
  /api/financial/credit-scores:
    delete:
      summary: 'CRUD /api/financial/credit-scores — Credit score tracking GET: list, POST: create, PUT: update, DELE'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/credit-scores — Credit score tracking GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_credit_scores
    get:
      summary: 'CRUD /api/financial/credit-scores — Credit score tracking GET: list, POST: create, PUT: update, DELE'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  credit_scores:
                    type: array
                    items:
                      $ref: '#/components/schemas/CreditScores'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/credit-scores — Credit score tracking GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_credit_scores
    post:
      summary: 'CRUD /api/financial/credit-scores — Credit score tracking GET: list, POST: create, PUT: update, DELE'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/credit-scores — Credit score tracking GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                bureau:
                  type: string
                  enum: &id015
                  - equifax
                  - experian
                  - transunion
                  example: equifax
                score:
                  type: string
                score_type:
                  type: string
                  enum: &id016
                  - fico
                  - vantage
                  - vantagescore
                  example: fico
                report_date:
                  type: string
                factors:
                  type: string
                credit_utilization:
                  type: string
                  minimum: 0
                  maximum: 100
                total_accounts:
                  type: string
                  minimum: 0
                  maximum: 999
                derogatory_marks:
                  type: string
                  minimum: 0
                  maximum: 999
                hard_inquiries:
                  type: string
                  minimum: 0
                  maximum: 999
                oldest_account_years:
                  type: string
                  minimum: 0
                  maximum: 100
                source:
                  type: string
                  enum: &id017
                  - manual
                  - plaid
                  - experian_api
                  example: manual
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - bureau
              - score
              - report_date
      operationId: post_api_financial_credit_scores
    put:
      summary: 'CRUD /api/financial/credit-scores — Credit score tracking GET: list, POST: create, PUT: update, DELE'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/credit-scores — Credit score tracking GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                bureau:
                  type: string
                  enum: *id015
                  example: equifax
                score:
                  type: string
                score_type:
                  type: string
                  enum: *id016
                  example: fico
                report_date:
                  type: string
                factors:
                  type: string
                credit_utilization:
                  type: string
                  minimum: 0
                  maximum: 100
                total_accounts:
                  type: string
                  minimum: 0
                  maximum: 999
                derogatory_marks:
                  type: string
                  minimum: 0
                  maximum: 999
                hard_inquiries:
                  type: string
                  minimum: 0
                  maximum: 999
                oldest_account_years:
                  type: string
                  minimum: 0
                  maximum: 100
                source:
                  type: string
                  enum: *id017
                  example: manual
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - bureau
              - score
              - report_date
      operationId: put_api_financial_credit_scores
  /api/financial/donations:
    delete:
      summary: 'CRUD /api/financial/donations — Charitable donation tracking GET: list all, POST: create, PUT: updat'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/donations — Charitable donation tracking GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_donations
    get:
      summary: 'CRUD /api/financial/donations — Charitable donation tracking GET: list all, POST: create, PUT: updat'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  charitable_donations:
                    type: array
                    items:
                      $ref: '#/components/schemas/CharitableDonations'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/donations — Charitable donation tracking GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_donations
    post:
      summary: 'CRUD /api/financial/donations — Charitable donation tracking GET: list all, POST: create, PUT: updat'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/donations — Charitable donation tracking GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                organization:
                  type: string
                  maxLength: 200
                ein:
                  type: string
                  maxLength: 20
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 50000
                donation_date:
                  type: string
                type:
                  type: string
                  enum: &id018
                  - cash
                  - securities
                  - property
                  - goods
                  - services
                  - mileage
                  example: cash
                tax_deductible:
                  type: string
                receipt_uploaded:
                  type: string
                category:
                  type: string
                  maxLength: 100
                  example: income
                acknowledgment:
                  type: string
                  maxLength: 500
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - organization
              - amount
              - donation_date
      operationId: post_api_financial_donations
    put:
      summary: 'CRUD /api/financial/donations — Charitable donation tracking GET: list all, POST: create, PUT: updat'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/donations — Charitable donation tracking GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                organization:
                  type: string
                  maxLength: 200
                ein:
                  type: string
                  maxLength: 20
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 50000
                donation_date:
                  type: string
                type:
                  type: string
                  enum: *id018
                  example: cash
                tax_deductible:
                  type: string
                receipt_uploaded:
                  type: string
                category:
                  type: string
                  maxLength: 100
                  example: income
                acknowledgment:
                  type: string
                  maxLength: 500
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - organization
              - amount
              - donation_date
      operationId: put_api_financial_donations
  /api/financial/entities:
    delete:
      summary: 'CRUD /api/financial/entities — Businesses, trusts, LLCs, partnerships GET: list all with cash flow s'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/entities — Businesses, trusts, LLCs, partnerships GET: list all with cash flow summaries,
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_entities
    get:
      summary: 'CRUD /api/financial/entities — Businesses, trusts, LLCs, partnerships GET: list all with cash flow s'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  entities:
                    type: array
                    items:
                      $ref: '#/components/schemas/Entities'
                  expenses:
                    type: object
                  loan_balance:
                    type: string
                  loans:
                    type: string
                  monthly_expenses:
                    type: string
                  monthly_net:
                    type: string
                  monthly_revenue:
                    type: string
                  revenue:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/entities — Businesses, trusts, LLCs, partnerships GET: list all with cash flow summaries,
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_entities
    post:
      summary: 'CRUD /api/financial/entities — Businesses, trusts, LLCs, partnerships GET: list all with cash flow s'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/entities — Businesses, trusts, LLCs, partnerships GET: list all with cash flow summaries,
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                type:
                  type: string
                  enum: &id019
                  - business
                  - trust
                  - llc
                  - s-corp
                  - c-corp
                  - sole proprietorship
                  - partnership
                  - foundation
                  - estate
                  - corporation
                  - nonprofit
                  - other
                  example: business
                entity_number:
                  type: string
                  example: 88-1234567
                state:
                  type: string
                  example: NV
                formation_date:
                  type: string
                  format: date
                  example: '2020-03-15'
                purpose:
                  type: string
                  example: Investment holding company
                estimated_value:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 500000
                details:
                  type: object
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - type
      operationId: post_api_financial_entities
    put:
      summary: 'CRUD /api/financial/entities — Businesses, trusts, LLCs, partnerships GET: list all with cash flow s'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/entities — Businesses, trusts, LLCs, partnerships GET: list all with cash flow summaries,
        POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                type:
                  type: string
                  enum: *id019
                  example: business
                entity_number:
                  type: string
                  example: 88-1234567
                state:
                  type: string
                  example: NV
                formation_date:
                  type: string
                  format: date
                  example: '2020-03-15'
                purpose:
                  type: string
                  example: Investment holding company
                estimated_value:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 500000
                details:
                  type: object
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - type
      operationId: put_api_financial_entities
  /api/financial/estate:
    delete:
      summary: 'CRUD /api/financial/estate — Estate documents tracking GET: list, POST: create, PUT: update, DELETE:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/estate — Estate documents tracking GET: list, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_estate
    get:
      summary: 'CRUD /api/financial/estate — Estate documents tracking GET: list, POST: create, PUT: update, DELETE:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  estate_documents:
                    type: array
                    items:
                      $ref: '#/components/schemas/EstateDocuments'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/estate — Estate documents tracking GET: list, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_estate
    post:
      summary: 'CRUD /api/financial/estate — Estate documents tracking GET: list, POST: create, PUT: update, DELETE:'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/estate — Estate documents tracking GET: list, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                  enum: &id020
                  - will
                  - living_trust
                  - revocable_trust
                  - irrevocable_trust
                  - poa_financial
                  - poa_healthcare
                  - healthcare_directive
                  - beneficiary_designation
                  - prenup
                  - postnup
                  - deed
                  example: will
                title:
                  type: string
                  maxLength: 200
                  example: Software Engineer
                status:
                  type: string
                  enum: &id021
                  - active
                  - draft
                  - expired
                  - superseded
                  example: active
                effective_date:
                  type: string
                  format: date
                expiration_date:
                  type: string
                  format: date
                attorney_contact_id:
                  type: string
                  format: uuid
                executor_family_member_id:
                  type: string
                  format: uuid
                trustee_family_member_id:
                  type: string
                  format: uuid
                agent_family_member_id:
                  type: string
                  format: uuid
                document_id:
                  type: string
                  format: uuid
                review_date:
                  type: string
                  format: date
                state:
                  type: string
                  example: NV
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - type
              - title
      operationId: post_api_financial_estate
    put:
      summary: 'CRUD /api/financial/estate — Estate documents tracking GET: list, POST: create, PUT: update, DELETE:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/estate — Estate documents tracking GET: list, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                  enum: *id020
                  example: will
                title:
                  type: string
                  maxLength: 200
                  example: Software Engineer
                status:
                  type: string
                  enum: *id021
                  example: active
                effective_date:
                  type: string
                  format: date
                expiration_date:
                  type: string
                  format: date
                attorney_contact_id:
                  type: string
                  format: uuid
                executor_family_member_id:
                  type: string
                  format: uuid
                trustee_family_member_id:
                  type: string
                  format: uuid
                agent_family_member_id:
                  type: string
                  format: uuid
                document_id:
                  type: string
                  format: uuid
                review_date:
                  type: string
                  format: date
                state:
                  type: string
                  example: NV
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - type
              - title
      operationId: put_api_financial_estate
  /api/financial/family:
    delete:
      summary: 'CRUD /api/financial/family — Family & household members GET: list, POST: create, PUT: update, DELETE'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/family — Family & household members GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_family
    get:
      summary: 'CRUD /api/financial/family — Family & household members GET: list, POST: create, PUT: update, DELETE'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  family_members:
                    type: array
                    items:
                      $ref: '#/components/schemas/FamilyMembers'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/family — Family & household members GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_family
    post:
      summary: 'CRUD /api/financial/family — Family & household members GET: list, POST: create, PUT: update, DELETE'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/family — Family & household members GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                full_name:
                  type: string
                  maxLength: 200
                  example: John Smith
                relationship:
                  type: string
                  enum: &id022
                  - spouse
                  - child
                  - parent
                  - sibling
                  - grandchild
                  - grandparent
                  - dependent
                  - ex_spouse
                  - partner
                  example: spouse
                date_of_birth:
                  type: string
                  example: '1990-05-20'
                is_dependent:
                  type: boolean
                is_minor:
                  type: boolean
                is_beneficiary:
                  type: boolean
                guardian_id:
                  type: string
                  format: uuid
                ssn_last_four:
                  type: string
                  example: '1234'
                employment_status:
                  type: string
                  enum: &id023
                  - employed
                  - self_employed
                  - unemployed
                  - retired
                  - student
                  - minor
                  example: employed
                annual_income:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 85000
                health_coverage:
                  type: string
                  enum: &id024
                  - employer
                  - marketplace
                  - medicare
                  - medicaid
                  - tricare
                  - cobra
                  - uninsured
                  example: employer
                education_status:
                  type: string
                  enum: &id025
                  - preschool
                  - k12
                  - undergraduate
                  - graduate
                  - vocational
                  - none
                  example: preschool
                education_target_year:
                  type: integer
                education_est_cost:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 50000
                special_needs:
                  type: boolean
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - full_name
              - relationship
      operationId: post_api_financial_family
    put:
      summary: 'CRUD /api/financial/family — Family & household members GET: list, POST: create, PUT: update, DELETE'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/family — Family & household members GET: list, POST: create, PUT: update, DELETE:
        remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                full_name:
                  type: string
                  maxLength: 200
                  example: John Smith
                relationship:
                  type: string
                  enum: *id022
                  example: spouse
                date_of_birth:
                  type: string
                  example: '1990-05-20'
                is_dependent:
                  type: boolean
                is_minor:
                  type: boolean
                is_beneficiary:
                  type: boolean
                guardian_id:
                  type: string
                  format: uuid
                ssn_last_four:
                  type: string
                  example: '1234'
                employment_status:
                  type: string
                  enum: *id023
                  example: employed
                annual_income:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 85000
                health_coverage:
                  type: string
                  enum: *id024
                  example: employer
                education_status:
                  type: string
                  enum: *id025
                  example: preschool
                education_target_year:
                  type: integer
                education_est_cost:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 50000
                special_needs:
                  type: boolean
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - full_name
              - relationship
      operationId: put_api_financial_family
  /api/financial/goals:
    delete:
      summary: 'CRUD /api/financial/goals — Financial goals tracking GET: list, POST: create, PUT: update, DELETE: r'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/goals — Financial goals tracking GET: list, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_goals
    get:
      summary: 'CRUD /api/financial/goals — Financial goals tracking GET: list, POST: create, PUT: update, DELETE: r'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  financial_goals:
                    type: array
                    items:
                      $ref: '#/components/schemas/FinancialGoals'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/goals — Financial goals tracking GET: list, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_goals
    post:
      summary: 'CRUD /api/financial/goals — Financial goals tracking GET: list, POST: create, PUT: update, DELETE: r'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/goals — Financial goals tracking GET: list, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                category:
                  type: string
                  enum: &id026
                  - retirement
                  - home_purchase
                  - education
                  - emergency_fund
                  - debt_payoff
                  - travel
                  - vehicle
                  - wedding
                  - business
                  - custom
                  example: retirement
                target_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 100000
                current_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 25000
                monthly_contribution:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 500
                target_date:
                  type: string
                  format: date
                  example: '2030-06-01'
                priority:
                  type: string
                  enum: &id027
                  - high
                  - medium
                  - low
                  example: high
                linked_account_id:
                  type: string
                  format: uuid
                linked_family_member_id:
                  type: string
                  format: uuid
                status:
                  type: string
                  enum: &id028
                  - active
                  - achieved
                  - paused
                  - abandoned
                  example: active
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - category
      operationId: post_api_financial_goals
    put:
      summary: 'CRUD /api/financial/goals — Financial goals tracking GET: list, POST: create, PUT: update, DELETE: r'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/goals — Financial goals tracking GET: list, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                category:
                  type: string
                  enum: *id026
                  example: retirement
                target_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 100000
                current_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 25000
                monthly_contribution:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 500
                target_date:
                  type: string
                  format: date
                  example: '2030-06-01'
                priority:
                  type: string
                  enum: *id027
                  example: high
                linked_account_id:
                  type: string
                  format: uuid
                linked_family_member_id:
                  type: string
                  format: uuid
                status:
                  type: string
                  enum: *id028
                  example: active
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - category
      operationId: put_api_financial_goals
  /api/financial/history:
    get:
      summary: Retrieve history
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  history:
                    type: array
                    items:
                      type: object
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/financial/history — Net worth history for charts Query params: ?range=30|90|365|all


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_history
  /api/financial/insurance:
    delete:
      summary: 'CRUD /api/financial/insurance — Insurance policies GET: list all, POST: create, PUT: update, DELETE:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/insurance — Insurance policies GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_insurance
    get:
      summary: 'CRUD /api/financial/insurance — Insurance policies GET: list all, POST: create, PUT: update, DELETE:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  insurance_policies:
                    type: array
                    items:
                      $ref: '#/components/schemas/InsurancePolicies'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/insurance — Insurance policies GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_insurance
    post:
      summary: 'CRUD /api/financial/insurance — Insurance policies GET: list all, POST: create, PUT: update, DELETE:'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/insurance — Insurance policies GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                type:
                  type: string
                  enum: &id029
                  - life
                  - health
                  - auto
                  - home
                  - umbrella
                  - disability
                  - business
                  - boat
                  - renters
                  - other
                  example: life
                carrier:
                  type: string
                  maxLength: 200
                  example: State Farm
                policy_number:
                  type: string
                  example: POL-12345
                coverage_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 500000
                deductible:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 1000
                premium_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 150.0
                premium_frequency:
                  type: string
                  enum: &id030
                  - weekly
                  - biweekly
                  - monthly
                  - quarterly
                  - annually
                  example: weekly
                effective_date:
                  type: string
                  format: date
                expiration_date:
                  type: string
                  format: date
                beneficiaries:
                  type: string
                linked_asset_id:
                  type: string
                  format: uuid
                linked_entity_id:
                  type: string
                  format: uuid
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - type
              - carrier
              - premium_amount
      operationId: post_api_financial_insurance
    put:
      summary: 'CRUD /api/financial/insurance — Insurance policies GET: list all, POST: create, PUT: update, DELETE:'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/insurance — Insurance policies GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                type:
                  type: string
                  enum: *id029
                  example: life
                carrier:
                  type: string
                  maxLength: 200
                  example: State Farm
                policy_number:
                  type: string
                  example: POL-12345
                coverage_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 500000
                deductible:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 1000
                premium_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 150.0
                premium_frequency:
                  type: string
                  enum: *id030
                  example: weekly
                effective_date:
                  type: string
                  format: date
                expiration_date:
                  type: string
                  format: date
                beneficiaries:
                  type: string
                linked_asset_id:
                  type: string
                  format: uuid
                linked_entity_id:
                  type: string
                  format: uuid
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - type
              - carrier
              - premium_amount
      operationId: put_api_financial_insurance
  /api/financial/integration-costs:
    get:
      summary: Retrieve integration cost
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  plaid:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/financial/integration-costs — View all external API cost tracking Shows call counts and costs
        by service, endpoint, and connection


        **Authentication:** Requires admin role


        **Required role:** `admin`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_integration_costs
  /api/financial/liabilities:
    delete:
      summary: 'CRUD /api/financial/liabilities GET: list all, POST: create, PUT: update, DELETE: remove'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/liabilities GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_liabilities
    get:
      summary: 'CRUD /api/financial/liabilities GET: list all, POST: create, PUT: update, DELETE: remove'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  liabilities:
                    type: array
                    items:
                      $ref: '#/components/schemas/Liabilities'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/liabilities GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_liabilities
    post:
      summary: 'CRUD /api/financial/liabilities GET: list all, POST: create, PUT: update, DELETE: remove'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/liabilities GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                type:
                  type: string
                  enum: &id031
                  - mortgage
                  - student_loan
                  - auto_loan
                  - credit_card
                  - personal_loan
                  - business_loan
                  - medical
                  - other
                  example: mortgage
                lender:
                  type: string
                  maxLength: 200
                  example: Chase Bank
                original_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 200000
                current_balance:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 175000
                interest_rate:
                  type: number
                  example: 4.5
                monthly_payment:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 1500.0
                minimum_payment:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                credit_limit:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                utilization_rate:
                  type: string
                category:
                  type: string
                  maxLength: 100
                  example: income
                details:
                  type: object
                origination_date:
                  type: string
                  format: date
                maturity_date:
                  type: string
                  format: date
                linked_asset_id:
                  type: string
                  format: uuid
                linked_entity_id:
                  type: string
                  format: uuid
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - type
              - lender
              - current_balance
      operationId: post_api_financial_liabilities
    put:
      summary: 'CRUD /api/financial/liabilities GET: list all, POST: create, PUT: update, DELETE: remove'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/liabilities GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                type:
                  type: string
                  enum: *id031
                  example: mortgage
                lender:
                  type: string
                  maxLength: 200
                  example: Chase Bank
                original_amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 200000
                current_balance:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 175000
                interest_rate:
                  type: number
                  example: 4.5
                monthly_payment:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 1500.0
                minimum_payment:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                credit_limit:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                utilization_rate:
                  type: string
                category:
                  type: string
                  maxLength: 100
                  example: income
                details:
                  type: object
                origination_date:
                  type: string
                  format: date
                maturity_date:
                  type: string
                  format: date
                linked_asset_id:
                  type: string
                  format: uuid
                linked_entity_id:
                  type: string
                  format: uuid
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - type
              - lender
              - current_balance
      operationId: put_api_financial_liabilities
  /api/financial/overview:
    get:
      summary: Convert amount to monthly equivalent
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  achieved:
                    type: string
                  active:
                    type: boolean
                  current_total:
                    type: number
                  progress:
                    type: number
                  target_total:
                    type: number
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/financial/overview — Aggregate dashboard snapshot (one call) Returns net worth, history, cash
        flows, entities, taxes, connected accounts, insurance summary


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_overview
  /api/financial/personal-docs:
    delete:
      summary: 'CRUD /api/financial/personal-docs — Personal documents (IDs, passports, licenses) GET: list, POST: c'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/personal-docs — Personal documents (IDs, passports, licenses) GET: list, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_personal_docs
    get:
      summary: 'CRUD /api/financial/personal-docs — Personal documents (IDs, passports, licenses) GET: list, POST: c'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  personal_documents:
                    type: array
                    items:
                      $ref: '#/components/schemas/PersonalDocuments'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/personal-docs — Personal documents (IDs, passports, licenses) GET: list, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_personal_docs
    post:
      summary: 'CRUD /api/financial/personal-docs — Personal documents (IDs, passports, licenses) GET: list, POST: c'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/personal-docs — Personal documents (IDs, passports, licenses) GET: list, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                family_member_id:
                  type: string
                  format: uuid
                type:
                  type: string
                  enum: &id032
                  - passport
                  - drivers_license
                  - state_id
                  - birth_certificate
                  - social_security_card
                  - marriage_certificate
                  - divorce_decree
                  - citizenship_certificate
                  - green_card
                  - visa
                  - military_id
                  - tribal_id
                  - global_entry
                  - tsa_precheck
                  - professional_license
                  - concealed_carry
                  - other
                  example: passport
                issuing_authority:
                  type: string
                  maxLength: 200
                  example: State of Nevada
                document_number:
                  type: string
                  maxLength: 100
                  example: DL-123456
                issue_date:
                  type: string
                  format: date
                expiration_date:
                  type: string
                  format: date
                country:
                  type: string
                  example: US
                state:
                  type: string
                  example: NV
                status:
                  type: string
                  enum: &id033
                  - active
                  - expired
                  - lost
                  - revoked
                  example: active
                file_document_id:
                  type: string
                  format: uuid
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - type
      operationId: post_api_financial_personal_docs
    put:
      summary: 'CRUD /api/financial/personal-docs — Personal documents (IDs, passports, licenses) GET: list, POST: c'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/personal-docs — Personal documents (IDs, passports, licenses) GET: list, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                family_member_id:
                  type: string
                  format: uuid
                type:
                  type: string
                  enum: *id032
                  example: passport
                issuing_authority:
                  type: string
                  maxLength: 200
                  example: State of Nevada
                document_number:
                  type: string
                  maxLength: 100
                  example: DL-123456
                issue_date:
                  type: string
                  format: date
                expiration_date:
                  type: string
                  format: date
                country:
                  type: string
                  example: US
                state:
                  type: string
                  example: NV
                status:
                  type: string
                  enum: *id033
                  example: active
                file_document_id:
                  type: string
                  format: uuid
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - type
      operationId: put_api_financial_personal_docs
  /api/financial/personal-loans:
    delete:
      summary: 'CRUD /api/financial/personal-loans — Personal loans to individuals GET: list with totals, POST: crea'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/personal-loans — Personal loans to individuals GET: list with totals, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_personal_loans
    get:
      summary: 'CRUD /api/financial/personal-loans — Personal loans to individuals GET: list with totals, POST: crea'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  loans:
                    type: array
                    items:
                      $ref: '#/components/schemas/Liabilities'
                  outstanding:
                    type: string
                  total_loaned:
                    type: string
                  total_repaid:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/personal-loans — Personal loans to individuals GET: list with totals, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_personal_loans
    post:
      summary: 'CRUD /api/financial/personal-loans — Personal loans to individuals GET: list with totals, POST: crea'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/personal-loans — Personal loans to individuals GET: list with totals, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                borrower_name:
                  type: string
                  maxLength: 200
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 50000
                loan_date:
                  type: string
                  maxLength: 50
                status:
                  type: string
                  maxLength: 50
                  example: active
                repaid_amount:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - borrower_name
              - amount
      operationId: post_api_financial_personal_loans
    put:
      summary: 'CRUD /api/financial/personal-loans — Personal loans to individuals GET: list with totals, POST: crea'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/personal-loans — Personal loans to individuals GET: list with totals, POST: create,
        PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                borrower_name:
                  type: string
                  maxLength: 200
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 50000
                loan_date:
                  type: string
                  maxLength: 50
                status:
                  type: string
                  maxLength: 50
                  example: active
                repaid_amount:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - borrower_name
              - amount
      operationId: put_api_financial_personal_loans
  /api/financial/profile:
    get:
      summary: GET/PUT /api/financial/profile — User profile (single row per user, upsert) Risk tolerance, retireme
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  profile:
                    type: string
                  success:
                    type: boolean
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET/PUT /api/financial/profile — User profile (single row per user, upsert) Risk tolerance, retirement
        settings, household info


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_profile
    put:
      summary: GET/PUT /api/financial/profile — User profile (single row per user, upsert) Risk tolerance, retireme
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET/PUT /api/financial/profile — User profile (single row per user, upsert) Risk tolerance, retirement
        settings, household info


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                life_expectancy:
                  description: Field read by the handler.
                retirement_age:
                  description: Field read by the handler.
                state_of_residence:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: put_api_financial_profile
  /api/financial/snapshot:
    post:
      summary: Create snapshot
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/financial/snapshot — Record a net worth snapshot Called by cron worker daily + available for
        manual trigger Calculates totals from all connected accounts (Plaid + manual with live prices)


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_api_financial_snapshot
  /api/financial/subscriptions:
    delete:
      summary: 'CRUD /api/financial/subscriptions — Recurring subscriptions GET: list all, POST: create, PUT: update'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/subscriptions — Recurring subscriptions GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_subscriptions
    get:
      summary: 'CRUD /api/financial/subscriptions — Recurring subscriptions GET: list all, POST: create, PUT: update'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  subscriptions:
                    type: array
                    items:
                      $ref: '#/components/schemas/Subscriptions'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/subscriptions — Recurring subscriptions GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_subscriptions
    post:
      summary: 'CRUD /api/financial/subscriptions — Recurring subscriptions GET: list all, POST: create, PUT: update'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/subscriptions — Recurring subscriptions GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                category:
                  type: string
                  enum: &id034
                  - streaming
                  - music
                  - software
                  - fitness
                  - food
                  - gaming
                  - news
                  - cloud
                  - education
                  - utility
                  - other
                  example: streaming
                amount:
                  type: number
                  minimum: 1
                  maximum: 1000000000000
                  example: 50000
                frequency:
                  type: string
                  enum: &id035
                  - weekly
                  - monthly
                  - quarterly
                  - annual
                  example: weekly
                status:
                  type: string
                  enum: &id036
                  - active
                  - paused
                  - cancelled
                  - trialing
                  example: active
                next_billing_date:
                  type: string
                  format: date
                trial_end_date:
                  type: string
                  format: date
                payment_method:
                  type: string
                auto_renew:
                  type: boolean
                shared_with:
                  type: integer
                  minimum: 1
                  maximum: 50
                start_date:
                  type: string
                  format: date
                  example: '2026-01-01'
                cancel_date:
                  type: string
                  format: date
                family_member_id:
                  type: string
                  format: uuid
                  maxLength: 36
                details:
                  type: object
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - category
              - amount
              - frequency
      operationId: post_api_financial_subscriptions
    put:
      summary: 'CRUD /api/financial/subscriptions — Recurring subscriptions GET: list all, POST: create, PUT: update'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/subscriptions — Recurring subscriptions GET: list all, POST: create, PUT: update,
        DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 200
                  example: John Smith
                category:
                  type: string
                  enum: *id034
                  example: streaming
                amount:
                  type: number
                  minimum: 1
                  maximum: 1000000000000
                  example: 50000
                frequency:
                  type: string
                  enum: *id035
                  example: weekly
                status:
                  type: string
                  enum: *id036
                  example: active
                next_billing_date:
                  type: string
                  format: date
                trial_end_date:
                  type: string
                  format: date
                payment_method:
                  type: string
                auto_renew:
                  type: boolean
                shared_with:
                  type: integer
                  minimum: 1
                  maximum: 50
                start_date:
                  type: string
                  format: date
                  example: '2026-01-01'
                cancel_date:
                  type: string
                  format: date
                family_member_id:
                  type: string
                  format: uuid
                  maxLength: 36
                details:
                  type: object
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - name
              - category
              - amount
              - frequency
      operationId: put_api_financial_subscriptions
  /api/financial/tax:
    delete:
      summary: 'CRUD /api/financial/tax — Tax profiles GET: list all years, POST: create, PUT: update, DELETE: remov'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/tax — Tax profiles GET: list all years, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_tax
    get:
      summary: 'CRUD /api/financial/tax — Tax profiles GET: list all years, POST: create, PUT: update, DELETE: remov'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  tax_profiles:
                    type: array
                    items:
                      $ref: '#/components/schemas/TaxProfiles'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/tax — Tax profiles GET: list all years, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_tax
    post:
      summary: 'CRUD /api/financial/tax — Tax profiles GET: list all years, POST: create, PUT: update, DELETE: remov'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/tax — Tax profiles GET: list all years, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                year:
                  type: string
                filing_status:
                  type: string
                  maxLength: 50
                  example: married_filing_jointly
                gross_income:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                taxable_income:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                federal_tax:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                state_tax:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                self_employment_tax:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                effective_rate:
                  type: string
                quarterly_paid:
                  type: string
                details:
                  type: object
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - year
      operationId: post_api_financial_tax
    put:
      summary: 'CRUD /api/financial/tax — Tax profiles GET: list all years, POST: create, PUT: update, DELETE: remov'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/tax — Tax profiles GET: list all years, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                year:
                  type: string
                filing_status:
                  type: string
                  maxLength: 50
                  example: married_filing_jointly
                gross_income:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                taxable_income:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                federal_tax:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                state_tax:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                self_employment_tax:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                effective_rate:
                  type: string
                quarterly_paid:
                  type: string
                details:
                  type: object
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - year
      operationId: put_api_financial_tax
  /api/financial/transactions:
    get:
      summary: Fetch all transactions for a single access token using /transactions/sync
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  institutions:
                    type: string
                  stats:
                    type: string
                  transactions:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/financial/transactions Fetch transactions via Plaid /transactions/sync, compute financial stats
        Query params:


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_transactions
  /api/financial/vehicles:
    delete:
      summary: 'CRUD /api/financial/vehicles — Vehicle tracking GET: list all, POST: create, PUT: update, DELETE: re'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/vehicles — Vehicle tracking GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_financial_vehicles
    get:
      summary: 'CRUD /api/financial/vehicles — Vehicle tracking GET: list all, POST: create, PUT: update, DELETE: re'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  vehicles:
                    type: array
                    items:
                      $ref: '#/components/schemas/Vehicles'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/vehicles — Vehicle tracking GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_financial_vehicles
    post:
      summary: 'CRUD /api/financial/vehicles — Vehicle tracking GET: list all, POST: create, PUT: update, DELETE: re'
      tags:
      - financial
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/vehicles — Vehicle tracking GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                year:
                  type: string
                make:
                  type: string
                  maxLength: 100
                model:
                  type: string
                  maxLength: 100
                trim_level:
                  type: string
                  maxLength: 100
                vin:
                  type: string
                  maxLength: 17
                license_plate:
                  type: string
                  maxLength: 20
                type:
                  type: string
                  enum: &id037
                  - car
                  - truck
                  - suv
                  - van
                  - motorcycle
                  - boat
                  - rv
                  - atv
                  - aircraft
                  - other
                  example: car
                ownership:
                  type: string
                  enum: &id038
                  - owned
                  - leased
                  - financed
                  - company
                  example: owned
                purchase_date:
                  type: string
                  format: date
                purchase_price:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 250000
                current_value:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 350000
                mileage:
                  type: string
                  maximum: 0
                condition:
                  type: string
                  enum: &id039
                  - excellent
                  - good
                  - fair
                  - poor
                  example: excellent
                loan_balance:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                monthly_payment:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 1500.0
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - make
              - model
      operationId: post_api_financial_vehicles
    put:
      summary: 'CRUD /api/financial/vehicles — Vehicle tracking GET: list all, POST: create, PUT: update, DELETE: re'
      tags:
      - financial
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'CRUD /api/financial/vehicles — Vehicle tracking GET: list all, POST: create, PUT: update, DELETE: remove


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                year:
                  type: string
                make:
                  type: string
                  maxLength: 100
                model:
                  type: string
                  maxLength: 100
                trim_level:
                  type: string
                  maxLength: 100
                vin:
                  type: string
                  maxLength: 17
                license_plate:
                  type: string
                  maxLength: 20
                type:
                  type: string
                  enum: *id037
                  example: car
                ownership:
                  type: string
                  enum: *id038
                  example: owned
                purchase_date:
                  type: string
                  format: date
                purchase_price:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 250000
                current_value:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 350000
                mileage:
                  type: string
                  maximum: 0
                condition:
                  type: string
                  enum: *id039
                  example: excellent
                loan_balance:
                  type: string
                  minimum: 0
                  maximum: 1000000000000
                monthly_payment:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  example: 1500.0
                notes:
                  type: string
                  maxLength: 2000
                  example: Important details
              required:
              - make
              - model
      operationId: put_api_financial_vehicles
  /api/health:
    get:
      summary: Retrieve health
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  level:
                    type: string
                  message:
                    type: string
                  scim:
                    type: string
                  services:
                    type: string
                  timestamp:
                    type: string
                  version:
                    type: string
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/health — Public health check endpoint No auth required. Checks D1 and KV availability.


        **Rate limit:** 30 per minute'
      security: []
      operationId: get_api_health
  /api/integrations/calendar-summary:
    get:
      summary: Retrieve calendar summary
      tags:
      - integrations
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  allocation:
                    type: string
                  focus_hours:
                    type: string
                  meeting_hours:
                    type: string
                  meeting_pct:
                    type: string
                  summary:
                    type: string
                  today:
                    type: string
                  total_hours:
                    type: string
                  upcoming:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/integrations/calendar-summary Returns time allocation: meetings vs focus, upcoming schedule


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_integrations_calendar_summary
  /api/integrations/calendar-sync:
    post:
      summary: Create calendar sync
      tags:
      - integrations
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/integrations/calendar-sync Fetches upcoming calendar events via Google Calendar API, categorizes,
        caches


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_api_integrations_calendar_sync
  /api/integrations/connections:
    delete:
      summary: Delete connection
      tags:
      - integrations
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/integrations/connections — List all user connections (OAuth + IMAP) DELETE /api/integrations/connections?id=X&type=oauth|imap
        — Revoke a connection


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: delete_api_integrations_connections
    get:
      summary: Retrieve connection
      tags:
      - integrations
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/integrations/connections — List all user connections (OAuth + IMAP) DELETE /api/integrations/connections?id=X&type=oauth|imap
        — Revoke a connection


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_integrations_connections
  /api/integrations/email-summary:
    get:
      summary: Retrieve email summary
      tags:
      - integrations
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  financial_emails:
                    type: string
                  subscriptions:
                    type: object
                  summary:
                    type: string
                  total_cached:
                    type: string
                  total_financial:
                    type: string
                  total_spending:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/integrations/email-summary Returns cached email insights: financial emails, subscriptions, spending


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_integrations_email_summary
  /api/integrations/gmail-sync:
    post:
      summary: Create gmail sync
      tags:
      - integrations
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/integrations/gmail-sync Fetches recent emails via Gmail API, filters financial ones, caches
        metadata


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_api_integrations_gmail_sync
  /api/integrations/google-auth:
    post:
      summary: Create google auth
      tags:
      - integrations
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/integrations/google-auth Generates Google OAuth authorization URL with CSRF protection


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_api_integrations_google_auth
  /api/integrations/google-callback:
    post:
      summary: Create google callback
      tags:
      - integrations
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/integrations/google-callback Handles Google OAuth callback: validates state, exchanges code,
        stores tokens


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                  maxLength: 2000
                  example: abc123
                state:
                  type: string
                  maxLength: 200
                  example: NV
      operationId: post_api_integrations_google_callback
  /api/integrations/imap-connect:
    post:
      summary: Create imap connect
      tags:
      - integrations
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/integrations/imap-connect Saves IMAP connection credentials (encrypted)


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                auth_method:
                  description: Field read by the handler.
                display_name:
                  description: Field read by the handler.
                email:
                  description: Field read by the handler.
                imap_host:
                  description: Field read by the handler.
                imap_port:
                  description: Field read by the handler.
                password:
                  description: Field read by the handler.
                smtp_host:
                  description: Field read by the handler.
                smtp_port:
                  description: Field read by the handler.
                username:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_api_integrations_imap_connect
  /api/integrations/imap-discover:
    post:
      summary: Create imap discover
      tags:
      - integrations
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/integrations/imap-discover Auto-discovers IMAP/SMTP settings for an email address


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_api_integrations_imap_discover
  /api/integrations/microsoft-auth:
    post:
      summary: Create microsoft auth
      tags:
      - integrations
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/integrations/microsoft-auth Generates Microsoft OAuth authorization URL with CSRF protection


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_api_integrations_microsoft_auth
  /api/integrations/microsoft-callback:
    post:
      summary: Create microsoft callback
      tags:
      - integrations
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/integrations/microsoft-callback Handles Microsoft OAuth callback: validates state, exchanges
        code, stores tokens


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                  maxLength: 2000
                  example: abc123
                state:
                  type: string
                  maxLength: 200
                  example: NV
      operationId: post_api_integrations_microsoft_callback
  /api/me/subscriptions:
    get:
      summary: Returns the signed-in user's product_subscriptions. Used by other
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/me/subscriptions Returns the signed-in user''s product_subscriptions. Used by other abundera.ai
        subdomains (Sign, pro.qr, …) to check entitlements without


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_me_subscriptions
  /api/notifications:
    delete:
      summary: Notifications API GET /api/notifications — list unread/recent PUT /api/notifications — mark as read/
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'Notifications API GET /api/notifications — list unread/recent PUT /api/notifications — mark as read/dismissed


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_notifications
    get:
      summary: Notifications API GET /api/notifications — list unread/recent PUT /api/notifications — mark as read/
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  notifications:
                    type: array
                    items:
                      $ref: '#/components/schemas/Notifications'
                  success:
                    type: boolean
                  unread_count:
                    type: integer
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'Notifications API GET /api/notifications — list unread/recent PUT /api/notifications — mark as read/dismissed


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      parameters:
      - name: page
        in: query
        schema:
          type: integer
          default: 1
        description: Page number
      - name: limit
        in: query
        schema:
          type: integer
          default: 20
        description: Items per page (max 100)
      operationId: get_api_notifications
    put:
      summary: Notifications API GET /api/notifications — list unread/recent PUT /api/notifications — mark as read/
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'Notifications API GET /api/notifications — list unread/recent PUT /api/notifications — mark as read/dismissed


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  format: uuid
                  maxLength: 200
                  example: 550e8400-e29b-41d4-a716-446655440000
                action:
                  type: string
                  maxLength: 50
      operationId: put_api_notifications
  /api/push/subscribe:
    post:
      summary: Create subscribe
      tags:
      - api
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/push/subscribe — Register a push subscription for the authenticated user Requires auth. Upserts
        into push_subscriptions table.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                endpoint:
                  type: string
                keys:
                  type: string
      operationId: post_api_push_subscribe
  /api/push/vapid-key:
    get:
      summary: Retrieve vapid key
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  key:
                    type: string
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/push/vapid-key — Return VAPID public key for push subscription Public endpoint (no auth required
        — key is public information)


        **Rate limit:** 30 per minute'
      security: []
      operationId: get_api_push_vapid_key
  /api/security-timeline:
    get:
      summary: Retrieve security timeline
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/security-timeline — recent security events for current user Shows login events, passkey changes,
        API key creation, etc.


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_security_timeline
  /api/sessions:
    delete:
      summary: Delete session (sessions)
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/sessions — list active sessions for current user DELETE /api/sessions?id=... — revoke a specific
        session DELETE /api/sessions?all=true — revoke all sessions except current


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: delete_api_sessions
    get:
      summary: Retrieve session
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  revoked:
                    type: string
                  success:
                    type: boolean
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/sessions — list active sessions for current user DELETE /api/sessions?id=... — revoke a specific
        session DELETE /api/sessions?all=true — revoke all sessions except current


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_sessions
  /api/status:
    get:
      summary: Retrieve statu (status)
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  api_key:
                    type: string
                  custom_uptime_ratios:
                    type: string
                  format:
                    type: string
                  level:
                    type: string
                  logs:
                    type: array
                    items:
                      $ref: '#/components/schemas/NotificationLogs'
                  logs_limit:
                    type: string
                  message:
                    type: string
                  response_times:
                    type: string
                  response_times_average:
                    type: string
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/status — Public status endpoint Aggregates internal health checks + UptimeRobot monitors + D1
        history. Cached 60s in KV.


        **Rate limit:** 30 per minute'
      security: []
      operationId: get_api_status
  /api/status/history:
    get:
      summary: Retrieve history
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  level:
                    type: string
                  message:
                    type: string
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'GET /api/status/history?range=7d|30d|90d — Public historical status data Returns daily uptime percentages
        + response times + incidents from D1


        **Rate limit:** 30 per minute'
      security: []
      operationId: get_api_status_history
  /api/status/subscribe:
    delete:
      summary: Delete subscribe
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/status/subscribe — Subscribe to downtime alerts (requires Turnstile) GET  /api/status/subscribe?token=xxx
        — Verify email DELETE /api/status/subscribe?token=xxx — Unsubscribe


        **Turnstile verification** required


        **Rate limit:** 30 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_api_status_subscribe
    get:
      summary: Retrieve subscribe
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/status/subscribe — Subscribe to downtime alerts (requires Turnstile) GET  /api/status/subscribe?token=xxx
        — Verify email DELETE /api/status/subscribe?token=xxx — Unsubscribe


        **Turnstile verification** required


        **Rate limit:** 30 per minute'
      security: []
      operationId: get_api_status_subscribe
    post:
      summary: Create subscribe
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'POST /api/status/subscribe — Subscribe to downtime alerts (requires Turnstile) GET  /api/status/subscribe?token=xxx
        — Verify email DELETE /api/status/subscribe?token=xxx — Unsubscribe


        **Turnstile verification** required


        **Rate limit:** 30 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  maxLength: 254
                  example: user@example.com
                turnstileToken:
                  type: string
      operationId: post_api_status_subscribe
  /api/waitlist:
    post:
      summary: 'Cloudflare Pages Function: Waitlist Subscription Abundera.ai Security features:'
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 5 per 15 minutes
      description: 'Cloudflare Pages Function: Waitlist Subscription Abundera.ai Security features:


        **Turnstile verification** required


        **Rate limit:** 5 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_api_waitlist
  /api/waitlist-count:
    get:
      summary: 'Cloudflare Pages Function: Waitlist Count abundera.ai Returns the count of waitlist signups for disp'
      tags:
      - api
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  count:
                    type: integer
                  display:
                    type: string
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 5 per 15 minutes
      description: 'Cloudflare Pages Function: Waitlist Count abundera.ai Returns the count of waitlist signups for display


        **Rate limit:** 5 per 15 minutes'
      security: []
      operationId: get_api_waitlist_count
  /api/webhooks:
    get:
      summary: User Webhooks — list and create webhook endpoints for the current user GET  /api/webhooks — list use
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'User Webhooks — list and create webhook endpoints for the current user GET  /api/webhooks — list user''s
        endpoints POST /api/webhooks — create new endpoint


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_api_webhooks
    post:
      summary: User Webhooks — list and create webhook endpoints for the current user GET  /api/webhooks — list use
      tags:
      - webhooks
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 30 per minute
      description: 'User Webhooks — list and create webhook endpoints for the current user GET  /api/webhooks — list user''s
        endpoints POST /api/webhooks — create new endpoint


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 30 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  example: https://example.com/webhook
                events:
                  type: array
                  items:
                    type: string
                description:
                  type: string
                  example: Monthly contribution
              required:
              - url
      operationId: post_api_webhooks
  /api/webhooks/{id}:
    delete:
      summary: User Webhook — single endpoint operations (user-scoped) GET    /api/webhooks/:id — get endpoint deta
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 10 per 15 minutes
      description: 'User Webhook — single endpoint operations (user-scoped) GET    /api/webhooks/:id — get endpoint details
        PUT    /api/webhooks/:id — update endpoint


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      parameters:
      - &id040
        name: id
        in: path
        required: true
        schema:
          type: string
      operationId: delete_api_webhooks_id
    get:
      summary: User Webhook — single endpoint operations (user-scoped) GET    /api/webhooks/:id — get endpoint deta
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 10 per 15 minutes
      description: 'User Webhook — single endpoint operations (user-scoped) GET    /api/webhooks/:id — get endpoint details
        PUT    /api/webhooks/:id — update endpoint


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      parameters:
      - *id040
      operationId: get_api_webhooks_id
    put:
      summary: User Webhook — single endpoint operations (user-scoped) GET    /api/webhooks/:id — get endpoint deta
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'User Webhook — single endpoint operations (user-scoped) GET    /api/webhooks/:id — get endpoint details
        PUT    /api/webhooks/:id — update endpoint


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      parameters:
      - *id040
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                active:
                  description: Field read by the handler.
                description:
                  description: Field read by the handler.
                events:
                  description: Field read by the handler.
                url:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: put_api_webhooks_id
  /auth/api-keys:
    delete:
      summary: API Key Management GET    /auth/api-keys — List keys for current user (prefix + name, no secrets) PO
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'API Key Management GET    /auth/api-keys — List keys for current user (prefix + name, no secrets) POST   /auth/api-keys
        — Create new API key (returns full key once)


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_auth_api_keys
    get:
      summary: API Key Management GET    /auth/api-keys — List keys for current user (prefix + name, no secrets) PO
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  active:
                    type: boolean
                  allowed_ips:
                    type: string
                  created_at:
                    type: string
                    format: date-time
                  expires_at:
                    type: string
                    format: date-time
                  id:
                    type: string
                    format: uuid
                  inactive:
                    type: string
                  key_prefix:
                    type: string
                  last_used_at:
                    type: string
                    format: date-time
                  name:
                    type: string
                  product:
                    type: string
                  rate_limit:
                    type: string
                  request_count:
                    type: integer
                  revoked:
                    type: string
                  scopes:
                    type: string
                  valid:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'API Key Management GET    /auth/api-keys — List keys for current user (prefix + name, no secrets) POST   /auth/api-keys
        — Create new API key (returns full key once)


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_api_keys
    post:
      summary: API Key Management GET    /auth/api-keys — List keys for current user (prefix + name, no secrets) PO
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'API Key Management GET    /auth/api-keys — List keys for current user (prefix + name, no secrets) POST   /auth/api-keys
        — Create new API key (returns full key once)


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 100
                  example: John Smith
                scopes:
                  type: array
                  items:
                    type: string
                  example: &id041
                  - read:financial
                  - write:financial
                expires_in_days:
                  type: string
                  minimum: 0
                  maximum: 1
                allowed_ips:
                  type: array
                  items:
                    type: string
                  maxLength: 20
                  example: &id042
                  - 203.0.113.0/24
                reauth_token:
                  type: string
                product:
                  type: string
                keyId:
                  type: string
              required:
              - keyId
      operationId: post_auth_api_keys
    put:
      summary: API Key Management GET    /auth/api-keys — List keys for current user (prefix + name, no secrets) PO
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'API Key Management GET    /auth/api-keys — List keys for current user (prefix + name, no secrets) POST   /auth/api-keys
        — Create new API key (returns full key once)


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 100
                  example: John Smith
                scopes:
                  type: array
                  items:
                    type: string
                  example: *id041
                expires_in_days:
                  type: string
                  minimum: 0
                  maximum: 1
                allowed_ips:
                  type: array
                  items:
                    type: string
                  maxLength: 20
                  example: *id042
                reauth_token:
                  type: string
                product:
                  type: string
                keyId:
                  type: string
              required:
              - keyId
      operationId: put_auth_api_keys
  /auth/approvals:
    get:
      summary: Approval Workflows GET  /auth/approvals — List approval requests for current user POST /auth/approva
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Approval Workflows GET  /auth/approvals — List approval requests for current user POST /auth/approvals
        — Approve or reject a pending request


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_approvals
    post:
      summary: Approval Workflows GET  /auth/approvals — List approval requests for current user POST /auth/approva
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Approval Workflows GET  /auth/approvals — List approval requests for current user POST /auth/approvals
        — Approve or reject a pending request


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                approval_id:
                  type: string
                  maxLength: 200
                decision:
                  type: string
                reason:
                  type: string
                  maxLength: 1000
                  example: No longer needed
      operationId: post_auth_approvals
  /auth/audit:
    get:
      summary: 'Same cookie-forwarding pattern as /auth/webhooks (ADR 077): the'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /auth/audit?product=<id> — federated audit-log proxy (ADR 081). Same cookie-forwarding pattern as
        /auth/webhooks (ADR 077): the product is the source of truth for its `audit_log` rows, this


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_audit
  /auth/avatar:
    get:
      summary: 'PUT: authenticated. Accepts base64-encoded image up to 2MB'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'PUT /auth/avatar — Upload a user profile photo to R2. GET /auth/avatar?key=... — Serve a photo from R2
        (public, no auth). PUT: authenticated. Accepts base64-encoded image up to 2MB.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_avatar
    put:
      summary: 'PUT: authenticated. Accepts base64-encoded image up to 2MB'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'PUT /auth/avatar — Upload a user profile photo to R2. GET /auth/avatar?key=... — Serve a photo from R2
        (public, no auth). PUT: authenticated. Accepts base64-encoded image up to 2MB.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mime_type:
                  type: string
                data:
                  type: string
      operationId: put_auth_avatar
  /auth/backup-codes-setup:
    post:
      summary: 'Registration Step 3: Generate backup codes (decoupled from TOTP) POST /auth/backup-codes-setup Body:'
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Registration Step 3: Generate backup codes (decoupled from TOTP) POST /auth/backup-codes-setup Body: {
        userId, setupToken }


        **Authentication:** Requires session cookie (JWT)


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                userId:
                  type: string
                setupToken:
                  type: string
              required:
              - userId
      operationId: post_auth_backup_codes_setup
  /auth/cancel-closure:
    post:
      summary: Create cancel closure
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/cancel-closure — Cancel pending account closure Requires active session. No reauth needed (low
        risk, high convenience).


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_auth_cancel_closure
  /auth/certificates:
    delete:
      summary: 'mTLS Client Certificate Management GET: list certificates, POST: upload certificate, DELETE: revoke '
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'mTLS Client Certificate Management GET: list certificates, POST: upload certificate, DELETE: revoke certificate
        Requires Pro+ tier and passkey reauth for mutations.


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_auth_certificates
    get:
      summary: 'mTLS Client Certificate Management GET: list certificates, POST: upload certificate, DELETE: revoke '
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  fingerprint_sha256:
                    type: string
                  issuer_dn:
                    type: string
                  not_after:
                    type: string
                  not_before:
                    type: string
                  public_key_pem:
                    type: string
                  serial_number:
                    type: string
                  subject_dn:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'mTLS Client Certificate Management GET: list certificates, POST: upload certificate, DELETE: revoke certificate
        Requires Pro+ tier and passkey reauth for mutations.


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_certificates
    post:
      summary: 'mTLS Client Certificate Management GET: list certificates, POST: upload certificate, DELETE: revoke '
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'mTLS Client Certificate Management GET: list certificates, POST: upload certificate, DELETE: revoke certificate
        Requires Pro+ tier and passkey reauth for mutations.


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 100
                  example: John Smith
                pem:
                  type: string
                scopes:
                  type: array
                  items:
                    type: string
                  maxLength: 0
                  example: *id041
                allowed_ips:
                  type: array
                  items:
                    type: string
                  example: *id042
                id:
                  type: string
                  format: uuid
                  example: 550e8400-e29b-41d4-a716-446655440000
              required:
              - id
      operationId: post_auth_certificates
  /auth/close-account:
    post:
      summary: Create close account
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/close-account — Initiate 30-day account closure Requires active session + passkey re-authentication
        token. Cancels Stripe subscription, revokes API keys, revokes session.


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  description: Field read by the handler.
                reauth_token:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_auth_close_account
  /auth/contact-channels:
    delete:
      summary: GET/POST/PUT/DELETE /auth/contact-channels Manage user notification channels (email, phone) All meth
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET/POST/PUT/DELETE /auth/contact-channels Manage user notification channels (email, phone) All methods
        require authentication


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: delete_auth_contact_channels
    get:
      summary: GET/POST/PUT/DELETE /auth/contact-channels Manage user notification channels (email, phone) All meth
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  created_at:
                    type: string
                    format: date-time
                  id:
                    type: string
                    format: uuid
                  label:
                    type: string
                  notify_recovery:
                    type: string
                  notify_security:
                    type: string
                  type:
                    type: string
                  value:
                    type: string
                  verified:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET/POST/PUT/DELETE /auth/contact-channels Manage user notification channels (email, phone) All methods
        require authentication


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_contact_channels
    post:
      summary: GET/POST/PUT/DELETE /auth/contact-channels Manage user notification channels (email, phone) All meth
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET/POST/PUT/DELETE /auth/contact-channels Manage user notification channels (email, phone) All methods
        require authentication


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                action:
                  description: Field read by the handler.
                channelId:
                  description: Field read by the handler.
                code:
                  description: Field read by the handler.
                label:
                  description: Field read by the handler.
                notify_recovery:
                  description: Field read by the handler.
                notify_security:
                  description: Field read by the handler.
                reauth_token:
                  description: Field read by the handler.
                type:
                  description: Field read by the handler.
                value:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_auth_contact_channels
    put:
      summary: GET/POST/PUT/DELETE /auth/contact-channels Manage user notification channels (email, phone) All meth
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET/POST/PUT/DELETE /auth/contact-channels Manage user notification channels (email, phone) All methods
        require authentication


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                action:
                  description: Field read by the handler.
                channelId:
                  description: Field read by the handler.
                code:
                  description: Field read by the handler.
                label:
                  description: Field read by the handler.
                notify_recovery:
                  description: Field read by the handler.
                notify_security:
                  description: Field read by the handler.
                reauth_token:
                  description: Field read by the handler.
                type:
                  description: Field read by the handler.
                value:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: put_auth_contact_channels
  /auth/credentials:
    get:
      summary: Retrieve credential
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  created_at:
                    type: string
                    format: date-time
                  device_name:
                    type: string
                  id:
                    type: string
                    format: uuid
                  last_used_at:
                    type: string
                    format: date-time
                  sign_count:
                    type: integer
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /auth/credentials — list user''s registered passkeys Returns passkey metadata (no secrets) for settings
        page display


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_credentials
  /auth/data-export:
    post:
      summary: Create data export
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/data-export — Export all user data as JSON Requires active session + passkey re-authentication
        token. Collects data from control plane and user''s shard (if assigned).


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                reauth_token:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_auth_data_export
  /auth/data-import:
    post:
      summary: Create data import
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/data-import — CSV bulk import for transactions, assets, liabilities Accepts JSON body with
        { type, rows } where rows is parsed CSV data Max 500 rows per import


        **Authentication:** Requires authentication + core plan or higher


        **Minimum plan:** `core`


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                  example: checking
                rows:
                  type: string
      operationId: post_auth_data_import
  /auth/delegates:
    delete:
      summary: Account Delegation CRUD GET    /auth/delegates — List delegates for current user POST   /auth/delega
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Account Delegation CRUD GET    /auth/delegates — List delegates for current user POST   /auth/delegates
        — Invite a delegate by email


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_auth_delegates
    get:
      summary: Account Delegation CRUD GET    /auth/delegates — List delegates for current user POST   /auth/delega
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Account Delegation CRUD GET    /auth/delegates — List delegates for current user POST   /auth/delegates
        — Invite a delegate by email


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_delegates
    post:
      summary: Account Delegation CRUD GET    /auth/delegates — List delegates for current user POST   /auth/delega
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Account Delegation CRUD GET    /auth/delegates — List delegates for current user POST   /auth/delegates
        — Invite a delegate by email


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  example: user@example.com
                role:
                  type: string
                  example: member
                scopes:
                  type: array
                  items:
                    type: string
                  example: *id041
                delegateId:
                  type: string
                  maxLength: 200
      operationId: post_auth_delegates
    put:
      summary: Account Delegation CRUD GET    /auth/delegates — List delegates for current user POST   /auth/delega
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Account Delegation CRUD GET    /auth/delegates — List delegates for current user POST   /auth/delegates
        — Invite a delegate by email


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  example: user@example.com
                role:
                  type: string
                  example: member
                scopes:
                  type: array
                  items:
                    type: string
                  example: *id041
                delegateId:
                  type: string
                  maxLength: 200
      operationId: put_auth_delegates
  /auth/ip-allowlist:
    delete:
      summary: IP Allowlist Management GET    /auth/ip-allowlist — List allowed IPs/CIDRs for current user POST   /
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'IP Allowlist Management GET    /auth/ip-allowlist — List allowed IPs/CIDRs for current user POST   /auth/ip-allowlist
        — Add an IP or CIDR range


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_auth_ip_allowlist
    get:
      summary: IP Allowlist Management GET    /auth/ip-allowlist — List allowed IPs/CIDRs for current user POST   /
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  valid:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'IP Allowlist Management GET    /auth/ip-allowlist — List allowed IPs/CIDRs for current user POST   /auth/ip-allowlist
        — Add an IP or CIDR range


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_ip_allowlist
    post:
      summary: IP Allowlist Management GET    /auth/ip-allowlist — List allowed IPs/CIDRs for current user POST   /
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'IP Allowlist Management GET    /auth/ip-allowlist — List allowed IPs/CIDRs for current user POST   /auth/ip-allowlist
        — Add an IP or CIDR range


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ip_or_cidr:
                  type: string
                label:
                  type: string
                entryId:
                  type: string
      operationId: post_auth_ip_allowlist
  /auth/jwks:
    get:
      summary: Retrieve jwk (jwks)
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /auth/jwks (accessible via /v1/auth/jwks) — JSON Web Key Set endpoint (RFC 7517) Returns the public
        key(s) used for JWT verification. Public endpoint — no auth required. Cache-friendly (1-hour max-age).


        **Rate limit:** 10 per 15 minutes'
      security: []
      operationId: get_auth_jwks
  /auth/kyc:
    get:
      summary: KYC (Know Your Customer) Submission GET  /auth/kyc — Get current KYC status for authenticated user P
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'KYC (Know Your Customer) Submission GET  /auth/kyc — Get current KYC status for authenticated user POST
        /auth/kyc — Submit KYC documents for verification


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_kyc
    post:
      summary: KYC (Know Your Customer) Submission GET  /auth/kyc — Get current KYC status for authenticated user P
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'KYC (Know Your Customer) Submission GET  /auth/kyc — Get current KYC status for authenticated user POST
        /auth/kyc — Submit KYC documents for verification


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_auth_kyc
  /auth/login-complete:
    post:
      summary: WebAuthn Login Complete — verifies authentication assertion via SimpleWebAuthn POST /auth/login-comp
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 5 per 15 minutes
      description: 'WebAuthn Login Complete — verifies authentication assertion via SimpleWebAuthn POST /auth/login-complete
        Body: WebAuthn credential assertion (from @simplewebauthn/browser format)


        **Rate limit:** 5 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  format: uuid
                  maxLength: 200
                  example: 550e8400-e29b-41d4-a716-446655440000
                redirect:
                  type: string
      operationId: post_auth_login_complete
  /auth/login-start:
    post:
      summary: WebAuthn Login Start — generates authentication options via SimpleWebAuthn POST /auth/login-start Ra
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 5 per 15 minutes
      description: 'WebAuthn Login Start — generates authentication options via SimpleWebAuthn POST /auth/login-start Rate
        limit: 10 attempts per 15 minutes per IP


        **Turnstile verification** required


        **Rate limit:** 5 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                turnstileToken:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_auth_login_start
  /auth/logout:
    get:
      summary: Retrieve logout
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/logout — Clear session cookie + audit log Supports: single session logout, "logout all" (bumps
        token_version)


        **Authentication:** Requires session cookie (JWT)


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_logout
    post:
      summary: Create logout (logout)
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/logout — Clear session cookie + audit log Supports: single session logout, "logout all" (bumps
        token_version)


        **Authentication:** Requires session cookie (JWT)


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                all:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_auth_logout
  /auth/logout-all:
    post:
      summary: Create logout all
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/logout-all — Revoke ALL sessions for the current user Stores a timestamp in KV; any JWT with
        iat <= that timestamp is rejected by requireAuth


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_auth_logout_all
  /auth/me:
    get:
      summary: Retrieve me (me)
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /auth/me — Return current user info (session or API key)


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_me
  /auth/passkeys:
    delete:
      summary: Delete passkey (passkeys)
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /auth/passkeys — List registered passkeys DELETE /auth/passkeys — Revoke a specific passkey Requires
        auth. Delete requires reauth.


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_auth_passkeys
    get:
      summary: Retrieve passkey
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /auth/passkeys — List registered passkeys DELETE /auth/passkeys — Revoke a specific passkey Requires
        auth. Delete requires reauth.


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_passkeys
  /auth/reauth-start:
    post:
      summary: Create reauth start
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/reauth-start — Passkey re-authentication challenge Requires active session. Scopes to current
        user''s credentials only. Rate limit: 10 per 15 minutes per IP.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_auth_reauth_start
  /auth/reauth-verify:
    post:
      summary: Create reauth verify
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/reauth-verify — Verify passkey re-authentication Returns short-lived reauth token (5 min) for
        sensitive operations. Rate limit: 5 per 15 minutes per IP.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  format: uuid
                  maxLength: 500
                  example: 550e8400-e29b-41d4-a716-446655440000
                action:
                  type: string
                  maxLength: 100
              required:
              - id
      operationId: post_auth_reauth_verify
  /auth/recovery-code:
    post:
      summary: 'Recovery Step 2: Verify backup code (requires valid TOTP recovery token) POST /auth/recovery-code Bo'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Recovery Step 2: Verify backup code (requires valid TOTP recovery token) POST /auth/recovery-code Body:
        { recoveryToken, code }


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                recoveryToken:
                  type: string
                code:
                  type: string
                  example: abc123
      operationId: post_auth_recovery_code
  /auth/recovery-code-direct:
    post:
      summary: 'Recovery for non-TOTP users: backup code + email verification POST /auth/recovery-code-direct Body: '
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Recovery for non-TOTP users: backup code + email verification POST /auth/recovery-code-direct Body: {
        email, code }


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  example: user@example.com
                code:
                  type: string
                  example: abc123
      operationId: post_auth_recovery_code_direct
  /auth/recovery-codes-regenerate:
    post:
      summary: Create recovery codes regenerate
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/recovery-codes/regenerate — Generate new backup codes Requires active session + passkey re-authentication
        token. Invalidates all existing codes and generates 8 new ones.


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                reauth_token:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_auth_recovery_codes_regenerate
  /auth/recovery-email-request:
    post:
      summary: 'Break-glass recovery: Send magic link email POST /auth/recovery-email-request Body: { email }'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Break-glass recovery: Send magic link email POST /auth/recovery-email-request Body: { email }


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  maxLength: 320
                  example: user@example.com
      operationId: post_auth_recovery_email_request
  /auth/recovery-email-verify:
    post:
      summary: 'Break-glass recovery: Validate magic link, gate credential wipe, re-enroll POST /auth/recovery-email'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Break-glass recovery: Validate magic link, gate credential wipe, re-enroll POST /auth/recovery-email-verify
        Body: { action, ... }


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                action:
                  type: string
                token:
                  type: string
                uid:
                  type: string
                requestId:
                  type: string
                code:
                  type: string
                  example: abc123
                enrollToken:
                  type: string
                credential:
                  type: string
              required:
              - requestId
              - enrollToken
              - credential
      operationId: post_auth_recovery_email_verify
  /auth/recovery-register-passkey:
    post:
      summary: 'Recovery Step 3: Register new passkey after recovery POST /auth/recovery-register-passkey Body: { pa'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Recovery Step 3: Register new passkey after recovery POST /auth/recovery-register-passkey Body: { passkeyToken,
        action: "options" | "verify", credential? }


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                passkeyToken:
                  type: string
                action:
                  type: string
                credential:
                  type: string
              required:
              - credential
      operationId: post_auth_recovery_register_passkey
  /auth/recovery-totp:
    post:
      summary: 'Recovery Step 1: Verify TOTP code (gatekeeper) POST /auth/recovery-totp Body: { email, code }'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Recovery Step 1: Verify TOTP code (gatekeeper) POST /auth/recovery-totp Body: { email, code }


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  example: user@example.com
                code:
                  type: string
                  example: abc123
      operationId: post_auth_recovery_totp
  /auth/recovery-totp-verify:
    post:
      summary: 'TOTP recovery: email verification, cooling-off, credential wipe POST /auth/recovery-totp-verify Body'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'TOTP recovery: email verification, cooling-off, credential wipe POST /auth/recovery-totp-verify Body:
        { action, ... }


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                action:
                  type: string
                requestId:
                  type: string
                code:
                  type: string
                  example: abc123
              required:
              - requestId
      operationId: post_auth_recovery_totp_verify
  /auth/refresh:
    post:
      summary: Revoke all tokens in the compromised family (token reuse attack response)
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/refresh — Rotate access + refresh tokens Reads refresh token from HttpOnly cookie, issues new
        pair. Implements refresh token rotation: old token is invalidated on use.


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_auth_refresh
  /auth/register-complete:
    post:
      summary: 'Registration Step 5: Finalize registration, issue session POST /auth/register-complete Body: { userI'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 5 per 15 minutes
      description: 'Registration Step 5: Finalize registration, issue session POST /auth/register-complete Body: { userId,
        backupCodesConfirmed: true }


        **Rate limit:** 5 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                userId:
                  type: string
                backupCodesConfirmed:
                  type: string
                setupToken:
                  type: string
      operationId: post_auth_register_complete
  /auth/register-start:
    post:
      summary: 'Registration Step 1: Validate invite token, create user, generate passkey creation options POST /aut'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '403':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 5 per 15 minutes
      description: 'Registration Step 1: Validate invite token, create user, generate passkey creation options POST /auth/register-start
        Body: { token, email, displayName }


        **Rate limit:** 5 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                token:
                  type: string
                email:
                  type: string
                  example: user@example.com
                displayName:
                  type: string
                tos_accepted:
                  type: boolean
                  example: true
                privacy_accepted:
                  type: boolean
                  example: true
                age_verified:
                  type: boolean
                  example: true
                electronic_comms:
                  type: string
      operationId: post_auth_register_start
  /auth/register-validate:
    post:
      summary: Create register validate
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 5 per 15 minutes
      description: 'POST /auth/register-validate — Validate invite token and return pre-fill data Body: { token } Returns:
        { email, displayName } from invite


        **Rate limit:** 5 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                token:
                  type: string
              required:
              - token
      operationId: post_auth_register_validate
  /auth/register-verify:
    post:
      summary: 'Registration Step 2: Verify passkey registration response, store credential POST /auth/register-veri'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 5 per 15 minutes
      description: 'Registration Step 2: Verify passkey registration response, store credential POST /auth/register-verify
        Body: { userId, credential } (credential from @simplewebauthn/browser)


        **Rate limit:** 5 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                userId:
                  type: string
                credential:
                  type: string
                setupToken:
                  type: string
      operationId: post_auth_register_verify
  /auth/service/abuse-blocklist:
    delete:
      summary: /auth/service/abuse-blocklist — cross-product abuse signal store. GET    ?email_hash=&customer_id=&f
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: '/auth/service/abuse-blocklist — cross-product abuse signal store. GET    ?email_hash=&customer_id=&fingerprint=&ip_hash=  →
        check (any-of match) POST   { email_hash, stripe_customer_id, card_fingerprint, ip_hash,


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_auth_service_abuse_blocklist
    get:
      summary: /auth/service/abuse-blocklist — cross-product abuse signal store. GET    ?email_hash=&customer_id=&f
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: '/auth/service/abuse-blocklist — cross-product abuse signal store. GET    ?email_hash=&customer_id=&fingerprint=&ip_hash=  →
        check (any-of match) POST   { email_hash, stripe_customer_id, card_fingerprint, ip_hash,


        **Rate limit:** 10 per 15 minutes'
      security: []
      operationId: get_auth_service_abuse_blocklist
    post:
      summary: /auth/service/abuse-blocklist — cross-product abuse signal store. GET    ?email_hash=&customer_id=&f
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: '/auth/service/abuse-blocklist — cross-product abuse signal store. GET    ?email_hash=&customer_id=&fingerprint=&ip_hash=  →
        check (any-of match) POST   { email_hash, stripe_customer_id, card_fingerprint, ip_hash,


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email_hash:
                  type: string
                stripe_customer_id:
                  type: string
                card_fingerprint:
                  type: string
                ip_hash:
                  type: string
                product_id:
                  type: string
                cohort:
                  type: string
                severity:
                  type: string
                amount_cents:
                  type: string
                currency:
                  type: string
                  example: USD
                stripe_charge_id:
                  type: string
                stripe_dispute_id:
                  type: string
                notes:
                  type: string
                  example: Important details
                expires_at:
                  type: string
                  format: date
                  example: '2026-12-31'
      operationId: post_auth_service_abuse_blocklist
  /auth/service/email-validate:
    post:
      summary: '/auth/service/email-validate — cross-product email gatekeeper. POST { email: "user@example.com" } → '
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: '/auth/service/email-validate — cross-product email gatekeeper. POST { email: "user@example.com" } → 200
        { valid: true } | 400 { valid: false, reason, suggestion? }


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_auth_service_email_validate
  /auth/service/notification-prefs:
    post:
      summary: 'ADR 080: abundera.ai owns the single `notification_prefs` table'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/service/notification-prefs — federated prefs checker. ADR 080: abundera.ai owns the single
        `notification_prefs` table (a JSON column on `user_preferences`). Every product in the family


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                topic:
                  description: Field read by the handler.
                user_email:
                  description: Field read by the handler.
                user_id:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_auth_service_notification_prefs
  /auth/service/orgs:
    get:
      summary: 'X-Service-Secret gated. Body for POST:'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET  /auth/service/orgs?owner_user_id=<id>   List orgs owned by user POST /auth/service/orgs                       Create
        a new org X-Service-Secret gated. Body for POST:


        **Rate limit:** 10 per 15 minutes'
      security: []
      operationId: get_auth_service_orgs
    post:
      summary: 'X-Service-Secret gated. Body for POST:'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET  /auth/service/orgs?owner_user_id=<id>   List orgs owned by user POST /auth/service/orgs                       Create
        a new org X-Service-Secret gated. Body for POST:


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  example: John Smith
                owner_user_id:
                  type: string
                plan_gate:
                  type: string
      operationId: post_auth_service_orgs
  /auth/service/orgs/by-domain:
    get:
      summary: 'Reverse lookup: given an incoming Host header, return the org row +'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /auth/service/orgs/by-domain?host=<hostname> Reverse lookup: given an incoming Host header, return
        the org row + matched hostname row (or 404). Called by product middleware on every


        **Rate limit:** 10 per 15 minutes'
      security: []
      operationId: get_auth_service_orgs_by_domain
  /auth/service/orgs/{id}:
    delete:
      summary: Delete org (/auth/service/orgs/{id})
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET    /auth/service/orgs/:id    Read org with branding PATCH  /auth/service/orgs/:id    Update name /
        plan_gate / status DELETE /auth/service/orgs/:id    Soft-delete (status=''deleted'')


        **Rate limit:** 10 per 15 minutes'
      security: []
      parameters:
      - &id043
        name: id
        in: path
        required: true
        schema:
          type: string
      operationId: delete_auth_service_orgs_id
    get:
      summary: Retrieve org (/auth/service/orgs/{id})
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET    /auth/service/orgs/:id    Read org with branding PATCH  /auth/service/orgs/:id    Update name /
        plan_gate / status DELETE /auth/service/orgs/:id    Soft-delete (status=''deleted'')


        **Rate limit:** 10 per 15 minutes'
      security: []
      parameters:
      - *id043
      operationId: get_auth_service_orgs_id
    patch:
      summary: Update org (/auth/service/orgs/{id})
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET    /auth/service/orgs/:id    Read org with branding PATCH  /auth/service/orgs/:id    Update name /
        plan_gate / status DELETE /auth/service/orgs/:id    Soft-delete (status=''deleted'')


        **Rate limit:** 10 per 15 minutes'
      security: []
      parameters:
      - *id043
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: patch_auth_service_orgs_id
  /auth/service/orgs/{id}/branding:
    get:
      summary: 'Body keys (all optional): display_name, logo_url, primary_color,'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /auth/service/orgs/:id/branding   Read branding PUT /auth/service/orgs/:id/branding   Upsert any subset
        of branding fields Body keys (all optional): display_name, logo_url, primary_color,


        **Rate limit:** 10 per 15 minutes'
      security: []
      parameters:
      - &id044
        name: id
        in: path
        required: true
        schema:
          type: string
      operationId: get_auth_service_orgs_id_branding
    put:
      summary: 'Body keys (all optional): display_name, logo_url, primary_color,'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /auth/service/orgs/:id/branding   Read branding PUT /auth/service/orgs/:id/branding   Upsert any subset
        of branding fields Body keys (all optional): display_name, logo_url, primary_color,


        **Rate limit:** 10 per 15 minutes'
      security: []
      parameters:
      - *id044
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: put_auth_service_orgs_id_branding
  /auth/service/orgs/{id}/hostnames:
    get:
      summary: '{ hostname, product, purpose, dcv_method? }'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET  /auth/service/orgs/:id/hostnames           List hostnames POST /auth/service/orgs/:id/hostnames           Register
        a new hostname POST body:


        **Rate limit:** 10 per 15 minutes'
      security: []
      parameters:
      - &id045
        name: id
        in: path
        required: true
        schema:
          type: string
      operationId: get_auth_service_orgs_id_hostnames
    post:
      summary: '{ hostname, product, purpose, dcv_method? }'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET  /auth/service/orgs/:id/hostnames           List hostnames POST /auth/service/orgs/:id/hostnames           Register
        a new hostname POST body:


        **Rate limit:** 10 per 15 minutes'
      security: []
      parameters:
      - *id045
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                hostname:
                  type: string
                product:
                  type: string
                purpose:
                  type: string
                  example: Investment holding company
                dcv_method:
                  type: string
      operationId: post_auth_service_orgs_id_hostnames
  /auth/service/orgs/{id}/hostnames/{hostname_id}:
    delete:
      summary: DELETE removes the upstream provider record (best-effort — already-gone
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 10 per 15 minutes
      description: 'GET    /auth/service/orgs/:id/hostnames/:hostname_id   Read one DELETE /auth/service/orgs/:id/hostnames/:hostname_id   Revoke
        + cleanup DELETE removes the upstream provider record (best-effort — already-gone


        **Rate limit:** 10 per 15 minutes'
      security: []
      parameters:
      - &id046
        name: id
        in: path
        required: true
        schema:
          type: string
      - &id047
        name: hostname_id
        in: path
        required: true
        schema:
          type: string
      operationId: delete_auth_service_orgs_id_hostnames_hostname_id
    get:
      summary: DELETE removes the upstream provider record (best-effort — already-gone
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 10 per 15 minutes
      description: 'GET    /auth/service/orgs/:id/hostnames/:hostname_id   Read one DELETE /auth/service/orgs/:id/hostnames/:hostname_id   Revoke
        + cleanup DELETE removes the upstream provider record (best-effort — already-gone


        **Rate limit:** 10 per 15 minutes'
      security: []
      parameters:
      - *id046
      - *id047
      operationId: get_auth_service_orgs_id_hostnames_hostname_id
  /auth/service/orgs/{id}/hostnames/{hostname_id}/verify:
    post:
      summary: Polls the upstream backend (CF for SaaS / Resend) and updates the
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/service/orgs/:id/hostnames/:hostname_id/verify Polls the upstream backend (CF for SaaS / Resend)
        and updates the hostname row + KV mirror. Idempotent — safe to call repeatedly.


        **Rate limit:** 10 per 15 minutes'
      security: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: hostname_id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_auth_service_orgs_id_hostnames_hostname_id_verify
  /auth/service/product-subscription:
    post:
      summary: Service-to-service endpoint (no end-user auth). Accepts an upsert to
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/service/product-subscription Service-to-service endpoint (no end-user auth). Accepts an upsert
        to `product_subscriptions` from any Abundera sibling service (qr, sign,


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user_email:
                  type: string
                user_id:
                  type: string
                  format: uuid
                  example: 550e8400-e29b-41d4-a716-446655440001
                product_id:
                  type: string
                tier:
                  type: string
                billing_interval:
                  type: string
                status:
                  type: string
                  example: active
                stripe_subscription_id:
                  type: string
                current_period_end:
                  type: string
                cohort:
                  type: string
                customer_name:
                  type: string
                customer_phone:
                  type: string
                metadata:
                  type: object
      operationId: post_auth_service_product_subscription
  /auth/service/push-prefs:
    get:
      summary: User-level DND / quiet hours / timezone live on abundera.ai because
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/service/push-prefs — federated push-prefs checker. User-level DND / quiet hours / timezone
        live on abundera.ai because they apply across every product in the family (if a user is asleep,


        **Rate limit:** 10 per 15 minutes'
      security: []
      operationId: get_auth_service_push_prefs
    post:
      summary: User-level DND / quiet hours / timezone live on abundera.ai because
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/service/push-prefs — federated push-prefs checker. User-level DND / quiet hours / timezone
        live on abundera.ai because they apply across every product in the family (if a user is asleep,


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user_id:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_auth_service_push_prefs
  /auth/service/refund-email:
    post:
      summary: Service-to-service endpoint that fires the `refund_processed` email
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/service/refund-email Service-to-service endpoint that fires the `refund_processed` email for
        a buyer. Called by product webhooks on `charge.refunded`. Refunds


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user_email:
                  type: string
                user_id:
                  type: string
                  format: uuid
                  example: 550e8400-e29b-41d4-a716-446655440001
                product_id:
                  type: string
                tier:
                  type: string
                amount:
                  type: number
                  example: 50000
                currency:
                  type: string
                  example: USD
                customer_name:
                  type: string
                stripe_charge_id:
                  type: string
                stripe_subscription_id:
                  type: string
              required:
              - product_id
      operationId: post_auth_service_refund_email
  /auth/service/stripe-customer:
    post:
      summary: 'ADR 078: abundera.ai is the single authority for the shared'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/service/stripe-customer — federated Stripe-customer resolver. ADR 078: abundera.ai is the single
        authority for the shared `stripe_customer_id` per user. Every product in the family


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user_email:
                  description: Field read by the handler.
                user_id:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_auth_service_stripe_customer
  /auth/service/user-subscriptions:
    get:
      summary: 'Service-to-service lookup: return a user''s current product_subscriptions'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /auth/service/user-subscriptions?email=<email> OR ?user_id=<uuid> Service-to-service lookup: return
        a user''s current product_subscriptions keyed by product_id. Used by pro.qr.abundera.ai (and future siblings) to


        **Rate limit:** 10 per 15 minutes'
      security: []
      operationId: get_auth_service_user_subscriptions
  /auth/sessions:
    delete:
      summary: Session Management GET    /auth/sessions — List active sessions for current user DELETE /auth/sessio
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Session Management GET    /auth/sessions — List active sessions for current user DELETE /auth/sessions
        — Revoke session(s)


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: delete_auth_sessions
    get:
      summary: Session Management GET    /auth/sessions — List active sessions for current user DELETE /auth/sessio
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Session Management GET    /auth/sessions — List active sessions for current user DELETE /auth/sessions
        — Revoke session(s)


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      parameters:
      - name: page
        in: query
        schema:
          type: integer
          default: 1
        description: Page number
      - name: limit
        in: query
        schema:
          type: integer
          default: 20
        description: Items per page (max 100)
      operationId: get_auth_sessions
  /auth/signup-public-start:
    post:
      summary: 'Public self-signup, Step 1: email + name + consent → email a 6-digit code. POST /auth/signup-public-'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Public self-signup, Step 1: email + name + consent → email a 6-digit code. POST /auth/signup-public-start
        Body: { email, displayName, turnstileToken, tos_accepted, privacy_accepted,


        **Turnstile verification** required


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  example: user@example.com
                displayName:
                  type: string
                turnstileToken:
                  type: string
                tos_accepted:
                  type: boolean
                  example: true
                privacy_accepted:
                  type: boolean
                  example: true
                age_verified:
                  type: boolean
                  example: true
                electronic_comms:
                  type: string
                product:
                  type: string
                return_url:
                  type: string
              required:
              - turnstileToken
      operationId: post_auth_signup_public_start
  /auth/signup-public-verify:
    post:
      summary: 'Public self-signup, Step 2: verify the 6-digit email code, mint a single-use auth_invites token, ret'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Public self-signup, Step 2: verify the 6-digit email code, mint a single-use auth_invites token, return
        it to the client so they can finish via /register. POST /auth/signup-public-verify


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_auth_signup_public_verify
  /auth/ssh-keys:
    delete:
      summary: 'SSH Public Key Management GET: list keys, POST: add key, DELETE: revoke key Requires Pro+ tier and p'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'SSH Public Key Management GET: list keys, POST: add key, DELETE: revoke key Requires Pro+ tier and passkey
        reauth for mutations.


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      operationId: delete_auth_ssh_keys
    get:
      summary: 'SSH Public Key Management GET: list keys, POST: add key, DELETE: revoke key Requires Pro+ tier and p'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  fingerprint_sha256:
                    type: string
                  key_type:
                    type: string
                  public_key:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'SSH Public Key Management GET: list keys, POST: add key, DELETE: revoke key Requires Pro+ tier and passkey
        reauth for mutations.


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_ssh_keys
    post:
      summary: 'SSH Public Key Management GET: list keys, POST: add key, DELETE: revoke key Requires Pro+ tier and p'
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'SSH Public Key Management GET: list keys, POST: add key, DELETE: revoke key Requires Pro+ tier and passkey
        reauth for mutations.


        **Authentication:** Requires authentication + pro plan or higher


        **Minimum plan:** `pro`


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 100
                  example: John Smith
                public_key:
                  type: string
                scopes:
                  type: array
                  items:
                    type: string
                  maxLength: 0
                  example: *id041
                allowed_ips:
                  type: array
                  items:
                    type: string
                  example: *id042
                id:
                  type: string
                  format: uuid
                  example: 550e8400-e29b-41d4-a716-446655440000
              required:
              - id
      operationId: post_auth_ssh_keys
  /auth/sso:
    get:
      summary: SSO (Single Sign-On) Endpoints GET  /auth/sso — Initiate SSO login flow (redirect to IdP) POST /auth
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  authn_request_id:
                    type: string
                    format: uuid
                  connection_id:
                    type: string
                    format: uuid
                  nonce:
                    type: string
                  type:
                    type: string
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'SSO (Single Sign-On) Endpoints GET  /auth/sso — Initiate SSO login flow (redirect to IdP) POST /auth/sso
        — SSO callback handler (OIDC code exchange or SAML Response)


        **Rate limit:** 10 per 15 minutes'
      security: []
      operationId: get_auth_sso
    post:
      summary: SSO (Single Sign-On) Endpoints GET  /auth/sso — Initiate SSO login flow (redirect to IdP) POST /auth
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'SSO (Single Sign-On) Endpoints GET  /auth/sso — Initiate SSO login flow (redirect to IdP) POST /auth/sso
        — SSO callback handler (OIDC code exchange or SAML Response)


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                  maxLength: 4096
                  example: abc123
                state:
                  type: string
                  maxLength: 128
                  example: NV
      operationId: post_auth_sso
  /auth/team-invite-bridge:
    post:
      summary: Create team invite bridge
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /auth/team-invite-bridge Cross-service endpoint. Allows a sibling service (currently pro.qr.abundera.ai)
        to mint an auth_invite on abundera.ai''s side


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  example: user@example.com
                team_name:
                  type: string
                return_url:
                  type: string
      operationId: post_auth_team_invite_bridge
  /auth/token:
    post:
      summary: 'Token Exchange Endpoint — OAuth2 Client Credentials Pattern POST /auth/token — Exchange API key for '
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Token Exchange Endpoint — OAuth2 Client Credentials Pattern POST /auth/token — Exchange API key for short-lived
        JWT Flow:


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                grant_type:
                  type: string
                api_key:
                  type: string
      operationId: post_auth_token
  /auth/totp-setup:
    post:
      summary: 'Registration Step 3: Generate TOTP secret, return otpauth URI for QR code POST /auth/totp-setup Body'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Registration Step 3: Generate TOTP secret, return otpauth URI for QR code POST /auth/totp-setup Body:
        { userId }


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                userId:
                  type: string
                setupToken:
                  type: string
              required:
              - userId
      operationId: post_auth_totp_setup
  /auth/totp-verify-setup:
    post:
      summary: 'Registration Step 4: Verify TOTP code, generate backup codes, finalize enrollment POST /auth/totp-ve'
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Registration Step 4: Verify TOTP code, generate backup codes, finalize enrollment POST /auth/totp-verify-setup
        Body: { userId, code }


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                userId:
                  type: string
                code:
                  type: string
                  example: abc123
                setupToken:
                  type: string
      operationId: post_auth_totp_verify_setup
  /auth/user-preferences:
    get:
      summary: 'GET/PUT /auth/user-preferences — Theme, currency, date format, notifications, privacy Reads/upserts '
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  cleaned:
                    type: string
                  msg:
                    type: string
                  ok:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET/PUT /auth/user-preferences — Theme, currency, date format, notifications, privacy Reads/upserts into
        user_preferences table (control plane)


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_user_preferences
    put:
      summary: 'GET/PUT /auth/user-preferences — Theme, currency, date format, notifications, privacy Reads/upserts '
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET/PUT /auth/user-preferences — Theme, currency, date format, notifications, privacy Reads/upserts into
        user_preferences table (control plane)


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ai_features_enabled:
                  description: Field read by the handler.
                currency:
                  description: Field read by the handler.
                date_format:
                  description: Field read by the handler.
                language:
                  description: Field read by the handler.
                marketing_opt_in:
                  description: Field read by the handler.
                notification_prefs:
                  description: Field read by the handler.
                number_format:
                  description: Field read by the handler.
                push_prefs:
                  description: Field read by the handler.
                theme:
                  description: Field read by the handler.
                timezone:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: put_auth_user_preferences
  /auth/user-profile:
    get:
      summary: 'GET/PUT /auth/user-profile — Read/update profile fields on auth_users Fields: phone, date_of_birth, '
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET/PUT /auth/user-profile — Read/update profile fields on auth_users Fields: phone, date_of_birth, address_line1,
        address_city, address_state, address_zip, address_country


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_user_profile
    put:
      summary: 'GET/PUT /auth/user-profile — Read/update profile fields on auth_users Fields: phone, date_of_birth, '
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET/PUT /auth/user-profile — Read/update profile fields on auth_users Fields: phone, date_of_birth, address_line1,
        address_city, address_state, address_zip, address_country


        **Authentication:** Requires session cookie or API key + re-authentication


        **Re-authentication required** for write operations


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                address_zip:
                  description: Field read by the handler.
                date_of_birth:
                  description: Field read by the handler.
                display_name:
                  description: Field read by the handler.
                phone:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: put_auth_user_profile
  /auth/user-settings:
    put:
      summary: Update user setting
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'PUT /auth/user-settings — Update per-user settings Body: { recovery_enabled: boolean } Requires authenticated
        session


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                recovery_enabled:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: put_auth_user_settings
  /auth/validate-key:
    post:
      summary: Create validate key
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /v1/auth/validate-key — Internal API key validation for product services Product services (sign.abundera.ai,
        etc.) call this to validate API keys. Secured by X-Service-Secret header (shared secret per product).


        **Rate limit:** 10 per 15 minutes'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                key:
                  type: string
      operationId: post_auth_validate_key
  /auth/webhooks:
    get:
      summary: Federated outbound-webhooks bridge (ADR 077). GET    /auth/webhooks?product=<id>      → proxy to {pr
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Federated outbound-webhooks bridge (ADR 077). GET    /auth/webhooks?product=<id>      → proxy to {product}/api/webhooks
        POST   /auth/webhooks?product=<id>      → proxy to {product}/api/webhooks


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_auth_webhooks
    post:
      summary: Federated outbound-webhooks bridge (ADR 077). GET    /auth/webhooks?product=<id>      → proxy to {pr
      tags:
      - auth
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Federated outbound-webhooks bridge (ADR 077). GET    /auth/webhooks?product=<id>      → proxy to {product}/api/webhooks
        POST   /auth/webhooks?product=<id>      → proxy to {product}/api/webhooks


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_auth_webhooks
  /auth/webhooks/{id}:
    delete:
      summary: Federated delete — forwards to {product}/api/webhooks/:id with the
      tags:
      - auth
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 10 per 15 minutes
      description: 'DELETE /auth/webhooks/:id?product=<id> Federated delete — forwards to {product}/api/webhooks/:id with
        the caller''s session cookie. Product is the source of truth for webhook


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      operationId: delete_auth_webhooks_id
  /billing/checkout:
    post:
      summary: 'Legacy checkout: buy core platform plan by Stripe price ID'
      tags:
      - billing
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /billing/checkout — Create Stripe Checkout Session Returns { url } for client-side redirect to Stripe-hosted
        checkout Supports two modes:


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                product:
                  type: string
                tier:
                  type: string
                interval = "monthly":
                  type: string
                promo_code:
                  type: string
      operationId: post_billing_checkout
  /billing/pause:
    post:
      summary: Create pause (pause)
      tags:
      - billing
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /billing/pause — Pause subscription Requires authentication. Rate limited: 3 per hour. Uses Stripe
        pause_collection API to pause billing.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_billing_pause
  /billing/plans:
    get:
      summary: Retrieve plan (plans)
      tags:
      - billing
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  annual_savings_percent:
                    type: string
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /billing/plans?product=sign — Return plan catalog for a product Public endpoint — no authentication
        required. Returns pricing tiers with monthly/annual prices.


        **Rate limit:** 10 per 15 minutes'
      security: []
      operationId: get_billing_plans
  /billing/portal:
    post:
      summary: Accept only https://*.abundera.ai return URLs — blocks open-redirect
      tags:
      - billing
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /billing/portal — Create Stripe Customer Portal session Body: { return_url?: string } — allowlisted
        to https://*.abundera.ai, defaults to https://abundera.ai/account/billing/


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                return_url:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_billing_portal
  /billing/refund:
    post:
      summary: Create refund (refund)
      tags:
      - billing
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 3 per hour
      description: 'POST /billing/refund — Process money-back guarantee refund Only available within the guarantee period
        (default 30 days from subscription start)


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 3 per hour'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_billing_refund
  /billing/resume:
    post:
      summary: Create resume (resume)
      tags:
      - billing
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /billing/resume — Resume paused subscription Requires authentication. Rate limited: 3 per hour.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_billing_resume
  /billing/status:
    get:
      summary: Retrieve statu (status)
      tags:
      - billing
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  base_price_cents:
                    type: string
                  billing:
                    type: string
                  billing_interval:
                    type: string
                  current_period_end:
                    type: string
                  discount_expires_at:
                    type: string
                    format: date-time
                  discount_percent:
                    type: string
                  discount_source:
                    type: string
                  effective_price_cents:
                    type: string
                  product_id:
                    type: string
                    format: uuid
                  product_name:
                    type: string
                  product_url:
                    type: string
                  tier:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'GET /billing/status — Return user''s current billing status Returns platform plan + all active product
        subscriptions with effective pricing. Requires authentication. Defaults to none/none if no billing record exists.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_billing_status
  /billing/validate-promo:
    post:
      summary: Create validate promo
      tags:
      - billing
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'POST /billing/validate-promo — Validate a promo code and preview the discount Returns { valid, code, discount_percent,
        discount_source, expires_at } Requires authentication.


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                  maxLength: 50
                  example: abc123
                product:
                  type: string
                tier:
                  type: string
                interval = "monthly":
                  type: string
      operationId: post_billing_validate_promo
  /leads/tiktok-vcard:
    post:
      summary: (forwarded by Zapier or LeadsBridge from TikTok's lead webhook)
      tags:
      - leads
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /v1/leads/tiktok-vcard — receive a TikTok Lead Form submission (forwarded by Zapier or LeadsBridge
        from TikTok''s lead webhook). Flow:


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_leads_tiktok_vcard
  /mail/company-contacts:
    get:
      summary: Retrieve company contact
      tags:
      - mail
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'GET /mail/company-contacts       — Search/list companies (?q=comcast&industry=telecom) GET /mail/company-contacts/:id    —
        Single company profile (via path param)


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_mail_company_contacts
  /mail/credits:
    get:
      summary: Retrieve credit
      tags:
      - mail
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'GET  /mail/credits — Remaining tier quota + purchased credits POST /mail/credits — Purchase credits (placeholder
        for Stripe integration)


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_mail_credits
  /mail/letters:
    get:
      summary: Retrieve letter
      tags:
      - mail
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  allowed:
                    type: string
                  reason:
                    type: string
                  useCredit:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /mail/letters — Create a letter (draft or send) GET  /mail/letters — List user''s letters


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_mail_letters
    post:
      summary: Create letter (letters)
      tags:
      - mail
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /mail/letters — Create a letter (draft or send) GET  /mail/letters — List user''s letters


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                template_type:
                  type: string
                recipient_name:
                  type: string
                  maxLength: 200
                recipient_company:
                  type: string
                recipient_address:
                  type: string
                  maxLength: 1000
                recipient_email:
                  type: string
                  maxLength: 320
                delivery_method:
                  type: string
                letter_content:
                  type: string
      operationId: post_mail_letters
  /mail/templates:
    get:
      summary: Retrieve template
      tags:
      - mail
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  category:
                    type: string
                  description:
                    type: string
                  id:
                    type: string
                    format: uuid
                  name:
                    type: string
                  tier_minimum:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'GET /mail/templates — Available letter templates for user''s tier


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_mail_templates
  /mail/tips:
    get:
      summary: Retrieve tip (tips)
      tags:
      - mail
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /mail/tips              — Submit a tip GET  /mail/tips              — List tips (filter: ?company_contact_id=&category=&status=)
        POST /mail/tips/:id/vote     — Upvote/downvote/confirm/deny


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      operationId: get_mail_tips
    post:
      summary: Create tip (tips)
      tags:
      - mail
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /mail/tips              — Submit a tip GET  /mail/tips              — List tips (filter: ?company_contact_id=&category=&status=)
        POST /mail/tips/:id/vote     — Upvote/downvote/confirm/deny


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                tip_type:
                  type: string
                category:
                  type: string
                  example: income
                title:
                  type: string
                  example: Software Engineer
                content:
                  type: string
                company_contact_id:
                  type: string
                vote_type:
                  type: string
      operationId: post_mail_tips
  /mail/verify-address:
    post:
      summary: Create verify address
      tags:
      - mail
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /mail/verify-address — Lob address verification


        **Authentication:** Requires session cookie or API key


        **Rate limit:** 20 per minute'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                address_line1:
                  type: string
                address_line2:
                  type: string
                city:
                  type: string
                state:
                  type: string
                  example: NV
                zip_code:
                  type: string
      operationId: post_mail_verify_address
  /me/ip:
    get:
      summary: Retrieve ip (ip)
      tags:
      - me
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'GET /v1/me/ip — return the caller''s apparent IP, for the "+ My IP" helper button in the /account/api-keys/
        iframe''s allowlist form. Location note: must live at `functions/me/ip.js`. The `/v1/*`


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_me_ip
  /plaid/exchange-token:
    post:
      summary: Plaid webhook receiver (webhooks/plaid.js) enforces timestamp MAX_AGE < 300s tolerance. POST /plaid/
      tags:
      - plaid
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Plaid webhook receiver (webhooks/plaid.js) enforces timestamp MAX_AGE < 300s tolerance. POST /plaid/exchange-token
        Exchange Plaid public token for access token, encrypt and store in D1


        **Authentication:** Requires authentication + starter plan or higher


        **Minimum plan:** `starter`


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                publicToken:
                  type: string
                  maxLength: 500
                institutionId:
                  type: string
                  maxLength: 200
                institutionName:
                  type: string
                  maxLength: 200
                linkType:
                  type: string
                  maxLength: 50
              required:
              - publicToken
      operationId: post_plaid_exchange_token
  /plaid/link-token:
    post:
      summary: Plaid webhook receiver (webhooks/plaid.js) enforces timestamp MAX_AGE < 300s tolerance. POST /plaid/
      tags:
      - plaid
      responses:
        '201':
          description: Created successfully
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 10 per 15 minutes
      description: 'Plaid webhook receiver (webhooks/plaid.js) enforces timestamp MAX_AGE < 300s tolerance. POST /plaid/link-token
        Create a Plaid Link token for bank or investment linking


        **Authentication:** Requires authentication + starter plan or higher


        **Minimum plan:** `starter`


        **Rate limit:** 10 per 15 minutes'
      security:
      - bearerAuth: []
      - apiKeyAuth: []
      - cookieAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                oauthStateId:
                  description: Field read by the handler.
                type:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_plaid_link_token
  /products:
    get:
      summary: Retrieve product
      tags:
      - products
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  notificationTopics:
                    type: string
                  scopes:
                    type: string
                  unavailable:
                    type: string
                  webhookEventTypes:
                    type: string
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'GET /v1/products — public product registry feed. The /account/api-keys/ page fetches this to populate
        the product dropdown + scope chips without hardcoding a client-side copy of the


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_products
  /scim/v2/.search:
    get:
      summary: Responds 501 Not Implemented with the SCIM error envelope. This is an
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /scim/v2/.search — RFC 7644 §3.4.3 (optional "search with POST"). Responds 501 Not Implemented with
        the SCIM error envelope. This is an optional feature — we declare it unsupported instead of partially


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_scim_v2_.search
    post:
      summary: Responds 501 Not Implemented with the SCIM error envelope. This is an
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /scim/v2/.search — RFC 7644 §3.4.3 (optional "search with POST"). Responds 501 Not Implemented with
        the SCIM error envelope. This is an optional feature — we declare it unsupported instead of partially


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_scim_v2_.search
  /scim/v2/Bulk:
    post:
      summary: Entra's SCIM provisioning optionally uses /Bulk to batch ops during
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /scim/v2/Bulk — RFC 7644 §3.7. Entra''s SCIM provisioning optionally uses /Bulk to batch ops during
        large syncs (though the practical default is single-resource serial).


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                Operations:
                  description: Field read by the handler.
                failOnErrors:
                  description: Field read by the handler.
                schemas:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_scim_v2_Bulk
  /scim/v2/Groups:
    get:
      summary: /scim/v2/Groups — collection. GET  list with filter + pagination POST create a new group and initial
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '/scim/v2/Groups — collection. GET  list with filter + pagination POST create a new group and initial members


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_scim_v2_Groups
    post:
      summary: /scim/v2/Groups — collection. GET  list with filter + pagination POST create a new group and initial
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '/scim/v2/Groups — collection. GET  list with filter + pagination POST create a new group and initial members


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_scim_v2_Groups
  /scim/v2/Groups/.search:
    post:
      summary: '/Users/.search: 501 Not Implemented. Use GET /Groups?filter=... instead'
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /scim/v2/Groups/.search — RFC 7644 §3.4.3. Same treatment as /Users/.search: 501 Not Implemented.
        Use GET /Groups?filter=... instead.


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_scim_v2_Groups_.search
  /scim/v2/Groups/{id}:
    delete:
      summary: /scim/v2/Groups/{id} — single-resource handlers. GET / PUT / PATCH / DELETE semantics mirror Users/[
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: '/scim/v2/Groups/{id} — single-resource handlers. GET / PUT / PATCH / DELETE semantics mirror Users/[id].js.
        The important extras:


        **Rate limit:** 20 per minute'
      security: []
      parameters:
      - &id048
        name: id
        in: path
        required: true
        schema:
          type: string
      operationId: delete_scim_v2_Groups_id
    get:
      summary: /scim/v2/Groups/{id} — single-resource handlers. GET / PUT / PATCH / DELETE semantics mirror Users/[
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: '/scim/v2/Groups/{id} — single-resource handlers. GET / PUT / PATCH / DELETE semantics mirror Users/[id].js.
        The important extras:


        **Rate limit:** 20 per minute'
      security: []
      parameters:
      - *id048
      operationId: get_scim_v2_Groups_id
    patch:
      summary: /scim/v2/Groups/{id} — single-resource handlers. GET / PUT / PATCH / DELETE semantics mirror Users/[
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '/scim/v2/Groups/{id} — single-resource handlers. GET / PUT / PATCH / DELETE semantics mirror Users/[id].js.
        The important extras:


        **Rate limit:** 20 per minute'
      security: []
      parameters:
      - *id048
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: patch_scim_v2_Groups_id
    put:
      summary: /scim/v2/Groups/{id} — single-resource handlers. GET / PUT / PATCH / DELETE semantics mirror Users/[
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '/scim/v2/Groups/{id} — single-resource handlers. GET / PUT / PATCH / DELETE semantics mirror Users/[id].js.
        The important extras:


        **Rate limit:** 20 per minute'
      security: []
      parameters:
      - *id048
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: put_scim_v2_Groups_id
  /scim/v2/Me:
    get:
      summary: Returns the SCIM token's connection metadata so an IdP admin can check
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'GET /scim/v2/Me — debug endpoint. Returns the SCIM token''s connection metadata so an IdP admin can check
        "am I hitting the right tenant?" without asking us. Analogous to the


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_scim_v2_Me
  /scim/v2/ResourceTypes:
    get:
      summary: Enumerates the resource types we expose (User + Group). IdPs use this
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'GET /scim/v2/ResourceTypes — RFC 7644 §4. Enumerates the resource types we expose (User + Group). IdPs
        use this to build their attribute-mapping UIs. Response shape is the standard


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_scim_v2_ResourceTypes
  /scim/v2/ResourceTypes/{id}:
    get:
      summary: Fetches a single ResourceType by its `id` (e.g. "User" or "Group")
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: 'GET /scim/v2/ResourceTypes/{id} — RFC 7644 §4. Fetches a single ResourceType by its `id` (e.g. "User"
        or "Group"). Compliance test utilities (PingIdentity, suvera, WSO2) iterate the


        **Rate limit:** 20 per minute'
      security: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      operationId: get_scim_v2_ResourceTypes_id
  /scim/v2/Schemas:
    get:
      summary: Returns full Schema objects for User, Group, and the EnterpriseUser
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'GET /scim/v2/Schemas — RFC 7644 §4. Returns full Schema objects for User, Group, and the EnterpriseUser
        extension. IdPs parse these to validate attribute-mapping UI options;


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_scim_v2_Schemas
  /scim/v2/Schemas/{id}:
    get:
      summary: 'Fetches a single Schema by its URN id:'
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: 'GET /scim/v2/Schemas/{id} — RFC 7644 §4. Fetches a single Schema by its URN id: /scim/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:User


        **Rate limit:** 20 per minute'
      security: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      operationId: get_scim_v2_Schemas_id
  /scim/v2/ServiceProviderConfig:
    get:
      summary: IdPs (Okta, Entra, Workspace, JumpCloud) probe this on first connect to
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'GET /scim/v2/ServiceProviderConfig — RFC 7644 §4. IdPs (Okta, Entra, Workspace, JumpCloud) probe this
        on first connect to discover what we support. The response body is static; middleware has


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_scim_v2_ServiceProviderConfig
  /scim/v2/Users:
    get:
      summary: /scim/v2/Users — collection endpoint. GET  list with filter + pagination (RFC 7644 §3.4.2) POST crea
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '/scim/v2/Users — collection endpoint. GET  list with filter + pagination (RFC 7644 §3.4.2) POST create
        a new user (RFC 7644 §3.3)


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_scim_v2_Users
    post:
      summary: /scim/v2/Users — collection endpoint. GET  list with filter + pagination (RFC 7644 §3.4.2) POST crea
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '/scim/v2/Users — collection endpoint. GET  list with filter + pagination (RFC 7644 §3.4.2) POST create
        a new user (RFC 7644 §3.3)


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_scim_v2_Users
  /scim/v2/Users/.search:
    post:
      summary: Per-resource-type search-via-POST. Same rationale as the root-level
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /scim/v2/Users/.search — RFC 7644 §3.4.3. Per-resource-type search-via-POST. Same rationale as the
        root-level .search: we return 501 Not Implemented so compliance testers see a


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_scim_v2_Users_.search
  /scim/v2/Users/{id}:
    delete:
      summary: /scim/v2/Users/{id} — single-resource handlers. GET    read one User (404 if not in the current conn
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: '/scim/v2/Users/{id} — single-resource handlers. GET    read one User (404 if not in the current connection''s
        scope) PUT    full-replace semantics (RFC 7644 §3.5.1) — rare; most IdPs PATCH


        **Rate limit:** 20 per minute'
      security: []
      parameters:
      - &id049
        name: id
        in: path
        required: true
        schema:
          type: string
      operationId: delete_scim_v2_Users_id
    get:
      summary: /scim/v2/Users/{id} — single-resource handlers. GET    read one User (404 if not in the current conn
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: '/scim/v2/Users/{id} — single-resource handlers. GET    read one User (404 if not in the current connection''s
        scope) PUT    full-replace semantics (RFC 7644 §3.5.1) — rare; most IdPs PATCH


        **Rate limit:** 20 per minute'
      security: []
      parameters:
      - *id049
      operationId: get_scim_v2_Users_id
    patch:
      summary: /scim/v2/Users/{id} — single-resource handlers. GET    read one User (404 if not in the current conn
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '/scim/v2/Users/{id} — single-resource handlers. GET    read one User (404 if not in the current connection''s
        scope) PUT    full-replace semantics (RFC 7644 §3.5.1) — rare; most IdPs PATCH


        **Rate limit:** 20 per minute'
      security: []
      parameters:
      - *id049
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: patch_scim_v2_Users_id
    put:
      summary: /scim/v2/Users/{id} — single-resource handlers. GET    read one User (404 if not in the current conn
      tags:
      - scim
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: '/scim/v2/Users/{id} — single-resource handlers. GET    read one User (404 if not in the current connection''s
        scope) PUT    full-replace semantics (RFC 7644 §3.5.1) — rare; most IdPs PATCH


        **Rate limit:** 20 per minute'
      security: []
      parameters:
      - *id049
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: put_scim_v2_Users_id
  /track/referer:
    post:
      summary: Create referer (referer)
      tags:
      - track
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'POST /v1/track/referer — Anonymous external-referer page-visit log. No auth, no PII, rate-limited per-IP.
        Writes to LOGS_DB.referer_log.


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                landing_path:
                  description: Field read by the handler.
                landing_url:
                  description: Field read by the handler.
                language:
                  description: Field read by the handler.
                referer_host:
                  description: Field read by the handler.
                referer_path:
                  description: Field read by the handler.
                referer_url:
                  description: Field read by the handler.
                site_host:
                  description: Field read by the handler.
                utm_campaign:
                  description: Field read by the handler.
                utm_content:
                  description: Field read by the handler.
                utm_medium:
                  description: Field read by the handler.
                utm_source:
                  description: Field read by the handler.
                utm_term:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_track_referer
  /videos/r2/{path}:
    get:
      summary: Stream video + poster assets from the abundera-videos R2 bucket. MP4s and JPGs are large; this avoid
      tags:
      - videos
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '403':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
      x-rateLimit: 20 per minute
      description: 'Stream video + poster assets from the abundera-videos R2 bucket. MP4s and JPGs are large; this avoids
        shipping them through CF Pages (which has a 25 MiB per-file limit and bloats every deploy with


        **Rate limit:** 20 per minute'
      security: []
      parameters:
      - name: path
        in: path
        required: true
        schema:
          type: string
      operationId: get_videos_r2_path
  /webhooks/billing:
    get:
      summary: Billing Webhook Handler POST /webhooks/billing — Handle Stripe webhook events This is a PUBLIC_ENDPO
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  level:
                    type: string
                  message:
                    type: string
        '400':
          description: Invalid webhook payload or signature.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: 'Billing Webhook Handler POST /webhooks/billing — Handle Stripe webhook events This is a PUBLIC_ENDPOINT
        — no session cookie or JWT required.


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_webhooks_billing
    post:
      summary: Billing Webhook Handler POST /webhooks/billing — Handle Stripe webhook events This is a PUBLIC_ENDPO
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '400':
          description: Invalid webhook payload or signature.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: 'Billing Webhook Handler POST /webhooks/billing — Handle Stripe webhook events This is a PUBLIC_ENDPOINT
        — no session cookie or JWT required.


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_webhooks_billing
  /webhooks/lob:
    post:
      summary: Create lob (lob)
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '400':
          description: Invalid webhook payload or signature.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: 'POST /webhooks/lob — Lob delivery status webhook Updates mail_letters status based on Lob events


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                body:
                  description: Field read by the handler.
                date_created:
                  description: Field read by the handler.
                event_type:
                  description: Field read by the handler.
                id:
                  description: Field read by the handler.
                tracking_events:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_webhooks_lob
  /webhooks/plaid:
    post:
      summary: Create plaid (plaid)
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '400':
          description: Invalid webhook payload or signature.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: 'POST /webhooks/plaid — Plaid webhook receiver Verifies ES256 JWT signature, processes events, creates
        notifications See docs/PLAID_BILLING.md for cost tracking


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_webhooks_plaid
  /webhooks/sign-envelope:
    post:
      summary: Create sign envelope
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '400':
          description: Invalid webhook payload or signature.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: 'POST /webhooks/sign-envelope Receives signed-envelope events from sign.abundera.ai for the Sales Rep Agreement
        template. Auth: HMAC signature in `X-Sign-Signature` header


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_webhooks_sign_envelope
  /webhooks/twilio-sms:
    get:
      summary: Send an SMS notification to a user
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                type: object
                properties:
                  API_KEY_SID:
                    type: string
                  sid:
                    type: string
                  success:
                    type: boolean
        '400':
          description: Invalid webhook payload or signature.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: 'POST /webhooks/twilio-sms — Twilio SMS webhook handler Receives incoming SMS, parses commands, responds
        with TwiML Also exports sendSmsNotification() for outbound SMS from notification system


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_webhooks_twilio_sms
    post:
      summary: Send an SMS notification to a user
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '400':
          description: Invalid webhook payload or signature.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: 'POST /webhooks/twilio-sms — Twilio SMS webhook handler Receives incoming SMS, parses commands, responds
        with TwiML Also exports sendSmsNotification() for outbound SMS from notification system


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                length:
                  description: Field read by the handler.
                slice:
                  description: Field read by the handler.
                split:
                  description: Field read by the handler.
              additionalProperties: true
      operationId: post_webhooks_twilio_sms
  /webhooks/zeptomail:
    get:
      summary: ZeptoMail Webhook Handler POST /webhooks/zeptomail — Handle ZeptoMail delivery event notifications T
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '400':
          description: Invalid webhook payload or signature.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: 'ZeptoMail Webhook Handler POST /webhooks/zeptomail — Handle ZeptoMail delivery event notifications This
        is a PUBLIC_ENDPOINT — no session cookie or JWT required.


        **Rate limit:** 20 per minute'
      security: []
      operationId: get_webhooks_zeptomail
    post:
      summary: ZeptoMail Webhook Handler POST /webhooks/zeptomail — Handle ZeptoMail delivery event notifications T
      tags:
      - webhooks
      responses:
        '200':
          description: Successful response
          headers: *id001
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
        '400':
          description: Invalid webhook payload or signature.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-rateLimit: 20 per minute
      description: 'ZeptoMail Webhook Handler POST /webhooks/zeptomail — Handle ZeptoMail delivery event notifications This
        is a PUBLIC_ENDPOINT — no session cookie or JWT required.


        **Rate limit:** 20 per minute'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      operationId: post_webhooks_zeptomail
  /v1/analysis/run:
    post:
      tags:
      - v1
      summary: /v1/analysis/run
      description: POST /v1/analysis/run — Create run. This description was auto-generated from the handler implementation;
        for full request/response semantics see the source under `functions/`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                categories:
                  description: Field read by the handler.
                engineIds:
                  description: Field read by the handler.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  errors:
                    description: Response field detected from handler.
                  findings:
                    description: Response field detected from handler.
                  ran:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
  /v1/analysis/findings:
    get:
      tags:
      - v1
      summary: /v1/analysis/findings
      description: "/analysis/findings:\n  get:\n    tags: [analysis/findings]\n    summary: List or retrieve analysis findings\
        \ for the authenticated user\n    description: |\n      Returns analysis findings for the authenticated user. Requires\
        \ a valid bearer JWT and an active subscription.\n      When the `id` query parameter is supplied, returns a single\
        \ finding object. Otherwise returns a filtered list of findings ordered by severity (critical → high → medium → low)\
        \ then by recency.\n      Findings are cached for 5 minutes using a stale-while-revalidate KV strategy. Health/medical\
        \ findings are suppressed unless the user has explicitly granted health data consent in their account record.\n  \
        \    Expired findings (past `expires_at`) are excluded from list results. Snoozed findings whose snooze period is\
        \ still active are also excluded from list results.\n    security:\n      - bearerAuth: []\n    parameters:\n    \
        \  - name: id\n        in: query\n        required: false\n        description: Return a single finding by its ID\
        \ instead of a list.\n        schema: { type: string }\n      - name: status\n        in: query\n        required:\
        \ false\n        description: Filter findings by status. Defaults to \"open\". Pass \"all\" to skip status filtering.\n\
        \        schema: { type: string, default: open }\n      - name: category\n        in: query\n        required: false\n\
        \        description: Filter findings by category value stored on the finding row.\n        schema: { type: string\
        \ }\n    responses:\n      '200':\n        description: Findings returned successfully\n        content:\n       \
        \   application/json:\n            schema:\n              oneOf:\n                - description: Single finding (when\
        \ id param is supplied)\n                  type: object\n                  properties:\n                    finding:\
        \ { type: object }\n                - description: Finding list\n                  type: object\n                \
        \  properties:\n                    findings:\n                      type: array\n                      items: { type:\
        \ object }\n                    count: { type: integer }\n      '401':\n        description: Authentication required\
        \ or token invalid\n      '403':\n        description: No active subscription\n        content:\n          application/json:\n\
        \            schema:\n              type: object\n              properties:\n                error: { type: string\
        \ }\n      '404':\n        description: Finding not found or user shard not available\n        content:\n        \
        \  application/json:\n            schema:\n              type: object\n              properties:\n               \
        \ error: { type: string }\n      '500':\n        description: Unexpected server error\n  post:\n    tags: [analysis/findings]\n\
        \    summary: Dismiss, snooze, or reopen a finding\n    description: |\n      Updates the status of a finding owned\
        \ by the authenticated user. Requires a valid bearer JWT and an active subscription.\n      Three actions are supported:\n\
        \      - `dismiss` — marks the finding as dismissed and records `dismissed_at`.\n      - `snooze` — sets the finding\
        \ to snoozed status with a `snooze_until` timestamp. The snooze window defaults to 30 days if `snoozeDays` is not\
        \ supplied.\n      - `reopen` — clears dismissed and snooze state, returning the finding to open status.\n      Dismiss\
        \ and snooze actions record AI engine feedback signals asynchronously via `waitUntil` for quality metrics. The findings\
        \ list cache for the user is invalidated on success. The action is written to the audit log.\n      Request body is\
        \ capped at 1024 bytes.\n    security:\n      - bearerAuth: []\n    requestBody:\n      required: true\n      content:\n\
        \        application/json:\n          schema:\n            type: object\n            required: [findingId, action]\n\
        \            properties:\n              findingId:\n                type: string\n                description: ID\
        \ of the finding to update. Format is userId:engineId.\n              action:\n                type: string\n    \
        \            enum: [dismiss, snooze, reopen]\n                description: Action to apply to the finding.\n     \
        \         snoozeDays:\n                type: integer\n                description: Number of days to snooze the finding.\
        \ Only used when action is snooze. Defaults to 30.\n    responses:\n      '200':\n        description: Finding updated\
        \ successfully\n        content:\n          application/json:\n            schema:\n              type: object\n \
        \             properties:\n                ok: { type: boolean, const: true }\n                action: { type: string,\
        \ enum: [dismiss, snooze, reopen] }\n                findingId: { type: string }\n      '400':\n        description:\
        \ Missing or invalid request fields\n        content:\n          application/json:\n            schema:\n        \
        \      type: object\n              properties:\n                error: { type: string }\n      '401':\n        description:\
        \ Authentication required or token invalid\n      '403':\n        description: No active subscription\n        content:\n\
        \          application/json:\n            schema:\n              type: object\n              properties:\n       \
        \         error: { type: string }\n      '404':\n        description: Finding not found or user shard not available\n\
        \        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n\
        \                error: { type: string }\n      '500':\n        description: Unexpected server error"
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  action:
                    description: Response field detected from handler.
                  count:
                    description: Response field detected from handler.
                  filteredFindings:
                    description: Response field detected from handler.
                  findings:
                    description: Response field detected from handler.
                  length:
                    description: Response field detected from handler.
                  'true':
                    description: Response field detected from handler.
        '400':
          description: Invalid request
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
    post:
      tags:
      - v1
      summary: /v1/analysis/findings
      description: "/analysis/findings:\n  get:\n    tags: [analysis/findings]\n    summary: List or retrieve analysis findings\
        \ for the authenticated user\n    description: |\n      Returns analysis findings for the authenticated user. Requires\
        \ a valid bearer JWT and an active subscription.\n      When the `id` query parameter is supplied, returns a single\
        \ finding object. Otherwise returns a filtered list of findings ordered by severity (critical → high → medium → low)\
        \ then by recency.\n      Findings are cached for 5 minutes using a stale-while-revalidate KV strategy. Health/medical\
        \ findings are suppressed unless the user has explicitly granted health data consent in their account record.\n  \
        \    Expired findings (past `expires_at`) are excluded from list results. Snoozed findings whose snooze period is\
        \ still active are also excluded from list results.\n    security:\n      - bearerAuth: []\n    parameters:\n    \
        \  - name: id\n        in: query\n        required: false\n        description: Return a single finding by its ID\
        \ instead of a list.\n        schema: { type: string }\n      - name: status\n        in: query\n        required:\
        \ false\n        description: Filter findings by status. Defaults to \"open\". Pass \"all\" to skip status filtering.\n\
        \        schema: { type: string, default: open }\n      - name: category\n        in: query\n        required: false\n\
        \        description: Filter findings by category value stored on the finding row.\n        schema: { type: string\
        \ }\n    responses:\n      '200':\n        description: Findings returned successfully\n        content:\n       \
        \   application/json:\n            schema:\n              oneOf:\n                - description: Single finding (when\
        \ id param is supplied)\n                  type: object\n                  properties:\n                    finding:\
        \ { type: object }\n                - description: Finding list\n                  type: object\n                \
        \  properties:\n                    findings:\n                      type: array\n                      items: { type:\
        \ object }\n                    count: { type: integer }\n      '401':\n        description: Authentication required\
        \ or token invalid\n      '403':\n        description: No active subscription\n        content:\n          application/json:\n\
        \            schema:\n              type: object\n              properties:\n                error: { type: string\
        \ }\n      '404':\n        description: Finding not found or user shard not available\n        content:\n        \
        \  application/json:\n            schema:\n              type: object\n              properties:\n               \
        \ error: { type: string }\n      '500':\n        description: Unexpected server error\n  post:\n    tags: [analysis/findings]\n\
        \    summary: Dismiss, snooze, or reopen a finding\n    description: |\n      Updates the status of a finding owned\
        \ by the authenticated user. Requires a valid bearer JWT and an active subscription.\n      Three actions are supported:\n\
        \      - `dismiss` — marks the finding as dismissed and records `dismissed_at`.\n      - `snooze` — sets the finding\
        \ to snoozed status with a `snooze_until` timestamp. The snooze window defaults to 30 days if `snoozeDays` is not\
        \ supplied.\n      - `reopen` — clears dismissed and snooze state, returning the finding to open status.\n      Dismiss\
        \ and snooze actions record AI engine feedback signals asynchronously via `waitUntil` for quality metrics. The findings\
        \ list cache for the user is invalidated on success. The action is written to the audit log.\n      Request body is\
        \ capped at 1024 bytes.\n    security:\n      - bearerAuth: []\n    requestBody:\n      required: true\n      content:\n\
        \        application/json:\n          schema:\n            type: object\n            required: [findingId, action]\n\
        \            properties:\n              findingId:\n                type: string\n                description: ID\
        \ of the finding to update. Format is userId:engineId.\n              action:\n                type: string\n    \
        \            enum: [dismiss, snooze, reopen]\n                description: Action to apply to the finding.\n     \
        \         snoozeDays:\n                type: integer\n                description: Number of days to snooze the finding.\
        \ Only used when action is snooze. Defaults to 30.\n    responses:\n      '200':\n        description: Finding updated\
        \ successfully\n        content:\n          application/json:\n            schema:\n              type: object\n \
        \             properties:\n                ok: { type: boolean, const: true }\n                action: { type: string,\
        \ enum: [dismiss, snooze, reopen] }\n                findingId: { type: string }\n      '400':\n        description:\
        \ Missing or invalid request fields\n        content:\n          application/json:\n            schema:\n        \
        \      type: object\n              properties:\n                error: { type: string }\n      '401':\n        description:\
        \ Authentication required or token invalid\n      '403':\n        description: No active subscription\n        content:\n\
        \          application/json:\n            schema:\n              type: object\n              properties:\n       \
        \         error: { type: string }\n      '404':\n        description: Finding not found or user shard not available\n\
        \        content:\n          application/json:\n            schema:\n              type: object\n              properties:\n\
        \                error: { type: string }\n      '500':\n        description: Unexpected server error"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                action:
                  description: Field read by the handler.
                findingId:
                  description: Field read by the handler.
                snoozeDays:
                  description: Field read by the handler.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  action:
                    description: Response field detected from handler.
                  count:
                    description: Response field detected from handler.
                  filteredFindings:
                    description: Response field detected from handler.
                  findings:
                    description: Response field detected from handler.
                  length:
                    description: Response field detected from handler.
                  'true':
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
  /v1/analysis/chat:
    post:
      tags:
      - v1
      summary: /v1/analysis/chat
      description: POST /v1/analysis/chat — Create chat. This description was auto-generated from the handler implementation;
        for full request/response semantics see the source under `functions/`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                conversationId:
                  description: Field read by the handler.
                question:
                  description: Field read by the handler.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  ai_chat_daily_limit:
                    description: Response field detected from handler.
                  answer:
                    description: Response field detected from handler.
                  chatCount:
                    description: Response field detected from handler.
                  conversationId:
                    description: Response field detected from handler.
                  dailyLimit:
                    description: Response field detected from handler.
                  escalationOffered:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
  /v1/mail/templates:
    get:
      tags:
      - v1
      summary: /v1/mail/templates
      description: GET /v1/mail/templates — Retrieve template. This description was auto-generated from the handler implementation;
        for full request/response semantics see the source under `functions/`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  available:
                    description: Response field detected from handler.
                  templates:
                    description: Response field detected from handler.
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
    options:
      tags:
      - v1
      summary: /v1/mail/templates
      description: /v1/mail/templates
      responses:
        '200':
          description: OK
        '429':
          description: Rate limited
  /v1/mail/credits:
    get:
      tags:
      - v1
      summary: /v1/mail/credits
      description: GET /v1/mail/credits — Retrieve credit. This description was auto-generated from the handler implementation;
        for full request/response semantics see the source under `functions/`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  maxSends:
                    description: Response field detected from handler.
                  periodDays:
                    description: Response field detected from handler.
                  period_days:
                    description: Response field detected from handler.
                  purchasedCredits:
                    description: Response field detected from handler.
                  purchased_credits:
                    description: Response field detected from handler.
                  remaining_tier:
                    description: Response field detected from handler.
                  tier_allowance:
                    description: Response field detected from handler.
                  unlimited:
                    description: Response field detected from handler.
                  used:
                    description: Response field detected from handler.
                  used_this_period:
                    description: Response field detected from handler.
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
    options:
      tags:
      - v1
      summary: /v1/mail/credits
      description: /v1/mail/credits
      responses:
        '200':
          description: OK
        '429':
          description: Rate limited
  /v1/mail/company-contacts:
    get:
      tags:
      - v1
      summary: /v1/mail/company-contacts
      description: GET /v1/mail/company-contacts — Retrieve company contact. This description was auto-generated from the
        handler implementation; for full request/response semantics see the source under `functions/`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  companies:
                    description: Response field detected from handler.
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
    options:
      tags:
      - v1
      summary: /v1/mail/company-contacts
      description: /v1/mail/company-contacts
      responses:
        '200':
          description: OK
        '429':
          description: Rate limited
  /v1/mail/tips:
    get:
      tags:
      - v1
      summary: /v1/mail/tips
      description: GET /v1/mail/tips — Retrieve tip. This description was auto-generated from the handler implementation;
        for full request/response semantics see the source under `functions/`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  REDEMPTION_OPTIONS:
                    description: Response field detected from handler.
                  id:
                    description: Response field detected from handler.
                  initialStatus:
                    description: Response field detected from handler.
                  points_awarded:
                    description: Response field detected from handler.
                  redemption_options:
                    description: Response field detected from handler.
                  rep:
                    description: Response field detected from handler.
                  reputation:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
                  success:
                    description: Response field detected from handler.
                  tip:
                    description: Response field detected from handler.
                  tips:
                    description: Response field detected from handler.
                  'true':
                    description: Response field detected from handler.
        '400':
          description: Invalid request
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
    post:
      tags:
      - v1
      summary: /v1/mail/tips
      description: POST /v1/mail/tips — Create tip. This description was auto-generated from the handler implementation; for
        full request/response semantics see the source under `functions/`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                category:
                  description: Field read by the handler.
                company_contact_id:
                  description: Field read by the handler.
                content:
                  description: Field read by the handler.
                tip_type:
                  description: Field read by the handler.
                title:
                  description: Field read by the handler.
                vote_type:
                  description: Field read by the handler.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  REDEMPTION_OPTIONS:
                    description: Response field detected from handler.
                  id:
                    description: Response field detected from handler.
                  initialStatus:
                    description: Response field detected from handler.
                  points_awarded:
                    description: Response field detected from handler.
                  redemption_options:
                    description: Response field detected from handler.
                  rep:
                    description: Response field detected from handler.
                  reputation:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
                  success:
                    description: Response field detected from handler.
                  tip:
                    description: Response field detected from handler.
                  tips:
                    description: Response field detected from handler.
                  'true':
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
    options:
      tags:
      - v1
      summary: /v1/mail/tips
      description: /v1/mail/tips
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Request body.
              additionalProperties: true
      responses:
        '200':
          description: OK
        '400':
          description: Invalid request
        '429':
          description: Rate limited
  /v1/mail/verify-address:
    post:
      tags:
      - v1
      summary: /v1/mail/verify-address
      description: POST /v1/mail/verify-address — Create verify address. This description was auto-generated from the handler
        implementation; for full request/response semantics see the source under `functions/`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                address_line1:
                  description: Field read by the handler.
                address_line2:
                  description: Field read by the handler.
                city:
                  description: Field read by the handler.
                state:
                  description: Field read by the handler.
                zip_code:
                  description: Field read by the handler.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  city:
                    description: Response field detected from handler.
                  deliverability:
                    description: Response field detected from handler.
                  primary_line:
                    description: Response field detected from handler.
                  secondary_line:
                    description: Response field detected from handler.
                  state:
                    description: Response field detected from handler.
                  zip_code:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
    options:
      tags:
      - v1
      summary: /v1/mail/verify-address
      description: /v1/mail/verify-address
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Request body.
              additionalProperties: true
      responses:
        '200':
          description: OK
        '400':
          description: Invalid request
        '429':
          description: Rate limited
  /v1/mail/letters:
    get:
      tags:
      - v1
      summary: /v1/mail/letters
      description: GET /v1/mail/letters — Retrieve letter. This description was auto-generated from the handler implementation;
        for full request/response semantics see the source under `functions/`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  delivery_method:
                    description: Response field detected from handler.
                  id:
                    description: Response field detected from handler.
                  initialStatus:
                    description: Response field detected from handler.
                  letterId:
                    description: Response field detected from handler.
                  letters:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
                  total:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
    post:
      tags:
      - v1
      summary: /v1/mail/letters
      description: POST /v1/mail/letters — Create letter. This description was auto-generated from the handler implementation;
        for full request/response semantics see the source under `functions/`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                delivery_method:
                  description: Field read by the handler.
                letter_content:
                  description: Field read by the handler.
                recipient_address:
                  description: Field read by the handler.
                recipient_company:
                  description: Field read by the handler.
                recipient_email:
                  description: Field read by the handler.
                recipient_name:
                  description: Field read by the handler.
                template_type:
                  description: Field read by the handler.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  delivery_method:
                    description: Response field detected from handler.
                  id:
                    description: Response field detected from handler.
                  initialStatus:
                    description: Response field detected from handler.
                  letterId:
                    description: Response field detected from handler.
                  letters:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
                  total:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
    options:
      tags:
      - v1
      summary: /v1/mail/letters
      description: /v1/mail/letters
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Request body.
              additionalProperties: true
      responses:
        '200':
          description: OK
        '400':
          description: Invalid request
        '429':
          description: Rate limited
  /v1/admin/evidence-export:
    get:
      tags:
      - v1
      summary: /v1/admin/evidence-export
      description: GET /v1/admin/evidence-export — Retrieve evidence export. This description was auto-generated from the
        handler implementation; for full request/response semantics see the source under `functions/`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
  /v1/admin/status-update:
    get:
      tags:
      - v1
      summary: 'Request body:'
      description: "Request body:\n  severity   {string}  — \"P1\" | \"P2\" | \"P3\" | \"P4\"\n  component  {string}  — affected\
        \ component name (from VALID_COMPONENTS)\n  status     {string}  — \"investigating\" | \"identified\" | \"monitoring\"\
        \ | \"resolved\"\n  message    {string}  — update text (optional for P1/P2 — template used if absent)\n  title   \
        \   {string}  — optional short title/summary\n  use_template {boolean} — if true, override message with the P1/P2\
        \ template\nResponse:\n  { ok: true, id: <update_id>, message: <stored_message>, ... }"
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  INCIDENT_TEMPLATES:
                    description: Response field detected from handler.
                  component:
                    description: Response field detected from handler.
                  created_at:
                    description: Response field detected from handler.
                  effectiveComponent:
                    description: Response field detected from handler.
                  effectiveMessage:
                    description: Response field detected from handler.
                  effectiveTitle:
                    description: Response field detected from handler.
                  id:
                    description: Response field detected from handler.
                  message:
                    description: Response field detected from handler.
                  now:
                    description: Response field detected from handler.
                  severity:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
                  template_used:
                    description: Response field detected from handler.
                  templates:
                    description: Response field detected from handler.
                  title:
                    description: Response field detected from handler.
                  'true':
                    description: Response field detected from handler.
                  updateId:
                    description: Response field detected from handler.
                  updates:
                    description: Response field detected from handler.
                  valid_components:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
    post:
      tags:
      - v1
      summary: 'Request body:'
      description: "Request body:\n  severity   {string}  — \"P1\" | \"P2\" | \"P3\" | \"P4\"\n  component  {string}  — affected\
        \ component name (from VALID_COMPONENTS)\n  status     {string}  — \"investigating\" | \"identified\" | \"monitoring\"\
        \ | \"resolved\"\n  message    {string}  — update text (optional for P1/P2 — template used if absent)\n  title   \
        \   {string}  — optional short title/summary\n  use_template {boolean} — if true, override message with the P1/P2\
        \ template\nResponse:\n  { ok: true, id: <update_id>, message: <stored_message>, ... }"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                component:
                  description: Field read by the handler.
                message:
                  description: Field read by the handler.
                severity:
                  description: Field read by the handler.
                status:
                  description: Field read by the handler.
                title:
                  description: Field read by the handler.
                use_template:
                  description: Field read by the handler.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  INCIDENT_TEMPLATES:
                    description: Response field detected from handler.
                  component:
                    description: Response field detected from handler.
                  created_at:
                    description: Response field detected from handler.
                  effectiveComponent:
                    description: Response field detected from handler.
                  effectiveMessage:
                    description: Response field detected from handler.
                  effectiveTitle:
                    description: Response field detected from handler.
                  id:
                    description: Response field detected from handler.
                  message:
                    description: Response field detected from handler.
                  now:
                    description: Response field detected from handler.
                  severity:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
                  template_used:
                    description: Response field detected from handler.
                  templates:
                    description: Response field detected from handler.
                  title:
                    description: Response field detected from handler.
                  'true':
                    description: Response field detected from handler.
                  updateId:
                    description: Response field detected from handler.
                  updates:
                    description: Response field detected from handler.
                  valid_components:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
  /v1/admin/ai-usage:
    get:
      tags:
      - v1
      summary: /v1/admin/ai-usage
      description: GET /v1/admin/ai-usage — Retrieve ai usage. This description was auto-generated from the handler implementation;
        for full request/response semantics see the source under `functions/`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  days:
                    description: Response field detected from handler.
                  usage:
                    description: Response field detected from handler.
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
  /v1/admin/recovery-telemetry:
    get:
      tags:
      - v1
      summary: /v1/admin/recovery-telemetry
      description: GET /v1/admin/recovery-telemetry — Retrieve recovery telemetry. This description was auto-generated from
        the handler implementation; for full request/response semantics see the source under `functions/`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  avg_completion_seconds:
                    description: Response field detected from handler.
                  completed:
                    description: Response field detected from handler.
                  days:
                    description: Response field detected from handler.
                  denied:
                    description: Response field detected from handler.
                  expired:
                    description: Response field detected from handler.
                  generated_at:
                    description: Response field detected from handler.
                  in_progress:
                    description: Response field detected from handler.
                  'null':
                    description: Response field detected from handler.
                  period_days:
                    description: Response field detected from handler.
                  summary:
                    description: Response field detected from handler.
                  total_requests:
                    description: Response field detected from handler.
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
    options:
      tags:
      - v1
      summary: /v1/admin/recovery-telemetry
      description: /v1/admin/recovery-telemetry
      responses:
        '200':
          description: OK
        '429':
          description: Rate limited
  /v1/admin/audit-verify:
    post:
      tags:
      - v1
      summary: /v1/admin/audit-verify
      description: POST /v1/admin/audit-verify — Create audit verify. This description was auto-generated from the handler
        implementation; for full request/response semantics see the source under `functions/`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  anchorCount:
                    description: Response field detected from handler.
                  anchorErrors:
                    description: Response field detected from handler.
                  anchor_count:
                    description: Response field detected from handler.
                  anchor_errors:
                    description: Response field detected from handler.
                  anchorsValid:
                    description: Response field detected from handler.
                  anchors_valid:
                    description: Response field detected from handler.
                  broken_at_id:
                    description: Response field detected from handler.
                  chain_valid:
                    description: Response field detected from handler.
                  entries:
                    description: Response field detected from handler.
                  lastAnchorTime:
                    description: Response field detected from handler.
                  last_anchor_time:
                    description: Response field detected from handler.
                  'null':
                    description: Response field detected from handler.
                  sub:
                    description: Response field detected from handler.
                  total_entries:
                    description: Response field detected from handler.
                  undefined:
                    description: Response field detected from handler.
                  valid:
                    description: Response field detected from handler.
                  verified_at:
                    description: Response field detected from handler.
                  verified_by:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
  /v1/admin/ai-quality:
    get:
      tags:
      - v1
      summary: /v1/admin/ai-quality
      description: GET /v1/admin/ai-quality — Retrieve ai quality. This description was auto-generated from the handler implementation;
        for full request/response semantics see the source under `functions/`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  alerts:
                    description: Response field detected from handler.
                  engines:
                    description: Response field detected from handler.
                  message:
                    description: Response field detected from handler.
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
  /v1/leads/tiktok-vcard:
    post:
      tags:
      - v1
      summary: receive a TikTok Lead Form submission
      description: "(forwarded by Zapier or LeadsBridge from TikTok's lead webhook).\nFlow:\n  1. Verify HMAC signature against\
        \ TIKTOK_LEAD_WEBHOOK_SECRET.\n  2. Normalize the submitted vCard fields.\n  3. Sign a 7-day JWT carrying the vCard\
        \ data (stateless — no DB write\n     required for the MVP; the token IS the lead record).\n  4. Email the user a\
        \ \"Customize your QR business card\" link to\n     https://aqr.net/edit?token=<jwt>. aqr.net validates the JWT\n\
        \     against the same JWKS and pre-fills its vCard editor.\nRequest body (Zapier/LeadsBridge will map TikTok's fields\
        \ to these names):\n  {\n    \"full_name\":   \"Cisco Caceres\",\n    \"phone\":       \"+12066597857\",\n    \"email\"\
        :       \"cisco@abundera.ai\",\n    \"company\":     \"Abundera, Inc.\",\n    \"job_title\":   \"Founder\",\n    \"\
        tiktok_lead_id\": \"...\",  // optional, for analytics\n    \"campaign\":    \"qr-vcard-aaron-en\"\n  }\nHeaders:\n\
        \  X-TikTok-Lead-Signature: hex(hmac-sha256(secret, raw_body))"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  code:
                    description: Response field detected from handler.
                  edit_link_ttl_days:
                    description: Response field detected from handler.
                  email:
                    description: Response field detected from handler.
                  error:
                    description: Response field detected from handler.
                  sent_to:
                    description: Response field detected from handler.
                  'true':
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
  /v1/admin/support/conversations:
    get:
      tags:
      - v1
      summary: /v1/admin/support/conversations
      description: GET /v1/admin/support/conversations — Retrieve conversation. This description was auto-generated from the
        handler implementation; for full request/response semantics see the source under `functions/`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  conversations:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
    post:
      tags:
      - v1
      summary: /v1/admin/support/conversations
      description: POST /v1/admin/support/conversations — Create conversation. This description was auto-generated from the
        handler implementation; for full request/response semantics see the source under `functions/`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                action:
                  description: Field read by the handler.
                conversationId:
                  description: Field read by the handler.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  conversations:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
  /v1/admin/support/{conversationId}/messages:
    get:
      tags:
      - v1
      summary: /v1/admin/support/{conversationId}/messages
      description: GET /v1/admin/support/{conversationId}/messages — Retrieve message. This description was auto-generated
        from the handler implementation; for full request/response semantics see the source under `functions/`.
      parameters:
      - name: conversationId
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  messages:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
                  userId:
                    description: Response field detected from handler.
                  user_id:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
    post:
      tags:
      - v1
      summary: /v1/admin/support/{conversationId}/messages
      description: POST /v1/admin/support/{conversationId}/messages — Create message. This description was auto-generated
        from the handler implementation; for full request/response semantics see the source under `functions/`.
      parameters:
      - name: conversationId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                content:
                  description: Field read by the handler.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  messages:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
                  userId:
                    description: Response field detected from handler.
                  user_id:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
  /v1/analysis/chat/escalate:
    post:
      tags:
      - v1
      summary: /v1/analysis/chat/escalate
      description: POST /v1/analysis/chat/escalate — Create escalate. This description was auto-generated from the handler
        implementation; for full request/response semantics see the source under `functions/`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                conversationId:
                  description: Field read by the handler.
                reason:
                  description: Field read by the handler.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  message:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
  /v1/analysis/chat/conversations:
    get:
      tags:
      - v1
      summary: /v1/analysis/chat/conversations
      description: "/analysis/chat/conversations:\n  get:\n    tags: [analysis/chat/conversations]\n    summary: List user's\
        \ support conversations\n    description: |\n      Returns the most recent support conversations belonging to the\
        \ authenticated user, ordered by last update descending. Up to 20 conversations are returned per call.\n      Requires\
        \ a valid bearer JWT. The user identity is extracted from the token's `sub` claim to scope the query.\n      No pagination\
        \ cursor is exposed; this call always returns the latest 20 conversations.\n    security:\n      - bearerAuth: []\n\
        \    responses:\n      '200':\n        description: Conversations listed successfully\n        content:\n        \
        \  application/json:\n            schema:\n              type: object\n              properties:\n               \
        \ conversations:\n                  type: array\n                  items:\n                    type: object\n    \
        \                properties:\n                      id: { type: string }\n                      status: { type: string\
        \ }\n                      escalation_reason: { type: string, nullable: true }\n                      assigned_admin_id:\
        \ { type: string, nullable: true }\n                      last_message_at: { type: string, format: date-time }\n \
        \                     message_count: { type: integer }\n                      created_at: { type: string, format:\
        \ date-time }\n      '401':\n        description: Authentication required or token invalid\n      '500':\n       \
        \ description: Internal server error\n        content:\n          application/json:\n            schema:\n       \
        \       type: object\n              properties:\n                error: { type: string }\n  post:\n    tags: [analysis/chat/conversations]\n\
        \    summary: Create a new support conversation\n    description: |\n      Creates a new support conversation for\
        \ the authenticated user. The conversation starts in `ai_only` status and is assigned to the user's existing data\
        \ shard for message storage.\n      Requires a valid bearer JWT. The user identity is taken from the token's `sub`\
        \ claim. If no shard record exists for the user, the request is rejected with a 404.\n      No request body is required.\
        \ The conversation ID is generated server-side as a UUID and the creation timestamp is recorded. Returns the new conversation\
        \ ID on success.\n    security:\n      - bearerAuth: []\n    responses:\n      '201':\n        description: Conversation\
        \ created\n        content:\n          application/json:\n            schema:\n              type: object\n      \
        \        properties:\n                conversationId: { type: string, format: uuid }\n      '401':\n        description:\
        \ Authentication required or token invalid\n      '404':\n        description: User shard not found\n        content:\n\
        \          application/json:\n            schema:\n              type: object\n              properties:\n       \
        \         error: { type: string }\n      '500':\n        description: Internal server error\n        content:\n  \
        \        application/json:\n            schema:\n              type: object\n              properties:\n         \
        \       error: { type: string }"
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  conversationId:
                    description: Response field detected from handler.
                  conversations:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
    post:
      tags:
      - v1
      summary: /v1/analysis/chat/conversations
      description: "/analysis/chat/conversations:\n  get:\n    tags: [analysis/chat/conversations]\n    summary: List user's\
        \ support conversations\n    description: |\n      Returns the most recent support conversations belonging to the\
        \ authenticated user, ordered by last update descending. Up to 20 conversations are returned per call.\n      Requires\
        \ a valid bearer JWT. The user identity is extracted from the token's `sub` claim to scope the query.\n      No pagination\
        \ cursor is exposed; this call always returns the latest 20 conversations.\n    security:\n      - bearerAuth: []\n\
        \    responses:\n      '200':\n        description: Conversations listed successfully\n        content:\n        \
        \  application/json:\n            schema:\n              type: object\n              properties:\n               \
        \ conversations:\n                  type: array\n                  items:\n                    type: object\n    \
        \                properties:\n                      id: { type: string }\n                      status: { type: string\
        \ }\n                      escalation_reason: { type: string, nullable: true }\n                      assigned_admin_id:\
        \ { type: string, nullable: true }\n                      last_message_at: { type: string, format: date-time }\n \
        \                     message_count: { type: integer }\n                      created_at: { type: string, format:\
        \ date-time }\n      '401':\n        description: Authentication required or token invalid\n      '500':\n       \
        \ description: Internal server error\n        content:\n          application/json:\n            schema:\n       \
        \       type: object\n              properties:\n                error: { type: string }\n  post:\n    tags: [analysis/chat/conversations]\n\
        \    summary: Create a new support conversation\n    description: |\n      Creates a new support conversation for\
        \ the authenticated user. The conversation starts in `ai_only` status and is assigned to the user's existing data\
        \ shard for message storage.\n      Requires a valid bearer JWT. The user identity is taken from the token's `sub`\
        \ claim. If no shard record exists for the user, the request is rejected with a 404.\n      No request body is required.\
        \ The conversation ID is generated server-side as a UUID and the creation timestamp is recorded. Returns the new conversation\
        \ ID on success.\n    security:\n      - bearerAuth: []\n    responses:\n      '201':\n        description: Conversation\
        \ created\n        content:\n          application/json:\n            schema:\n              type: object\n      \
        \        properties:\n                conversationId: { type: string, format: uuid }\n      '401':\n        description:\
        \ Authentication required or token invalid\n      '404':\n        description: User shard not found\n        content:\n\
        \          application/json:\n            schema:\n              type: object\n              properties:\n       \
        \         error: { type: string }\n      '500':\n        description: Internal server error\n        content:\n  \
        \        application/json:\n            schema:\n              type: object\n              properties:\n         \
        \       error: { type: string }"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  description: Request payload. Exact field set depends on the endpoint; check the handler source for body
                    destructuring patterns.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  conversationId:
                    description: Response field detected from handler.
                  conversations:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
  /v1/analysis/chat/ws-ticket:
    post:
      tags:
      - v1
      summary: /v1/analysis/chat/ws-ticket
      description: POST /v1/analysis/chat/ws-ticket — Create ws ticket. This description was auto-generated from the handler
        implementation; for full request/response semantics see the source under `functions/`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                conversationId:
                  description: Field read by the handler.
              additionalProperties: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  expiresIn:
                    description: Response field detected from handler.
                  ticket:
                    description: Response field detected from handler.
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
        '429':
          description: Rate limited
  /v1/analysis/chat/{conversationId}/messages:
    get:
      tags:
      - v1
      summary: /v1/analysis/chat/{conversationId}/messages
      description: "/analysis/chat/{conversationId}/messages:\n  get:\n    tags: [analysis-chat]\n    summary: Retrieve message\
        \ history for a conversation\n    description: |\n      Returns the ordered message history for a single analysis\
        \ chat conversation. Up to 50 messages\n      are returned per request, sorted oldest-first by creation time.\n  \
        \    Authentication is required. The caller must present a valid bearer JWT. The conversation ID\n      is validated\
        \ against the authenticated user's identity (IDOR protection) — requests for\n      conversations owned by another\
        \ user are rejected before any messages are fetched.\n      Messages are fetched from the user's assigned shard database.\
        \ The response also includes\n      the current status of the conversation.\n    security:\n      - bearerAuth: []\n\
        \    parameters:\n      - name: conversationId\n        in: path\n        required: true\n        schema:\n      \
        \    type: string\n        description: Unique identifier of the conversation whose messages are being retrieved.\n\
        \    responses:\n      '200':\n        description: Message history returned successfully\n        content:\n    \
        \      application/json:\n            schema:\n              type: object\n              properties:\n           \
        \     messages:\n                  type: array\n                  items:\n                    type: object\n     \
        \               properties:\n                      id:\n                        type: string\n                   \
        \   role:\n                        type: string\n                      content:\n                        type: string\n\
        \                      is_human_reply:\n                        type: boolean\n                      created_at:\n\
        \                        type: string\n                status:\n                  type: string\n      '400':\n   \
        \     description: Missing or invalid conversation ID\n        content:\n          application/json:\n           \
        \ schema:\n              type: object\n              properties:\n                error:\n                  type:\
        \ string\n      '401':\n        description: Authentication required or token invalid\n      '403':\n        description:\
        \ Conversation belongs to a different user\n      '500':\n        description: Internal error loading messages\n \
        \       content:\n          application/json:\n            schema:\n              type: object\n              properties:\n\
        \                error:\n                  type: string"
      parameters:
      - name: conversationId
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
                  messages:
                    description: Response field detected from handler.
                  status:
                    description: Response field detected from handler.
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
  /api/docs:
    get:
      tags:
      - docs
      summary: Retrieve doc (docs)
      description: GET /api/docs — Retrieve doc. This description was auto-generated from the handler implementation; for
        full request/response semantics see the source under `functions/`.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
        '429':
          description: Rate limited
        '404':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
  /api/docs/{slug}:
    get:
      tags:
      - docs
      summary: /api/docs/{slug}
      description: GET /api/docs/{slug} — Retrieve doc. This description was auto-generated from the handler implementation;
        for full request/response semantics see the source under `functions/`.
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                properties:
                  ok:
                    type: boolean
                    description: True when the request succeeded.
        '429':
          description: Rate limited
        '400':
          description: Error
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - error
                properties:
                  ok:
                    type: boolean
                    const: false
                    description: False on error.
                  error:
                    type: string
                    description: Machine-readable error code.
                  retry_after:
                    type: integer
                    description: Seconds to wait before retry. Present on 429.
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'JWT session token from WebAuthn login flow. Set as cookie `abundera_session` by the browser, or pass manually:
        `Authorization: Bearer <jwt>`'
    apiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'API key for programmatic access. Format: `abnd_live_<hex>`. Create via Settings > API Keys (Pro plan required).
        Pass as: `Authorization: Bearer abnd_live_...`. All endpoints accept API keys via the same requireAuth() chokepoint
        as JWT sessions. Keys are scoped and rate-limited per-user per-tier. Keys without IP restrictions require a 1-90 day
        expiry. Keys unused for 90+ days are auto-deactivated.'
    cookieAuth:
      type: apiKey
      in: cookie
      name: abundera_session
      description: Session cookie set after WebAuthn login. Used automatically by the browser dashboard.
  responses:
    Unauthorized:
      description: Authentication required. Provide a valid JWT session cookie or API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Authentication required.
            request_id: req_a1b2c3d4e5
    Forbidden:
      description: Authenticated but insufficient permissions or plan tier.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Forbidden.
            request_id: req_a1b2c3d4e5
    TooManyRequests:
      description: Rate limit exceeded. See Retry-After header.
      headers:
        Retry-After:
          description: Seconds until rate limit window resets
          schema:
            type: integer
            example: 60
        X-RateLimit-Limit:
          description: Max requests allowed per window
          schema:
            type: integer
            example: 30
        X-RateLimit-Remaining:
          description: Remaining requests in current window
          schema:
            type: integer
            example: 0
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RateLimitError'
    NotFound:
      description: Resource not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Not found.
            request_id: req_a1b2c3d4e5
    InternalServerError:
      description: Unexpected server error. Contact support with the request_id.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Internal server error.
            request_id: req_a1b2c3d4e5
  schemas:
    Error:
      type: object
      description: Standard error response returned by all endpoints on failure.
      properties:
        error:
          type: string
          description: Human-readable error message
          example: Authentication required.
        request_id:
          type: string
          description: Unique request ID for support reference
          example: req_a1b2c3d4e5
      required:
      - error
    Success:
      type: object
      description: Standard success response for write operations.
      properties:
        success:
          type: boolean
          example: true
        id:
          type: string
          description: ID of created/updated resource (when applicable)
          format: uuid
        request_id:
          type: string
          description: Unique request ID
    RateLimitError:
      type: object
      description: Returned when the client exceeds the rate limit for this endpoint.
      properties:
        error:
          type: string
          example: Too many requests. Please try again later.
        request_id:
          type: string
          example: req_a1b2c3d4e5
      required:
      - error
    NotificationLogs:
      type: object
      properties:
        id:
          type: integer
        request_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        ts:
          type: string
        notification_type:
          type: string
        event:
          type: string
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        recipient:
          type: string
        subject:
          type: string
          example: Welcome!
        status:
          type: string
          default: sent
          example: active
        error_message:
          type: string
        metadata:
          type: string
      description: Domain model for notification_logs table
      required:
      - notification_type
      - event
    Assets:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        parent_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        name:
          type: string
          example: John Smith
        category:
          type: string
          example: income
        type:
          type: string
          example: checking
        purchase_price:
          type: number
          example: 250000.0
        current_value:
          type: number
          example: 350000.0
        purchase_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        ownership:
          type: string
          default: owned
          example: owned
        location:
          type: string
          example: Las Vegas, NV
        identifier_label:
          type: string
        identifier_value:
          type: string
        details:
          type: string
        is_active:
          type: integer
          default: 1
        notes:
          type: string
          example: Important details
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for assets table
      required:
      - user_id
      - name
      - category
      - type
    Liabilities:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        name:
          type: string
          example: John Smith
        type:
          type: string
          example: checking
        lender:
          type: string
          example: Chase Bank
        original_amount:
          type: number
          example: 200000.0
        current_balance:
          type: number
          example: 175000.0
        interest_rate:
          type: number
          example: 4.5
        monthly_payment:
          type: number
          example: 1500.0
        minimum_payment:
          type: number
        origination_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        maturity_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        linked_asset_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        linked_entity_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        credit_limit:
          type: number
        utilization_rate:
          type: number
        category:
          type: string
          example: income
        details:
          type: string
        is_active:
          type: integer
          default: 1
        notes:
          type: string
          example: Important details
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for liabilities table
      required:
      - user_id
      - name
      - type
      - lender
      - current_balance
    CashFlows:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        name:
          type: string
          example: John Smith
        direction:
          type: string
        type:
          type: string
          example: checking
        amount:
          type: number
          example: 50000.0
        frequency:
          type: string
          example: monthly
        linked_entity_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        linked_asset_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        family_member_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        category:
          type: string
          example: income
        details:
          type: string
        is_active:
          type: integer
          default: 1
        start_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        end_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        notes:
          type: string
          example: Important details
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for cash_flows table
      required:
      - user_id
      - name
      - direction
      - type
      - amount
      - frequency
    Entities:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        name:
          type: string
          example: John Smith
        type:
          type: string
          example: checking
        entity_number:
          type: string
          example: 88-1234567
        state:
          type: string
          example: NV
        formation_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        purpose:
          type: string
          example: Investment holding company
        estimated_value:
          type: number
          example: 500000.0
        details:
          type: string
        is_active:
          type: integer
          default: 1
        notes:
          type: string
          example: Important details
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for entities table
      required:
      - user_id
      - name
      - type
    InsurancePolicies:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        name:
          type: string
          example: John Smith
        type:
          type: string
          example: checking
        carrier:
          type: string
          example: State Farm
        policy_number:
          type: string
          example: POL-12345
        coverage_amount:
          type: number
          example: 500000.0
        deductible:
          type: number
          example: 1000.0
        premium_amount:
          type: number
          example: 150.0
        premium_frequency:
          type: string
          default: monthly
        effective_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        expiration_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        beneficiaries:
          type: string
        linked_asset_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        linked_entity_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        is_active:
          type: integer
          default: 1
        notes:
          type: string
          example: Important details
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for insurance_policies table
      required:
      - user_id
      - name
      - type
      - carrier
      - premium_amount
    Affiliations:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        name:
          type: string
          example: John Smith
        type:
          type: string
          example: checking
        role:
          type: string
          example: member
        membership_number:
          type: string
          example: MEM-12345
        join_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        annual_dues:
          type: number
          default: 0
          example: 250.0
        status:
          type: string
          example: active
        service_branch:
          type: string
        rank:
          type: string
        service_start:
          type: string
        service_end:
          type: string
        benefits:
          type: string
        id_number:
          type: string
        is_active:
          type: integer
          default: 1
        notes:
          type: string
          example: Important details
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for affiliations table
      required:
      - user_id
      - name
      - type
    ContactsNetwork:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        full_name:
          type: string
          example: John Smith
        relationship:
          type: string
          example: spouse
        category:
          type: string
          example: income
        email:
          type: string
          example: user@example.com
        phone:
          type: string
          example: '+15551234567'
        company:
          type: string
          example: Acme Corp
        title:
          type: string
          example: Software Engineer
        is_emergency_contact:
          type: integer
          default: 0
        is_active:
          type: integer
          default: 1
        notes:
          type: string
          example: Important details
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for contacts_network table
      required:
      - user_id
      - full_name
      - relationship
      - category
    Subscriptions:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        name:
          type: string
          example: John Smith
        category:
          type: string
          example: income
        amount:
          type: number
          example: 50000.0
        frequency:
          type: string
          example: monthly
        status:
          type: string
          default: active
          example: active
        next_billing_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        trial_end_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        payment_method:
          type: string
        auto_renew:
          type: integer
          default: 1
        shared_with:
          type: integer
          default: 1
        start_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        cancel_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        family_member_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        details:
          type: string
        notes:
          type: string
          example: Important details
        is_active:
          type: integer
          default: 1
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for subscriptions table
      required:
      - user_id
      - name
      - category
      - amount
      - frequency
    FamilyMembers:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        full_name:
          type: string
          example: John Smith
        relationship:
          type: string
          example: spouse
        date_of_birth:
          type: string
          example: '1990-05-20'
        is_dependent:
          type: integer
          default: 0
        is_minor:
          type: integer
          default: 0
        is_beneficiary:
          type: integer
          default: 0
        guardian_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        ssn_last_four:
          type: string
          example: '1234'
        employment_status:
          type: string
        annual_income:
          type: number
          example: 85000.0
        health_coverage:
          type: string
        education_status:
          type: string
        education_target_year:
          type: integer
        education_est_cost:
          type: number
          example: 50000.0
        special_needs:
          type: integer
          default: 0
        notes:
          type: string
          example: Important details
        is_active:
          type: integer
          default: 1
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for family_members table
      required:
      - user_id
      - full_name
      - relationship
    FinancialGoals:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        name:
          type: string
          example: John Smith
        category:
          type: string
          example: income
        target_amount:
          type: number
          example: 100000.0
        current_amount:
          type: number
          default: 0
          example: 25000.0
        monthly_contribution:
          type: number
          example: 500.0
        target_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        priority:
          type: string
          default: medium
          example: high
        linked_account_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        linked_family_member_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        status:
          type: string
          default: active
          example: active
        notes:
          type: string
          example: Important details
        is_active:
          type: integer
          default: 1
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for financial_goals table
      required:
      - user_id
      - name
      - category
    EstateDocuments:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        type:
          type: string
          example: checking
        title:
          type: string
          example: Software Engineer
        status:
          type: string
          default: active
          example: active
        effective_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        expiration_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        attorney_contact_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        executor_family_member_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        trustee_family_member_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        agent_family_member_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        document_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        review_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        state:
          type: string
          example: NV
        notes:
          type: string
          example: Important details
        is_active:
          type: integer
          default: 1
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for estate_documents table
      required:
      - user_id
      - type
      - title
    BeneficiaryDesignations:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        asset_type:
          type: string
          example: retirement_401k
        asset_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        asset_description:
          type: string
          example: Fidelity 401k
        beneficiary_type:
          type: string
          example: primary
        beneficiary_family_member_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        beneficiary_entity_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        beneficiary_name:
          type: string
          example: Jane Smith
        percentage:
          type: number
          example: 100.0
        last_verified_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        notes:
          type: string
          example: Important details
        is_active:
          type: integer
          default: 1
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for beneficiary_designations table
      required:
      - user_id
      - asset_type
      - beneficiary_type
    PersonalDocuments:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        family_member_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        type:
          type: string
          example: checking
        issuing_authority:
          type: string
          example: State of Nevada
        document_number:
          type: string
          example: DL-123456
        issue_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        expiration_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        country:
          type: string
          example: US
        state:
          type: string
          example: NV
        status:
          type: string
          default: active
          example: active
        file_document_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        notes:
          type: string
          example: Important details
        is_active:
          type: integer
          default: 1
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for personal_documents table
      required:
      - user_id
      - type
    Notifications:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        type:
          type: string
          default: info
          example: checking
        title:
          type: string
          example: Software Engineer
        body:
          type: string
        severity:
          type: string
          default: info
        source:
          type: string
        action_url:
          type: string
        metadata:
          type: string
        read:
          type: integer
          default: 0
        dismissed:
          type: integer
          default: 0
      description: Domain model for notifications table
      required:
      - user_id
      - title
    CharitableDonations:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        organization:
          type: string
        ein:
          type: string
        amount:
          type: number
          example: 50000.0
        donation_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        type:
          type: string
          default: cash
          example: checking
        tax_deductible:
          type: integer
          default: 1
        receipt_uploaded:
          type: integer
          default: 0
        category:
          type: string
          example: income
        acknowledgment:
          type: string
        notes:
          type: string
          example: Important details
        is_active:
          type: integer
          default: 1
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for charitable_donations table
      required:
      - user_id
      - organization
      - amount
      - donation_date
    Vehicles:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        year:
          type: integer
        make:
          type: string
        model:
          type: string
        trim_level:
          type: string
        vin:
          type: string
        license_plate:
          type: string
        type:
          type: string
          default: car
          example: checking
        ownership:
          type: string
          default: owned
          example: owned
        purchase_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        purchase_price:
          type: number
          example: 250000.0
        current_value:
          type: number
          example: 350000.0
        mileage:
          type: integer
        condition:
          type: string
          default: good
        loan_balance:
          type: number
        monthly_payment:
          type: number
          example: 1500.0
        notes:
          type: string
          example: Important details
        is_active:
          type: integer
          default: 1
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for vehicles table
      required:
      - user_id
      - make
      - model
    BudgetCategories:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        name:
          type: string
          example: John Smith
        type:
          type: string
          default: needs
          example: checking
        monthly_limit:
          type: number
          default: 0
        color:
          type: string
          default: '#6366f1'
        notes:
          type: string
          example: Important details
        is_active:
          type: integer
          default: 1
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for budget_categories table
      required:
      - user_id
      - name
    CreditScores:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        bureau:
          type: string
        score:
          type: integer
        score_type:
          type: string
          default: fico
        report_date:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
        factors:
          type: string
        credit_utilization:
          type: number
        total_accounts:
          type: integer
        derogatory_marks:
          type: integer
        hard_inquiries:
          type: integer
        oldest_account_years:
          type: number
        source:
          type: string
          default: manual
        notes:
          type: string
          example: Important details
        is_active:
          type: integer
          default: 1
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for credit_scores table
      required:
      - user_id
      - bureau
      - score
      - report_date
    AlertPreferences:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        engine_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        category:
          type: string
          example: income
        channel:
          type: string
          default: in_app
        frequency:
          type: string
          default: realtime
          example: monthly
        threshold_amount:
          type: number
        is_enabled:
          type: integer
          default: 1
        details:
          type: string
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for alert_preferences table
      required:
      - user_id
      - category
    TaxProfiles:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        user_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        year:
          type: integer
        filing_status:
          type: string
          default: married_joint
          example: married_filing_jointly
        gross_income:
          type: number
        taxable_income:
          type: number
        federal_tax:
          type: number
        state_tax:
          type: number
        self_employment_tax:
          type: number
        effective_rate:
          type: number
        quarterly_paid:
          type: number
        details:
          type: string
        notes:
          type: string
          example: Important details
        source_type:
          type: string
          default: manual
        source_id:
          type: string
          format: uuid
          example: 550e8400-e29b-41d4-a716-446655440000
        updated_at:
          type: string
          format: date-time
          example: '2026-01-15T12:00:00Z'
      description: Domain model for tax_profiles table
      required:
      - user_id
      - year
