Appearance
Product data
2 reads, no writes, on train 2026-11. Scopes: pim:read.
| Operation | Method | Scope | Path |
|---|---|---|---|
| The product catalogue with its family attributes | GET | pim:read | /api/v1/pim/v1/products |
| One product's attributes | GET | pim:read | /api/v1/pim/v1/products/{product_id} |
The product catalogue with its family attributes
GET /api/v1/pim/v1/products
Scopes: pim:read
A page of products with their product data: the family each belongs to, whether that family has a template at all, how many required attributes are still empty, and which fields Tightly owns. family_id narrows to one family, and limit and offset page, with total for the whole set.
| Optional | In | What it is |
|---|---|---|
family_id | query | Only products in this family. |
limit | query | Rows per page. Clamped to 500. |
offset | query | Rows to skip. |
Tightly-Version | header | The date train to answer on. |
bash
curl "https://api.app.tightly.io/api/v1/pim/v1/products" \
-H "Authorization: Bearer $TIGHTLY_API_KEY"What it answers
json
{
"data": {
"limit": 100,
"offset": 0,
"rows": [
{
"family_id": "knitwear",
"has_template": true,
"missing_required_count": 2,
"owned_fields": [
"composition",
"care"
],
"product_id": "4410092",
"title": "Terry Crew"
}
],
"total": 1284
},
"message": {
"desc": "",
"service": "inventory",
"severity": "INFO"
}
}What it refuses
- 401 No usable key: malformed, unknown, revoked, expired or stopped. One refusal covers all five, in the sentence the seam's
key_invalidcarries, because telling a caller which is which maps the surface for them. This door resolves the key in its own decorator rather than at the seam, so the body carriesdata.errorrather thanmessage.code. - 403 The key is valid and the organisation's plan does not include Product data, which is included with Essentials+ and Pro. Specific on purpose: it is only ever shown to the holder of a valid key, so it leaks nothing and it tells an integrator to renew the plan rather than rotate a key that was never the problem. The plan is re-checked on every request, because a key minted on Pro keeps resolving after a downgrade.
- 429
One product's attributes
GET /api/v1/pim/v1/products/{product_id}
Scopes: pim:read
One product's attributes, resolved against its family template: every attribute the family declares, grouped as the family groups them, each with whether it is required, whether it is filled, its value, and whether it is a value the family does not declare at all (not_in_family, kept and shown rather than dropped).
| Required | In | What it is |
|---|---|---|
product_id | path | The product. |
| Optional | In | What it is |
|---|---|---|
Tightly-Version | header | The date train to answer on. |
bash
curl "https://api.app.tightly.io/api/v1/pim/v1/products/<product_id>" \
-H "Authorization: Bearer $TIGHTLY_API_KEY"What it answers
json
{
"data": {
"awaiting_write_back": [
"composition"
],
"family_id": "knitwear",
"groups": {
"Fabric": [
{
"attribute": "composition",
"filled": true,
"not_in_family": false,
"required": true,
"value": "80% cotton, 20% polyester"
},
{
"attribute": "gsm",
"filled": false,
"not_in_family": false,
"required": true,
"value": null
}
]
},
"has_template": true,
"missing_optional": [
"origin"
],
"missing_required": [
"gsm",
"care"
],
"not_in_family": [
"legacy_swatch_code"
],
"owned_fields": [
"composition",
"care"
],
"product_id": "4410092"
…
}
}What it refuses
- 401 No usable key: malformed, unknown, revoked, expired or stopped. One refusal covers all five, in the sentence the seam's
key_invalidcarries, because telling a caller which is which maps the surface for them. This door resolves the key in its own decorator rather than at the seam, so the body carriesdata.errorrather thanmessage.code. - 403 The key is valid and the organisation's plan does not include Product data, which is included with Essentials+ and Pro. Specific on purpose: it is only ever shown to the holder of a valid key, so it leaks nothing and it tells an integrator to renew the plan rather than rotate a key that was never the problem. The plan is re-checked on every request, because a key minted on Pro keeps resolving after a downgrade.
- 404 No such product for this key's organisation. Deliberately not "product X not found".
- 429