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

# Create Transactions API

> Create up to 500 Breezing transactions in a single wallet API request, with automatic contact, asset, and internal-transfer detection.



## OpenAPI

````yaml POST /transactions
openapi: 3.1.0
info:
  title: Breezing Public API
  version: 1.0.0
  description: >-
    Crypto accounting API for programmatic access and AI agents. Authenticate
    with an API key using the Authorization header: `Bearer brz_...`
servers:
  - url: https://api.breezing.io/v1
security:
  - BearerAuth: []
paths:
  /transactions:
    post:
      tags:
        - Transactions
      summary: Create transactions in a wallet
      description: >-
        Insert 1 to 500 transactions into a wallet in one call. All transactions
        are inserted atomically (if any row fails validation, none are inserted)
        and then handed to the same downstream pipeline that CSV imports use:


        1. **Process worker** auto-creates contacts for new walletFrom/walletTo
        addresses, auto-creates assets for new token/feeToken symbols, detects
        internal transfers (between the user's own wallets) and sets
        isInternal/walletFromId/walletToId.

        2. When all rows are processed, the worker chains into **fiat pricing**
        (when doFiat=true; backfills amountFiat/feeFiat then queues balance
        calc) or **balance calculation directly** (when doFiat=false).

        3. NGL is NOT recalculated automatically. Call POST /v1/ngl/calculate
        when ready.


        **Amount/fee sign convention.** Pass POSITIVE decimals. The server signs
        them based on direction: amounts become negative for direction="out";
        fees become negative for "out" and FORCED to "0" for "in" (Breezing's
        invariant, fees can never be positive and must be zero on incoming
        legs).


        **transactionId** is required and is the EXTERNAL reference (blockchain
        hash, exchange order id, invoice number…). It is NOT deduped. Multiple
        rows can share one. It is NOT the Breezing database id.


        **Per-wallet gating.** Returns 409 TASK_IN_PROGRESS if a `processingTrx`
        or `importTransactions` task is already running for the wallet (covers
        CSV imports, chain syncs, and prior POST /v1/transactions calls).
        Different wallets in the same company can be loaded in parallel. Call
        GET /v1/tasks?walletId=X first.
      parameters:
        - schema:
            type: string
            description: >-
              Organization ID. Use GET /v1/companies to discover available
              org/company pairs.
            example: '1'
          required: true
          description: >-
            Organization ID. Use GET /v1/companies to discover available
            org/company pairs.
          name: orgId
          in: query
        - schema:
            type: string
            description: >-
              Company ID. Use GET /v1/companies to discover available companies
              and their access levels.
            example: '1'
          required: true
          description: >-
            Company ID. Use GET /v1/companies to discover available companies
            and their access levels.
          name: companyId
          in: query
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTransactionsBody'
      responses:
        '200':
          description: Transactions inserted successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      created:
                        type: integer
                        description: Number of rows inserted.
                      walletId:
                        type: integer
                      taskId:
                        type: integer
                        nullable: true
                        description: >-
                          Task id for the post-insert processing job. Poll GET
                          /v1/tasks to monitor progress. Null on rare timing
                          edges where the worker already finished. Fall back to
                          GET /v1/tasks?walletId={id}.
                      transactionIds:
                        type: array
                        items:
                          type: integer
                        description: >-
                          Database ids of the inserted rows, in the same order
                          as the request body. transactionId (the external
                          reference) is preserved separately.
                    required:
                      - created
                      - walletId
                      - taskId
                      - transactionIds
                required:
                  - success
                  - data
        '400':
          description: Bad request (validation failure on the body or a row)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - success
                  - error
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - success
                  - error
        '403':
          description: >-
            API key has no access to this company, has read-only access where
            write was required, or the company subscription is inactive
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - success
                  - error
        '404':
          description: Wallet not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - success
                  - error
        '409':
          description: A processing or import task is already running for this wallet
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - success
                  - error
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - success
                  - error
      security:
        - BearerAuth: []
components:
  schemas:
    CreateTransactionsBody:
      type: object
      properties:
        walletId:
          type: integer
          minimum: 0
          exclusiveMinimum: true
          description: >-
            Wallet to add transactions to. Must belong to orgId/companyId. Any
            wallet type is allowed; transactions are tagged
            addedVia="publicApi".
          example: 1
        doFiat:
          type: boolean
          default: true
          description: >-
            When true (default), the process worker chain queues the
            fiat-pricing worker after processing (fills amountFiat/feeFiat).
            When false, balance calculation is queued directly without fiat
            backfill.
        transactions:
          type: array
          items:
            $ref: '#/components/schemas/CreateTransactionInput'
          minItems: 1
          maxItems: 500
          description: >-
            Transactions to insert (1 to 500). All inserted atomically. If any
            row fails validation, none are inserted.
      required:
        - walletId
        - transactions
    CreateTransactionInput:
      type: object
      properties:
        direction:
          type: string
          enum:
            - in
            - out
          description: >-
            Transaction direction. "in" = wallet received the asset; "out" =
            wallet sent the asset. Server normalizes the sign of amount/fee
            based on this value (negative for "out", positive for "in").
          example: in
        date:
          type: integer
          minimum: 0
          exclusiveMinimum: true
          description: Transaction timestamp in unix SECONDS (not milliseconds).
          example: 1700000000
        transactionId:
          type: string
          minLength: 1
          description: >-
            External reference id (blockchain tx hash, exchange order id,
            invoice number, etc.). Required. NOT deduped. Multiple rows can
            share one. NOT the Breezing internal id.
          example: 0xabc123…
        token:
          type: string
          minLength: 1
          description: Token symbol (e.g. "ETH", "USDC").
          example: ETH
        amount:
          anyOf:
            - type: string
            - type: number
          description: >-
            Token amount as a POSITIVE decimal (server signs it based on
            direction). Strings preferred for precision.
          example: '1.5'
        fee:
          anyOf:
            - type: string
            - type: number
          description: >-
            Fee in token as a POSITIVE decimal. Server forces "0" when
            direction="in"; negates for "out". Defaults to "0".
          example: '0.001'
        feeToken:
          type: string
          description: Fee token symbol. Defaults to `token` when omitted.
        amountFiat:
          anyOf:
            - type: string
            - type: number
          description: >-
            Fiat equivalent of amount as a POSITIVE decimal (server signs by
            direction). If omitted or "0", the system computes it later via the
            fiat-pricing worker when `doFiat=true`.
          example: '3000.00'
        feeFiat:
          anyOf:
            - type: string
            - type: number
          description: >-
            Fiat equivalent of fee as a POSITIVE decimal (server signs by
            direction). Server forces "0" for direction="in".
          example: '2.00'
        type:
          type: string
          description: Freeform type label (e.g. "trade", "transfer").
        chain:
          type: string
          description: Blockchain identifier. Defaults to the wallet chain when omitted.
        tokenAddress:
          type: string
          description: Token contract address.
        feeTokenAddress:
          type: string
          description: Fee token contract address.
        walletFrom:
          type: string
          description: >-
            Source wallet address. The process worker auto-creates a contact for
            new addresses.
        walletTo:
          type: string
          description: >-
            Destination wallet address. The process worker auto-creates a
            contact for new addresses.
        account:
          type: string
          description: Contra (income/expense) account code. Leave empty for uncategorized.
        assetAccount:
          type: string
          description: Balance-sheet asset account. Omit to use the DB default "(auto)".
        feeAssetAccount:
          type: string
          description: >-
            Balance-sheet asset account for the fee. Omit to use the DB default
            "(auto)".
        accountingDescription:
          type: string
          description: >-
            Description that syncs as the journal-entry description to
            Xero/QuickBooks/Bexio.
        note:
          type: string
          description: Internal note (not synced to accounting software).
        extraLabel:
          type: string
          description: Freeform tagging label.
        vat:
          type: string
          description: >-
            VAT or sales tax code (e.g. "Output 8.1% VAT"). Omit for DB default
            "no-vat".
        isSpam:
          type: boolean
          description: Mark as spam.
        isNFT:
          type: boolean
          description: Mark as NFT.
        skipNgl:
          type: boolean
          description: Exclude from NGL calculation.
        skipNglReason:
          type: string
          description: Reason for skipNgl=true.
        currency:
          type: string
          description: 3-letter fiat currency. Defaults to the company currency.
        functionName:
          type: string
          description: Smart-contract function name (free text).
        tokenId:
          type: string
          description: NFT token id.
      required:
        - direction
        - date
        - transactionId
        - token
        - amount

````