REST API v1

Integration via REST API

Fetch La Grana products, stock levels and your individual prices directly into your system. Full automation with JWT authentication.

🔐
JWT Auth
Secure authentication with JWT tokens and automatic refresh.
REST + JSON
Standard REST endpoints with JSON responses. Simple and predictable.
💰
Individual prices
Each account receives individual prices and discount — reflected directly in API responses.
Authentication
La Grana API uses JWT (JSON Web Tokens). First obtain a token, then attach it to every request in the Authorization header.
POST /api/token/ Get access token
FieldTypeDescription
usernamerequiredYour La Grana system login
passwordrequiredYour password
cURL
curl -X POST https://b2b.lagrana.pl/api/token/ \
  -H "Content-Type: application/json" \
  -d '{"username": "twoj_login", "password": "haslo"}'
Response
{
  "access":  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

The access token is valid for 60 minutes. Refresh via POST /api/token/refresh/ with the refresh token.

Attach token to every request:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Base URL and format
Direct all requests to the address below. The API returns and accepts data in JSON format (UTF-8). All list endpoints are paginated — use the next field to iterate through pages.
https://b2b.lagrana.pl/api/
Paginated response
{
  "count": 1248,        // total number of results
  "next":  "https://b2b.lagrana.pl/api/products/?page=2",
  "previous": null,
  "results": [ /* ... */ ]
}
Products
Full product catalog with descriptions, images, attributes and your individual prices. client_price is the final price after discount; client_price_without_discount is the base price before discount.
GET /api/products/ Product list (paginated)
ParameterTypeDescription
pageoptionalPage number (default 1)
brandoptionalFilter by brand name
categoriesoptionalFilter by category ID
statusoptionalFilter by status ID
activeoptionaltrue / false
searchoptionalSearch by SKU or status

Response fields

id sku name brand ean active vat_rate for_who advantages stock_warehouse stock_supplier added_at updated_at client_price client_price_without_discount categories [ ] status { } prod_image [ ] description { } additional [ ]

price fields   nested objects/arrays

Response
{
  "count": 1248,
  "next": "https://b2b.lagrana.pl/api/products/?page=2",
  "previous": null,
  "results": [
    {
      "id": 42,
      "sku": "LG-12345",
      "name": "Nazwa produktu",
      "brand": "BrandName",
      "ean": "1234567890123",
      "active": true,
      "vat_rate": 23,
      "for_who": "Dla niej",
      "advantages": ["Zaletą jest...", "..."],
      "stock_warehouse": 24,
      "stock_supplier": 10,
      "added_at": "2025-01-15T08:00:00Z",
      "updated_at": "2026-03-01T12:00:00Z",
      "client_price": "84.15",               // price after discount
      "client_price_without_discount": "99.00", // base price
      "categories": [
        { "id": 3, "name_pl": "Wibratory", "name_en": "Vibrators", "parent": null }
      ],
      "status": { "id": 1, "name": "Nowość" },
      "prod_image": [
        { "image": "https://cdn.lagrana.pl/img/lg-12345-1.jpg", "main_image": true, "hoover_image": false },
        { "image": "https://cdn.lagrana.pl/img/lg-12345-2.jpg", "main_image": false, "hoover_image": true }
      ],
      "description": {
        "id": 5, "product": 42,
        "lang_pl": "Opis po polsku...",
        "lang_en": "Description in English...",
        "lang_de": "Beschreibung auf Deutsch...",
        // also: lang_nl, lang_fr, lang_es, lang_it, lang_gr, lang_cz, lang_sk, lang_ua, lang_ru
      },
      "additional": [
        { "id": 101, "product": 42, "item": "Kolor", "value": "Czarny" },
        { "id": 102, "product": 42, "item": "Długość", "value": "18 cm" }
      ]
    }
  ]
}
GET /api/products/{id}/ Single product by ID

Returns a single product object with the same fields as the list. Use the numeric internal ID from the id field, or use the products-sku endpoint to look up by SKU.

Product by SKU
Fetch a single product directly by its SKU code — useful for synchronizing with external systems where the internal ID is unknown.
GET /api/products-sku/{sku}/ Product by SKU
cURL
curl "https://b2b.lagrana.pl/api/products-sku/LG-12345/" \
  -H "Authorization: Bearer $TOKEN"

Returns the same fields as GET /api/products/{id}/. Returns 404 if the SKU does not exist.

GET /api/products-sku/ Filterable list

Same filtering parameters as /api/products/ (brand, categories, status, active, search). The detail endpoint uses SKU as the key instead of numeric ID.

Categories
Full category list with multilingual names. Use the parent field to build a category tree.
GET /api/categories/ Category list
Response
[
  {
    "id": 1,
    "name_pl": "Wibratory",
    "name_en": "Vibrators",
    "name_de": "Vibratoren",
    "name_nl": null,
    "name_fr": null,
    "name_es": null,
    "name_it": null,
    "name_gr": null,
    "name_cz": null,
    "name_sk": null,
    "name_ua": null,
    "name_ru": null,
    "parent": null   // ID of parent category, null = top level
  }
]
Stock levels
Lightweight endpoint for checking availability without fetching full product data. Supports the same filters as /api/products/.
GET /api/stock/ Stock for all active products
ParameterTypeDescription
brandoptionalFilter by brand
categoriesoptionalFilter by category ID
searchoptionalSearch by SKU
Response
{
  "count": 1248,
  "results": [
    { "sku": "LG-12345", "stock_warehouse": 24, "stock_supplier": 10 },
    { "sku": "LG-12346", "stock_warehouse": 0,  "stock_supplier": 50 }
  ]
}

stock_warehouse — quantity in La Grana warehouse
stock_supplier — quantity available at supplier

Orders
Create and list your orders. Each account only sees its own orders. You can reference products by internal ID or SKU.
GET /api/orders/ List your orders
Response
{
  "count": 3,
  "results": [
    {
      "id": 7,
      "external_id": "WC-1234",    // your reference number (optional)
      "status": "pending",
      "currency": "PLN",
      "total_gross": "267.00",
      "notes": "Uwagi do zamówienia",
      "created_at": "2026-03-01T12:00:00Z",
      "updated_at": "2026-03-01T12:05:00Z",
      "items_read": [
        {
          "product": 42, "sku": "LG-12345", "name": "Nazwa produktu",
          "qty": 3, "unit_price_gross": "89.00",
          "vat_rate": 23, "line_total_gross": "267.00"
        }
      ]
    }
  ]
}
POST /api/orders/ Create an order
FieldTypeDescription
itemsrequiredArray of order items (see below)
external_idoptionalYour own reference number (e.g. WooCommerce order ID)
currencyoptionalPLN / EUR (default: PLN)
notesoptionalOrder notes

Each item in the items array:

FieldTypeDescription
productproduct or skuInternal product ID
skuproduct or skuProduct SKU (alternative to product)
qtyoptionalQuantity (default: 1)
Request body
{
  "external_id": "WC-5678",
  "currency": "PLN",
  "notes": "Pilne",
  "items": [
    { "product": 42, "qty": 3 },
    { "sku": "LG-12346", "qty": 1 }
  ]
}
XML Feed
An alternative to JSON API — a product feed in XML format, accessible via a unique token (no JWT required). Useful for platforms that support XML product import (e.g. PrestaShop, IdoSell). Contact us to obtain your token.
GET /api/xml/{token}/ Product XML feed
XML
<?xml version="1.0" encoding="UTF-8"?>
<products>
  <product>
    <id>42</id>
    <sku>LG-12345</sku>
    <name>Nazwa produktu</name>
    <description>Opis po polsku...</description>
    <category>Wibratory</category>
    <brand>BrandName</brand>
    <price>84.15</price>   <!-- your price -->
    <stock>24</stock>
    <image>https://cdn.lagrana.pl/img/lg-12345-1.jpg</image>
    <active>true</active>
  </product>
</products>

The feed requires no authentication header — the token in the URL grants access. Prices reflect your individual rates.

Error codes
The API uses standard HTTP codes. Error responses include a detail field with a description.
CodeMeaning
200Success
201Created (e.g. new order)
400Request error — check parameters or required fields
401Missing authentication or expired token
403No permission to access resource
404Resource not found
429Request limit exceeded (rate limiting)
Example — Python
Python
import requests

# 1. Uzyskaj token
resp = requests.post("https://b2b.lagrana.pl/api/token/", json={
    "username": "twoj_login",
    "password": "haslo"
})
token = resp.json()["access"]
headers = {"Authorization": f"Bearer {token}"}

# 2. Pobierz produkty (wszystkie strony)
url = "https://b2b.lagrana.pl/api/products/"
while url:
    data = requests.get(url, headers=headers).json()
    for p in data["results"]:
        print(p["sku"], p["client_price"], p["stock_warehouse"])
    url = data["next"]

# 3. Pobierz produkt po SKU
p = requests.get(
    "https://b2b.lagrana.pl/api/products-sku/LG-12345/",
    headers=headers
).json()
print(p["name"], p["client_price"], p["client_price_without_discount"])

# 4. Utwórz zamówienie
order = requests.post("https://b2b.lagrana.pl/api/orders/", json={
    "external_id": "WC-1234",
    "items": [
        {"sku": "LG-12345", "qty": 3},
        {"sku": "LG-12346", "qty": 1},
    ]
}, headers=headers)
print(order.json())
Example — PHP
PHP
// 1. Uzyskaj token
$res = file_get_contents('https://b2b.lagrana.pl/api/token/', false,
    stream_context_create(['http' => [
        'method'  => 'POST',
        'header'  => 'Content-Type: application/json',
        'content' => json_encode(['username'=>'login', 'password'=>'haslo'])
    ]])
);
$token = json_decode($res)->access;
$authHeader = "Authorization: Bearer $token";

// 2. Pobierz produkty
$url = 'https://b2b.lagrana.pl/api/products/';
while ($url) {
    $data = json_decode(file_get_contents($url, false,
        stream_context_create(['http' => ['header' => $authHeader]])
    ));
    foreach ($data->results as $p) {
        echo $p->sku . ' ' . $p->client_price . ' ' . $p->stock_warehouse . "\n";
    }
    $url = $data->next;
}

// 3. Utwórz zamówienie
$order = file_get_contents('https://b2b.lagrana.pl/api/orders/', false,
    stream_context_create(['http' => [
        'method'  => 'POST',
        'header'  => "Content-Type: application/json\r\n" . $authHeader,
        'content' => json_encode([
            'external_id' => 'WC-1234',
            'items' => [
                ['sku' => 'LG-12345', 'qty' => 3],
                ['sku' => 'LG-12346', 'qty' => 1],
            ]
        ])
    ]])
);
var_dump(json_decode($order));
Example — cURL
Shell
# Uzyskaj token i zapisz
TOKEN=$(curl -s -X POST https://b2b.lagrana.pl/api/token/ \
  -H "Content-Type: application/json" \
  -d '{"username":"login","password":"haslo"}' \
  | python3 -c "import sys,json;print(json.load(sys.stdin)['access'])")

# Pobierz produkty (pierwsza strona)
curl "https://b2b.lagrana.pl/api/products/" \
  -H "Authorization: Bearer $TOKEN"

# Pobierz produkt po SKU
curl "https://b2b.lagrana.pl/api/products-sku/LG-12345/" \
  -H "Authorization: Bearer $TOKEN"

# Pobierz stany magazynowe
curl "https://b2b.lagrana.pl/api/stock/" \
  -H "Authorization: Bearer $TOKEN"

# Utwórz zamówienie
curl -X POST "https://b2b.lagrana.pl/api/orders/" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"external_id":"WC-1234","items":[{"sku":"LG-12345","qty":3}]}'
Ready to integrate?

Log in and start using the API

API access is granted on request — contact us or log in if you already have an account.

Log in Request access