Categories
Product categories, for goods or for finished products.
Version v1.1, updated
A category groups products of one kind: product_kind says whether it holds goods or finished products. A product can only be in a category of its own kind.
Fields
Send says the field is in responses. Receive says a write accepts it; a reference is sent as an object, such as category for category_id. Totals, VAT, numbers and statuses are computed by BIRP and never received.
List categories
Lists the product categories of the company.
Scope:
categories:read.Idempotency: a read; send it as often as you need.
/v1/categoriesParameters
limitinteger, in query- Page size, 1 to 200. Default 50.Default
50 cursorstring, in query- next_cursor of the previous page. Pages are ordered by id.Example
opaque-cursor-example updated_sincestring (date-time), in query- Only records changed at or after this time: ISO 8601 date and time with an offset or Z.Example
2026-09-01T00:00:00Z external_idstring, in query- Identifier in an external system. Requires source.Example
1042 sourcestring, in query- External system of external_id, in lowercase. Requires external_id.Example
woocommerce
curl "https://api.birp.io/v1/categories" \
-H "Authorization: Bearer $BIRP_API_KEY"const response = await fetch("https://api.birp.io/v1/categories", {
headers: {
Authorization: `Bearer ${process.env.BIRP_API_KEY}`,
},
});
if (!response.ok) throw new Error(`BIRP API error ${response.status}`);
const result = await response.json();<?php
$ch = curl_init("https://api.birp.io/v1/categories");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BIRP_API_KEY"),
],
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);import os
import requests
response = requests.request(
"GET",
"https://api.birp.io/v1/categories",
headers={
"Authorization": f"Bearer {os.environ['BIRP_API_KEY']}",
},
timeout=10,
)
response.raise_for_status()
result = response.json(){
"data": [
{
"created_at": "2026-09-01T07:30:00.000Z",
"description": "Flours for resale",
"external_ids": [],
"id": "00000000-0000-4000-8000-000000000021",
"name": "Flour",
"product_kind": "goods",
"updated_at": "2026-09-28T14:05:12.417Z"
}
],
"meta": {
"has_more": false,
"limit": 50,
"next_cursor": null
}
}Errors particular to this operation:
422
validation_failed
Get a category
Returns one category of the company.
Scope:
categories:read.Idempotency: a read; send it as often as you need.
/v1/categories/{id}Parameters
idrequiredstring (uuid), in path- Category identifier.Example
00000000-0000-4000-8000-000000000021
curl "https://api.birp.io/v1/categories/00000000-0000-4000-8000-000000000021" \
-H "Authorization: Bearer $BIRP_API_KEY"const response = await fetch("https://api.birp.io/v1/categories/00000000-0000-4000-8000-000000000021", {
headers: {
Authorization: `Bearer ${process.env.BIRP_API_KEY}`,
},
});
if (!response.ok) throw new Error(`BIRP API error ${response.status}`);
const result = await response.json();<?php
$ch = curl_init("https://api.birp.io/v1/categories/00000000-0000-4000-8000-000000000021");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BIRP_API_KEY"),
],
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);import os
import requests
response = requests.request(
"GET",
"https://api.birp.io/v1/categories/00000000-0000-4000-8000-000000000021",
headers={
"Authorization": f"Bearer {os.environ['BIRP_API_KEY']}",
},
timeout=10,
)
response.raise_for_status()
result = response.json(){
"data": {
"created_at": "2026-09-01T07:30:00.000Z",
"description": "Flours for resale",
"external_ids": [],
"id": "00000000-0000-4000-8000-000000000021",
"name": "Flour",
"product_kind": "goods",
"updated_at": "2026-09-28T14:05:12.417Z"
}
}Errors particular to this operation:
404
not_found
Create a category
Creates a category for goods or for finished products.
Scope:
categories:write.Idempotency:
Idempotency-Keyrequired. See Idempotency.
Two categories of the same kind cannot share a name.
/v1/categoriesParameters
Idempotency-Keyrequiredstring, in header- Unique value for this request (for example a UUID), 1 to 128 printable ASCII characters. A retry with the same key and the same request gets the stored response for 24 hours, with Idempotency-Replayed: true; the same key with a different request answers 422 idempotency_key_reused. Required on POST, optional on PUT, PATCH and DELETE.Example
00000000-0000-4000-8000-0000000000a1
Request body
application/json
namerequiredstring- Category name, unique per kind in the company.
descriptionstring | nullexternal_idsarray of ExternalIdInputexternal_ids[].sourcerequiredstring- External system, in lowercase (for example woocommerce, shopify_product).
external_ids[].external_idrequiredstring- Identifier in that system.
product_kindrequiredstring- Kind of the products it groups. Never changes.One of
goods,finished_product
curl -X POST "https://api.birp.io/v1/categories" \
-H "Authorization: Bearer $BIRP_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"description":"Flours for resale","name":"Flour","product_kind":"goods"}'const response = await fetch("https://api.birp.io/v1/categories", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BIRP_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"description": "Flours for resale",
"name": "Flour",
"product_kind": "goods"
}),
});
if (!response.ok) throw new Error(`BIRP API error ${response.status}`);
const result = await response.json();<?php
$ch = curl_init("https://api.birp.io/v1/categories");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BIRP_API_KEY"),
"Idempotency-Key: " . bin2hex(random_bytes(16)),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"description": "Flours for resale",
"name": "Flour",
"product_kind": "goods"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);import os
import uuid
import requests
response = requests.request(
"POST",
"https://api.birp.io/v1/categories",
json={
"description": "Flours for resale",
"name": "Flour",
"product_kind": "goods"
},
headers={
"Authorization": f"Bearer {os.environ['BIRP_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
timeout=10,
)
response.raise_for_status()
result = response.json(){
"data": {
"created_at": "2026-09-01T07:30:00.000Z",
"description": "Flours for resale",
"external_ids": [],
"id": "00000000-0000-4000-8000-000000000021",
"name": "Flour",
"product_kind": "goods",
"updated_at": "2026-09-28T14:05:12.417Z"
}
}Errors particular to this operation:
409
category_name_taken409
external_id_conflict422
validation_failed
Update a category
Changes the name or the description of a category.
Scope:
categories:write.Idempotency:
Idempotency-Keyaccepted and recommended.
The kind of a category never changes.
/v1/categories/{id}Parameters
Idempotency-Keystring, in header- Unique value for this request (for example a UUID), 1 to 128 printable ASCII characters. A retry with the same key and the same request gets the stored response for 24 hours, with Idempotency-Replayed: true; the same key with a different request answers 422 idempotency_key_reused. Required on POST, optional on PUT, PATCH and DELETE.Example
00000000-0000-4000-8000-0000000000a1 idrequiredstring (uuid), in path- Category identifier.Example
00000000-0000-4000-8000-000000000021
Request body
application/json
namestringdescriptionstring | null
curl -X PATCH "https://api.birp.io/v1/categories/00000000-0000-4000-8000-000000000021" \
-H "Authorization: Bearer $BIRP_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"description":"Flours for resale"}'const response = await fetch("https://api.birp.io/v1/categories/00000000-0000-4000-8000-000000000021", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.BIRP_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"description": "Flours for resale"
}),
});
if (!response.ok) throw new Error(`BIRP API error ${response.status}`);
const result = await response.json();<?php
$ch = curl_init("https://api.birp.io/v1/categories/00000000-0000-4000-8000-000000000021");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BIRP_API_KEY"),
"Idempotency-Key: " . bin2hex(random_bytes(16)),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"description": "Flours for resale"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);import os
import uuid
import requests
response = requests.request(
"PATCH",
"https://api.birp.io/v1/categories/00000000-0000-4000-8000-000000000021",
json={
"description": "Flours for resale"
},
headers={
"Authorization": f"Bearer {os.environ['BIRP_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
timeout=10,
)
response.raise_for_status()
result = response.json(){
"data": {
"created_at": "2026-09-01T07:30:00.000Z",
"description": "Flours for resale",
"external_ids": [],
"id": "00000000-0000-4000-8000-000000000021",
"name": "Flour",
"product_kind": "goods",
"updated_at": "2026-09-28T14:05:12.417Z"
}
}Errors particular to this operation:
404
not_found409
category_name_taken422
validation_failed
Related
- products
- sync-products