> ## 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 goods owner, pull new stock movements from your warehouse via the Procuros API, paginate over them, mark them as processed, or report processing errors.

This is the right section for you if you are the owner of the goods and looking to receive stock movements from your warehouse or fulfilment provider.

Throughout this guide you will learn how to pull new stock movements from the Procuros API, as well as how to paginate over them, mark them as processed, or report errors with the stock movements.

It is important to mark the stock movements as processed (either successfully or not) so that the Procuros network can communicate this to your trade partners. This will also prevent them from re-appearing in future `GET` requests for transactions data, as well as trigger the error management process in case you mark any documents as "processing failed".

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/incoming-transactions/list-incoming-transactions.md).

> [!NOTE]
>
> Trade partners may send updated versions of a document. Always check the `isLatestVersion` field before importing — if it is `false`, a newer version exists and this one should be skipped. See [Document Versioning](https://docs.procuros.io/en/api/v2/features-document-versioning.md) for full details.

## 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.

## Pull New Stock Movements

The API call [List incoming Transactions](https://docs.procuros.io/en/api/v2/incoming-transactions/list-incoming-transactions.md) is used to fetch all incoming transactions.

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

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

$client = new \GuzzleHttp\Client();

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

$body = json_decode((string) $response->getBody());

$items = $body->items;
```

### Pagination

The response body has a `hasMore` flag. If it's `true` not all items are in the response.

You will then want to fetch the other items as well. Therefore, you can use the `nextPageUrl` flag from the response body and perform the same request with the new URL again.

```php php theme={null}
if ($body->hasMore) {
	$response = $client->request('GET', $body->nextPageUrl, [
    'headers' => [
      'Accept' => 'application/json',
      'Authorization' => 'Bearer <your-api-token>',
    ],
  ]);

  ... // don't forget to check for errors

  $body = json_decode((string) $response->getBody());

  $items = array_merge($items, $body->items);
}
```

> [!NOTE]
>
> If you are running your code only once a day or so, we recommend to perform the request with the new URL until `hasMore` is false. When doing so you can be sure to fetch all currently available items.

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

## Mark Stock Movements as Processed

To mark a stock movement as processed, use the API call [Mark transaction processed](https://docs.procuros.io/en/api/v2/incoming-transactions/mark-transaction-processed.md).

On the happy path of a transaction being processed successfully, you can make an API call such as:

```php php theme={null}
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$transaction_id = 'abc-123'; // Get the transaction ID from the original `GET /v2/transactions` call
$response = $client->request('POST', "https://api.procuros.io/v2/transactions/{$transaction_id}", [
  'headers' => [
    'Accept' => 'application/json',
    'Authorization' => 'Bearer <your-api-token>',
  ],
  'json' => [
    'success' => true
  ]
]);

... // Remember to check the request was successful
```

### Mark Multiple Stock Movements as Processed

In addition to the above, you can specify a list of items that should be marked as processed in a single API call, via the [Bulk mark transactions processed](https://docs.procuros.io/en/api/v2/incoming-transactions/bulk-mark-transactions-processed.md) endpoint.

```php php theme={null}
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

// You can find the IDs from the original `GET /v2/transactions` call
$items = [
  [
    'procurosTransactionId' => 'abc-123',
    'success' => true
  ],
  [
    'procurosTransactionId' => 'def-456',
    'success' => true
  ]
];

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

... // Remember to check the request was successful
```

## Report an Error Processing Stock Movements

In the event a stock movement was not able to be processed, you can use the same 2 API calls listed above ([Mark transaction processed](https://docs.procuros.io/en/api/v2/incoming-transactions/mark-transaction-processed.md) and [Bulk mark transactions processed](https://docs.procuros.io/en/api/v2/incoming-transactions/bulk-mark-transactions-processed.md)) to mark these stock movements as "failed to process".

In this case you must set the `success` flag to `false`. Additionally you should (but are not required to) add a `reason` for the stock movement not being processed, which will be used for solving the issue.

### Single Stock Movement

```php php theme={null}
$transaction_id = 'abc-123';
$response = $client->request('POST', "https://api.procuros.io/v2/transactions/{$transaction_id}", [
  'headers' => [
    'Accept' => 'application/json',
    'Authorization' => 'Bearer <your-api-token>',
  ],
  'json' => [
    'success' => false,
    'reason' => 'Unknown product in stock movement'
  ]
]);
```

### Bulk Error Reporting

```php php theme={null}
$items = [
  [
    'procurosTransactionId' => 'abc-123',
    'success' => false,
    'reason' => 'Unknown product in stock movement'
  ],
  [
    'procurosTransactionId' => 'def-456',
    'success' => true
  ],
];

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


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