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

# Stock Movements

> As a warehouse or fulfillment provider, send stock movements to your customers via the Procuros API: check enabled trade partners, build the payload, and track status.

This is the right section for you if you are acting as a warehouse or fulfilment provider and want to tell your customers about changes to their stock. Examples are stock adjustments, transfers between storage locations, and the consumption or output of a work order.

Throughout this guide you will learn how to send stock movements to the Procuros API.

PHP examples are included but you will likely also want to look at the relevant API calls in the [API reference](https://docs.procuros.io/en/api/v2/overview.md).

## Process

These are usually the steps taken when sending a stock movement to Procuros:

1. Check, if this document should be sent via Procuros (see: [Enabled Trade Partners](https://docs.procuros.io/en/api/v2/features-enabled-trade-partners.md))
2. Verify this document has not already been sent (see: [Tracking Document Status](https://docs.procuros.io/en/api/v2/features-tracking-document-status.md))
3. Build the transaction payload to be sent via Procuros.
4. Send the transaction payload via the Procuros API

## Authentication

You will need an API token to authenticate. We use a bearer token which has to be included in each request you send to the API.

Please read the [Authentication](https://docs.procuros.io/en/api/v2/concept-authentication.md) section of our API reference for a detailed description.

## Error Handling

The API will return a `2xx` status code for successful requests. Anything else indicates an error.

Please read the [Errors](https://docs.procuros.io/en/api/v2/concept-error-handling.md) section of our API reference for a detailed description plus examples of how to handle them.

## Send stock movements

The API call [Send transaction](https://docs.procuros.io/en/api/v2/outgoing-transactions/send-transaction.md) is used to create transactions, including stock movements.

The following fields are required:

* `type` (Transaction type. In this case `STOCK_MOVEMENT`)
* `content.header.stockMovementIdentifier`
* `content.header.stockMovementDate`
* `content.header.goodsOwner` or `content.header.technicalRecipient`, with at least one identifier

All other fields are optional. Your trade partner can require more fields.

Procuros sends the stock movement to the `technicalRecipient`. If you do not set a `technicalRecipient`, Procuros sends it to the `goodsOwner`.

Each entry in `items` is one movement. Use these fields to describe it:

* `type`: the business reason of the movement, for example `ADJUSTMENT` or `TRANSFER`.
* `action`: the effect on the stock, for example `DECREMENT` or `MOVE`.
* `fromLocation` and `toLocation`: the storage locations the goods leave and go to.
* `sourceDocumentType`, `sourceDocumentIdentifier` and `sourceDocumentLineIdentifier`: the document that caused the movement, for example a `WORK_ORDER`.

All details can be found in the `STOCK_MOVEMENT` schema as described in the [API reference](https://docs.procuros.io/en/api/v2/outgoing-transactions/send-transaction.md).

An example request would look like:

```php php theme={null}
// install dependency
// $ composer require guzzlehttp/guzzle

<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$transaction = [
  "type" => "STOCK_MOVEMENT",
  "content" => [
    "header" => [
      "stockMovementIdentifier" => "STOCK_MOVEMENT_123456",
      "stockMovementDate" => "2026-10-01T09:00:00Z",
      "movementNotes" => "Recount of zone A after a damage report",
      "goodsOwner" => [
        "name" => "Test Receiver GmbH",
        "identifiers" => [
          [
            "domain" => "GS1",
            "identifier" => "4200000654321"
          ]
        ]
      ],
      "warehouse" => [
        "name" => "Test Sender GmbH",
        "identifiers" => [
          [
            "domain" => "GS1",
            "identifier" => "4200000123456"
          ]
        ]
      ]
    ],
    "items" => [
      [
        "lineNumber" => 1,
        "movementDate" => "2026-10-01T07:30:00Z",
        "type" => "ADJUSTMENT",
        "action" => "DECREMENT",
        "quantity" => 8,
        "reasonCode" => "DAMAGE",
        "reason" => "Pallet damaged by forklift",
        "fromLocation" => [
          "identifier" => "A-01-03",
          "status" => "AVAILABLE"
        ],
        "identity" => [
          "senderPartnerId" => "PRD-0001",
          "receiverPartnerId" => "AB-MM-9988",
          "gtin" => "12345678901234"
        ],
        "name" => "Name of the product",
        "unitOfMeasure" => "EA"
      ],
      [
        "lineNumber" => 2,
        "movementDate" => "2026-10-01T07:45:00Z",
        "type" => "TRANSFER",
        "action" => "MOVE",
        "sourceDocumentType" => "WORK_ORDER",
        "sourceDocumentIdentifier" => "WO-2026-004711",
        "sourceDocumentLineIdentifier" => "10",
        "quantity" => 100,
        "fromLocation" => [
          "identifier" => "A-01-03",
          "status" => "BLOCKED"
        ],
        "toLocation" => [
          "identifier" => "B-02-01",
          "status" => "AVAILABLE"
        ],
        "identity" => [
          "senderPartnerId" => "PRD-0002",
          "gtin" => "98765432109876"
        ],
        "unitOfMeasure" => "EA"
      ]
    ]
  ]
];

$response = $client->request('POST', 'https://api.procuros.io/v2/transactions', [
  'headers' => [
    'Accept' => 'application/json',
    'Authorization' => 'Bearer <your-api-token>',
  ],
  'json' => $transaction,
]);
```

## Mark Document Status

Finally, as per the instructions mentioned under [Tracking Document Status](https://docs.procuros.io/en/api/v2/features-tracking-document-status.md) you must now track the status of the document locally, based on the returned HTTP response.

The document should be marked with either status `TRANSMITTED` or `NO_ACTION`. If there is an error with the document and it is not accepted, do not mark it with a status so it may be retried. For more information on retrying failed documents, please see: [Retrying Documents](https://docs.procuros.io/en/api/v2/features-tracking-document-status.md#retrying-documents).

For example:

```php php theme={null}
$statusCode = $response->getStatusCode();

if ($statusCode == 201) {
  $document->updateProcurosStatus("TRANSMITTED");
} else if ($statusCode == 202) {
  $document->updateProcurosStatus("NO_ACTION");
} else {
  // No need to do anything if it's not accepted, in an error case the document should be retried.
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.