Skip to content

Products

Resale goods and finished products: list, read, create, update and upsert.

Version v1.1, updated

On this page

A product is either resale goods (goods), bought and sold as they are, or a finished product (finished_product) that the company makes. Both kinds share one list and one SKU space.

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.

Product
FieldTypeRequiredReceive (inbound)Send (outbound)Notes
archived_atstring or nullNoNoYesWhen the product was archived. ISO 8601 date and time in UTC, with millisecond precision and a Z suffix.
barcodestring or nullNoYesYesBarcode of the product.
category_idstring (uuid) or nullNoYesYesCategory of the product.
created_atstringYesNoYesCreation time. ISO 8601 date and time in UTC, with millisecond precision and a Z suffix.
currencystring or nullNoYesYesCurrency of the price, an uppercase ISO 4217 code.
external_idsarray of ExternalIdYesYesYesIdentifiers of the product in external systems.
idstring (uuid)YesNoYesProduct identifier.
image_urlstring or nullNoNoYesTemporary URL of the product image: it expires, so read it again instead of storing it. Finished products only.
kindstringYesYesYesgoods: bought and resold. finished_product: produced by the company.
namestringYesYesYesProduct name.
pricestring or nullNoYesYesSale price. Decimal string with two decimals.
skustringYesYesYesReference of the product. A goods item and a finished product can share one; a reference by sku then needs kind.
statusstringYesYesYesarchived when the product was archived in BIRP. One of: active, archived.
unitstring or nullNoYesYesDefault unit of measure, free text (for example kg or pcs).
updated_atstringYesNoYesLast change. ISO 8601 date and time in UTC, with millisecond precision and a Z suffix.

List products

Lists the products of the company, resale goods and finished products together, ordered by id.

  • Scope: products:read.

  • Idempotency: a read; send it as often as you need.

GET/v1/products
List products

Parameters

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
skustring, in query
Exact product reference. May match one goods item and one finished product.Example SP-FLOUR-25
barcodestring, in query
Exact barcode.Example 2000000000015
statusstring, in query
active or archived.One of active, archivedExample active
kindstring, in query
goods or finished_product.One of goods, finished_productExample goods
GET /v1/products
curl "https://api.birp.io/v1/products" \
  -H "Authorization: Bearer $BIRP_API_KEY"
200 OKJSON
{
  "data": [
    {
      "archived_at": null,
      "barcode": "2000000000015",
      "category_id": "00000000-0000-4000-8000-000000000021",
      "created_at": "2026-09-01T07:30:00.000Z",
      "currency": "MDL",
      "external_ids": [
        {
          "external_id": "1042",
          "source": "woocommerce"
        }
      ],
      "id": "00000000-0000-4000-8000-000000000011",
      "image_url": null,
      "kind": "goods",
      "name": "Wheat flour 25 kg",
      "price": "12.50",
      "sku": "SP-FLOUR-25",
      "status": "active",
      "unit": "kg",
      "updated_at": "2026-09-28T14:05:12.417Z"
    },
    {
      "archived_at": null,
      "barcode": "2000000000022",
      "category_id": "00000000-0000-4000-8000-000000000022",
      "created_at": "2026-09-01T07:30:00.000Z",
      "currency": "EUR",
      "external_ids": [],
      "id": "00000000-0000-4000-8000-000000000012",
      "image_url": "https://files.example.com/temporary/white-bread.png",
      "kind": "finished_product",
      "name": "White bread 500 g",
      "price": "3.20",
      "sku": "FP-BREAD-500",
      "status": "active",
      "unit": "pcs",
      "updated_at": "2026-09-28T14:05:12.417Z"
    }
  ],
  "meta": {
    "has_more": true,
    "limit": 50,
    "next_cursor": "opaque-cursor-example"
  }
}

Errors particular to this operation:

  • 422 validation_failed

Get a product

Returns one product of the company.

  • Scope: products:read.

  • Idempotency: a read; send it as often as you need.

GET/v1/products/{id}
Get a product

Parameters

idrequiredstring (uuid), in path
Product identifier.Example 00000000-0000-4000-8000-000000000011
GET /v1/products/{id}
curl "https://api.birp.io/v1/products/00000000-0000-4000-8000-000000000011" \
  -H "Authorization: Bearer $BIRP_API_KEY"
200 OKJSON
{
  "data": {
    "archived_at": null,
    "barcode": "2000000000015",
    "category_id": "00000000-0000-4000-8000-000000000021",
    "created_at": "2026-09-01T07:30:00.000Z",
    "currency": "MDL",
    "external_ids": [
      {
        "external_id": "1042",
        "source": "woocommerce"
      }
    ],
    "id": "00000000-0000-4000-8000-000000000011",
    "image_url": null,
    "kind": "goods",
    "name": "Wheat flour 25 kg",
    "price": "12.50",
    "sku": "SP-FLOUR-25",
    "status": "active",
    "unit": "kg",
    "updated_at": "2026-09-28T14:05:12.417Z"
  }
}

Errors particular to this operation:

  • 404 not_found

Create a product

Creates a product of either kind.

  • Scope: products:write.

  • Idempotency: Idempotency-Key required. See Idempotency.

Without sku, BIRP gives the product a reference from the company numbering. A SKU that another product of the company has, of either kind, is refused.

POST/v1/products
Create a product

Parameters

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

skustring
Product reference. A write refuses a SKU that another product of the company already has, of either kind. Left out on create: generated by the company numbering.
kindrequiredstring
goods (bought and resold) or finished_product (made by the company). Never changes.One of goods, finished_product
namerequiredstring
Product name.
unitstring | null
Unit of sale, free text as in BIRP (for example pcs, kg).
pricestring | null
Sale price, decimal string with at most two decimals. Use prices up to 99999.99: a larger price can be refused with 422 validation_failed.
barcodestring | null
Barcode, unique in the company across all products. Null removes it.
categoryReference | null
Category of the same kind as the product. Null removes it.
category.idstring (uuid)
BIRP id of the record.
category.sourcestring
External system of external_id, in lowercase.
category.external_idstring
Identifier of the record in an external system. Requires source.
currencystring
ISO 4217 code of the price. Left out on create: the company currency.
external_idsarray of ExternalIdInput
Identifiers in external systems, at most one per source.
external_ids[].sourcerequiredstring
External system, in lowercase (for example woocommerce, shopify_product).
external_ids[].external_idrequiredstring
Identifier in that system.
POST /v1/products
curl -X POST "https://api.birp.io/v1/products" \
  -H "Authorization: Bearer $BIRP_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"barcode":"2000000000015","category":{"id":"00000000-0000-4000-8000-000000000021"},"currency":"MDL","external_ids":[{"external_id":"1042","source":"woocommerce"}],"kind":"goods","name":"Wheat flour 25 kg","price":"12.50","sku":"SP-FLOUR-25","unit":"kg"}'
201 CreatedJSON
{
  "data": {
    "archived_at": null,
    "barcode": "2000000000015",
    "category_id": "00000000-0000-4000-8000-000000000021",
    "created_at": "2026-09-01T07:30:00.000Z",
    "currency": "MDL",
    "external_ids": [
      {
        "external_id": "1042",
        "source": "woocommerce"
      }
    ],
    "id": "00000000-0000-4000-8000-000000000011",
    "image_url": null,
    "kind": "goods",
    "name": "Wheat flour 25 kg",
    "price": "12.50",
    "sku": "SP-FLOUR-25",
    "status": "active",
    "unit": "kg",
    "updated_at": "2026-09-28T14:05:12.417Z"
  }
}

Errors particular to this operation:

  • 409 barcode_taken

  • 409 external_id_conflict

  • 409 sku_taken

  • 422 reference_not_found

  • 422 validation_failed

Update a product

Changes the fields you send and leaves the others as they are.

  • Scope: products:write.

  • Idempotency: Idempotency-Key accepted and recommended.

null clears a field that can be empty. The kind never changes. "status": "archived" archives the product, "active" restores it.

PATCH/v1/products/{id}
Update a product

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
Product identifier.Example 00000000-0000-4000-8000-000000000011

Request body

application/json

skustring
Product reference. A write refuses a SKU that another product of the company already has, of either kind. Left out on create: generated by the company numbering.
namestring
Product name.
unitstring | null
Unit of sale, free text as in BIRP (for example pcs, kg).
pricestring | null
Sale price, decimal string with at most two decimals. Use prices up to 99999.99: a larger price can be refused with 422 validation_failed.
statusstring
archived hides the product from new documents in BIRP; active restores it.One of active, archived
barcodestring | null
Barcode, unique in the company across all products. Null removes it.
categoryReference | null
Category of the same kind as the product. Null removes it.
category.idstring (uuid)
BIRP id of the record.
category.sourcestring
External system of external_id, in lowercase.
category.external_idstring
Identifier of the record in an external system. Requires source.
currencystring
ISO 4217 code of the price. Left out on create: the company currency.
PATCH /v1/products/{id}
curl -X PATCH "https://api.birp.io/v1/products/00000000-0000-4000-8000-000000000011" \
  -H "Authorization: Bearer $BIRP_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"price":"12.50","status":"active"}'
200 OKJSON
{
  "data": {
    "archived_at": null,
    "barcode": "2000000000015",
    "category_id": "00000000-0000-4000-8000-000000000021",
    "created_at": "2026-09-01T07:30:00.000Z",
    "currency": "MDL",
    "external_ids": [
      {
        "external_id": "1042",
        "source": "woocommerce"
      }
    ],
    "id": "00000000-0000-4000-8000-000000000011",
    "image_url": null,
    "kind": "goods",
    "name": "Wheat flour 25 kg",
    "price": "12.50",
    "sku": "SP-FLOUR-25",
    "status": "active",
    "unit": "kg",
    "updated_at": "2026-09-28T14:05:12.417Z"
  }
}

Errors particular to this operation:

  • 404 not_found

  • 409 barcode_taken

  • 409 sku_taken

  • 422 reference_not_found

  • 422 validation_failed

Create or update a product by its external id

Creates the product linked to an external id, or updates it when it exists.

  • Scope: products:write.

  • Idempotency: Idempotency-Key accepted and recommended.

When the external id is new, the upsert first looks for a product of the same kind with the sku of the body. If it finds one, it links the external id to it instead of creating a product.

PUT/v1/products/external/{source}/{external_id}
Create or update a product by its external id

Parameters

sourcerequiredstring, in path
External system, in lowercase.Example woocommerce
external_idrequiredstring, in path
Identifier of the product in that system.Example 1042
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

Request body

application/json

skustring
Product reference. A write refuses a SKU that another product of the company already has, of either kind. Left out on create: generated by the company numbering.
kindrequiredstring
goods (bought and resold) or finished_product (made by the company). Never changes.One of goods, finished_product
namerequiredstring
Product name.
unitstring | null
Unit of sale, free text as in BIRP (for example pcs, kg).
pricestring | null
Sale price, decimal string with at most two decimals. Use prices up to 99999.99: a larger price can be refused with 422 validation_failed.
statusstring
archived or active.One of active, archived
barcodestring | null
Barcode, unique in the company across all products. Null removes it.
categoryReference | null
Category of the same kind as the product. Null removes it.
category.idstring (uuid)
BIRP id of the record.
category.sourcestring
External system of external_id, in lowercase.
category.external_idstring
Identifier of the record in an external system. Requires source.
currencystring
ISO 4217 code of the price. Left out on create: the company currency.
external_idsarray of ExternalIdInput
Identifiers in external systems, at most one per source.
external_ids[].sourcerequiredstring
External system, in lowercase (for example woocommerce, shopify_product).
external_ids[].external_idrequiredstring
Identifier in that system.
PUT /v1/products/external/{source}/{external_id}
curl -X PUT "https://api.birp.io/v1/products/external/woocommerce/1042" \
  -H "Authorization: Bearer $BIRP_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"currency":"MDL","kind":"goods","name":"Wheat flour 25 kg","price":"12.50","sku":"SP-FLOUR-25","unit":"kg"}'
200 OKJSON
{
  "data": {
    "archived_at": null,
    "barcode": "2000000000015",
    "category_id": "00000000-0000-4000-8000-000000000021",
    "created_at": "2026-09-01T07:30:00.000Z",
    "currency": "MDL",
    "external_ids": [
      {
        "external_id": "1042",
        "source": "woocommerce"
      }
    ],
    "id": "00000000-0000-4000-8000-000000000011",
    "image_url": null,
    "kind": "goods",
    "name": "Wheat flour 25 kg",
    "price": "12.50",
    "sku": "SP-FLOUR-25",
    "status": "active",
    "unit": "kg",
    "updated_at": "2026-09-28T14:05:12.417Z"
  }
}

Errors particular to this operation:

  • 409 barcode_taken

  • 409 kind_mismatch

  • 409 sku_taken

  • 422 reference_not_found

  • 422 validation_failed

Create or update up to 100 products

Upserts up to 100 products in one request and reports the result of each.

  • Scope: products:write.

  • Idempotency: Idempotency-Key required. See Idempotency.

See Batch operations for matching, validation and partial failure.

POST/v1/products/batch
Create or update up to 100 products

Parameters

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

itemsrequiredarray of ProductBatchItem
items[].datarequiredProductUpsert
A product by its external id: created when unknown, otherwise updated with the fields sent (fields left out are not touched).
items[].matchrequiredProductReference
How to find the product: id (must exist), external_id with source, or sku. Not found by external id or SKU: created.
POST /v1/products/batch
curl -X POST "https://api.birp.io/v1/products/batch" \
  -H "Authorization: Bearer $BIRP_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"data":{"currency":"MDL","kind":"goods","name":"Wheat flour 25 kg","price":"12.50","sku":"SP-FLOUR-25","unit":"kg"},"match":{"external_id":"1042","source":"woocommerce"}},{"data":{"kind":"finished_product","name":"White bread 500 g","price":"3.20"},"match":{"sku":"FP-BREAD-500"}},{"data":{"kind":"goods","name":"Rye flour 25 kg"},"match":{"id":"00000000-0000-4000-8000-000000000099"}}]}'
200 OKJSON
{
  "data": {
    "results": [
      {
        "id": "00000000-0000-4000-8000-000000000011",
        "index": 0,
        "status": "updated"
      },
      {
        "id": "00000000-0000-4000-8000-000000000012",
        "index": 1,
        "status": "updated"
      },
      {
        "errors": [
          {
            "code": "reference_not_found",
            "field": "match",
            "message": "matches no record of the company"
          }
        ],
        "index": 2,
        "status": "failed"
      }
    ],
    "summary": {
      "created": 0,
      "failed": 1,
      "updated": 2
    }
  }
}

Errors particular to this operation:

  • 422 validation_failed

  • sync-products
  • categories
  • batches
  • references-and-external-ids