openapi: "3.1.0"
info:
  title: "Soledgic API"
  version: "2026-03-01"
  description: "Platform payment infrastructure API for creator platforms and marketplaces. Handles checkout sessions,
    internal wallet balances, atomic revenue splits, escrow-style holds, ACH payouts, and a double-entry ledger —
    everything that happens to money after it arrives on your platform.


    All amounts are in cents. Authentication is via the x-api-key header. Test keys (slk_test_) are available
    immediately; live keys (slk_live_) unlock after KYB approval.


    Resource flow for a typical marketplace integration:

    1. POST /v1/participants — create a creator account

    2. POST /v1/checkout-sessions — create a hosted payment page; revenue split applied on completion

    3. GET /v1/wallets?owner_id={participant_id} — check creator earnings balance

    4. GET /v1/participants/{participant_id}/payout-eligibility — verify payout readiness

    5. POST /v1/payouts — initiate ACH payout to creator bank account


    All operationIds use camelCase verb+noun format (e.g. createCheckoutSession, requestPayout) so AI coding agents can
    infer intent from the function name alone. Parameter descriptions include where to obtain each value. Dashboard and
    operator control-plane routes are intentionally excluded from this spec."
  license:
    name: "Proprietary"
    identifier: "LicenseRef-Proprietary"
servers:
  - url: "https://api.soledgic.com"
    description: "Public Soledgic API host"
security:
  - ApiKeyAuth: []
tags:
  - name: "Accounting"
    description: "Journal adjustments, opening balances, transfers, bills, expenses, income, period close"
  - name: "Balances"
    description: "Query creator balances, platform summary, and cash runway"
  - name: "Banking"
    description: "Bank account management and statement import"
  - name: "Creators"
    description: "Create and manage creator accounts, splits, and contractor relationships"
  - name: "Invoicing"
    description: "Invoice management and PDF generation"
  - name: "KYC"
    description: "Business KYB and creator KYC intake packets for review and payout readiness"
  - name: "Other"
    description: "Additional public endpoints that do not fall under a primary product tag"
  - name: "Payments"
    description: "Checkout sessions, payouts, refunds, and payment-adjacent platform flows"
  - name: "Reports"
    description: "Financial reports — balance sheet, P&L, trial balance, aging, statements"
  - name: "Risk"
    description: "Risk evaluation, policy configuration, alerts, and preflight authorization"
  - name: "Tax"
    description: "Tax document generation and summaries"
  - name: "Transactions"
    description: "List and import transactions"
  - name: "Treasury"
    description: "Platform treasury resources for participants, wallets, holds, and internal transfers"
  - name: "Webhooks"
    description: "Webhook endpoint management"
paths:
  /v1/participants:
    get:
      operationId: "listParticipants"
      summary: "List treasury participants or create a new participant-backed account."
      tags:
        - "Treasury"
      responses:
        "200":
          description: "Success"
          headers: &a1
            X-Request-Id:
              description: "Unique request identifier"
              schema:
                type: "string"
                examples:
                  - "req_abc123"
            Soledgic-Version:
              description: "API version used"
              schema:
                type: "string"
                examples:
                  - "2026-03-01"
            X-RateLimit-Remaining:
              description: "Remaining requests in current window"
              schema:
                type: "integer"
            X-RateLimit-Reset:
              description: "Unix timestamp when rate limit resets"
              schema:
                type: "integer"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantsListResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "createParticipant"
      summary: "List treasury participants or create a new participant-backed account."
      tags:
        - "Treasury"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ParticipantCreateRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content: &a2
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantCreateResponse"
        "201":
          description: "Participant created"
          headers: *a1
          content: *a2
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/participants/{participant_id}:
    get:
      operationId: "getParticipant"
      summary: "Get a participant balance snapshot, including active holds."
      tags:
        - "Treasury"
      parameters:
        - name: "participant_id"
          in: "path"
          required: true
          schema:
            type: "string"
          description: "The unique identifier for the creator or seller. Create one via POST /v1/participants if it does not exist
            yet. Use your platform's stable user ID here."
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantDetailResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/participants/{participant_id}/payout-eligibility:
    get:
      operationId: "checkPayoutEligibility"
      summary: "Check whether a participant is currently eligible for payout."
      tags:
        - "Treasury"
      parameters:
        - name: "participant_id"
          in: "path"
          required: true
          schema:
            type: "string"
          description: "The unique identifier for the creator or seller. Create one via POST /v1/participants if it does not exist
            yet. Use your platform's stable user ID here."
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ParticipantEligibilityResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/kyc/business:
    get:
      operationId: "getBusinessVerification"
      summary: "Retrieve or submit the API key organization KYB profile for review. Submission never auto-approves KYB."
      tags:
        - "KYC"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "submitBusinessVerification"
      summary: "Retrieve or submit the API key organization KYB profile for review. Submission never auto-approves KYB."
      tags:
        - "KYC"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                business_type:
                  type: "string"
                  enum:
                    - "individual"
                    - "sole_proprietor"
                    - "llc"
                    - "corporation"
                    - "partnership"
                    - "nonprofit"
                legal_name:
                  type: "string"
                tax_id_type:
                  type: "string"
                  enum:
                    - "ssn"
                    - "ein"
                    - "itin"
                tax_id_last4:
                  type: "string"
                primary_contact:
                  type: "object"
                  additionalProperties: true
                business_address:
                  type: "object"
                  additionalProperties: true
                beneficial_owners:
                  type: "array"
                  items:
                    type: "object"
                    additionalProperties: true
                document_evidence:
                  type: "array"
                  items:
                    type: "object"
                    additionalProperties: true
                submit_for_review:
                  type: "boolean"
                metadata:
                  type: "object"
                  additionalProperties: true
              required:
                - "business_type"
                - "legal_name"
                - "primary_contact"
                - "business_address"
                - "document_evidence"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/kyc/creators/{participant_id}:
    get:
      operationId: "getCreatorVerification"
      summary: "Retrieve or submit a creator KYC packet bound to the participant creator_balance, not the consumer wallet."
      tags:
        - "KYC"
      parameters:
        - name: "participant_id"
          in: "path"
          required: true
          schema:
            type: "string"
          description: "The unique identifier for the creator or seller. Create one via POST /v1/participants if it does not exist
            yet. Use your platform's stable user ID here."
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "submitCreatorVerification"
      summary: "Retrieve or submit a creator KYC packet bound to the participant creator_balance, not the consumer wallet."
      tags:
        - "KYC"
      parameters:
        - name: "participant_id"
          in: "path"
          required: true
          schema:
            type: "string"
          description: "The unique identifier for the creator or seller. Create one via POST /v1/participants if it does not exist
            yet. Use your platform's stable user ID here."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                legal_name:
                  type: "string"
                display_name:
                  type: "string"
                  description: "Human-readable display name for this participant, shown in dashboards and receipts."
                email:
                  type: "string"
                  description: "Email address for this participant. Used for payout notifications and compliance communications."
                date_of_birth:
                  type: "string"
                tax_id_type:
                  type: "string"
                  enum:
                    - "ssn"
                    - "ein"
                    - "itin"
                tax_id_last4:
                  type: "string"
                business_type:
                  type: "string"
                  enum:
                    - "individual"
                    - "sole_proprietor"
                    - "llc"
                    - "corporation"
                    - "partnership"
                address:
                  type: "object"
                  additionalProperties: true
                document_evidence:
                  type: "array"
                  items:
                    type: "object"
                    additionalProperties: true
                certify_tax_info:
                  type: "boolean"
                submit_for_review:
                  type: "boolean"
                metadata:
                  type: "object"
                  additionalProperties: true
              required:
                - "legal_name"
                - "email"
                - "date_of_birth"
                - "address"
                - "document_evidence"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/wallets:
    get:
      operationId: "listWallets"
      summary: "List scoped wallets or create a consumer credit wallet."
      tags:
        - "Other"
      parameters:
        - name: "owner_id"
          in: "query"
          required: false
          schema:
            type: "string"
          description: "Your platform's stable identifier for the wallet owner. Use the same value as participant_id for creator
            wallets."
        - name: "owner_type"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "wallet_type"
          in: "query"
          required: false
          schema:
            type: "string"
            enum:
              - "consumer_credit"
              - "creator_earnings"
          description: "Type of wallet. 'creator_earnings' = payout-eligible seller proceeds. 'consumer_credit' = closed-loop
            platform credits."
        - name: "limit"
          in: "query"
          required: false
          schema:
            type: "number"
        - name: "offset"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WalletListResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "createWallet"
      summary: "List scoped wallets or create a consumer credit wallet."
      tags:
        - "Other"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WalletCreateRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WalletCreateResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/wallets/{wallet_id}:
    get:
      operationId: "getWallet"
      summary: "Get a wallet object by wallet id."
      tags:
        - "Treasury"
      parameters:
        - name: "wallet_id"
          in: "path"
          required: true
          schema:
            type: "string"
          description: "UUID of the wallet object. Obtain via GET /v1/wallets?owner_id={participant_id} or from a participant
            creation response."
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WalletDetailResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/wallet-sessions:
    post:
      operationId: "createWalletSession"
      summary: "Create a short-lived hosted wallet page session for a customer wallet or an explicit creator earnings account.
        Consumer sessions use `user_wallet` and default to balance, activity, and top-up access; creator sessions use
        `participant_identity_links` and `creator_balance` with read-only balance/activity access."
      tags:
        - "Other"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                wallet_id:
                  type: "string"
                  description: "UUID of the wallet object. Obtain via GET /v1/wallets?owner_id={participant_id} or from a participant
                    creation response."
                owner_id:
                  type: "string"
                  description: "Your platform's stable identifier for the wallet owner. Use the same value as participant_id for creator
                    wallets."
                external_user_id:
                  type: "string"
                owner_type:
                  type: "string"
                  enum:
                    - "user"
                    - "consumer"
                    - "participant"
                    - "creator"
                customer_email:
                  type: "string"
                permissions:
                  type: "array"
                  items:
                    type: "string"
                    enum:
                      - "view_balance"
                      - "list_activity"
                      - "top_up"
                      - "request_refund"
                  description: "Hosted wallet session permissions. Omit this for defaults: buyer sessions include view_balance,
                    list_activity, and top_up; creator earnings sessions include view_balance and list_activity only."
                success_url:
                  type: "string"
                  description: "URL Soledgic redirects to after a successful payment. Receives checkout_session_id as a query parameter."
                cancel_url:
                  type: "string"
                  description: "URL Soledgic redirects to if the buyer cancels before completing payment."
                expires_in_minutes:
                  type: "number"
                idempotency_key:
                  type: "string"
                  description: "A client-generated unique string for safe retries. If the same key is sent twice the second request
                    returns the first response without side effects. Use a UUID or a stable composite like order_id +
                    attempt_number."
                metadata:
                  type: "object"
                  additionalProperties: true
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/wallets/{wallet_id}/entries:
    get:
      operationId: "listWalletEntries"
      summary: "List wallet ledger entries for a wallet object."
      tags:
        - "Treasury"
      parameters:
        - name: "wallet_id"
          in: "path"
          required: true
          schema:
            type: "string"
          description: "UUID of the wallet object. Obtain via GET /v1/wallets?owner_id={participant_id} or from a participant
            creation response."
        - name: "limit"
          in: "query"
          required: false
          schema:
            type: "number"
        - name: "offset"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WalletEntriesResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/wallets/{wallet_id}/topups:
    post:
      operationId: "depositToWallet"
      summary: "Top up a wallet when its wallet type supports external funding."
      tags:
        - "Treasury"
      parameters:
        - name: "wallet_id"
          in: "path"
          required: true
          schema:
            type: "string"
          description: "UUID of the wallet object. Obtain via GET /v1/wallets?owner_id={participant_id} or from a participant
            creation response."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WalletMutationRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WalletDepositResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/wallets/{wallet_id}/withdrawals:
    post:
      operationId: "withdrawFromWallet"
      summary: "Withdraw or debit funds from a wallet when the wallet is redeemable."
      tags:
        - "Treasury"
      parameters:
        - name: "wallet_id"
          in: "path"
          required: true
          schema:
            type: "string"
          description: "UUID of the wallet object. Obtain via GET /v1/wallets?owner_id={participant_id} or from a participant
            creation response."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WalletMutationRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WalletWithdrawalResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/transfers:
    post:
      operationId: "transferBetweenWallets"
      summary: "Move funds between wallets when both wallets explicitly permit transfer."
      tags:
        - "Treasury"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TransferFundsRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransferFundsResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/holds:
    get:
      operationId: "createHold"
      summary: "List held funds across participants, with optional readiness filtering."
      tags:
        - "Treasury"
      parameters:
        - name: "participant_id"
          in: "query"
          required: false
          schema:
            type: "string"
          description: "The unique identifier for the creator or seller. Create one via POST /v1/participants if it does not exist
            yet. Use your platform's stable user ID here."
        - name: "venture_id"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "ready_only"
          in: "query"
          required: false
          schema:
            type: "boolean"
        - name: "limit"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HoldsListResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/holds/summary:
    get:
      operationId: "getHoldsSummary"
      summary: "Get an aggregate summary of held and releasable funds."
      tags:
        - "Treasury"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HoldsSummaryResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/holds/{hold_id}/release:
    post:
      operationId: "releaseHold"
      summary: "Release a held-funds entry and optionally execute the transfer."
      tags:
        - "Treasury"
      parameters:
        - name: "hold_id"
          in: "path"
          required: true
          schema:
            type: "string"
          description: "UUID of the hold to release. Obtain via GET /v1/holds."
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/HoldReleaseRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HoldReleaseResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/checkout-sessions:
    post:
      operationId: "createCheckoutSession"
      summary: "Create a hosted or direct checkout session for a participant sale."
      tags:
        - "Payments"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TreasuryCheckoutSessionRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CheckoutSessionResourceResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/sandbox/checkouts/{checkout_id}/complete:
    post:
      operationId: "sandboxCompleteCheckout"
      summary: "Complete a sandbox checkout without contacting a payment processor. Test API keys only."
      tags:
        - "Payments"
      parameters:
        - name: "checkout_id"
          in: "path"
          required: true
          schema:
            type: "string"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SandboxCheckoutActionRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SandboxCheckoutActionResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/sandbox/checkouts/{checkout_id}/fail:
    post:
      operationId: "sandboxFailCheckout"
      summary: "Fail a sandbox checkout and queue the matching sandbox webhook. Test API keys only."
      tags:
        - "Payments"
      parameters:
        - name: "checkout_id"
          in: "path"
          required: true
          schema:
            type: "string"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SandboxCheckoutActionRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SandboxCheckoutActionResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/sandbox/webhooks/test:
    post:
      operationId: "sandboxSendTestWebhook"
      summary: "Queue a predefined sandbox webhook event for the ledger webhook endpoints. Test API keys only."
      tags:
        - "Payments"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SandboxWebhookTestRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SandboxWebhookTestResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/sandbox/events:
    get:
      operationId: "listSandboxEvents"
      summary: "List recent sandbox webhook delivery events for this ledger."
      tags:
        - "Payments"
      parameters:
        - name: "event_type"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "checkout_id"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "order_id"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "payment_id"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "limit"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SandboxEventsResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/sandbox/cleanup:
    post:
      operationId: "sandboxCleanup"
      summary: "Preview or clean run-scoped sandbox data, or reset all sandbox runtime data for a test ledger. Test API keys
        only; webhook endpoints are preserved."
      tags:
        - "Payments"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SandboxCleanupRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SandboxCleanupResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/payouts:
    post:
      operationId: "requestPayout"
      summary: "Create a payout for a creator earnings wallet or participant. Sandbox payouts are simulated; live payouts use
        the configured processor payout rail."
      tags:
        - "Payments"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TreasuryPayoutRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PayoutResourceResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/refunds:
    get:
      operationId: "listRefunds"
      summary: "List refunds or create a Soledgic-routed refund against a recorded sale."
      tags:
        - "Payments"
      parameters:
        - name: "sale_reference"
          in: "query"
          required: false
          schema:
            type: "string"
          description: "The checkout session ID or external order ID that identifies the original sale to refund."
        - name: "limit"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RefundsListResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "createRefund"
      summary: "List refunds or create a Soledgic-routed refund against a recorded sale."
      tags:
        - "Payments"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TreasuryRefundRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RefundResourceResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/refund-requests:
    get:
      operationId: "listRefundRequests"
      summary: "Create and review buyer-facing refund requests before money movement is approved."
      tags:
        - "Other"
      parameters:
        - name: "status"
          in: "query"
          required: false
          schema:
            type: "string"
            enum:
              - "pending"
              - "processing"
              - "completed"
              - "rejected"
              - "cancelled"
              - "failed"
        - name: "sale_reference"
          in: "query"
          required: false
          schema:
            type: "string"
          description: "The checkout session ID or external order ID that identifies the original sale to refund."
        - name: "customer_id"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "limit"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "createRefundRequest"
      summary: "Create and review buyer-facing refund requests before money movement is approved."
      tags:
        - "Other"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                sale_reference:
                  type: "string"
                  description: "The checkout session ID or external order ID that identifies the original sale to refund."
                customer_id:
                  type: "string"
                customer_email:
                  type: "string"
                amount:
                  type: "number"
                  description: "Amount in cents (integer). $10.00 = 1000. Must be a positive integer."
                reason:
                  type: "string"
                  description: "Human-readable reason for this action. Stored in the audit log and surfaced to participants where
                    applicable."
                refund_from:
                  type: "string"
                  enum:
                    - "both"
                    - "platform_only"
                    - "creator_only"
                idempotency_key:
                  type: "string"
                  description: "A client-generated unique string for safe retries. If the same key is sent twice the second request
                    returns the first response without side effects. Use a UUID or a stable composite like order_id +
                    attempt_number."
                metadata:
                  type: "object"
                  additionalProperties: true
              required:
                - "sale_reference"
                - "reason"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/refund-requests/{id}/approve:
    post:
      operationId: "approveRefundRequest"
      summary: "Approve a pending refund request and execute the Soledgic-routed refund."
      tags:
        - "Other"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                reviewed_by_actor:
                  type: "string"
                metadata:
                  type: "object"
                  additionalProperties: true
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/refund-requests/{id}/reject:
    post:
      operationId: "rejectRefundRequest"
      summary: "Reject a pending refund request without moving funds."
      tags:
        - "Other"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                reason:
                  type: "string"
                  description: "Human-readable reason for this action. Stored in the audit log and surfaced to participants where
                    applicable."
                reviewed_by_actor:
                  type: "string"
                metadata:
                  type: "object"
                  additionalProperties: true
              required:
                - "reason"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/refund-requests/{id}/cancel:
    post:
      operationId: "cancelRefundRequest"
      summary: "Cancel a pending buyer refund request before approval."
      tags:
        - "Other"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                reason:
                  type: "string"
                  description: "Human-readable reason for this action. Stored in the audit log and surfaced to participants where
                    applicable."
                metadata:
                  type: "object"
                  additionalProperties: true
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/ap-aging:
    get:
      operationId: "getAccountsPayableAging"
      summary: "Accounts Payable Aging Report"
      tags:
        - "Reports"
      parameters:
        - name: "as_of_date"
          in: "query"
          required: false
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/ar-aging:
    get:
      operationId: "getAccountsReceivableAging"
      summary: "Accounts Receivable Aging Report"
      tags:
        - "Reports"
      parameters:
        - name: "as_of_date"
          in: "query"
          required: false
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/balance-sheet:
    get:
      operationId: "getBalanceSheet"
      summary: "Balance Sheet Report"
      tags:
        - "Reports"
      parameters:
        - name: "as_of_date"
          in: "query"
          required: false
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/close-period:
    post:
      operationId: "closeAccountingPeriod"
      summary: "Close Accounting Period"
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                year:
                  type: "number"
                month:
                  type: "number"
                quarter:
                  type: "number"
                notes:
                  type: "string"
              required:
                - "year"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/configure-alerts:
    post:
      operationId: "configureRiskAlerts"
      summary: "Configure Alerts"
      tags:
        - "Risk"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                action:
                  type: "string"
                  enum:
                    - "list"
                    - "create"
                    - "update"
                    - "delete"
                    - "test"
                config_id:
                  type: "string"
                  format: "uuid"
                alert_type:
                  type: "string"
                  enum:
                    - "breach_risk"
                    - "projection_created"
                    - "instrument_invalidated"
                channel:
                  type: "string"
                  enum:
                    - "slack"
                    - "email"
                    - "webhook"
                config:
                  type: "object"
                  additionalProperties: true
                webhook_url:
                  type: "string"
                  format: "uri"
                recipients:
                  type: "array"
                  items:
                    type: "string"
                thresholds:
                  type: "object"
                  properties:
                    coverage_ratio_below:
                      type: "number"
                    shortfall_above:
                      type: "number"
                is_active:
                  type: "boolean"
              required:
                - "action"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/delete-creator:
    post:
      operationId: "deleteCreator"
      summary: "Soft-delete a creator (sets is_active = false with transaction guard)"
      tags:
        - "Creators"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                creator_id:
                  type: "string"
                  description: "The participant_id of the creator associated with this order. Must already exist via POST
                    /v1/participants."
              required:
                - "creator_id"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/export-report:
    post:
      operationId: "exportReport"
      summary: "Export Report"
      tags:
        - "Reports"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExportReportRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
            text/csv:
              schema:
                type: "string"
                description: "CSV file content"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/frozen-statements:
    post:
      operationId: "listFrozenStatements"
      summary: "Frozen Statements"
      tags:
        - "Reports"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                action:
                  type: "string"
                  enum:
                    - "generate"
                    - "list"
                    - "get"
                    - "compare"
                period_id:
                  type: "string"
                  format: "uuid"
                statement_type:
                  type: "string"
                  enum:
                    - "balance_sheet"
                    - "income_statement"
                    - "trial_balance"
              required:
                - "action"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/generate-pdf:
    post:
      operationId: "generateInvoicePdf"
      summary: "Generate PDF Reports"
      tags:
        - "Invoicing"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                report_type:
                  type: "string"
                  enum:
                    - "invoice"
                    - "statement"
                    - "balance_sheet"
                    - "income_statement"
                    - "trial_balance"
                    - "1099_nec"
                period_id:
                  type: "string"
                  format: "uuid"
                creator_id:
                  type: "string"
                start_date:
                  type: "string"
                  format: "date"
                end_date:
                  type: "string"
                  format: "date"
                tax_year:
                  type: "integer"
                ledger_id:
                  type: "string"
                  format: "uuid"
              required:
                - "report_type"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/pdf:
              schema:
                type: "string"
                format: "binary"
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/generate-report:
    post:
      operationId: "generateFinancialReport"
      summary: "Generate Report"
      tags:
        - "Reports"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                report_type:
                  type: "string"
                  enum:
                    - "transaction_detail"
                    - "creator_earnings"
                    - "platform_revenue"
                    - "payout_summary"
                    - "reconciliation"
                start_date:
                  type: "string"
                  format: "date"
                end_date:
                  type: "string"
                  format: "date"
                creator_id:
                  type: "string"
                format:
                  type: "string"
                  enum:
                    - "json"
                    - "csv"
              required:
                - "report_type"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/get-runway:
    get:
      operationId: "getCashRunway"
      summary: "Get Runway"
      tags:
        - "Balances"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/get-transactions:
    get:
      operationId: "listTransactions"
      summary: "Get Transactions"
      tags:
        - "Transactions"
      parameters:
        - name: "creator_id"
          in: "query"
          required: false
          schema:
            type: "string"
          description: "The participant_id of the creator associated with this order. Must already exist via POST /v1/participants."
        - name: "type"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "status"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "start_date"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "end_date"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "page"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "per_page"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "include_entries"
          in: "query"
          required: false
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetTransactionsResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/health-check:
    post:
      operationId: "getHealthStatus"
      summary: "Health Check"
      tags:
        - "Other"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                action:
                  type: "string"
                  enum:
                    - "run"
                    - "status"
                    - "history"
                    - "run_all"
                ledger_id:
                  type: "string"
              required:
                - "action"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/import-bank-statement:
    post:
      operationId: "importBankStatement"
      summary: "Import Bank Statement"
      tags:
        - "Banking"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                bank_account_id:
                  type: "string"
                  format: "uuid"
                lines:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      date:
                        type: "string"
                        format: "date"
                      description:
                        type: "string"
                      amount:
                        type: "number"
                      type:
                        type: "string"
                        enum:
                          - "debit"
                          - "credit"
                    required:
                      - "date"
                      - "description"
                      - "amount"
                auto_match:
                  type: "boolean"
              required:
                - "bank_account_id"
                - "lines"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/import-transactions:
    post:
      operationId: "importTransactions"
      summary: "Import Transactions"
      tags:
        - "Transactions"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                action:
                  type: "string"
                  enum:
                    - "parse_preview"
                    - "import"
                    - "get_templates"
                    - "save_template"
                format:
                  type: "string"
                  enum:
                    - "csv"
                    - "ofx"
                    - "qfx"
                    - "auto"
                data:
                  type: "string"
                  description: "Raw file content"
                mapping:
                  type: "object"
                  additionalProperties: true
                  description: "Column mapping configuration"
                template_id:
                  type: "string"
                template:
                  type: "object"
                  additionalProperties: true
                transactions:
                  type: "array"
                  items:
                    type: "object"
                    additionalProperties: true
                account_name:
                  type: "string"
              required:
                - "action"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/invoices:
    get:
      operationId: "listInvoices"
      summary: "Invoice Management"
      tags:
        - "Invoicing"
      parameters:
        - name: "status"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "customer_id"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "limit"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "offset"
          in: "query"
          required: false
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "createInvoice"
      summary: "Invoice Management"
      tags:
        - "Invoicing"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                customer_name:
                  type: "string"
                customer_email:
                  type: "string"
                  format: "email"
                customer_id:
                  type: "string"
                customer_address:
                  type: "object"
                  properties:
                    line1:
                      type: "string"
                    line2:
                      type: "string"
                    city:
                      type: "string"
                    state:
                      type: "string"
                    postal_code:
                      type: "string"
                    country:
                      type: "string"
                line_items:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      description:
                        type: "string"
                      quantity:
                        type: "number"
                      unit_price:
                        type: "integer"
                        description: "Price in cents"
                      amount:
                        type: "integer"
                        description: "Line total in cents"
                    required:
                      - "description"
                      - "amount"
                due_date:
                  type: "string"
                  format: "date"
                notes:
                  type: "string"
                terms:
                  type: "string"
                reference_id:
                  type: "string"
                metadata:
                  type: "object"
                  additionalProperties: true
              required:
                - "customer_name"
                - "line_items"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/list-ledgers:
    get:
      operationId: "listLedgers"
      summary: "List Ledgers"
      tags:
        - "Other"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/manage-bank-accounts:
    get:
      operationId: "listBankAccounts"
      summary: "Manage Bank Accounts"
      tags:
        - "Banking"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "createBankAccount"
      summary: "Manage Bank Accounts"
      tags:
        - "Banking"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                bank_name:
                  type: "string"
                account_name:
                  type: "string"
                account_type:
                  type: "string"
                  enum:
                    - "checking"
                    - "savings"
                    - "credit_card"
                    - "other"
                account_last_four:
                  type: "string"
              required:
                - "bank_name"
                - "account_name"
                - "account_type"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/manage-budgets:
    get:
      operationId: "listBudgets"
      summary: "Manage Budgets"
      tags:
        - "Accounting"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "createBudget"
      summary: "Manage Budgets"
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                name:
                  type: "string"
                category_code:
                  type: "string"
                budget_amount:
                  type: "number"
                budget_period:
                  type: "string"
                  enum:
                    - "weekly"
                    - "monthly"
                    - "quarterly"
                    - "annual"
                alert_at_percentage:
                  type: "number"
              required:
                - "name"
                - "budget_amount"
                - "budget_period"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/manage-contractors:
    get:
      operationId: "listContractors"
      summary: "Manage Contractors"
      tags:
        - "Creators"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "createContractor"
      summary: "Manage Contractors"
      tags:
        - "Creators"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                contractor_id:
                  type: "string"
                amount:
                  type: "number"
                  description: "Amount in cents (integer). $10.00 = 1000. Must be a positive integer."
                payment_date:
                  type: "string"
                payment_method:
                  type: "string"
                payment_reference:
                  type: "string"
                description:
                  type: "string"
              required:
                - "contractor_id"
                - "amount"
                - "payment_date"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/manage-recurring:
    get:
      operationId: "listRecurringTransactions"
      summary: "Manage Recurring Expenses"
      tags:
        - "Accounting"
      parameters:
        - name: "days"
          in: "query"
          required: false
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "createRecurringTransaction"
      summary: "Manage Recurring Expenses"
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                name:
                  type: "string"
                merchant_name:
                  type: "string"
                category_code:
                  type: "string"
                amount:
                  type: "number"
                  description: "Amount in cents (integer). $10.00 = 1000. Must be a positive integer."
                recurrence_interval:
                  type: "string"
                  enum:
                    - "weekly"
                    - "monthly"
                    - "quarterly"
                    - "annual"
                recurrence_day:
                  type: "number"
                start_date:
                  type: "string"
                end_date:
                  type: "string"
                business_purpose:
                  type: "string"
                is_variable_amount:
                  type: "boolean"
              required:
                - "name"
                - "merchant_name"
                - "category_code"
                - "amount"
                - "recurrence_interval"
                - "start_date"
                - "business_purpose"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/manage-splits:
    post:
      operationId: "manageSplitRules"
      summary: "Manage Splits"
      tags:
        - "Creators"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                action:
                  type: "string"
                  enum:
                    - "get"
                    - "set"
                    - "set_product"
                    - "delete_product"
                    - "list_product"
                creator_id:
                  type: "string"
                creator_percent:
                  type: "number"
                  minimum: 0
                  maximum: 100
                product_id:
                  type: "string"
              required:
                - "action"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/pay-bill:
    post:
      operationId: "payBill"
      summary: "Records payment of a bill (reduces A/P, reduces Cash)"
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                bill_transaction_id:
                  type: "string"
                amount:
                  type: "number"
                  description: "Amount in cents (integer). $10.00 = 1000. Must be a positive integer."
                vendor_name:
                  type: "string"
                reference_id:
                  type: "string"
                  description: "A stable client-side identifier used for deduplication on treasury writes. Use the same value on retries;
                    Soledgic will not duplicate the operation."
                payment_method:
                  type: "string"
                payment_date:
                  type: "string"
                metadata:
                  type: "object"
                  additionalProperties: true
              required:
                - "amount"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/preflight-authorization:
    post:
      operationId: "checkPreflightAuthorization"
      summary: "Preflight Authorization"
      tags:
        - "Risk"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                idempotency_key:
                  type: "string"
                  description: "A client-generated unique string for safe retries. If the same key is sent twice the second request
                    returns the first response without side effects. Use a UUID or a stable composite like order_id +
                    attempt_number."
                amount:
                  type: "number"
                  description: "Amount in cents (integer). $10.00 = 1000. Must be a positive integer."
                currency:
                  type: "string"
                  description: "Three-letter ISO 4217 currency code. Currently only USD is supported."
                counterparty_name:
                  type: "string"
                authorizing_instrument_id:
                  type: "string"
                expected_date:
                  type: "string"
                category:
                  type: "string"
              required:
                - "idempotency_key"
                - "amount"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/profit-loss:
    get:
      operationId: "getProfitLoss"
      summary: "Profit & Loss Report"
      tags:
        - "Reports"
      parameters:
        - name: "year"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "month"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "quarter"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "breakdown"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "start_date"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "end_date"
          in: "query"
          required: false
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "generateProfitLoss"
      summary: "Profit & Loss Report"
      tags:
        - "Reports"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/project-intent:
    post:
      operationId: "recordProjectIntent"
      summary: "Project Intent"
      tags:
        - "Risk"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                authorizing_instrument_id:
                  type: "string"
                until_date:
                  type: "string"
                horizon_count:
                  type: "number"
              required:
                - "authorizing_instrument_id"
                - "until_date"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/receive-payment:
    post:
      operationId: "recordReceivedPayment"
      summary: "Receive Payment"
      tags:
        - "Payments"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReceivePaymentRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReceivePaymentResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/record-adjustment:
    post:
      operationId: "recordJournalAdjustment"
      summary: "Record Adjustment Journal"
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RecordAdjustmentRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RecordAdjustmentResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/record-bill:
    post:
      operationId: "recordBill"
      summary: "Record Bill"
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                amount:
                  type: "number"
                  description: "Amount in cents (integer). $10.00 = 1000. Must be a positive integer."
                description:
                  type: "string"
                vendor_name:
                  type: "string"
                vendor_id:
                  type: "string"
                reference_id:
                  type: "string"
                  description: "A stable client-side identifier used for deduplication on treasury writes. Use the same value on retries;
                    Soledgic will not duplicate the operation."
                due_date:
                  type: "string"
                expense_category:
                  type: "string"
                paid:
                  type: "boolean"
                metadata:
                  type: "object"
                  additionalProperties: true
                authorizing_instrument_id:
                  type: "string"
                risk_evaluation_id:
                  type: "string"
              required:
                - "amount"
                - "description"
                - "vendor_name"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/record-expense:
    post:
      operationId: "recordExpense"
      summary: "Record Expense"
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                reference_id:
                  type: "string"
                  description: "A stable client-side identifier used for deduplication on treasury writes. Use the same value on retries;
                    Soledgic will not duplicate the operation."
                amount:
                  type: "number"
                  description: "Amount in cents (integer). $10.00 = 1000. Must be a positive integer."
                description:
                  type: "string"
                category:
                  type: "string"
                vendor_id:
                  type: "string"
                vendor_name:
                  type: "string"
                paid_from:
                  type: "string"
                  enum:
                    - "cash"
                    - "credit_card"
                receipt_url:
                  type: "string"
                tax_deductible:
                  type: "boolean"
                metadata:
                  type: "object"
                  additionalProperties: true
                authorizing_instrument_id:
                  type: "string"
                risk_evaluation_id:
                  type: "string"
              required:
                - "reference_id"
                - "amount"
                - "description"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/record-income:
    post:
      operationId: "recordIncome"
      summary: "Record Income"
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                reference_id:
                  type: "string"
                  description: "A stable client-side identifier used for deduplication on treasury writes. Use the same value on retries;
                    Soledgic will not duplicate the operation."
                amount:
                  type: "number"
                  description: "Amount in cents (integer). $10.00 = 1000. Must be a positive integer."
                description:
                  type: "string"
                category:
                  type: "string"
                customer_id:
                  type: "string"
                customer_name:
                  type: "string"
                received_to:
                  type: "string"
                  enum:
                    - "cash"
                invoice_id:
                  type: "string"
                metadata:
                  type: "object"
                  additionalProperties: true
              required:
                - "reference_id"
                - "amount"
                - "description"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/record-opening-balance:
    post:
      operationId: "recordOpeningBalance"
      summary: "Record Opening Balances"
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RecordOpeningBalanceRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RecordOpeningBalanceResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/record-transfer:
    post:
      operationId: "recordTransfer"
      summary: "Record Internal Transfer"
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RecordTransferRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RecordTransferResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/register-instrument:
    post:
      operationId: "registerPaymentInstrument"
      summary: "Register Authorizing Instrument"
      tags:
        - "Risk"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                external_ref:
                  type: "string"
                  description: "External reference for the instrument"
                extracted_terms:
                  type: "object"
                  description: "Contract terms extracted from the instrument"
                  additionalProperties: true
              required:
                - "external_ref"
                - "extracted_terms"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/reverse-transaction:
    post:
      operationId: "reverseTransaction"
      summary: "Reverse Transaction"
      tags:
        - "Payments"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReverseTransactionRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReverseTransactionResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/send-statements:
    post:
      operationId: "sendStatements"
      summary: "Soledgic Auto-Email Service"
      tags:
        - "Reports"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                action:
                  type: "string"
                  enum:
                    - "send_monthly_statements"
                    - "send_single_statement"
                    - "preview"
                    - "get_queue"
                ledger_id:
                  type: "string"
                  format: "uuid"
                creator_id:
                  type: "string"
                year:
                  type: "integer"
                month:
                  type: "integer"
                  minimum: 1
                  maximum: 12
                email_config:
                  type: "object"
                  additionalProperties: true
              required:
                - "action"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/receipts/generate:
    post:
      operationId: "generateReceipt"
      summary: "Generate a Soledgic-owned financial receipt for a checkout or sale transaction."
      tags:
        - "Other"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                checkout_id:
                  type: "string"
                sale_transaction_id:
                  type: "string"
                order_id:
                  type: "string"
                external_order_id:
                  type: "string"
                  description: "Your platform's unique identifier for this order. Used for idempotency and for correlating webhook events
                    back to your records."
                metadata:
                  type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/receipts/{receipt_id}:
    get:
      operationId: "getReceipt"
      summary: "Fetch a Soledgic-owned receipt reference by id."
      tags:
        - "Other"
      parameters:
        - name: "receipt_id"
          in: "path"
          required: true
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/trial-balance:
    get:
      operationId: "getTrialBalance"
      summary: "Trial Balance"
      tags:
        - "Reports"
      parameters:
        - name: "snapshot"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "as_of"
          in: "query"
          required: false
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "generateTrialBalance"
      summary: "Trial Balance"
      tags:
        - "Reports"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/upload-receipt:
    post:
      operationId: "uploadReceiptDocument"
      summary: "Upload Receipt"
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UploadReceiptRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UploadReceiptResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/webhooks:
    post:
      operationId: "manageWebhookEndpoints"
      summary: "Webhooks Management"
      tags:
        - "Webhooks"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                action:
                  type: "string"
                  enum:
                    - "list"
                    - "create"
                    - "update"
                    - "delete"
                    - "test"
                    - "deliveries"
                    - "retry"
                    - "replay"
                endpoint_id:
                  type: "string"
                  format: "uuid"
                delivery_id:
                  type: "string"
                  format: "uuid"
                url:
                  type: "string"
                  format: "uri"
                description:
                  type: "string"
                events:
                  type: "array"
                  items:
                    type: "string"
                is_active:
                  type: "boolean"
                event_type:
                  type: "string"
                status:
                  type: "string"
                  enum:
                    - "pending"
                    - "delivering"
                    - "delivered"
                    - "failed"
                    - "blocked"
                checkout_id:
                  type: "string"
                order_id:
                  type: "string"
                payment_id:
                  type: "string"
                limit:
                  type: "integer"
                  minimum: 1
                  maximum: 100
              required:
                - "action"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/reconciliations/unmatched:
    get:
      operationId: "listUnmatchedReconciliations"
      summary: "List unmatched ledger transactions that still need settlement or bank reconciliation."
      tags:
        - "Accounting"
      parameters:
        - name: "limit"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/reconciliations/matches:
    post:
      operationId: "createReconciliationMatch"
      summary: "Match a ledger transaction to an external bank or settlement transaction."
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                transaction_id:
                  type: "string"
                bank_transaction_id:
                  type: "string"
              required:
                - "transaction_id"
                - "bank_transaction_id"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/reconciliations/matches/{transaction_id}:
    delete:
      operationId: "deleteReconciliationMatch"
      summary: "Remove an existing reconciliation match for a transaction."
      tags:
        - "Accounting"
      parameters:
        - name: "transaction_id"
          in: "path"
          required: true
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/reconciliations/snapshots:
    post:
      operationId: "createReconciliationSnapshot"
      summary: "Create a reconciliation snapshot for an accounting period or as-of date."
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                period_id:
                  type: "string"
                as_of_date:
                  type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/reconciliations/snapshots/{period_id}:
    get:
      operationId: "getReconciliationSnapshot"
      summary: "Fetch the latest reconciliation snapshot for a period and verify its integrity hash."
      tags:
        - "Accounting"
      parameters:
        - name: "period_id"
          in: "path"
          required: true
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/reconciliations/auto-match:
    post:
      operationId: "autoMatchReconciliations"
      summary: "Attempt to automatically match a bank aggregator transaction to a ledger transaction."
      tags:
        - "Accounting"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                bank_aggregator_transaction_id:
                  type: "string"
              required:
                - "bank_aggregator_transaction_id"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/fraud/evaluations:
    post:
      operationId: "listFraudEvaluations"
      summary: "Evaluate a proposed transaction against configured fraud and policy rules."
      tags:
        - "Risk"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RiskEvaluationRequest"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RiskEvaluationResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/fraud/evaluations/{evaluation_id}:
    get:
      operationId: "getFraudEvaluation"
      summary: "Get a previously created fraud evaluation."
      tags:
        - "Risk"
      parameters:
        - name: "evaluation_id"
          in: "path"
          required: true
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/fraud/policies:
    get:
      operationId: "listFraudPolicies"
      summary: "List configured fraud policies or create a new policy rule."
      tags:
        - "Risk"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
    post:
      operationId: "createFraudPolicy"
      summary: "List configured fraud policies or create a new policy rule."
      tags:
        - "Risk"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                policy_type:
                  type: "string"
                  enum:
                    - "require_instrument"
                    - "budget_cap"
                    - "projection_guard"
                config:
                  type: "object"
                  additionalProperties: true
                severity:
                  type: "string"
                  enum:
                    - "hard"
                    - "soft"
                priority:
                  type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/fraud/policies/{policy_id}:
    delete:
      operationId: "deleteFraudPolicy"
      summary: "Delete a configured fraud policy."
      tags:
        - "Risk"
      parameters:
        - name: "policy_id"
          in: "path"
          required: true
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/compliance/overview:
    get:
      operationId: "getComplianceOverview"
      summary: "Get a ledger-scoped overview of compliance and monitoring signals."
      tags:
        - "Risk"
      parameters:
        - name: "days"
          in: "query"
          required: false
          schema:
            type: "number"
        - name: "hours"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/compliance/access-patterns:
    get:
      operationId: "getComplianceAccessPatterns"
      summary: "List suspicious or high-volume access patterns for the current ledger."
      tags:
        - "Risk"
      parameters:
        - name: "hours"
          in: "query"
          required: false
          schema:
            type: "number"
        - name: "limit"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/compliance/financial-activity:
    get:
      operationId: "getComplianceFinancialActivity"
      summary: "Summarize payout, sale, refund, and dispute activity for compliance review."
      tags:
        - "Risk"
      parameters:
        - name: "days"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/compliance/security-summary:
    get:
      operationId: "getComplianceSecuritySummary"
      summary: "Summarize risk-scored security and audit events for the current ledger."
      tags:
        - "Risk"
      parameters:
        - name: "days"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/documents:
    get:
      operationId: "listTaxDocuments"
      summary: "List generated tax documents for a tax year."
      tags:
        - "Tax"
      parameters:
        - name: "tax_year"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/documents/generate:
    post:
      operationId: "generateTaxDocuments"
      summary: "Generate tax documents for all participants that cross the filing threshold."
      tags:
        - "Tax"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                tax_year:
                  type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/documents/export:
    get:
      operationId: "exportTaxDocuments"
      summary: "Export generated tax documents as CSV or JSON."
      tags:
        - "Tax"
      parameters:
        - name: "tax_year"
          in: "query"
          required: false
          schema:
            type: "number"
        - name: "format"
          in: "query"
          required: false
          schema:
            type: "string"
            enum:
              - "csv"
              - "json"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
            text/csv:
              schema:
                type: "string"
                description: "CSV file content"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/documents/{document_id}:
    get:
      operationId: "getTaxDocument"
      summary: "Fetch a single generated tax document."
      tags:
        - "Tax"
      parameters:
        - name: "document_id"
          in: "path"
          required: true
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/documents/{document_id}/mark-filed:
    post:
      operationId: "markTaxDocumentFiled"
      summary: "Mark a generated tax document as filed."
      tags:
        - "Tax"
      parameters:
        - name: "document_id"
          in: "path"
          required: true
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/calculations/{participant_id}:
    get:
      operationId: "calculateTax"
      summary: "Calculate participant-level tax totals and shared tax profile status for a year."
      tags:
        - "Tax"
      parameters:
        - name: "participant_id"
          in: "path"
          required: true
          schema:
            type: "string"
          description: "The unique identifier for the creator or seller. Create one via POST /v1/participants if it does not exist
            yet. Use your platform's stable user ID here."
        - name: "tax_year"
          in: "query"
          required: false
          schema:
            type: "number"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/summaries/{tax_year}:
    get:
      operationId: "getTaxSummary"
      summary: "Generate and return tax summary totals for one year, optionally filtered to a participant."
      tags:
        - "Tax"
      parameters:
        - name: "tax_year"
          in: "path"
          required: true
          schema:
            type: "number"
        - name: "participant_id"
          in: "query"
          required: false
          schema:
            type: "string"
          description: "The unique identifier for the creator or seller. Create one via POST /v1/participants if it does not exist
            yet. Use your platform's stable user ID here."
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/earnings:
    get:
      operationId: "getCreatorEarnings"
      summary: "Return historical creator earnings for dashboard and reconciliation views."
      tags:
        - "Other"
      parameters:
        - name: "creator_id"
          in: "query"
          required: false
          schema:
            type: "string"
          description: "The participant_id of the creator associated with this order. Must already exist via POST /v1/participants."
        - name: "start_date"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "end_date"
          in: "query"
          required: false
          schema:
            type: "string"
        - name: "granularity"
          in: "query"
          required: false
          schema:
            type: "string"
            enum:
              - "day"
              - "week"
              - "month"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/credits:
    post:
      operationId: "getCredits"
      summary: "Issue, convert, redeem, and inspect platform credits."
      tags:
        - "Other"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                action:
                  type: "string"
                  enum:
                    - "issue"
                    - "convert"
                    - "redeem"
                    - "balance"
                user_id:
                  type: "string"
                creator_id:
                  type: "string"
                  description: "The participant_id of the creator associated with this order. Must already exist via POST
                    /v1/participants."
                credits:
                  type: "number"
                amount:
                  type: "number"
                  description: "Amount in cents (integer). $10.00 = 1000. Must be a positive integer."
                reference_id:
                  type: "string"
                  description: "A stable client-side identifier used for deduplication on treasury writes. Use the same value on retries;
                    Soledgic will not duplicate the operation."
                reason:
                  type: "string"
                  description: "Human-readable reason for this action. Stored in the audit log and surfaced to participants where
                    applicable."
                description:
                  type: "string"
                split_percent:
                  type: "number"
              required:
                - "action"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/invoices/{invoice_id}:
    get:
      operationId: "getInvoice"
      summary: "Fetch a single invoice by id."
      tags:
        - "Other"
      parameters:
        - name: "invoice_id"
          in: "path"
          required: true
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/invoices/{invoice_id}/send:
    post:
      operationId: "sendInvoice"
      summary: "Mark an invoice as sent and record the send event."
      tags:
        - "Other"
      parameters:
        - name: "invoice_id"
          in: "path"
          required: true
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/invoices/{invoice_id}/record-payment:
    post:
      operationId: "recordInvoicePayment"
      summary: "Record a payment against an invoice."
      tags:
        - "Other"
      parameters:
        - name: "invoice_id"
          in: "path"
          required: true
          schema:
            type: "string"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                amount_cents:
                  type: "number"
                payment_date:
                  type: "string"
                reference_id:
                  type: "string"
                  description: "A stable client-side identifier used for deduplication on treasury writes. Use the same value on retries;
                    Soledgic will not duplicate the operation."
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/invoices/{invoice_id}/void:
    post:
      operationId: "voidInvoice"
      summary: "Void an invoice with an optional reason."
      tags:
        - "Other"
      parameters:
        - name: "invoice_id"
          in: "path"
          required: true
          schema:
            type: "string"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                reason:
                  type: "string"
                  description: "Human-readable reason for this action. Stored in the audit log and surfaced to participants where
                    applicable."
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/manage-contractors/payment:
    post:
      operationId: "payContractor"
      summary: "Record a contractor payment."
      tags:
        - "Other"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                contractor_id:
                  type: "string"
                amount:
                  type: "number"
                  description: "Amount in cents (integer). $10.00 = 1000. Must be a positive integer."
                reference_id:
                  type: "string"
                  description: "A stable client-side identifier used for deduplication on treasury writes. Use the same value on retries;
                    Soledgic will not duplicate the operation."
              required:
                - "contractor_id"
                - "amount"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/manage-recurring/due:
    get:
      operationId: "listDueRecurringTransactions"
      summary: "List recurring transactions due for processing."
      tags:
        - "Other"
      parameters:
        - name: "as_of"
          in: "query"
          required: false
          schema:
            type: "string"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/submit-tax-info:
    post:
      operationId: "submitTaxInfo"
      summary: "Submit participant tax profile details for payout readiness."
      tags:
        - "Other"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                participant_id:
                  type: "string"
                  description: "The unique identifier for the creator or seller. Create one via POST /v1/participants if it does not exist
                    yet. Use your platform's stable user ID here."
                legal_name:
                  type: "string"
                tax_id_type:
                  type: "string"
                tax_id_last4:
                  type: "string"
                business_type:
                  type: "string"
                certify:
                  type: "boolean"
              required:
                - "participant_id"
                - "legal_name"
                - "tax_id_type"
                - "tax_id_last4"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/documents/mark-filed:
    post:
      operationId: "bulkMarkTaxDocumentsFiled"
      summary: "Mark generated tax documents filed for a tax year."
      tags:
        - "Other"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                tax_year:
                  type: "number"
              required:
                - "tax_year"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/documents/{document_id}/correct:
    post:
      operationId: "correctTaxDocument"
      summary: "Create a correction workflow for a generated tax document."
      tags:
        - "Other"
      parameters:
        - name: "document_id"
          in: "path"
          required: true
          schema:
            type: "string"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                reason:
                  type: "string"
                  description: "Human-readable reason for this action. Stored in the audit log and surfaced to participants where
                    applicable."
                updates:
                  type: "object"
                  additionalProperties: true
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/documents/deliver-copy-b:
    post:
      operationId: "deliverTaxDocumentCopyB"
      summary: "Deliver recipient tax document copies for a tax year."
      tags:
        - "Other"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                tax_year:
                  type: "number"
              required:
                - "tax_year"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/documents/{document_id}/pdf:
    post:
      operationId: "getTaxDocumentPdf"
      summary: "Generate or retrieve a PDF for one tax document."
      tags:
        - "Other"
      parameters:
        - name: "document_id"
          in: "path"
          required: true
          schema:
            type: "string"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                regenerate:
                  type: "boolean"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
  /v1/tax/documents/pdf/batch:
    post:
      operationId: "getTaxDocumentPdfBatch"
      summary: "Generate tax document PDFs in batch."
      tags:
        - "Other"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                tax_year:
                  type: "number"
                document_ids:
                  type: "array"
                  items:
                    type: "string"
              required:
                - "tax_year"
      responses:
        "200":
          description: "Success"
          headers: *a1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuccessEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
components:
  securitySchemes:
    ApiKeyAuth:
      type: "apiKey"
      in: "header"
      name: "x-api-key"
      description: "Your Soledgic API key"
  schemas:
    SuccessEnvelope:
      type: "object"
      properties:
        success:
          type: "boolean"
          const: true
        request_id:
          type: "string"
          description: "Unique request identifier"
          examples:
            - "req_abc123"
      required:
        - "success"
        - "request_id"
    ErrorEnvelope:
      type: "object"
      properties:
        success:
          type: "boolean"
          const: false
        error:
          type: "string"
        error_code:
          type: "string"
        request_id:
          type: "string"
      required:
        - "success"
        - "error"
        - "request_id"
    RateLimitError:
      type: "object"
      properties:
        success:
          type: "boolean"
          const: false
        error:
          type: "string"
        request_id:
          type: "string"
        retry_after:
          type: "integer"
          description: "Seconds until rate limit resets"
          examples:
            - 60
      required:
        - "success"
        - "error"
        - "request_id"
        - "retry_after"
    ReverseTransactionRequest:
      type: "object"
      properties:
        transaction_id:
          type: "string"
          format: "uuid"
          description: "Transaction UUID to reverse"
        reason:
          type: "string"
          description: "Reason for reversal (required for audit)"
        partial_amount:
          type: "integer"
          description: "Partial reversal amount in cents"
        idempotency_key:
          type: "string"
          description: "Unique key to prevent duplicate reversals"
        metadata:
          type: "object"
          additionalProperties: true
      required:
        - "transaction_id"
        - "reason"
    RecordAdjustmentRequest:
      type: "object"
      properties:
        idempotency_key:
          type: "string"
          description: "Unique key for safe retries of the adjustment request"
        adjustment_type:
          type: "string"
          enum:
            - "correction"
            - "reclassification"
            - "accrual"
            - "deferral"
            - "depreciation"
            - "write_off"
            - "year_end"
            - "opening_balance"
            - "other"
        entries:
          type: "array"
          minItems: 2
          description: "Journal entries (must balance)"
          items:
            type: "object"
            properties:
              account_type:
                type: "string"
              entity_id:
                type: "string"
              entry_type:
                type: "string"
                enum:
                  - "debit"
                  - "credit"
              amount:
                type: "integer"
            required:
              - "account_type"
              - "entry_type"
              - "amount"
        reason:
          type: "string"
          description: "Reason for adjustment (required for audit)"
        adjustment_date:
          type: "string"
          format: "date"
          description: "YYYY-MM-DD"
        original_transaction_id:
          type: "string"
          format: "uuid"
        supporting_documentation:
          type: "string"
        prepared_by:
          type: "string"
      required:
        - "idempotency_key"
        - "adjustment_type"
        - "entries"
        - "reason"
        - "prepared_by"
    RecordOpeningBalanceRequest:
      type: "object"
      properties:
        as_of_date:
          type: "string"
          format: "date"
          description: "YYYY-MM-DD"
        source:
          type: "string"
          enum:
            - "manual"
            - "imported"
            - "migrated"
            - "year_start"
        source_description:
          type: "string"
        balances:
          type: "array"
          items:
            type: "object"
            properties:
              account_type:
                type: "string"
              entity_id:
                type: "string"
              balance:
                type: "integer"
            required:
              - "account_type"
              - "balance"
      required:
        - "as_of_date"
        - "source"
        - "balances"
    RecordTransferRequest:
      type: "object"
      properties:
        from_account_type:
          type: "string"
        to_account_type:
          type: "string"
        amount:
          type: "integer"
          description: "Amount in cents"
        transfer_type:
          type: "string"
          enum:
            - "tax_reserve"
            - "payout_reserve"
            - "owner_draw"
            - "owner_contribution"
            - "operating"
            - "savings"
            - "investment"
            - "other"
        description:
          type: "string"
        reference_id:
          type: "string"
      required:
        - "from_account_type"
        - "to_account_type"
        - "amount"
        - "transfer_type"
    RiskEvaluationRequest:
      type: "object"
      properties:
        idempotency_key:
          type: "string"
        amount:
          type: "integer"
          description: "Amount in cents"
        currency:
          type: "string"
          default: "USD"
          enum:
            - "USD"
          description: "Money movement currently supports USD only. Local-currency presentment can be added later as a separate
            processor feature, but Soledgic ledger and wallet balances remain USD-native."
        counterparty_name:
          type: "string"
        authorizing_instrument_id:
          type: "string"
          format: "uuid"
        expected_date:
          type: "string"
          format: "date"
        category:
          type: "string"
      required:
        - "idempotency_key"
        - "amount"
    ExportReportRequest:
      type: "object"
      properties:
        report_type:
          type: "string"
          enum:
            - "transaction_detail"
            - "creator_earnings"
            - "platform_revenue"
            - "payout_summary"
            - "reconciliation"
            - "audit_log"
        format:
          type: "string"
          enum:
            - "csv"
            - "json"
        start_date:
          type: "string"
          format: "date"
        end_date:
          type: "string"
          format: "date"
        creator_id:
          type: "string"
      required:
        - "report_type"
        - "format"
    UploadReceiptRequest:
      type: "object"
      properties:
        file_url:
          type: "string"
          format: "uri"
          description: "File URL (must be Supabase storage)"
        file_name:
          type: "string"
        file_size:
          type: "integer"
          description: "File size in bytes (max 50MB)"
        mime_type:
          type: "string"
          enum:
            - "image/jpeg"
            - "image/png"
            - "image/gif"
            - "image/webp"
            - "application/pdf"
        merchant_name:
          type: "string"
        transaction_date:
          type: "string"
          format: "date"
        total_amount:
          type: "integer"
          description: "Amount in cents"
        transaction_id:
          type: "string"
          format: "uuid"
      required:
        - "file_url"
    ReceivePaymentRequest:
      type: "object"
      properties:
        amount:
          type: "integer"
          description: "Amount in cents"
        invoice_transaction_id:
          type: "string"
          format: "uuid"
        customer_name:
          type: "string"
        customer_id:
          type: "string"
        reference_id:
          type: "string"
        payment_method:
          type: "string"
        payment_date:
          type: "string"
          format: "date"
        metadata:
          type: "object"
          additionalProperties: true
      required:
        - "amount"
    ParticipantCreateRequest:
      type: "object"
      properties:
        participant_id:
          type: "string"
        user_id:
          type: "string"
          format: "uuid"
        display_name:
          type: "string"
        email:
          type: "string"
          format: "email"
        default_split_percent:
          type: "number"
          minimum: 0
          maximum: 100
        tax_info:
          type: "object"
          additionalProperties: true
        payout_preferences:
          type: "object"
          additionalProperties: true
        metadata:
          type: "object"
          additionalProperties: true
      required:
        - "participant_id"
    WalletMutationRequest:
      type: "object"
      properties:
        amount:
          type: "integer"
          description: "Amount in cents"
        reference_id:
          type: "string"
        description:
          type: "string"
        metadata:
          type: "object"
          additionalProperties: true
      required:
        - "amount"
        - "reference_id"
    WalletCreateRequest:
      type: "object"
      properties:
        owner_id:
          type: "string"
        participant_id:
          type: "string"
        owner_type:
          type: "string"
        wallet_type:
          type: "string"
          enum:
            - "consumer_credit"
            - "creator_earnings"
        name:
          type: "string"
        metadata:
          type: "object"
          additionalProperties: true
      required:
        - "wallet_type"
    TransferFundsRequest:
      type: "object"
      properties:
        from_wallet_id:
          type: "string"
          format: "uuid"
        to_wallet_id:
          type: "string"
          format: "uuid"
        from_participant_id:
          type: "string"
        to_participant_id:
          type: "string"
        amount:
          type: "integer"
          description: "Amount in cents"
        reference_id:
          type: "string"
        description:
          type: "string"
        metadata:
          type: "object"
          additionalProperties: true
      required:
        - "from_participant_id"
        - "to_participant_id"
        - "amount"
        - "reference_id"
    HoldReleaseRequest:
      type: "object"
      properties:
        execute_transfer:
          type: "boolean"
          default: true
    TreasuryCheckoutSessionRequest:
      type: "object"
      properties:
        participant_id:
          type: "string"
        amount:
          type: "integer"
          description: "Amount in cents"
        currency:
          type: "string"
          default: "USD"
          enum:
            - "USD"
          description: "Checkout sessions currently support USD only. Local-currency presentment can be added later as a separate
            processor feature, but Soledgic ledger and wallet balances remain USD-native."
        product_id:
          type: "string"
        product_name:
          type: "string"
        customer_email:
          type: "string"
          format: "email"
        customer_id:
          type: "string"
        buyer_user_id:
          type: "string"
        purchase_mode:
          type: "string"
          enum:
            - "direct_funded_wallet"
        sandbox_checkout_provider:
          type: "string"
          enum:
            - "soledgic"
          description: "For sandbox direct-funded wallet checkout, choose soledgic for the hosted Soledgic sandbox card form or
            omit this field for the processor-hosted test checkout. The Soledgic hosted sandbox card form accepts 4242
            4242 4242 4242 for success and 4000 0000 0000 0002 for decline testing. Defaults to processor-hosted
            checkout in sandbox mode."
        payment_method_id:
          type: "string"
        success_url:
          type: "string"
          format: "uri"
        cancel_url:
          type: "string"
          format: "uri"
        idempotency_key:
          type: "string"
        metadata:
          type: "object"
          additionalProperties:
            type: "string"
      required:
        - "participant_id"
        - "amount"
    TreasuryPayoutRequest:
      type: "object"
      properties:
        wallet_id:
          type: "string"
          format: "uuid"
        participant_id:
          type: "string"
        amount:
          type: "integer"
          description: "Amount in cents"
        reference_id:
          type: "string"
        reference_type:
          type: "string"
        description:
          type: "string"
        payout_method:
          type: "string"
        fees:
          type: "integer"
        fees_paid_by:
          type: "string"
          enum:
            - "platform"
            - "creator"
        metadata:
          type: "object"
          additionalProperties: true
      required:
        - "participant_id"
        - "amount"
        - "reference_id"
    TreasuryRefundRequest:
      type: "object"
      properties:
        sale_reference:
          type: "string"
        reason:
          type: "string"
        amount:
          type: "integer"
          description: "Amount in cents"
        refund_from:
          type: "string"
          enum:
            - "both"
            - "platform_only"
            - "creator_only"
        external_refund_id:
          type: "string"
        idempotency_key:
          type: "string"
        metadata:
          type: "object"
          additionalProperties: true
      required:
        - "sale_reference"
        - "reason"
    SandboxCheckoutActionRequest:
      type: "object"
      properties:
        idempotency_key:
          type: "string"
          description: "Stable retry key for this sandbox action. Required."
        payment_id:
          type: "string"
          description: "Optional fake sandbox payment id. Soledgic generates one when omitted."
        reason:
          type: "string"
          description: "Optional failure reason for sandbox checkout failure."
        metadata:
          type: "object"
          additionalProperties: true
          description: "Optional sandbox metadata stored on the checkout/test event."
      required:
        - "idempotency_key"
    SandboxWebhookTestRequest:
      type: "object"
      properties:
        idempotency_key:
          type: "string"
          description: "Stable retry key for this sandbox event. Required."
        event_type:
          type: "string"
          enum:
            - "sandbox.test"
            - "checkout.completed"
            - "checkout.failed"
            - "dispute.created"
            - "dispute.funds_withdrawn"
            - "chargeback.created"
            - "chargeback.funds_withdrawn"
            - "hold.created"
            - "hold.released"
            - "hold.failed"
            - "refund_request.created"
            - "refund_request.completed"
            - "refund_request.rejected"
            - "refund_request.cancelled"
            - "refund.created"
            - "sale.refunded"
            - "payout.created"
            - "payout.executed"
            - "payout.failed"
          default: "sandbox.test"
        payload:
          type: "object"
          additionalProperties: true
          description: "Optional safe payload fields merged under data."
      required:
        - "idempotency_key"
    CheckoutBreakdown:
      type: "object"
      properties:
        gross_amount:
          type: "number"
        creator_amount:
          type: "number"
        platform_amount:
          type: "number"
        creator_percent:
          type: "number"
    CreateCheckoutResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            provider:
              type: "string"
              enum:
                - "card"
            payment_id:
              type: "string"
            payment_intent_id:
              type: "string"
            client_secret:
              type:
                - "string"
                - "null"
            checkout_url:
              type:
                - "string"
                - "null"
            status:
              type:
                - "string"
                - "null"
            requires_action:
              type: "boolean"
            amount:
              type: "integer"
            currency:
              type: "string"
            breakdown:
              $ref: "#/components/schemas/CheckoutBreakdown"
            mode:
              type: "string"
              enum:
                - "direct"
                - "session"
            session_id:
              type: "string"
            expires_at:
              type: "string"
              format: "date-time"
    SandboxCheckoutActionResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            idempotent:
              type: "boolean"
            already_exists:
              type: "boolean"
            checkout_session:
              type: "object"
              properties:
                id:
                  type: "string"
                  format: "uuid"
                status:
                  type: "string"
                mode:
                  type: "string"
                  enum:
                    - "sandbox"
                payment_id:
                  type:
                    - "string"
                    - "null"
                reference_id:
                  type:
                    - "string"
                    - "null"
                amount:
                  type: "integer"
                  description: "Amount in cents"
                currency:
                  type: "string"
                creator_id:
                  type: "string"
                product_id:
                  type:
                    - "string"
                    - "null"
                product_name:
                  type:
                    - "string"
                    - "null"
                completed_at:
                  type:
                    - "string"
                    - "null"
                  format: "date-time"
                sale_transaction_id:
                  type:
                    - "string"
                    - "null"
                  format: "uuid"
                webhook_deliveries_queued:
                  type: "integer"
            webhook_deliveries:
              type: "array"
              items:
                type: "object"
                additionalProperties: true
    SandboxWebhookTestResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            event_type:
              type: "string"
            webhook_deliveries_queued:
              type: "integer"
            webhook_deliveries:
              type: "array"
              items:
                type: "object"
                additionalProperties: true
    SandboxEventsResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            count:
              type: "integer"
            events:
              type: "array"
              items:
                type: "object"
                additionalProperties: true
    SandboxCleanupRequest:
      type: "object"
      properties:
        dry_run:
          type: "boolean"
          description: "Defaults to true unless a destructive reset is explicitly confirmed."
        scope:
          type: "string"
          enum:
            - "run"
            - "sandbox_ledger"
          description: "run deletes rows matching source/run_id; sandbox_ledger resets sandbox runtime data."
        source:
          type: "string"
          description: "Optional metadata source selector for run-scoped cleanup."
        run_id:
          type: "string"
          description: "Optional metadata run id selector for run-scoped cleanup."
        confirm:
          type: "string"
          enum:
            - "cleanup_sandbox_run_data"
            - "cleanup_sandbox_runtime_data"
          description: "Required to execute cleanup. Use cleanup_sandbox_run_data for scope=run and cleanup_sandbox_runtime_data
            for scope=sandbox_ledger."
    SandboxCleanupResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            mode:
              type: "string"
              enum:
                - "sandbox"
            dry_run:
              type: "boolean"
            scope:
              type: "string"
              enum:
                - "run"
                - "sandbox_ledger"
            ledger_id:
              type: "string"
              format: "uuid"
            source:
              type:
                - "string"
                - "null"
            run_id:
              type:
                - "string"
                - "null"
            counts:
              type: "object"
              additionalProperties:
                type: "integer"
            estimated_deleted:
              type: "integer"
            cleaned:
              type: "boolean"
            deleted:
              type: "object"
              additionalProperties:
                type: "integer"
            cleanup:
              type: "object"
              additionalProperties: true
            preserved:
              type: "object"
              additionalProperties:
                type: "integer"
            message:
              type: "string"
    GetBalanceResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            balance:
              type: "object"
              properties:
                creator_id:
                  type: "string"
                available:
                  type: "number"
                pending:
                  type: "number"
                total_earned:
                  type: "number"
                total_paid_out:
                  type: "number"
                currency:
                  type: "string"
            balances:
              type: "array"
              items:
                type: "object"
                properties:
                  creator_id:
                    type: "string"
                  available:
                    type: "number"
                  pending:
                    type: "number"
                  currency:
                    type: "string"
            platform_summary:
              type: "object"
              properties:
                total_revenue:
                  type: "number"
                total_owed_creators:
                  type: "number"
                total_paid_out:
                  type: "number"
                cash_balance:
                  type: "number"
    ProcessPayoutResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            payout_id:
              type: "string"
            transaction_id:
              type: "string"
              format: "uuid"
            amount:
              type: "integer"
            status:
              type: "string"
    RecordRefundResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            transaction_id:
              type: "string"
              format: "uuid"
            refunded_amount:
              type: "integer"
            breakdown:
              type: "object"
              properties:
                from_creator:
                  type: "number"
                from_platform:
                  type: "number"
    ReverseTransactionResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            void_type:
              type: "string"
              enum:
                - "soft_delete"
                - "reversing_entry"
              description: "Whether the transaction was soft-deleted or reversed via entries"
            reversal_id:
              type:
                - "string"
                - "null"
              format: "uuid"
              description: "ID of the reversal transaction (null for some soft deletes)"
            original_transaction_id:
              type: "string"
              format: "uuid"
              description: "ID of the original transaction that was reversed"
            reversed_amount:
              type:
                - "number"
                - "null"
              description: "Reversed amount in major currency units (present for reversing entries)"
            is_partial:
              type:
                - "boolean"
                - "null"
              description: "Whether this was a partial reversal"
            voided_at:
              type:
                - "string"
                - "null"
              format: "date-time"
              description: "Timestamp when the transaction was voided (soft delete path)"
            reversed_at:
              type:
                - "string"
                - "null"
              format: "date-time"
              description: "Timestamp when the reversing entries were created"
            warning:
              type:
                - "string"
                - "null"
              description: "Warning message (e.g. when reversing a reconciled transaction)"
    TransactionEntry:
      type: "object"
      properties:
        id:
          type: "string"
          format: "uuid"
        account_id:
          type: "string"
          format: "uuid"
        entry_type:
          type: "string"
          enum:
            - "debit"
            - "credit"
        amount:
          type: "number"
        account:
          type: "object"
          properties:
            account_type:
              type: "string"
            entity_id:
              type:
                - "string"
                - "null"
            name:
              type: "string"
    Transaction:
      type: "object"
      properties:
        id:
          type: "string"
          format: "uuid"
        transaction_type:
          type: "string"
        reference_id:
          type:
            - "string"
            - "null"
        reference_type:
          type:
            - "string"
            - "null"
        description:
          type:
            - "string"
            - "null"
        amount:
          type: "number"
        currency:
          type: "string"
        status:
          type: "string"
        metadata:
          type: "object"
          additionalProperties: true
        created_at:
          type: "string"
          format: "date-time"
        entries:
          type: "array"
          items:
            $ref: "#/components/schemas/TransactionEntry"
    Pagination:
      type: "object"
      properties:
        total:
          type: "integer"
        page:
          type: "integer"
        per_page:
          type: "integer"
        total_pages:
          type: "integer"
    GetTransactionsResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            transactions:
              type: "array"
              items:
                $ref: "#/components/schemas/Transaction"
            pagination:
              $ref: "#/components/schemas/Pagination"
    RecordAdjustmentResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            transaction_id:
              type: "string"
              format: "uuid"
            adjustment_id:
              type: "string"
              format: "uuid"
            entries_created:
              type: "integer"
    RecordOpeningBalanceResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            opening_balance_id:
              type: "string"
              format: "uuid"
            transaction_id:
              type: "string"
              format: "uuid"
            summary:
              type: "object"
              properties:
                as_of_date:
                  type: "string"
                  format: "date"
                total_assets:
                  type: "number"
                total_liabilities:
                  type: "number"
                total_equity:
                  type: "number"
                accounts_set:
                  type: "integer"
    RecordTransferResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            transfer_id:
              type: "string"
              format: "uuid"
            transaction_id:
              type: "string"
              format: "uuid"
            amount:
              type: "integer"
            from_account:
              type: "string"
            to_account:
              type: "string"
    RiskEvaluationResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            cached:
              type: "boolean"
            evaluation:
              type: "object"
              properties:
                id:
                  type: "string"
                  format: "uuid"
                signal:
                  type: "string"
                  enum:
                    - "within_policy"
                    - "elevated_risk"
                    - "high_risk"
                risk_factors:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      policy_id:
                        type: "string"
                      policy_type:
                        type: "string"
                      severity:
                        type: "string"
                        enum:
                          - "hard"
                          - "soft"
                      indicator:
                        type: "string"
                valid_until:
                  type: "string"
                  format: "date-time"
                created_at:
                  type: "string"
                  format: "date-time"
                acknowledged_at:
                  type:
                    - "string"
                    - "null"
                  format: "date-time"
    UploadReceiptResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            receipt_id:
              type: "string"
              format: "uuid"
            status:
              type: "string"
              enum:
                - "uploaded"
                - "matched"
                - "orphan"
            linked_transaction_id:
              type:
                - "string"
                - "null"
    ReceivePaymentResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            transaction_id:
              type: "string"
              format: "uuid"
            amount:
              type: "integer"
    ParticipantSummary:
      type: "object"
      properties:
        id:
          type: "string"
        linked_user_id:
          type:
            - "string"
            - "null"
          format: "uuid"
        name:
          type:
            - "string"
            - "null"
        tier:
          type:
            - "string"
            - "null"
        ledger_balance:
          type: "number"
        held_amount:
          type: "number"
        available_balance:
          type: "number"
    Hold:
      type: "object"
      properties:
        id:
          type: "string"
        participant_id:
          type:
            - "string"
            - "null"
        participant_name:
          type:
            - "string"
            - "null"
        amount:
          type: "number"
        currency:
          type: "string"
        held_since:
          type: "string"
          format: "date-time"
        days_held:
          type: "integer"
        hold_reason:
          type:
            - "string"
            - "null"
        hold_until:
          type:
            - "string"
            - "null"
          format: "date-time"
        ready_for_release:
          type: "boolean"
        release_status:
          type: "string"
        transaction_reference:
          type:
            - "string"
            - "null"
        product_name:
          type:
            - "string"
            - "null"
        venture_id:
          type:
            - "string"
            - "null"
        connected_account_ready:
          type: "boolean"
    ParticipantsListResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            participants:
              type: "array"
              items:
                $ref: "#/components/schemas/ParticipantSummary"
    ParticipantDetailResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            participant:
              type: "object"
              properties:
                id:
                  type: "string"
                linked_user_id:
                  type:
                    - "string"
                    - "null"
                  format: "uuid"
                name:
                  type:
                    - "string"
                    - "null"
                tier:
                  type:
                    - "string"
                    - "null"
                custom_split_percent:
                  type:
                    - "number"
                    - "null"
                ledger_balance:
                  type: "number"
                held_amount:
                  type: "number"
                available_balance:
                  type: "number"
                holds:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      amount:
                        type: "number"
                      reason:
                        type:
                          - "string"
                          - "null"
                      release_date:
                        type:
                          - "string"
                          - "null"
                        format: "date-time"
                      status:
                        type: "string"
    ParticipantCreateResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            participant:
              type: "object"
              properties:
                id:
                  type: "string"
                account_id:
                  type: "string"
                  format: "uuid"
                created:
                  type: "boolean"
                linked_user_id:
                  type:
                    - "string"
                    - "null"
                  format: "uuid"
                identity_link_id:
                  type:
                    - "string"
                    - "null"
                display_name:
                  type:
                    - "string"
                    - "null"
                email:
                  type:
                    - "string"
                    - "null"
                identity_link_status:
                  type:
                    - "string"
                    - "null"
                  enum:
                    - "active"
                    - "pending"
                    - null
                default_split_percent:
                  type: "number"
                payout_preferences:
                  type: "object"
                  additionalProperties: true
                created_at:
                  type: "string"
                  format: "date-time"
    ParticipantEligibilityResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            eligibility:
              type: "object"
              properties:
                participant_id:
                  type: "string"
                eligible:
                  type: "boolean"
                available_balance:
                  type: "number"
                issues:
                  type: "array"
                  items:
                    type: "string"
                requirements:
                  type: "object"
                  additionalProperties: true
    WalletObject:
      type: "object"
      properties:
        id:
          type: "string"
          format: "uuid"
        object:
          type: "string"
          enum:
            - "wallet"
        wallet_type:
          type: "string"
          enum:
            - "consumer_credit"
            - "creator_earnings"
        scope_type:
          type: "string"
          enum:
            - "customer"
            - "participant"
        owner_id:
          type:
            - "string"
            - "null"
        owner_type:
          type:
            - "string"
            - "null"
        participant_id:
          type:
            - "string"
            - "null"
        account_type:
          type: "string"
        name:
          type:
            - "string"
            - "null"
        currency:
          type: "string"
        status:
          type: "string"
        balance:
          type: "number"
        held_amount:
          type: "number"
        available_balance:
          type: "number"
        redeemable:
          type: "boolean"
        transferable:
          type: "boolean"
        topup_supported:
          type: "boolean"
        payout_supported:
          type: "boolean"
        created_at:
          type:
            - "string"
            - "null"
          format: "date-time"
        metadata:
          type: "object"
          additionalProperties: true
      required:
        - "id"
        - "object"
        - "wallet_type"
        - "scope_type"
        - "account_type"
        - "currency"
        - "status"
        - "balance"
        - "held_amount"
        - "available_balance"
        - "redeemable"
        - "transferable"
        - "topup_supported"
        - "payout_supported"
        - "metadata"
    WalletListResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            wallets:
              type: "array"
              items:
                $ref: "#/components/schemas/WalletObject"
            total:
              type: "integer"
            limit:
              type: "integer"
            offset:
              type: "integer"
    WalletCreateResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            created:
              type: "boolean"
            wallet:
              $ref: "#/components/schemas/WalletObject"
    WalletDetailResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            wallet:
              $ref: "#/components/schemas/WalletObject"
    WalletEntriesResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            wallet:
              anyOf:
                - $ref: "#/components/schemas/WalletObject"
                - type: "null"
            entries:
              type: "array"
              items:
                type: "object"
                properties:
                  entry_id:
                    type: "string"
                    format: "uuid"
                  entry_type:
                    type: "string"
                    enum:
                      - "debit"
                      - "credit"
                  amount:
                    type: "number"
                  transaction_id:
                    type: "string"
                    format: "uuid"
                  reference_id:
                    type:
                      - "string"
                      - "null"
                  transaction_type:
                    type: "string"
                  description:
                    type:
                      - "string"
                      - "null"
                  status:
                    type: "string"
                  metadata:
                    type: "object"
                    additionalProperties: true
                  created_at:
                    type: "string"
                    format: "date-time"
            total:
              type: "integer"
            limit:
              type: "integer"
            offset:
              type: "integer"
    WalletDepositResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            topup:
              type: "object"
              properties:
                wallet_id:
                  type:
                    - "string"
                    - "null"
                  format: "uuid"
                owner_id:
                  type:
                    - "string"
                    - "null"
                transaction_id:
                  type: "string"
                  format: "uuid"
                balance:
                  type: "number"
    WalletWithdrawalResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            withdrawal:
              type: "object"
              properties:
                participant_id:
                  type: "string"
                transaction_id:
                  type: "string"
                  format: "uuid"
                balance:
                  type: "number"
    TransferFundsResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            transfer:
              type: "object"
              properties:
                transaction_id:
                  type: "string"
                  format: "uuid"
                from_participant_id:
                  type:
                    - "string"
                    - "null"
                to_participant_id:
                  type:
                    - "string"
                    - "null"
                from_balance:
                  type: "number"
                to_balance:
                  type: "number"
    HoldsListResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            holds:
              type: "array"
              items:
                $ref: "#/components/schemas/Hold"
            count:
              type: "integer"
    HoldsSummaryResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            summary:
              type: "object"
              additionalProperties: true
    HoldReleaseResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            release:
              type: "object"
              properties:
                id:
                  type: "string"
                hold_id:
                  type: "string"
                executed:
                  type: "boolean"
                transfer_id:
                  type:
                    - "string"
                    - "null"
                transfer_status:
                  type:
                    - "string"
                    - "null"
                amount:
                  type:
                    - "number"
                    - "null"
                currency:
                  type:
                    - "string"
                    - "null"
    CheckoutSessionResourceResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            checkout_session:
              type: "object"
              properties:
                id:
                  type: "string"
                mode:
                  type: "string"
                provider:
                  type:
                    - "string"
                    - "null"
                checkout_url:
                  type:
                    - "string"
                    - "null"
                payment_id:
                  type:
                    - "string"
                    - "null"
                payment_intent_id:
                  type:
                    - "string"
                    - "null"
                status:
                  type:
                    - "string"
                    - "null"
                requires_action:
                  type: "boolean"
                amount:
                  type: "integer"
                currency:
                  type: "string"
                expires_at:
                  type:
                    - "string"
                    - "null"
                  format: "date-time"
                sandbox:
                  type: "boolean"
                funding_transaction_id:
                  type:
                    - "string"
                    - "null"
                sale_transaction_id:
                  type:
                    - "string"
                    - "null"
                sale_reference:
                  type:
                    - "string"
                    - "null"
                breakdown:
                  $ref: "#/components/schemas/CheckoutBreakdown"
    PayoutResourceResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            payout:
              type: "object"
              properties:
                id:
                  type: "string"
                  format: "uuid"
                transaction_id:
                  type: "string"
                  format: "uuid"
                gross_amount:
                  type:
                    - "number"
                    - "null"
                fees:
                  type:
                    - "number"
                    - "null"
                net_amount:
                  type:
                    - "number"
                    - "null"
                previous_balance:
                  type:
                    - "number"
                    - "null"
                new_balance:
                  type:
                    - "number"
                    - "null"
    RefundResourceResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            warning:
              type:
                - "string"
                - "null"
            warning_code:
              type:
                - "string"
                - "null"
            refund:
              type: "object"
              properties:
                id:
                  type: "string"
                transaction_id:
                  type:
                    - "string"
                    - "null"
                reference_id:
                  type:
                    - "string"
                    - "null"
                sale_reference:
                  type:
                    - "string"
                    - "null"
                refunded_amount:
                  type: "number"
                currency:
                  type:
                    - "string"
                    - "null"
                status:
                  type:
                    - "string"
                    - "null"
                reason:
                  type:
                    - "string"
                    - "null"
                refund_from:
                  type:
                    - "string"
                    - "null"
                external_refund_id:
                  type:
                    - "string"
                    - "null"
                created_at:
                  type:
                    - "string"
                    - "null"
                  format: "date-time"
                breakdown:
                  type:
                    - "object"
                    - "null"
                  properties:
                    from_creator:
                      type: "number"
                    from_platform:
                      type: "number"
                is_full_refund:
                  type:
                    - "boolean"
                    - "null"
                repair_pending:
                  type:
                    - "boolean"
                    - "null"
    RefundsListResponse:
      allOf:
        - $ref: "#/components/schemas/SuccessEnvelope"
        - type: "object"
          properties:
            count:
              type: "integer"
            refunds:
              type: "array"
              items:
                type: "object"
                properties:
                  id:
                    type: "string"
                  transaction_id:
                    type:
                      - "string"
                      - "null"
                  reference_id:
                    type:
                      - "string"
                      - "null"
                  sale_reference:
                    type:
                      - "string"
                      - "null"
                  refunded_amount:
                    type: "number"
                  currency:
                    type: "string"
                  status:
                    type: "string"
                  reason:
                    type:
                      - "string"
                      - "null"
                  refund_from:
                    type:
                      - "string"
                      - "null"
                  external_refund_id:
                    type:
                      - "string"
                      - "null"
                  created_at:
                    type:
                      - "string"
                      - "null"
                    format: "date-time"
                  breakdown:
                    type:
                      - "object"
                      - "null"
                    properties:
                      from_creator:
                        type: "number"
                      from_platform:
                        type: "number"
                  repair_pending:
                    type:
                      - "boolean"
                      - "null"
                  last_error:
                    type:
                      - "string"
                      - "null"
  responses:
    BadRequest:
      description: "Validation error"
      headers: *a1
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
    Unauthorized:
      description: "Invalid or missing API key"
      headers: *a1
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
    NotFound:
      description: "Resource not found"
      headers: *a1
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
    Conflict:
      description: "Conflict (duplicate reference_id, idempotency collision, etc.)"
      headers: *a1
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
    RateLimited:
      description: "Rate limit exceeded"
      headers: *a1
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/RateLimitError"
    InternalError:
      description: "Internal server error"
      headers: *a1
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorEnvelope"
