External API
Give external partners, ERP systems, and scripts direct access to your product catalog through a lightweight, secure REST API.
The External API (/api/v1/ext/*) is designed for machine-to-machine integrations where a full user session is impractical. All requests authenticate with an API key carrying explicit scopes. The response format is consistent across every endpoint.
Overview
| Base URL | https://api.pixeepim.com/api/v1/ext |
|---|---|
| Auth | X-API-Key header |
| Read scope | ext:products:read |
| Write scope | ext:products:write |
| Rate limit | Standard tier (see Rate Limiting) |
| Max batch size | 500 products |
Create External API keys in Settings → API Keys. Select only the scopes
your integration needs — ext:products:read for read-only access,
ext:products:write to create or modify products.
Authentication
Pass the API key in the X-API-Key request header on every call. There is no session or token exchange.
All requests
curl https://api.pixeepim.com/api/v1/ext/products \
-H "X-API-Key: pm_live_abc123..."
All read endpoints require ext:products:read. Write endpoints (POST, PUT, PATCH) require ext:products:write.
Response envelope
Every response wraps the payload in a consistent envelope:
Success envelope
{
"success": true,
"data": { ... },
"meta": {
"total": 1250,
"page": 1,
"page_size": 50,
"updated_at": "2026-06-19T10:00:00Z"
},
"errors": []
}
For list endpoints, data is an array and meta.total holds the full count. For single-resource endpoints, data is an object.
Error responses carry success: false and a non-2xx HTTP status:
Error envelope
{
"success": false,
"data": null,
"meta": { "total": 0, "page": 1, "page_size": 0, "updated_at": "..." },
"errors": ["Produit avec EAN '123' introuvable."]
}
Status
Health check for the External API. Returns the authenticated key's name and assigned scopes. Use this to verify connectivity and key validity before integration testing.
Requires ext:products:read.
Request
curl https://api.pixeepim.com/api/v1/ext/status \
-H "X-API-Key: pm_live_abc123..."
Response
{
"success": true,
"data": {
"status": "ok",
"version": "1.0",
"api_key_name": "ERP Sync Key",
"api_key_scopes": ["ext:products:read", "ext:products:write"],
"timestamp": "2026-06-19T10:00:00Z"
},
"meta": { "total": 1, "page": 1, "page_size": 1, "updated_at": "..." },
"errors": []
}
List products
Returns a paginated list of products. Use updated_since to implement incremental polling, or supplier_code to filter by origin.
Query parameters
- Name
supplier_code- Type
- string
- Description
Filter by import source / supplier code (e.g.
KIMEX,INGRAM).
- Name
updated_since- Type
- string
- Description
ISO 8601 datetime — returns only products modified after this date. Example:
2026-01-01T00:00:00Z.
- Name
page- Type
- integer
- Description
Page number, starting at
1(default:1).
- Name
page_size- Type
- integer
- Description
Items per page, max
500(default:50).
Request
curl "https://api.pixeepim.com/api/v1/ext/products?page=1&page_size=100&updated_since=2026-06-01T00:00:00Z" \
-H "X-API-Key: pm_live_abc123..."
Response
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"ean": "3760000000001",
"title": "Support TV mural fixe",
"brand_name": "KIMEX",
"is_active": true,
"status": "active",
"weight": 1.5,
"updated_at": "2026-06-19T09:30:00Z"
}
],
"meta": {
"total": 1250,
"page": 1,
"page_size": 100,
"updated_at": "2026-06-19T10:00:00Z"
},
"errors": []
}
Delta sync
Dedicated endpoint for incremental synchronisation. Returns all products created or updated since the given since datetime. Preferred over /products?updated_since= for sync workflows because the intent is explicit and the parameter is required.
Query parameters
- Name
since- Type
- string
- Description
ISO 8601 datetime (e.g.
2026-06-18T00:00:00Z). Products modified at or after this timestamp are returned.
- Name
page- Type
- integer
- Description
Page number (default:
1).
- Name
page_size- Type
- integer
- Description
Items per page, max
500(default:100).
Store the updated_at from meta in your last-sync timestamp. Pass it as
since on the next call to process only new changes.
Request
curl "https://api.pixeepim.com/api/v1/ext/products/delta?since=2026-06-18T00:00:00Z" \
-H "X-API-Key: pm_live_abc123..."
Polling loop (Python)
import httpx, json
from datetime import datetime, timezone
API_KEY = "pm_live_abc123..."
BASE = "https://api.pixeepim.com/api/v1/ext"
last_sync = "2026-01-01T00:00:00Z"
while True:
r = httpx.get(
f"{BASE}/products/delta",
params={"since": last_sync, "page_size": 500},
headers={"X-API-Key": API_KEY},
)
body = r.json()
products = body["data"]
last_sync = body["meta"]["updated_at"]
process(products) # your integration logic
if len(products) < 500:
break # no more pages
Get a product
Retrieves a single product by its EAN.
Path parameters
- Name
ean- Type
- string
- Description
EAN-13 (or equivalent) of the product to retrieve.
Request
curl https://api.pixeepim.com/api/v1/ext/products/3760000000001 \
-H "X-API-Key: pm_live_abc123..."
Response
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"ean": "3760000000001",
"title": "Support TV mural fixe",
"brand_name": "KIMEX",
"status": "active",
"is_active": true,
"weight": 1.5,
"created_at": "2026-03-01T08:00:00Z",
"updated_at": "2026-06-19T09:30:00Z"
},
"meta": { "total": 1, "page": 1, "page_size": 1, "updated_at": "..." },
"errors": []
}
Create or upsert
Creates a new product or updates an existing one, matched by EAN.
- EAN not found → creates the product (
nameis required). - EAN already exists → updates non-null fields from the payload.
Requires ext:products:write.
Body parameters
- Name
ean- Type
- string
- Description
EAN-13 or equivalent. Used as the unique key for upsert matching.
- Name
name- Type
- string
- Description
Product title. Required when creating (EAN not found).
- Name
brand_name- Type
- string
- Description
Brand name. Matched or created automatically.
- Name
description- Type
- string
- Description
Long description (HTML allowed).
- Name
short_description- Type
- string
- Description
Short marketing description.
- Name
supplier_code- Type
- string
- Description
Import source identifier (e.g.
KIMEX).
- Name
reference- Type
- string
- Description
Manufacturer reference / SKU.
- Name
status- Type
- string
- Description
active,inactive, orarchived.
- Name
weight- Type
- number
- Description
Weight in kg.
- Name
width- Type
- number
- Description
Width in cm.
- Name
height- Type
- number
- Description
Height in cm.
- Name
depth- Type
- number
- Description
Depth in cm.
See Product fields for the full list.
Request
curl -X POST https://api.pixeepim.com/api/v1/ext/products \
-H "X-API-Key: pm_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"ean": "3760000000001",
"name": "Support TV mural fixe 37-75 pouces",
"brand_name": "KIMEX",
"supplier_code": "KIMEX",
"weight": 1.5,
"status": "active"
}'
Response
{
"success": true,
"data": {
"created": true,
"ean": "3760000000001",
"id": "550e8400-e29b-41d4-a716-446655440000",
"product": { ... }
},
"meta": { "total": 1, "page": 1, "page_size": 1, "updated_at": "..." },
"errors": []
}
Batch upsert
Upserts up to 500 products in a single request. Each product is processed independently — individual errors are collected without interrupting the rest of the batch.
Requires ext:products:write.
Body parameters
- Name
products- Type
- array
- Description
Array of product objects (max 500). Each item follows the same schema as the single upsert endpoint.
Request
curl -X POST https://api.pixeepim.com/api/v1/ext/products/batch \
-H "X-API-Key: pm_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"products": [
{ "ean": "3760000000001", "name": "Produit A", "brand_name": "KIMEX" },
{ "ean": "3760000000002", "name": "Produit B", "brand_name": "KIMEX" }
]
}'
Response
{
"success": true,
"data": {
"total": 2,
"created": 1,
"updated": 1,
"errors": 0,
"results": [
{ "ean": "3760000000001", "status": "created", "id": "..." },
{ "ean": "3760000000002", "status": "updated", "id": "..." }
]
},
"meta": { "total": 2, "page": 1, "page_size": 2, "updated_at": "..." },
"errors": []
}
Full update (PUT)
Fully replaces a product's writable fields. Fields not present in the payload are set to null. Returns 404 if the EAN does not exist (unlike POST /products which creates).
Requires ext:products:write.
Path parameters
- Name
ean- Type
- string
- Description
EAN of the product to replace.
The body follows the same schema as POST /products (see Product fields).
Request
curl -X PUT https://api.pixeepim.com/api/v1/ext/products/3760000000001 \
-H "X-API-Key: pm_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"ean": "3760000000001",
"name": "Support TV mural fixe — édition 2026",
"brand_name": "KIMEX",
"weight": 1.6,
"status": "active"
}'
Response
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"ean": "3760000000001",
"title": "Support TV mural fixe — édition 2026",
"updated_at": "2026-06-19T10:00:00Z"
},
"meta": { "total": 1, "page": 1, "page_size": 1, "updated_at": "..." },
"errors": []
}
Partial update (PATCH)
Updates only the fields provided. Null or omitted fields are left unchanged. Returns 404 if the EAN does not exist.
Requires ext:products:write.
Path parameters
- Name
ean- Type
- string
- Description
EAN of the product to partially update.
The body accepts any subset of product fields (all optional for PATCH).
Request
curl -X PATCH https://api.pixeepim.com/api/v1/ext/products/3760000000001 \
-H "X-API-Key: pm_live_abc123..." \
-H "Content-Type: application/json" \
-d '{ "status": "inactive", "weight": 1.6 }'
Response
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"ean": "3760000000001",
"status": "inactive",
"weight": 1.6,
"updated_at": "2026-06-19T10:05:00Z"
},
"meta": { "total": 1, "page": 1, "page_size": 1, "updated_at": "..." },
"errors": []
}
Product fields
The following fields are accepted by POST, PUT, and PATCH endpoints.
| Field | Type | Notes |
|---|---|---|
ean | string | EAN-13 or equivalent — required on POST |
name | string | Product title — required when creating via POST |
brand_name | string | Matched or created automatically |
description | string | Long description (HTML allowed) |
short_description | string | Short marketing text |
reference | string | Manufacturer reference / SKU |
supplier_code | string | Import source code (e.g. KIMEX) |
category_id | string (UUID) | Category UUID from your catalog |
asin | string | Amazon ASIN |
upc | string | Universal Product Code |
gtin | string | Global Trade Item Number |
status | string | active · inactive · archived |
is_active | boolean | Shorthand for status = active |
weight | number | Weight in kg |
width | number | Width in cm |
height | number | Height in cm |
depth | number | Depth in cm |
unit_of_measure | string | unit, pack, m, kg, … |
external_id | string | Your system's internal ID |
url_slug | string | SEO slug for e-commerce |