Inventory & Products | Products | Stock | Get Incoming Stock

Getting Product Incoming Stock Data

This document outlines the procedure for making API calls to retrieve upcoming/incoming stock data for a product from https://easycms.fi/public_api/get_products_incoming_stock/.

Important Note

The pid (Product ID) parameter is MANDATORY for this endpoint. You must provide a valid product ID to retrieve incoming stock data.

Product Incoming Stock Data Retrieval

Fetch upcoming stock that is expected to arrive for a product. This data comes from purchase orders, stock transfers, and other stock addition sources that have not yet been received into current stock.

Endpoint and Method

  • Endpoint: https://easycms.fi/public_api/get_products_incoming_stock/
  • Method: GET or POST

Parameters | Payload

  • TOKEN (api_key): Your unique API key for authentication. How to Create API Credentials.
  • username: Your login username.
  • password: Your login password.
  • account: Your specific account ID.

Required Parameter

  • pid: Product ID (MANDATORY) - The ID of the product to retrieve incoming stock for. Must be an integer.

Optional Filter Parameters

  • location_id: Filter results by a specific location ID. When provided, returns incoming stock only for this location.
  • shelf_id: Filter results by a specific shelf ID. Note: Requires location_id to be provided as well.

Pagination Parameters

  • start - Specify the starting point of the row from which to begin fetching incoming stock data (default: 0).
  • limit - Control the number of records returned in a single request (default: 50, max: 50).



Call Examples in Different Languages


# Get all incoming stock for a product
curl -X POST 'https://easycms.fi/public_api/get_products_incoming_stock' \
-H 'Authorization1: TOKEN' \
-d 'username=USERNAME&password=PASSWORD&account=ACCOUNT_ID&pid=12345'

# Get incoming stock for a specific location
curl -X POST 'https://easycms.fi/public_api/get_products_incoming_stock' \
-H 'Authorization1: TOKEN' \
-d 'username=USERNAME&password=PASSWORD&account=ACCOUNT_ID&pid=12345&location_id=1'

# Get incoming stock for a specific location and shelf
curl -X POST 'https://easycms.fi/public_api/get_products_incoming_stock' \
-H 'Authorization1: TOKEN' \
-d 'username=USERNAME&password=PASSWORD&account=ACCOUNT_ID&pid=12345&location_id=1&shelf_id=5'

$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => "https://easycms.fi/public_api/get_products_incoming_stock",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => http_build_query([
    'username' => 'USERNAME', 
    'password' => 'PASSWORD', 
    'account' => 'ACCOUNT_ID',
    'pid' => 12345,
    'location_id' => 1,  // optional
    'shelf_id' => 5      // optional, requires location_id
  ]),
  CURLOPT_HTTPHEADER => array("Authorization1: TOKEN"),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;

import requests
url = "https://easycms.fi/public_api/get_products_incoming_stock"
headers = {"Authorization1": "TOKEN"}
payload = {
    'username': 'USERNAME', 
    'password': 'PASSWORD', 
    'account': 'ACCOUNT_ID',
    'pid': 12345,
    'location_id': 1,  # optional
    'shelf_id': 5      # optional, requires location_id
}
response = requests.post(url, headers=headers, data=payload)
print(response.text)

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://easycms.fi/public_api/get_products_incoming_stock"))
    .headers("Authorization1", "TOKEN")
    .POST(HttpRequest.BodyPublishers.ofString(
        "username=USERNAME&password=PASSWORD&account=ACCOUNT_ID&pid=12345&location_id=1&shelf_id=5"))
    .build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

const https = require('https');
const data = new URLSearchParams({ 
  username: 'USERNAME', 
  password: 'PASSWORD', 
  account: 'ACCOUNT_ID',
  pid: 12345,
  location_id: 1,  // optional
  shelf_id: 5      // optional
}).toString();
const options = {
  hostname: 'easycms.fi',
  path: '/public_api/get_products_incoming_stock',
  method: 'POST',
  headers: {
    'Authorization1': 'TOKEN',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': data.length
  }
};
const req = https.request(options, (res) => {
  let data = '';
  res.on('data', (chunk) => { data += chunk; });
  res.on('end', () => { console.log(data); });
});
req.on('error', (e) => { console.error(e); });
req.write(data);
req.end();

import React, { useEffect, useState } from 'react';
function App() {
  const [incomingData, setIncomingData] = useState('');
  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('https://easycms.fi/public_api/get_products_incoming_stock', {
          method: 'POST',
          headers: {'Authorization1': 'TOKEN', 'Content-Type': 'application/x-www-form-urlencoded'},
          body: new URLSearchParams({
            username: 'USERNAME', 
            password: 'PASSWORD', 
            account: 'ACCOUNT_ID',
            pid: 12345
          }).toString()
        });
        const data = await response.text();
        setIncomingData(data);
      } catch (error) {
        console.error(error);
      }
    };
    fetchData();
  }, []);
  return (
{incomingData}
); } export default App;

import okhttp3.OkHttpClient
import okhttp3.FormBody
import okhttp3.Request

fun main() {
    val client = OkHttpClient()

    val formBody = FormBody.Builder()
        .add("username", "USERNAME")
        .add("password", "PASSWORD")
        .add("account", "ACCOUNT_ID")
        .add("pid", "12345")
        .add("location_id", "1")  // optional
        .add("shelf_id", "5")     // optional
        .build()

    val request = Request.Builder()
        .url("https://easycms.fi/public_api/get_products_incoming_stock")
        .post(formBody)
        .addHeader("Authorization1", "TOKEN")
        .build()

    client.newCall(request).execute().use { response ->
        if (!response.isSuccessful) throw IOException("Unexpected code $response")
        println(response.body?.string())
    }
}

using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
    static async Task Main()
    {
        var token = "TOKEN";
        var content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair("username", "USERNAME"),
            new KeyValuePair("password", "PASSWORD"),
            new KeyValuePair("account", "ACCOUNT_ID"),
            new KeyValuePair("pid", "12345"),
            new KeyValuePair("location_id", "1"),  // optional
            new KeyValuePair("shelf_id", "5")      // optional
        });
        using (var httpClient = new HttpClient())
        {
            httpClient.DefaultRequestHeaders.Add("Authorization1", token);
            var response = await httpClient.PostAsync("https://easycms.fi/public_api/get_products_incoming_stock", content);
            if (response.IsSuccessStatusCode)
            {
                var responseData = await response.Content.ReadAsStringAsync();
                Console.WriteLine(responseData);
            }
            else
            {
                Console.WriteLine($"Error: {response.StatusCode}");
            }
        }
    }
}




Handling Endpoint Results

When you make a request to the endpoint, you receive a JSON response containing various keys and values. Here's an explanation of the response keys and their meanings:


- `start`: This represents the starting index for the data. In this case, it's set to 0, indicating that the data starts from the first item.

- `limit`: The maximum number of items returned in the response. In this example, the limit is set to 50, meaning that the response will include up to 50 items.

- `count`: The number of items included in the current response.

- `total_count`: The total count of incoming stock entries available for this product.

- `WHERE`: (Optional) The filter condition that was applied. For example, "location_id = 1" when filtered by location.

    

- `stock`: The upcoming stock quantity expected to arrive.
- `location_id`: The unique identifier for the location/warehouse where stock will arrive.
- `location_name`: The name of the location/warehouse.
- `shelf_id`: The unique identifier for the shelf within the location.
- `shelf_name`: The name of the shelf.
- `coming_to_stock_date`: The expected date when the stock will arrive (YYYY-MM-DD format, null if not set).
- `best_before_date`: The best before date for the upcoming stock (YYYY-MM-DD format, null if not set).
- `reason`: Stock reason code indicating why this stock is coming:
  - `1` = Purchase (import from supplier)
  - `2` = Refund (return from customer)
  - `3` = Movement (transfer in)
  - `4` = Sale correction
- `price`: The sell price for the upcoming stock.
- `price_buy`: The buy price for the upcoming stock (null if not set).
- `supplier_id`: The supplier ID associated with this upcoming stock.
- `purchase_id`: The linked purchase order ID (0 if not linked to a purchase order).
- `datenew`: The date when this upcoming stock record was created (YYYY-MM-DD HH:MM:SS format).

These key-value pairs provide information about pending stock arrivals and can be used for inventory planning and forecasting in your application.
    

{
  "INFO": {
    "start": 0,
    "limit": 50,
    "count": 2,
    "total_count": 2,
    "WHERE": "pid = 12345"
  },
  "OUTPUT": [
    {
      "stock": 100.0,
      "location_id": 1,
      "location_name": "Main Warehouse",
      "shelf_id": 5,
      "shelf_name": "Shelf A1",
      "coming_to_stock_date": "2026-08-15",
      "best_before_date": "2027-08-15",
      "reason": 1,
      "price": 10.5,
      "price_buy": 6.0,
      "supplier_id": 3,
      "purchase_id": 456,
      "datenew": "2026-03-27 10:00:00"
    },
    {
      "stock": 50.0,
      "location_id": 2,
      "location_name": "Secondary Warehouse",
      "shelf_id": 3,
      "shelf_name": "Shelf B2",
      "coming_to_stock_date": "2026-09-01",
      "best_before_date": null,
      "reason": 3,
      "price": 10.5,
      "price_buy": null,
      "supplier_id": 1,
      "purchase_id": 0,
      "datenew": "2026-03-25 14:30:00"
    }
  ]
}
      

Error Handling

Here are the possible error messages and their meanings:

Error Code HTTP Status Description
MISSING_PID 400 The pid parameter is required
INVALID_PID 400 The pid must be a valid integer
PRODUCT_NOT_FOUND 404 The product with the specified pid does not exist
INVALID_LOCATION_ID 400 The location_id must be a valid integer
INVALID_SHELF_ID 400 The shelf_id must be a valid integer
SHELF_REQUIRES_LOCATION 400 shelf_id cannot be used without location_id
LOCATION_NOT_FOUND 404 The specified location does not exist
SHELF_NOT_FOUND 404 The specified shelf does not exist
UN-AUTHORIZED 401 Incorrect username or password
this_account_does_not_exist_or_your_credentials_do_not_match_this_account 401 The account doesn't exist or mismatched credentials
Maximum query size is 50 rows per query 400 Exceeded maximum limit of 50 rows per query

Error Response Example

{
  "status": "error",
  "error_code": "MISSING_PID",
  "message": "The pid parameter is required"
}

Empty Incoming Stock Response

When a product exists but has no incoming stock:

{
  "INFO": {
    "start": 0,
    "limit": 50,
    "count": 0,
    "total_count": 0,
    "pid": 12345
  },
  "OUTPUT": []
}

Use Cases

Get Total Incoming Stock Across All Locations

To calculate the total incoming stock for a product across all locations, sum the stock values from all items in the OUTPUT array.

// Example in JavaScript
const response = await getProductsIncomingStock(pid);
const totalIncoming = response.OUTPUT.reduce((sum, item) => sum + item.stock, 0);
console.log(`Total incoming stock: ${totalIncoming}`);

Check Incoming Stock at Specific Location

Use the location_id filter to check incoming stock at a specific warehouse:

POST /get_products_incoming_stock?pid=12345&location_id=1

Check Incoming Stock at Specific Shelf

Use both location_id and shelf_id to check incoming stock at a specific shelf:

POST /get_products_incoming_stock?pid=12345&location_id=1&shelf_id=5

Find Earliest Expected Arrival

Sort the results by coming_to_stock_date to find the earliest expected stock arrival:

const response = await getProductsIncomingStock(pid);
const sorted = response.OUTPUT.sort((a, b) => 
  new Date(a.coming_to_stock_date) - new Date(b.coming_to_stock_date)
);
const nextArrival = sorted[0];
console.log(`Next arrival: ${nextArrival.stock} units on ${nextArrival.coming_to_stock_date}`);

Combine with Current Stock Data

Use this endpoint together with get_products_stock to get a complete picture of both current and upcoming stock:

const [currentStock, incomingStock] = await Promise.all([
  getProductsStock(pid),
  getProductsIncomingStock(pid)
]);
console.log(`Current: ${currentStock.OUTPUT.reduce((s,i) => s+i.stock, 0)} units`);
console.log(`Incoming: ${incomingStock.OUTPUT.reduce((s,i) => s+i.stock, 0)} units`);