Inventory & Products | Products | Bundles | Get Product Bundles

Getting Product Bundles Data

This document outlines the procedure for making API calls to retrieve product bundle data from https://easycms.fi/public_api/get_product_bundles/.

Important Note

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

Product Bundles Data Retrieval

Fetch product bundle data effectively using the below API call.

Endpoint and Method

  • Endpoint: https://easycms.fi/public_api/get_product_bundles/
  • 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 parent bundle product to retrieve bundle items for. Must be an integer.

Optional Parameters

  • include_deleted: Set to 1 to include soft-deleted bundle items. Default: 0.
  • start - Specify the starting point for pagination (default: 0).
  • limit - Control the number of bundle items returned (default: 50, max: 50).



Call Examples in Different Languages


curl -X POST 'https://easycms.fi/public_api/get_product_bundles' \
-H 'Authorization1: TOKEN' \
-d 'username=USERNAME&password=PASSWORD&account=ACCOUNT_ID&pid=18958'

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

import requests
url = "https://easycms.fi/public_api/get_product_bundles"
headers = {"Authorization1": "TOKEN"}
payload = {
    'username': 'USERNAME', 
    'password': 'PASSWORD', 
    'account': 'ACCOUNT_ID',
    'pid': 18958
}
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_product_bundles"))
    .headers("Authorization1", "TOKEN")
    .POST(HttpRequest.BodyPublishers.ofString("username=USERNAME&password=PASSWORD&account=ACCOUNT_ID&pid=18958"))
    .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: 18958
}).toString();
const options = {
  hostname: 'easycms.fi',
  path: '/public_api/get_product_bundles',
  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 [productBundlesData, setProductBundlesData] = useState('');
  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('https://easycms.fi/public_api/get_product_bundles', {
          method: 'POST',
          headers: {'Authorization1': 'TOKEN', 'Content-Type': 'application/x-www-form-urlencoded'},
          body: new URLSearchParams({
            username: 'USERNAME', 
            password: 'PASSWORD', 
            account: 'ACCOUNT_ID',
            pid: 18958
          }).toString()
        });
        const data = await response.text();
        setProductBundlesData(data);
      } catch (error) {
        console.error(error);
      }
    };
    fetchData();
  }, []);
  return (
{productBundlesData}
); } export default App;

// Kotlin Example using OkHttp for POST request
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", "18958")
        .build()

    val request = Request.Builder()
        .url("https://easycms.fi/public_api/get_product_bundles")
        .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", "18958")
        });
        using (var httpClient = new HttpClient())
        {
            httpClient.DefaultRequestHeaders.Add("Authorization1", token);
            var response = await httpClient.PostAsync("https://easycms.fi/public_api/get_product_bundles", 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. In this case, there are 2 items in the response.

- `total_count`: The total count of items available in the dataset. In this response, there is a total of 2 items available.

- `pid`: The parent product ID that was queried for bundle data.

    

Each item in the OUTPUT array represents a single component within the bundle:

- `bundle_id`: Unique identifier for the bundle relationship (UUID).
- `parent_pid`: The parent (bundle) product ID.
- `child_pid`: The component product ID inside the bundle.
- `quantity`: Number of units of the child product in the bundle.
- `sort_order`: Display/ordering position.
- `created_at`: When this bundle item was created.
- `updated_at`: When this bundle item was last modified.
- `product`: Object containing child product details:
    - `pid`: The child product ID.
    - `product_name`: Object with locale-keyed names (e.g., "en_GB", "fi_FI").
    - `price`: Selling price.
    - `price_buy`: Purchase/buy price.
    - `barcode`: Product barcode.
    - `prdNumber`: Product reference number.
    - `vat`: VAT category ID.
    This field is `null` if the child product has been deleted.

These key-value pairs provide comprehensive information about the product bundles and can be used for various purposes in your application.
    

{
  "INFO": {
    "start": 0,
    "limit": 50,
    "count": 2,
    "total_count": 2,
    "pid": 18958,
    "docs": "https://cms.helpostikotisivut.fi/DOCUMENTATION/bt5/get_product_bundles.php"
  },
  "OUTPUT": [
    {
      "bundle_id": "3eb365d3-7a1b-4c9f-b8e2-5d6a4f3c2e10",
      "parent_pid": "18958",
      "child_pid": "11031",
      "quantity": 2,
      "sort_order": 0,
      "created_at": "2026-04-22 17:58:44",
      "updated_at": "2026-04-22 17:58:44",
      "product": {
        "pid": "11031",
        "product_name": {"en_GB": "Child Product A", "fi_FI": "Lapsituote A"},
        "price": 5.99,
        "price_buy": 3.00,
        "barcode": "6410001",
        "prdNumber": "REF001",
        "vat": "55"
      }
    },
    {
      "bundle_id": "4fc476e4-8b2c-5d0a-c9f3-6e7b5g4d3f21",
      "parent_pid": "18958",
      "child_pid": "11045",
      "quantity": 1,
      "sort_order": 1,
      "created_at": "2026-04-22 17:58:44",
      "updated_at": "2026-04-22 17:58:44",
      "product": {
        "pid": "11045",
        "product_name": {"en_GB": "Child Product B", "fi_FI": "Lapsituote B"},
        "price": 12.50,
        "price_buy": 7.00,
        "barcode": "6410002",
        "prdNumber": "REF002",
        "vat": "55"
      }
    }
  ]
}
      

Error Handling

Here are the possible error messages and their meanings:

Error Code HTTP Status Description
pid_parameter_is_required 400 The pid parameter is required
pid_must_be_a_valid_positive_integer 400 The pid must be a valid integer
product_not_found 404 Product with specified pid does not exist
UN-AUTHORIZED! 401 Authentication failed
UN-AUTHORIZED - _user_name_password_is_set_but_wrong_value! 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
UN-AUTHORIZED - header is set but the header value is not correct! 401 Incorrect authorization header value
Maximum query size is 50 rows per query 400 Exceeded maximum limit of 50 rows per query

Error Response Example

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

Related Endpoints

Important Notes

  • If the product exists but is_bundle != 1, the endpoint still returns its bundle items (they may exist from a previous state)
  • If a child product has been deleted, the bundle row is included but the product field is null
  • Bundle items are always returned sorted by sort_order ascending