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

# Transfer inventory between locations -- single or multi-item atomic

> ATOMIC-CREATE (2026-05-12): accepts items[] for multi-line atomic transfers OR
top-level product_id/quantity for single-item compat mode.
All items transfer in one DB transaction; any failure rolls back all items (no partial writes).
Inter-location transfer. Writes transfer_out + transfer_in ledger rows per item.
Intra-entity: no GL. Intercompany: posts Due From / Due To GL entries.
Field names: source_location_id (or from_location_id) and dest_location_id (or to_location_id) are accepted aliases.
entity_from_id is injected from API key entity_id; do not supply in request body.




## OpenAPI

````yaml /openapi.yaml post /inventory/transfers
openapi: 3.1.0
info:
  title: Arcus ERP Public API
  version: 1.0.0
  description: >
    Arcus ERP public REST API. Designed for external integrations and data
    migration.


    **Authentication.** Bearer token (API key) via the `Authorization` header.

    Format: `Authorization: Bearer ark_live_ent_<code>_<random>` (or
    `ark_test_*` for sandbox).

    API keys are issued per-entity in **Settings > Developers > API Keys**.


    **Entity scoping.** The entity is encoded in the API key prefix; routes are
    flat

    (e.g. `/v1/accounts`, `/v1/orders`, `/v1/products`). A small set of platform
    endpoints

    (migration, reconciliation, events, webhook endpoints, API keys) use the

    `/v1/entities/{entity_id}/...` form -- those are noted in their tags.


    **Key capabilities.**
      - Related-resource hydration via `?expand[]=` (see `x-arcus-expand` on each resource).
      - Cursor-based pagination (`starting_after` / `ending_before` / `limit`).
      - Idempotency via the `Idempotency-Key` header.
      - Webhook events for asynchronous notification.
      - Conditional requests / ETag for cache validation.
servers:
  - url: https://api.arcuserp.com/v1
    description: Arcus ERP API (accepts both live `ark_live_*` and test `ark_test_*` keys)
  - url: https://dev-api.arcuserp.com/v1
    description: >-
      Dev sandbox API (test-only data, accepts `ark_test_*` keys against dev
      RDS)
security: []
paths:
  /inventory/transfers:
    post:
      tags:
        - Inventory
      summary: Transfer inventory between locations -- single or multi-item atomic
      description: >
        ATOMIC-CREATE (2026-05-12): accepts items[] for multi-line atomic
        transfers OR

        top-level product_id/quantity for single-item compat mode.

        All items transfer in one DB transaction; any failure rolls back all
        items (no partial writes).

        Inter-location transfer. Writes transfer_out + transfer_in ledger rows
        per item.

        Intra-entity: no GL. Intercompany: posts Due From / Due To GL entries.

        Field names: source_location_id (or from_location_id) and
        dest_location_id (or to_location_id) are accepted aliases.

        entity_from_id is injected from API key entity_id; do not supply in
        request body.
      operationId: postInventoryTransfer
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - type: object
                  description: Multi-item atomic mode
                  required:
                    - source_location_id
                    - dest_location_id
                    - items
                  properties:
                    source_location_id:
                      type: string
                      format: uuid
                      description: 'Also accepted: from_location_id'
                    dest_location_id:
                      type: string
                      format: uuid
                      description: 'Also accepted: to_location_id'
                    notes:
                      type: string
                    items:
                      type: array
                      minItems: 1
                      items:
                        type: object
                        required:
                          - product_id
                          - quantity
                        properties:
                          product_id:
                            type: string
                            format: uuid
                          quantity:
                            type: integer
                            minimum: 1
                          notes:
                            type: string
                - type: object
                  description: Single-item compat mode
                  required:
                    - product_id
                    - source_location_id
                    - dest_location_id
                    - quantity
                  properties:
                    product_id:
                      type: string
                      format: uuid
                    source_location_id:
                      type: string
                      format: uuid
                      description: 'Also accepted: from_location_id'
                    dest_location_id:
                      type: string
                      format: uuid
                      description: 'Also accepted: to_location_id'
                    quantity:
                      type: integer
                      minimum: 1
                    notes:
                      type: string
            examples:
              multi_item_transfer:
                summary: Multi-item inter-location transfer (atomic)
                description: >
                  Transfer two SKUs from Warehouse A to Warehouse B in one
                  atomic transaction.

                  All items are inserted in one DB transaction -- any failure
                  rolls back all.

                  GL does NOT fire on draft create; it fires when the transfer
                  is submitted.

                  Field aliases: from_location_id / to_location_id also
                  accepted.
                value:
                  source_location_id: 91aa7588-4dc7-4edd-b172-7de91f5e1f78
                  dest_location_id: 828cabe6-3fa2-4fb7-a2af-2280bbaba335
                  notes: Weekly replenishment transfer to secondary warehouse
                  items:
                    - product_id: 7f6f3e14-eaad-4c45-b922-209f6dc6d140
                      quantity: 5
                      notes: Circuit Breaker 10A White
                    - product_id: ec9288c3-12b1-474f-bb09-b0b15bb7a8ff
                      quantity: 3
                      notes: Square D Breaker Black
              single_item_transfer:
                summary: Single-item transfer (compat mode)
                value:
                  product_id: 7f6f3e14-eaad-4c45-b922-209f6dc6d140
                  source_location_id: 91aa7588-4dc7-4edd-b172-7de91f5e1f78
                  dest_location_id: 828cabe6-3fa2-4fb7-a2af-2280bbaba335
                  quantity: 10
                  notes: Emergency stock transfer
      responses:
        '201':
          description: |
            Transfer initiated (draft status; GL fires on submit).
            The `data.availability_warnings` array lists any line item whose
            requested quantity exceeds source-location availability at create
            time (warn-at-create, hard-block-at-ship; NetSuite/Acumatica
            transfer-order pattern). Draft creation is not blocked, but
            shipping a short line returns a 400 `insufficient_stock`. The array
            is empty when every item has enough on hand at the source.
          content:
            application/json:
              schema:
                type: object
                properties:
                  object:
                    type: string
                    enum:
                      - inventory_transfer_result
                  data:
                    type: object
                    properties:
                      availability_warnings:
                        type: array
                        description: >-
                          Per-item source-availability shortfalls at create time
                          (empty when none).
                        items:
                          type: object
                          properties:
                            transfer_item_id:
                              type: string
                              format: uuid
                            product_id:
                              type: string
                              format: uuid
                            requested_qty:
                              type: integer
                            available_qty:
                              type: integer
                            shortfall:
                              type: integer
              examples:
                transfer_result:
                  summary: Transfer created in draft status
                  value:
                    data:
                      id: e1ce42dc-e9ae-40c4-a923-aa93100b0947
                      entity_from_id: 65dcd234-53c3-4f54-b772-ee349528d497
                      entity_to_id: 65dcd234-53c3-4f54-b772-ee349528d497
                      location_from_id: 91aa7588-4dc7-4edd-b172-7de91f5e1f78
                      location_to_id: 828cabe6-3fa2-4fb7-a2af-2280bbaba335
                      transfer_number: SB-TRF-0000001
                      status: draft
                      transfer_type: internal
                      notes: Weekly replenishment transfer to secondary warehouse
                      gl_posted: false
                      availability_warnings: []
                      items:
                        - id: d8c6bb7a-9c4c-446a-8518-d6f9398dbedc
                          transfer_id: e1ce42dc-e9ae-40c4-a923-aa93100b0947
                          product_id: 7f6f3e14-eaad-4c45-b922-209f6dc6d140
                          quantity_sent: '5.0000'
                          quantity_received: '0.0000'
                          notes: Circuit Breaker 10A White
        '400':
          $ref: '#/components/responses/Error'
        '401':
          $ref: '#/components/responses/Error'
        '403':
          $ref: '#/components/responses/Error'
      security:
        - ApiKeyAuth: []
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: |
        Client-generated unique key for idempotent POST/PATCH/DELETE operations.
        Alias for the Idempotency parameter. Max 255 chars. On retry with the
        same key, the original response is returned without re-executing the
        operation. Keys expire after 24 hours.
      schema:
        type: string
        maxLength: 255
  responses:
    Error:
      description: Error response (400/401/403/404/409/422/429/500)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  schemas:
    ErrorEnvelope:
      type: object
      description: |
        Canonical error response envelope. All API errors use this shape.
      required:
        - error
        - code
      properties:
        error:
          type: string
          description: Machine-readable error key
          example: not_found
        code:
          type: string
          description: Machine-readable error code (often same as error)
          example: not_found
        type:
          type: string
          enum:
            - validation_error
            - permission_error
            - not_found
            - conflict
            - rate_limit
            - internal
            - expand_error
            - not_implemented
          example: not_found
        hint:
          type: string
          description: Human-readable one-sentence explanation (English)
          example: >-
            The requested order does not exist or does not belong to this
            entity.
        param:
          type: string
          description: The parameter that caused the error, if applicable
          example: expand[0]
        required:
          type: string
          description: The scope required (only on insufficient_scope errors)
          example: accounts:read
        request_id:
          type: string
          description: >-
            Unique request ID for support tracing (maps to CloudWatch log
            stream)
          example: req_abc123
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      description: |
        API key issued per entity via Settings > Developers > API Keys.
        Each key carries scopes (e.g. orders:read, products:write).
        Bearer token format: Authorization: Bearer ark_live_ent_<code>_<random>
        Test keys use ark_test_ent_<code>_<random>. Both are issued per entity
        via Settings > Developers > API Keys.

````