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

# Create a new investor

> Create an investor with full KYC data. The request body is
flat: regulatory fields at the top level; only
`address`, `signed_agreements[]`, and `trusted_contact` are nested.




## OpenAPI

````yaml /api-reference/openapi.yaml post /investors
openapi: 3.0.0
info:
  title: Bluum Finance Investment API
  version: 1.0.0
  description: >
    The Bluum Finance API provides embeddable investment experiences, allowing
    fintech partners to manage investor accounts, facilitate trading, handle
    document uploads, and manage wallet operations.


    ### Response conventions


    Every resource response carries a small, consistent set of envelope keys

    followed by domain fields:


    ```json

    {
      "id": "<prefix>_<base32>",
      "object": "<resource>",
      "created": <unix_seconds>,
      "livemode": <boolean>,
      "metadata": { ... },
      ... domain fields ...
    }

    ```


    List endpoints return:


    ```json

    {
      "object": "list",
      "url": "/v1/<resource>",
      "has_more": false,
      "data": [ <resource>... ]
    }

    ```


    Errors are wrapped in:


    ```json

    {
      "error": {
        "type": "invalid_request_error",
        "code": "BLUM-400-001",
        "message": "...",
        "param": "tax_id"
      }
    }

    ```


    See `ResourceEnvelope`, `ListEnvelope`, and `ErrorEnvelope` in

    `shared-schemas.yaml` for the full schemas.


    ### Product entitlements


    Core investing (accounts, funding, trading, positions, documents,

    webhooks) is available to every tenant. Three surfaces are add-on products

    that must be enabled for your tenant before use:


    - **Market Data** — `/v1/market-data/*`

    - **Cash Management** — `/v1/cash-management/*`


    Calling a disabled product returns HTTP `403` with the legacy

    `{ "status": "error", "code": "PRODUCT_NOT_ENABLED", "message": "..." }`

    body (not the standard error envelope). Contact your Bluum account manager

    to enable a product.


    ### Field naming


    - snake_case throughout (no camelCase)

    - `email` / `phone` (not `email_address` / `phone_number`)

    - `first_name` / `middle_name` / `last_name` (not `given_name` /
    `family_name`)

    - `address: { street: [string], unit?, city, state?, postal_code?, country
    }`
      (the `street` array form preserves multi-line addresses; ISO 3166-1
      alpha-2 country code on `address.country` and on the top-level
      `country_of_*` fields)
    - `quantity` (not `qty`)

    - Status enums are lowercase Bluum-native vocabulary (e.g. `pending` /
    `filled` / `cancelled` / `failed`)


    Regulatory vocabulary (CAIS / FINRA / IRS / FATF) is preserved verbatim

    (e.g. `tax_id_type`, `country_of_tax_residence`, `is_politically_exposed`,

    `funding_source`).


    ### Terminology


    The investor resource lives at `/v1/investors`. Path parameter is

    `investor_id`.


    ### Asset classification


    Assets carry a canonical `(class, country)` pair:

    - `class`: `equity` | `etf` | `bond` | `bill` | `note` | `mutual_fund` |
      `derivative` | `cryptocurrency` | `commodity` | `real_estate` | `cash`
    - `country`: ISO 3166-1 alpha-2, lower-case (`us`, `ng`, …). Null for
      country-agnostic instruments (most crypto).

    ### Fixed income (bonds)


    Bond orders use the same `POST /v1/investors/{investor_id}/orders`

    endpoint as equities, with bond-specific semantics:

    - `quantity` carries **face value** (e.g. `"10000"` for $10k face),
      and must be a multiple of the bond's `min_increment`.
    - `limit_price` is quoted as **% of par** (e.g. `"99.875"` = 99.875%
      of face value).
    - `settlement_date` is optional; defaults to T+1 for US treasuries
      and T+2 for corporates.
    - Bond quote responses (`/v1/market-data/assets/{symbol}/quote`)
      include a `bond` block with clean/dirty price, accrued interest,
      and yield to maturity.

    Bond trading must be explicitly enabled on the tenant before orders

    will route. Contact Bluum support to flip `fixedIncomeEnabled`.


    ### Authentication


    HTTP Basic Authentication. **API Key** is the username, **API Secret** is

    the password. Base64-encode `API_KEY:API_SECRET` and send in the

    `Authorization` header.
servers:
  - url: https://api.bluumfinance.com/v1
    description: Production Environment
  - url: https://sandbox.api.bluumfinance.com/v1
    description: Sandbox/Testing Environment
  - url: https://service.bluumfinance.com/v1
    description: Production Environment (legacy alias)
  - url: https://test-service.bluumfinance.com/v1
    description: Sandbox/Testing Environment (legacy alias)
security:
  - BluumApiKeyAuth: []
  - BearerAuth: []
tags:
  - name: Investors
    description: Create and manage investor accounts, wallets, and transactions.
  - name: API Keys
    description: Mint, list, and revoke investor-scoped API keys for programmatic access.
  - name: Compliance
    description: Investor compliance workflows, KYC checks, and document submissions.
  - name: Transfers
    description: Deposit and withdrawal operations for investor wallets.
  - name: Funding Sources
    description: Connect and manage external funding sources (Plaid, bank accounts).
  - name: Trading
    description: Place, list, and cancel investor orders.
  - name: Positions
    description: View investor portfolio positions.
  - name: Assets
    description: Search and retrieve asset reference data.
  - name: Document Management
    description: Upload, list, and download documents.
  - name: Markets
    description: Market reference data, status, calendar, and halts.
  - name: Market Data
    description: Real-time quotes, snapshots, and historical bars (paywalled product).
  - name: Webhooks
    description: Register and manage webhook endpoints for event delivery.
  - name: Disclosures
    description: >-
      Partner-facing disclosure library (verbatim regulated copy, PDFs) +
      per-investor acceptance trail.
  - name: Cash Sweep
    description: >-
      High Yield Cash (HYC) / FDIC Bank Sweep enrollment, tier management, and
      interest reporting.
  - name: Cash Management
    description: >-
      Multi-currency, zero-day-liquidity yield on cash — programs, eligibility,
      enrollment, sweeps, withdrawals, earnings.
paths:
  /investors:
    post:
      tags:
        - Investors
      summary: Create a new investor
      description: |
        Create an investor with full KYC data. The request body is
        flat: regulatory fields at the top level; only
        `address`, `signed_agreements[]`, and `trusted_contact` are nested.
      operationId: createAccount
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NewAccountRequest'
            examples:
              individual:
                summary: Individual self-directed investor
                value:
                  account_type: individual
                  management_type: self_directed
                  tax_advantaged: false
                  first_name: Jane
                  last_name: Doe
                  date_of_birth: '1990-05-15'
                  email: jane.doe@example.com
                  phone: '+14155551234'
                  address:
                    street:
                      - 456 Oak Avenue
                    city: San Francisco
                    state: CA
                    postal_code: '94102'
                    country: US
                  tax_id: 987-65-4321
                  tax_id_type: SSN
                  country_of_tax_residence: US
                  country_of_citizenship: US
                  country_of_birth: US
                  funding_source:
                    - employment_income
                  annual_income:
                    min: '75000'
                    max: '99999'
                  liquid_net_worth:
                    min: '20000'
                    max: '49999'
                  is_control_person: false
                  is_affiliated_exchange_or_finra: false
                  is_politically_exposed: false
                  immediate_family_exposed: false
                  employment_status: employed
                  employer_name: Acme Inc
                  signed_agreements:
                    - type: investor_agreement
                      signed_at: '2026-01-15T10:30:00.000Z'
                      ip_address: 203.0.113.42
                    - type: margin_disclosure_acknowledged
                      signed_at: '2026-01-15T10:30:00.000Z'
                      ip_address: 203.0.113.42
      responses:
        '201':
          description: Investor created. Pending compliance approval.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Investor'
              examples:
                created:
                  summary: Investor created; compliance checks pending
                  value:
                    id: inv_01j9x8m2k7qpzwv3t5r6y8n0ab
                    object: investor
                    created: 1747776000
                    livemode: false
                    metadata: {}
                    status: onboarding
                    account_type: individual
                    management_type: self_directed
                    tax_advantaged: false
                    tax_designation: null
                    account_number: null
                    currency: USD
                    balance: '0.00'
                    buying_power: '0'
                    cash_withdrawable: '0'
                    last_equity: '0.00'
                    crypto_status: null
                    trading_type: null
                    first_name: Jane
                    middle_name: null
                    last_name: Doe
                    date_of_birth: '1990-05-15'
                    email: jane.doe@example.com
                    phone: '+14155551234'
                    address:
                      street:
                        - 456 Oak Avenue
                      unit: null
                      city: San Francisco
                      state: CA
                      postal_code: '94102'
                      country: US
                    tax_id_type: SSN
                    country_of_tax_residence: US
                    country_of_citizenship: US
                    country_of_birth: US
                    funding_source:
                      - employment_income
                    is_control_person: false
                    is_affiliated_exchange_or_finra: false
                    is_affiliated_exchange_or_iiroc: null
                    is_politically_exposed: false
                    immediate_family_exposed: false
                    employment_status: employed
                    employer_name: Acme Inc
                    employer_address: null
                    employment_position: null
                    signed_agreements:
                      - type: investor_agreement
                        signed_at: '2026-01-15T10:30:00.000Z'
                        ip_address: 203.0.113.42
                    trusted_contact: null
                    portfolios: []
                    compliance_checks:
                      - workflow_id: cw_01j9x8m2k7qpzwv3t5r6y8n0cd
                        check_type: identity_verification
                        status: pending
                        provider: persona-identity
                        external_id: inq_abc123def456
                        verification_url: >-
                          https://withpersona.com/verify?inquiry-id=inq_abc123def456
                        verification_token: null
                      - workflow_id: cw_01j9x8m2k7qpzwv3t5r6y8n0cd
                        check_type: screening
                        status: pending
                        provider: persona-screening
                        external_id: null
                        verification_url: null
                        verification_token: null
        '400':
          $ref: '#/components/responses/BadRequestError'
components:
  schemas:
    NewAccountRequest:
      description: |
        flat investor creation body. Regulatory fields live at
        the top level; only `address`, `signed_agreements[]`, and
        `trusted_contact` are nested (each is an independent sub-object).
      type: object
      required:
        - account_type
        - first_name
        - last_name
        - date_of_birth
        - email
        - phone
        - address
        - tax_id
        - tax_id_type
        - country_of_tax_residence
        - country_of_citizenship
        - country_of_birth
        - funding_source
        - annual_income
        - liquid_net_worth
        - is_control_person
        - is_affiliated_exchange_or_finra
        - is_politically_exposed
        - immediate_family_exposed
        - employment_status
        - signed_agreements
      properties:
        account_type:
          type: string
          enum:
            - individual
            - joint
            - corporate
          example: individual
        management_type:
          type: string
          enum:
            - self_directed
            - advised
          default: self_directed
        tax_advantaged:
          type: boolean
          default: false
        tax_designation:
          type: string
          nullable: true
        first_name:
          type: string
          example: Jane
        middle_name:
          type: string
          nullable: true
        last_name:
          type: string
          example: Doe
        date_of_birth:
          type: string
          format: date
          example: '1990-01-01'
        email:
          type: string
          format: email
          example: jane@example.com
        phone:
          type: string
          example: '+15555550123'
        address:
          type: object
          required:
            - street
            - city
            - country
          properties:
            street:
              type: array
              items:
                type: string
              minItems: 1
              description: >-
                One or more street lines (the array form is required even for
                single-line addresses).
              example:
                - 123 Market St
            unit:
              type: string
              nullable: true
            city:
              type: string
              example: Berkeley
            state:
              type: string
              description: Required for US tax residents. Optional otherwise.
              example: CA
            postal_code:
              type: string
              description: >-
                Required for US tax residents (5 digits, optionally `-4
                digits`). Optional otherwise.
              example: '94704'
            country:
              type: string
              description: ISO 3166-1 alpha-2 country code.
              example: US
        tax_id:
          type: string
          example: 401-23-4567
        tax_id_type:
          type: string
          enum:
            - SSN
            - ITIN
            - EIN
            - SIN
            - NINO
            - TFN
            - VAT
            - TIN
            - UTR
            - PAN
            - NIN
            - KRA_PIN
            - OTHER
        tax_id_country:
          type: string
          description: ISO 3166-1 alpha-2 of the tax-id issuing country.
          nullable: true
        country_of_tax_residence:
          type: string
          example: US
        country_of_citizenship:
          type: string
          example: US
        country_of_birth:
          type: string
          example: US
        funding_source:
          type: array
          items:
            type: string
            enum:
              - employment_income
              - investments
              - inheritance
              - business_income
              - savings
              - family
              - other
          example:
            - employment_income
        annual_income:
          type: object
          properties:
            min:
              type: string
            max:
              type: string
        liquid_net_worth:
          type: object
          properties:
            min:
              type: string
            max:
              type: string
        total_net_worth:
          type: object
          properties:
            min:
              type: string
            max:
              type: string
        permanent_resident:
          type: boolean
          nullable: true
        visa_type:
          type: string
          nullable: true
          enum:
            - E1
            - E2
            - E3
            - F1
            - H1B
            - TN1
            - O1
            - J1
            - L1
            - DACA
            - G4
            - OTHER
        visa_expiration_date:
          type: string
          format: date
          nullable: true
        is_control_person:
          type: boolean
        is_affiliated_exchange_or_finra:
          type: boolean
        is_affiliated_exchange_or_iiroc:
          type: boolean
          nullable: true
        is_politically_exposed:
          type: boolean
        immediate_family_exposed:
          type: boolean
        affiliated_company:
          type: object
          nullable: true
          description: >-
            Required when `is_affiliated_exchange_or_finra` or
            `is_control_person` is true. `ticker` is additionally required for
            control persons of a publicly traded company.
          properties:
            name:
              type: string
            address:
              type: string
            compliance_email:
              type: string
              format: email
            ticker:
              type: string
        employment_status:
          type: string
          enum:
            - employed
            - unemployed
            - student
            - retired
        employer_name:
          type: string
          nullable: true
        employer_address:
          type: string
          nullable: true
        employment_position:
          type: string
          nullable: true
        signed_agreements:
          type: array
          minItems: 2
          description: |
            Audit trail for each regulated acknowledgement the user clicked.
            Must contain at least `investor_agreement` and
            `margin_disclosure_acknowledged`; non-US tax residents must
            additionally include `w8ben_certification`.
          items:
            type: object
            required:
              - type
              - signed_at
              - ip_address
            properties:
              type:
                type: string
                enum:
                  - investor_agreement
                  - margin_disclosure_acknowledged
                  - w8ben_certification
                example: investor_agreement
              signed_at:
                type: string
                format: date-time
                description: ISO-8601 timestamp when the user clicked Accept.
              ip_address:
                type: string
                description: Client IP address at the time of click.
        trusted_contact:
          $ref: '#/components/schemas/TrustedContact'
        metadata:
          type: object
          additionalProperties:
            type: string
    Investor:
      description: |
        The investor (account) resource. flat: regulatory fields are
        flat at the top level; only `address`, `signed_agreements[]`, and
        `trusted_contact` retain meaningful nesting. The Alpaca-style
        `contact` / `identity` / `disclosures` block grouping is intentionally
        absent.
      allOf:
        - $ref: '#/components/schemas/ResourceEnvelope'
        - type: object
          properties:
            status:
              type: string
              enum:
                - onboarding
                - under_review
                - awaiting_documents
                - active
                - suspended
                - closed
                - declined
                - setup_failed
              description: Bluum-native account status.
              example: onboarding
            account_type:
              type: string
              enum:
                - individual
                - joint
                - corporate
              example: individual
            management_type:
              type: string
              enum:
                - self_directed
                - advised
              example: self_directed
            tax_advantaged:
              type: boolean
              example: false
            tax_designation:
              type: string
              nullable: true
            account_number:
              type: string
              nullable: true
            currency:
              type: string
              example: USD
            balance:
              type: string
              example: '0.00'
            buying_power:
              type: string
              description: >-
                Available buying power from the custodian brokerage account.
                Defaults to "0" when no custodian account exists yet.
              example: '10000.00'
            cash_withdrawable:
              type: string
              description: >-
                Amount of cash available for withdrawal from the custodian
                brokerage account. Defaults to "0" when no custodian account
                exists yet.
              example: '5000.00'
            last_equity:
              type: string
              example: '0.00'
            crypto_status:
              type: string
              nullable: true
            trading_type:
              type: string
              enum:
                - cash
                - margin
                - null
              nullable: true
            high_yield_cash_status:
              type: string
              description: High-Yield-Cash enrollment lifecycle for this account.
              enum:
                - not_registered
                - pending
                - active
                - unenrolled
              example: active
            high_yield_cash_status_at:
              type: string
              format: date-time
              nullable: true
              description: >-
                Timestamp of the transition into the current HYC status (null
                when not_registered).
            first_name:
              type: string
              example: Jane
            middle_name:
              type: string
              nullable: true
            last_name:
              type: string
              example: Doe
            date_of_birth:
              type: string
              format: date
              nullable: true
              example: '1990-01-01'
            email:
              type: string
              format: email
              example: jane@example.com
            phone:
              type: string
              nullable: true
              example: '+15555550123'
            address:
              type: object
              description: |
                Address record. `street` is an array of one or more street
                lines (multi-line addresses keep one entry per line).
              properties:
                street:
                  type: array
                  items:
                    type: string
                  example:
                    - 123 Market St
                unit:
                  type: string
                  nullable: true
                city:
                  type: string
                  nullable: true
                state:
                  type: string
                  nullable: true
                postal_code:
                  type: string
                  nullable: true
                country:
                  type: string
                  description: ISO 3166-1 alpha-2.
                  nullable: true
                  example: US
            tax_id_type:
              type: string
              enum:
                - SSN
                - ITIN
                - EIN
                - SIN
                - NINO
                - TFN
                - VAT
                - TIN
                - UTR
                - PAN
                - NIN
                - KRA_PIN
                - OTHER
              nullable: true
            country_of_tax_residence:
              type: string
              description: ISO 3166-1 alpha-2.
              nullable: true
            country_of_citizenship:
              type: string
              description: ISO 3166-1 alpha-2.
              nullable: true
            country_of_birth:
              type: string
              description: ISO 3166-1 alpha-2.
              nullable: true
            funding_source:
              type: array
              items:
                type: string
                enum:
                  - employment_income
                  - investments
                  - inheritance
                  - business_income
                  - savings
                  - family
                  - other
            is_control_person:
              type: boolean
            is_affiliated_exchange_or_finra:
              type: boolean
            is_affiliated_exchange_or_iiroc:
              type: boolean
              nullable: true
            is_politically_exposed:
              type: boolean
            immediate_family_exposed:
              type: boolean
            employment_status:
              type: string
              enum:
                - employed
                - unemployed
                - student
                - retired
              nullable: true
            employer_name:
              type: string
              nullable: true
            employer_address:
              type: string
              nullable: true
            employment_position:
              type: string
              nullable: true
            signed_agreements:
              type: array
              items:
                type: object
                required:
                  - type
                  - signed_at
                properties:
                  type:
                    type: string
                    description: |
                      Bluum-native agreement key. Translation to Alpaca's
                      wire keys (customer_agreement / account_agreement /
                      margin_agreement) happens internally.
                    enum:
                      - investor_agreement
                      - margin_disclosure_acknowledged
                      - w8ben_certification
                    example: investor_agreement
                  signed_at:
                    type: string
                    format: date-time
                  ip_address:
                    type: string
                    nullable: true
            trusted_contact:
              type: object
              nullable: true
              properties:
                first_name:
                  type: string
                last_name:
                  type: string
                email:
                  type: string
                  format: email
                phone:
                  type: string
                  nullable: true
            portfolios:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                  name:
                    type: string
                  status:
                    type: string
                  currency:
                    type: string
                    nullable: true
                  createdAt:
                    type: string
                    format: date-time
                  updatedAt:
                    type: string
                    format: date-time
            compliance_checks:
              type: array
              nullable: true
              items:
                $ref: '#/components/schemas/ComplianceCheckResponse'
    TrustedContact:
      description: |
        FINRA-defined "designated trusted contact" record. Per FINRA SR Rule
        4512, partners must give end-users a way to add or update a trusted
        contact post-onboarding. All four fields are required together.
      type: object
      required:
        - first_name
        - last_name
        - email
        - phone
      properties:
        first_name:
          type: string
          example: Mary
        last_name:
          type: string
          example: Doe
        email:
          type: string
          format: email
          example: mary@example.com
        phone:
          type: string
          description: Phone number in E.164 format.
          example: '+15555550199'
    ResourceEnvelope:
      type: object
      description: |
        Resource envelope. Domain fields are spread after the
        envelope keys (`id`, `object`, `created`, `livemode`, `metadata`).
        Some Bluum-original resources may emit only `object` + `livemode`
        without `id` / `created` (e.g. one-off action results).
      required:
        - object
        - livemode
      additionalProperties: true
      properties:
        id:
          type: string
          description: Prefixed public id (e.g. `inv_…`, `ord_…`, `dep_…`).
          example: inv_01j9x8m2k7qpzwv3t5r6y8n0ab
        object:
          type: string
          description: The resource type discriminator.
          example: investor
        created:
          type: integer
          nullable: true
          description: Unix-seconds timestamp of resource creation.
          example: 1747776000
        livemode:
          type: boolean
          description: |
            Whether this resource was created against a live API key.
            Test-mode keys always return `false`.
          example: false
        metadata:
          type: object
          additionalProperties:
            type: string
          description: Partner-set key/value map for cross-referencing.
    ComplianceCheckResponse:
      type: object
      properties:
        workflow_id:
          type: string
          description: The compliance workflow this check belongs to.
          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
        check_type:
          type: string
          enum:
            - identity_verification
            - tax_id_verification
            - screening
            - risk_assessment
            - business_verification
          description: The type of compliance check performed.
          example: identity_verification
        status:
          type: string
          enum:
            - pending
            - clear
            - failed
            - review_required
            - error
          description: >
            Current status of the check:

            - `pending` — Async verification in progress; use `verification_url`
            or `verification_token` for user completion.

            - `clear` — Verification passed.

            - `failed` — Verification failed.

            - `review_required` — Manual review needed (e.g., potential
            PEP/sanctions match).

            - `error` — Provider error during verification.
          example: pending
        provider:
          type: string
          nullable: true
          description: >-
            The verification provider handling this check (e.g.,
            persona-identity, persona-taxid, dojah).
          example: persona-identity
        external_id:
          type: string
          nullable: true
          description: Provider-specific reference ID for the verification.
          example: inq_abc123def456
        verification_url:
          type: string
          nullable: true
          description: |
            User-facing verification URL for async checks, when available.
          example: https://withpersona.com/verify?inquiry-id=inq_abc123def456
        verification_token:
          type: string
          nullable: true
          description: >
            Provider token or SDK configuration for client-side verification,
            when available.
          example: null
    ErrorEnvelope:
      type: object
      description: |
        Error envelope. The Bluum-specific `BLUM-XXX-XXX`
        code is carried in `error.code`; `error.type` is the broad
        category clients branch on.
      required:
        - error
      properties:
        error:
          type: object
          required:
            - type
            - code
            - message
          properties:
            type:
              type: string
              enum:
                - invalid_request_error
                - authentication_error
                - permission_error
                - not_found_error
                - conflict_error
                - idempotency_error
                - rate_limit_error
                - api_error
              example: invalid_request_error
            code:
              type: string
              description: The Bluum-specific error code.
              example: BLUM-400-001
            message:
              type: string
              description: Developer-facing message.
            param:
              type: string
              description: Field path of the invalid input.
              example: tax_id
            doc_url:
              type: string
              format: uri
              example: https://docs.bluum.finance/errors/BLUM-400-001
            request_log_url:
              type: string
              format: uri
              description: Deep link to the request log in the partner dashboard.
  responses:
    BadRequestError:
      description: The request was malformed or failed validation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              type: invalid_request_error
              code: BLUM-400-002
              message: Required field 'symbol' is missing.
              param: symbol
  securitySchemes:
    BluumApiKeyAuth:
      type: http
      scheme: basic
      description: >
        HTTP Basic Authentication using the **API Key** as username and **API
        Secret** as password.
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        JWT token from Clerk authentication

````