Download OpenAPI specification:
The API between the shared admin-ui and a node (brand admin + retailer portal).
Non-normative. Not part of the OBX standard; it is the contract between the shared
admin-ui (a static single-page app) and the reference nodes (node-go, node-php,
node-ts), so one UI works on every node. Other OBX implementations are free to build their
own UI.
Serving. A node serves the admin-ui build at / with single-page-app fallback: any
GET that is not under /admin/api, /obx/ or /.well-known/ and accepts text/html
returns index.html. UI routes that the node itself links to (e-mails):
/invite/{token}, /reset-password/{token}, /request-access, /login.
The node's public base URL comes from its configuration (OBX_PUBLIC_URL).
Sessions. Cookie obx_session (HttpOnly, Secure except on http://localhost,
SameSite=Lax, Path=/), sliding expiry, at most 30 days, invalidated on logout, password
change and blocking. Bearer tokens are NOT accepted here.
CSRF. Every POST/PUT/PATCH/DELETE under /admin/api MUST carry header
X-CSRF-Token equal to the csrf_token returned by GET /admin/api/session (which works
without being logged in and sets the matching HttpOnly cookie obx_csrf), else 403
csrf_failed. Login rotates the token (use the one in the login response).
Roles. admin (the brand) and retailer. /admin/api/portal/* is for retailers;
admins may call it too and get a preview of everything published (their downloads are
not logged). Everything else except public/session/setup/password/invite endpoints
requires admin. Before first-run setup every other endpoint answers 409
setup_required.
Catalog writes. /admin/api/catalog/* has exactly the semantics of the OBX Ingest API
(same bodies, results, errors, change-feed effects), just with session auth.
Errors. application/problem+json with obx_error (docs/protocol.md#errors).
Lists use limit + opaque cursor and return {items, next_cursor}.
{- "name": "string",
- "logo_url": "string",
- "accent_color": "string",
- "welcome_text": { },
- "portal_name": { },
- "languages": [
- "nl"
], - "default_language": "nl",
- "access_requests_enabled": true,
- "setup_required": true,
- "brands": [
- {
- "id": "string",
- "name": "string"
}
]
}{- "authenticated": true,
- "csrf_token": "string",
- "setup_required": true,
- "user": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "status": "invited",
- "language": "nl",
- "last_login_at": "2019-08-24T14:15:22Z",
- "invite_expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}, - "retailer": {
- "id": "string",
- "name": "string"
}
}401 invalid_credentials (same answer for unknown e-mail), 403 account_blocked. Rate limited per IP and per e-mail (10 per 15 min).
| X-CSRF-Token required | string |
| email required | string <email> (Email) <= 254 characters E-mail address. |
| password required | string <= 200 characters |
{- "password": "string"
}{- "authenticated": true,
- "csrf_token": "string",
- "setup_required": true,
- "user": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "status": "invited",
- "language": "nl",
- "last_login_at": "2019-08-24T14:15:22Z",
- "invite_expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}, - "retailer": {
- "id": "string",
- "name": "string"
}
}{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}Always 202 (no account enumeration). Link <public_url>/reset-password/<token>, valid 1 hour, one-time. Rate limited (5 per 15 min per IP).
| X-CSRF-Token required | string |
| email required | string <email> (Email) <= 254 characters E-mail address. |
{- "email": "[email protected]"
}{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}| X-CSRF-Token required | string |
| token required | string [ 20 .. 200 ] characters |
| password required | string (Password) [ 10 .. 72 ] characters 10-72 characters (72 keeps bcrypt-based nodes compatible). Nodes store argon2id or bcrypt hashes only. |
{- "token": "stringstringstringst",
- "password": "stringstri"
}{- "authenticated": true,
- "csrf_token": "string",
- "setup_required": true,
- "user": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "status": "invited",
- "language": "nl",
- "last_login_at": "2019-08-24T14:15:22Z",
- "invite_expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}, - "retailer": {
- "id": "string",
- "name": "string"
}
}{- "name": "string",
- "role": "admin",
- "retailer_name": "string",
- "expires_at": "2026-09-28T10:00:00Z"
}One-time (the token is consumed atomically), valid 7 days. Logs in.
| token required | string [ 20 .. 200 ] characters |
| X-CSRF-Token required | string |
| name | string <= 200 characters |
| password required | string (Password) [ 10 .. 72 ] characters 10-72 characters (72 keeps bcrypt-based nodes compatible). Nodes store argon2id or bcrypt hashes only. |
| language | string (LanguageTag) ^[a-z]{2,3}(-[A-Z]{2})?$ BCP 47 language tag, restricted to language or language-REGION. |
{- "name": "string",
- "password": "stringstri",
- "language": "nl"
}{- "authenticated": true,
- "csrf_token": "string",
- "setup_required": true,
- "user": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "status": "invited",
- "language": "nl",
- "last_login_at": "2019-08-24T14:15:22Z",
- "invite_expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}, - "retailer": {
- "id": "string",
- "name": "string"
}
}Changing the password requires current_password and ends all other sessions.
| X-CSRF-Token required | string |
| name | string [ 1 .. 200 ] characters |
| language | string (LanguageTag) ^[a-z]{2,3}(-[A-Z]{2})?$ BCP 47 language tag, restricted to language or language-REGION. |
| current_password | string <= 200 characters |
| new_password | string (Password) [ 10 .. 72 ] characters 10-72 characters (72 keeps bcrypt-based nodes compatible). Nodes store argon2id or bcrypt hashes only. |
{- "name": "string",
- "language": "nl",
- "current_password": "string",
- "new_password": "stringstri"
}{- "authenticated": true,
- "csrf_token": "string",
- "setup_required": true,
- "user": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "status": "invited",
- "language": "nl",
- "last_login_at": "2019-08-24T14:15:22Z",
- "invite_expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}, - "retailer": {
- "id": "string",
- "name": "string"
}
}Creates the brand profile, the first brand and the first admin (password chosen here;
there is never a default password) and logs in. Requires the one-time setup_code
that the node prints in its log on first start (or that the operator preset with
OBX_SETUP_CODE), so nobody else can claim a freshly deployed node. Rate limited
(10 per 15 min per IP). 409 setup_completed once done.
| X-CSRF-Token required | string |
| setup_code required | string [ 6 .. 64 ] characters |
required | object |
required | object |
{- "setup_code": "string",
- "company": {
- "name": "string",
- "first_brand_name": "string",
- "default_language": "nl",
- "languages": [
- "nl"
], - "accent_color": "string"
},
}{- "authenticated": true,
- "csrf_token": "string",
- "setup_required": true,
- "user": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "status": "invited",
- "language": "nl",
- "last_login_at": "2019-08-24T14:15:22Z",
- "invite_expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}, - "retailer": {
- "id": "string",
- "name": "string"
}
}{- "company": {
- "name": "string",
- "country": "string"
}, - "branding": {
- "display_name": "string",
- "logo_url": "string",
- "accent_color": "string",
- "welcome_text": { },
- "portal_name": { }
}, - "portal": {
- "access_requests_enabled": true,
- "allow_original_download": true,
- "allow_article_data_export": true,
- "retailer_api_self_service": false,
- "languages": [
- "nl"
], - "default_language": "nl"
}, - "defaults": {
- "rights": {
- "license": "retailer-use",
- "license_text": "string",
- "channels": [
- "webshop"
], - "territories": [
- "NL"
], - "embargo_until": "2026-09-28T10:00:00Z",
- "expires_at": "2026-09-28T10:00:00Z",
- "credit": "string",
- "model_release": true
}, - "ingest_status": "published"
}, - "node": {
- "software": "string",
- "version": "string",
- "email_configured": true,
- "renditions_server_generated": true,
- "max_upload_bytes": 0,
- "source_kinds": [
- "https_url"
], - "custom_domain_help": "string",
}
}Changing portal.allow_original_download or default rights affects what retailers see and is reflected in /changes (grant entries with resync, or asset upserts).
| X-CSRF-Token required | string |
object | |
object | |
object | |
object |
{- "company": {
- "name": "string",
- "country": "string"
}, - "branding": {
- "display_name": "string",
- "accent_color": "string",
- "welcome_text": { },
- "portal_name": { }
}, - "portal": {
- "access_requests_enabled": true,
- "allow_original_download": true,
- "allow_article_data_export": true,
- "retailer_api_self_service": false,
- "languages": [
- "nl"
], - "default_language": "nl"
}, - "defaults": {
- "rights": {
- "license": "retailer-use",
- "license_text": "string",
- "channels": [
- "webshop"
], - "territories": [
- "NL"
], - "embargo_until": "2026-09-28T10:00:00Z",
- "expires_at": "2026-09-28T10:00:00Z",
- "credit": "string",
- "model_release": true
}, - "ingest_status": "published"
}
}{- "company": {
- "name": "string",
- "country": "string"
}, - "branding": {
- "display_name": "string",
- "logo_url": "string",
- "accent_color": "string",
- "welcome_text": { },
- "portal_name": { }
}, - "portal": {
- "access_requests_enabled": true,
- "allow_original_download": true,
- "allow_article_data_export": true,
- "retailer_api_self_service": false,
- "languages": [
- "nl"
], - "default_language": "nl"
}, - "defaults": {
- "rights": {
- "license": "retailer-use",
- "license_text": "string",
- "channels": [
- "webshop"
], - "territories": [
- "NL"
], - "embargo_until": "2026-09-28T10:00:00Z",
- "expires_at": "2026-09-28T10:00:00Z",
- "credit": "string",
- "model_release": true
}, - "ingest_status": "published"
}, - "node": {
- "software": "string",
- "version": "string",
- "email_configured": true,
- "renditions_server_generated": true,
- "max_upload_bytes": 0,
- "source_kinds": [
- "https_url"
], - "custom_domain_help": "string",
}
}| X-CSRF-Token required | string |
{- "company": {
- "name": "string",
- "country": "string"
}, - "branding": {
- "display_name": "string",
- "logo_url": "string",
- "accent_color": "string",
- "welcome_text": { },
- "portal_name": { }
}, - "portal": {
- "access_requests_enabled": true,
- "allow_original_download": true,
- "allow_article_data_export": true,
- "retailer_api_self_service": false,
- "languages": [
- "nl"
], - "default_language": "nl"
}, - "defaults": {
- "rights": {
- "license": "retailer-use",
- "license_text": "string",
- "channels": [
- "webshop"
], - "territories": [
- "NL"
], - "embargo_until": "2026-09-28T10:00:00Z",
- "expires_at": "2026-09-28T10:00:00Z",
- "credit": "string",
- "model_release": true
}, - "ingest_status": "published"
}, - "node": {
- "software": "string",
- "version": "string",
- "email_configured": true,
- "renditions_server_generated": true,
- "max_upload_bytes": 0,
- "source_kinds": [
- "https_url"
], - "custom_domain_help": "string",
}
}{- "company": {
- "name": "string",
- "country": "string"
}, - "branding": {
- "display_name": "string",
- "logo_url": "string",
- "accent_color": "string",
- "welcome_text": { },
- "portal_name": { }
}, - "portal": {
- "access_requests_enabled": true,
- "allow_original_download": true,
- "allow_article_data_export": true,
- "retailer_api_self_service": false,
- "languages": [
- "nl"
], - "default_language": "nl"
}, - "defaults": {
- "rights": {
- "license": "retailer-use",
- "license_text": "string",
- "channels": [
- "webshop"
], - "territories": [
- "NL"
], - "embargo_until": "2026-09-28T10:00:00Z",
- "expires_at": "2026-09-28T10:00:00Z",
- "credit": "string",
- "model_release": true
}, - "ingest_status": "published"
}, - "node": {
- "software": "string",
- "version": "string",
- "email_configured": true,
- "renditions_server_generated": true,
- "max_upload_bytes": 0,
- "source_kinds": [
- "https_url"
], - "custom_domain_help": "string",
}
}{- "items": [
- {
- "kind": "brand",
- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "status": "published",
- "visibility": "visible",
- "etag": "string",
- "created_at": "2026-09-28T10:00:00Z",
- "updated_at": "2026-09-28T10:00:00Z",
- "data": { },
- "missing_files": [
- "original"
]
}
]
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
| name required | string [ 1 .. 200 ] characters |
Url (string) or null | |
Url (string) or null | |
LocalizedText (object) or null | |
| status | string (PublicationStatus) Enum: "published" "unpublished" Brand-side publication state. Only 'published' objects (with published parents) are visible through the OBX Protocol. |
| ^x-[a-z0-9]+-[a-z0-9_-]+$ pattern property | any |
{- "name": "string",
- "description": { },
- "status": "published"
}{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
{ }{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}| q | string <= 200 characters Matches style number, name, GTIN, SKU (case-insensitive substring). |
| brand | string Brand external id. |
| status | string Enum: "published" "unpublished" |
| visibility | string Enum: "visible" "hidden" "pending_files" |
| sort | string Default: "updated_desc" Enum: "updated_desc" "style_number" "name" |
| cursor | string (Cursor) [ 1 .. 4096 ] characters Opaque pagination or feed cursor. Clients MUST NOT parse or construct it. |
| limit | integer [ 1 .. 200 ] Default: 50 |
{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "brand_external_id": "string",
- "style_number": "string",
- "name": { },
- "status": "published",
- "visibility": "visible",
- "variant_count": 0,
- "asset_count": 0,
- "pending_asset_count": 0,
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string",
- "total": 0
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
{- "record": {
- "kind": "brand",
- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "status": "published",
- "visibility": "visible",
- "etag": "string",
- "created_at": "2026-09-28T10:00:00Z",
- "updated_at": "2026-09-28T10:00:00Z",
- "data": { },
- "missing_files": [
- "original"
]
}, - "variants": [
- {
- "kind": "brand",
- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "status": "published",
- "visibility": "visible",
- "etag": "string",
- "created_at": "2026-09-28T10:00:00Z",
- "updated_at": "2026-09-28T10:00:00Z",
- "data": { },
- "missing_files": [
- "original"
]
}
], - "assets": [
- {
- "record": {
- "kind": "brand",
- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "status": "published",
- "visibility": "visible",
- "etag": "string",
- "created_at": "2026-09-28T10:00:00Z",
- "updated_at": "2026-09-28T10:00:00Z",
- "data": { },
- "missing_files": [
- "original"
]
}, - "renditions": {
- "property1": {
- "name": "original",
- "url_expires_at": "2026-09-28T10:00:00Z",
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string"
}, - "property2": {
- "name": "original",
- "url_expires_at": "2026-09-28T10:00:00Z",
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string"
}
}
}
]
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
ExternalId (string) or null | |
| style_number required | string [ 1 .. 200 ] characters |
required | object (LocalizedText) non-empty Free text per language, keyed by BCP 47 tag. At least one language. Example: {"nl": "Trui", "en": "Sweater"}. |
LocalizedText (object) or null | |
| item_type | string or null^[a-z][a-z0-9_]{0,63}$ |
| gpc_brick | string or null^[0-9]{8}$ |
| target_group | string or null^[a-z][a-z0-9_]{0,63}$ |
| season | string or null <= 64 characters |
| collection | string or null <= 200 characters |
Array of Materials (objects) or null | |
Array of Care (objects) or null | |
CountryCode (string) or null | |
Url (string) or null | |
object or null | |
| status | string (PublicationStatus) Enum: "published" "unpublished" Brand-side publication state. Only 'published' objects (with published parents) are visible through the OBX Protocol. |
| ^x-[a-z0-9]+-[a-z0-9_-]+$ pattern property | any |
{- "brand_external_id": "KO-1001",
- "style_number": "string",
- "name": { },
- "description": { },
- "item_type": "string",
- "gpc_brick": "string",
- "target_group": "string",
- "season": "string",
- "collection": "string",
- "materials": [
- {
- "part": "main",
- "fibers": [
- {
- "fiber": "string",
- "percentage": 1
}
]
}
], - "care": [
- {
- "code": "string",
- "text": { }
}
], - "country_of_origin": "NL",
- "attributes": {
- "property1": "string",
- "property2": "string"
}, - "status": "published"
}{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
{ }{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}Same as Ingest PUT /products/{external_id}/asset-order.
| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
| color_code required | string or null |
| asset_external_ids required | Array of strings (ExternalId) non-empty unique [ items [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ ] All assets of this product+colour in the desired order; they get positions 1..n atomically. |
{- "color_code": "string",
- "asset_external_ids": [
- "KO-1001"
]
}[- {
- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}
]| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
| product_external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
GtinInput (string) or null | |
| sku | string or null <= 200 characters |
required | object (Color) |
| size | string or null <= 64 characters |
| size_system | string or null <= 16 characters |
| status | string (PublicationStatus) Enum: "published" "unpublished" Brand-side publication state. Only 'published' objects (with published parents) are visible through the OBX Protocol. |
| ^x-[a-z0-9]+-[a-z0-9_-]+$ pattern property | any |
{- "product_external_id": "KO-1001",
- "gtin": "2000010010011",
- "sku": "string",
- "color": {
- "code": "string",
- "name": { },
- "supplier_color": "string"
}, - "size": "string",
- "size_system": "string",
- "status": "published"
}{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
{ }{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
| product_external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| color_code | string or null <= 64 characters |
| variant_external_ids | Array of strings or null (ExternalId) [ items [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ ] |
| media_type | string Value: "image" |
| role required | string (Role) Enum: "packshot" "model" "detail" "ghost" "flatlay" "scene" "swatch" "size_chart" "other" What the image shows. Stable key; labels are presentation. |
View (string) or null | |
| position required | integer [ 1 .. 999 ] |
| filename | string or null <= 255 characters Download filename; default |
LocalizedText (object) or null | |
object or null Partial Rights; omitted fields take the node's default rights (Settings). null = all defaults. | |
object or null Omitted fields default to ai_generated=false, ai_edited=false, source=photo (generated when ai_generated), c2pa=none (nodes MAY detect embedded C2PA). | |
object or null Attach previously uploaded blobs atomically. Omit to keep current files (or upload via PUT .../files/{rendition}). | |
| status | string (PublicationStatus) Enum: "published" "unpublished" Brand-side publication state. Only 'published' objects (with published parents) are visible through the OBX Protocol. |
| ^x-[a-z0-9]+-[a-z0-9_-]+$ pattern property | any |
{- "product_external_id": "KO-1001",
- "color_code": "string",
- "variant_external_ids": [
- "KO-1001"
], - "media_type": "image",
- "role": "packshot",
- "view": "front",
- "position": 1,
- "filename": "string",
- "alt_text": { },
- "rights": {
- "license": "retailer-use",
- "license_text": "string",
- "channels": [
- "webshop"
], - "territories": [
- "NL"
], - "embargo_until": "2026-09-28T10:00:00Z",
- "expires_at": "2026-09-28T10:00:00Z",
- "credit": "string",
- "model_release": true
}, - "provenance": {
- "ai_generated": true,
- "ai_edited": true,
- "source": "photo",
- "c2pa": "embedded",
- "generator": "string"
}, - "files": {
- "original": {
- "sha256": "string",
- "width": 1,
- "height": 1
}, - "web": {
- "sha256": "string",
- "width": 1,
- "height": 1
}, - "square": {
- "sha256": "string",
- "width": 1,
- "height": 1
}, - "thumb": {
- "sha256": "string",
- "width": 1,
- "height": 1
}
}, - "status": "published"
}{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
{ }{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| X-CSRF-Token required | string |
{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}Same as Ingest PUT /assets/{external_id}/files/{rendition}. The admin-ui generates web/square/thumb in the browser when the node reports renditions_server_generated=false (Settings.node).
| external_id required | string (ExternalId) [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ Examples: KO-1001 The brand's own identifier for an object (from its PIM/ERP/spreadsheet). 1-200 characters, no control characters and no '/'. Leading/trailing whitespace is trimmed by nodes. Compared case-sensitively. |
| rendition required | string (RenditionName) Enum: "original" "web" "square" "thumb" Rendition name. |
| OBX-Content-SHA256 | string (Sha256) ^[a-f0-9]{64}$ Lowercase hex SHA-256 of the exact bytes. |
| X-CSRF-Token required | string |
{- "index": 0,
- "op": "upsert",
- "kind": "brand",
- "external_id": "KO-1001",
- "result": "created",
- "id": "prd_01J9ZK3Q7T5W",
- "visibility": "visible",
- "etag": "string",
- "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "warnings": [
- "string"
]
}| sha256 required | string (Sha256) ^[a-f0-9]{64}$ Lowercase hex SHA-256 of the exact bytes. |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}| sha256 required | string (Sha256) ^[a-f0-9]{64}$ Lowercase hex SHA-256 of the exact bytes. |
| X-CSRF-Token required | string |
{- "sha256": "string",
- "bytes": 1,
- "content_type": "string",
- "width": 1,
- "height": 1,
- "created": true
}| source_id | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: source_id=prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| cursor | string (Cursor) [ 1 .. 4096 ] characters Opaque pagination or feed cursor. Clients MUST NOT parse or construct it. |
| limit | integer [ 1 .. 200 ] Default: 50 |
{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "source_id": "prd_01J9ZK3Q7T5W",
- "trigger": "upload",
- "status": "queued",
- "mode": "upsert",
- "dry_run": true,
- "created_at": "2026-09-28T10:00:00Z",
- "started_at": "2026-09-28T10:00:00Z",
- "finished_at": "2026-09-28T10:00:00Z",
- "files": [
- {
- "name": "string",
- "bytes": 0,
- "sha256": "string"
}
], - "counts": {
- "rows": 0,
- "files": 0,
- "created": 0,
- "updated": 0,
- "unchanged": 0,
- "unpublished": 0,
- "errors": 0,
- "warnings": 0
}, - "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "errors_preview": [
- {
- "file": "string",
- "row": 1,
- "column": "string",
- "severity": "error",
- "obx_error": "invalid_request",
- "detail": "string",
- "value": "string"
}
]
}
], - "next_cursor": "string"
}| X-CSRF-Token required | string |
| package | string <application/zip> |
| csv | string <text/csv> |
| assets_csv | string <text/csv> |
| images | Array of strings |
| images_manifest | Array of objects Same as Ingest ImagesManifest (blobs uploaded via /admin/api/catalog/blobs/{sha256}). |
object |
{- "id": "prd_01J9ZK3Q7T5W",
- "source_id": "prd_01J9ZK3Q7T5W",
- "trigger": "upload",
- "status": "queued",
- "mode": "upsert",
- "dry_run": true,
- "created_at": "2026-09-28T10:00:00Z",
- "started_at": "2026-09-28T10:00:00Z",
- "finished_at": "2026-09-28T10:00:00Z",
- "files": [
- {
- "name": "string",
- "bytes": 0,
- "sha256": "string"
}
], - "counts": {
- "rows": 0,
- "files": 0,
- "created": 0,
- "updated": 0,
- "unchanged": 0,
- "unpublished": 0,
- "errors": 0,
- "warnings": 0
}, - "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "errors_preview": [
- {
- "file": "string",
- "row": 1,
- "column": "string",
- "severity": "error",
- "obx_error": "invalid_request",
- "detail": "string",
- "value": "string"
}
]
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
{- "id": "prd_01J9ZK3Q7T5W",
- "source_id": "prd_01J9ZK3Q7T5W",
- "trigger": "upload",
- "status": "queued",
- "mode": "upsert",
- "dry_run": true,
- "created_at": "2026-09-28T10:00:00Z",
- "started_at": "2026-09-28T10:00:00Z",
- "finished_at": "2026-09-28T10:00:00Z",
- "files": [
- {
- "name": "string",
- "bytes": 0,
- "sha256": "string"
}
], - "counts": {
- "rows": 0,
- "files": 0,
- "created": 0,
- "updated": 0,
- "unchanged": 0,
- "unpublished": 0,
- "errors": 0,
- "warnings": 0
}, - "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "errors_preview": [
- {
- "file": "string",
- "row": 1,
- "column": "string",
- "severity": "error",
- "obx_error": "invalid_request",
- "detail": "string",
- "value": "string"
}
]
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| cursor | string (Cursor) [ 1 .. 4096 ] characters Opaque pagination or feed cursor. Clients MUST NOT parse or construct it. |
| limit | integer [ 1 .. 200 ] Default: 50 |
{- "items": [
- {
- "file": "string",
- "row": 1,
- "column": "string",
- "severity": "error",
- "obx_error": "invalid_request",
- "detail": "string",
- "value": "string"
}
], - "next_cursor": "string"
}{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "kind": "https_url",
- "enabled": true,
- "schedule": {
- "frequency": "manual",
- "time": "string",
- "weekday": 1,
- "timezone": "Europe/Amsterdam"
}, - "mode": "upsert",
- "allow_mass_unpublish": true,
- "credentials": {
- "password": "string",
- "private_key": "string",
- "access_key_id": "string",
- "secret_access_key": "string",
- "headers": {
- "property1": "string",
- "property2": "string"
}
}, - "credentials_set": {
- "password": true,
- "private_key": true,
- "access_key_id": true,
- "secret_access_key": true,
- "headers": [
- "string"
]
}, - "last_run": {
- "id": "prd_01J9ZK3Q7T5W",
- "source_id": "prd_01J9ZK3Q7T5W",
- "trigger": "upload",
- "status": "queued",
- "mode": "upsert",
- "dry_run": true,
- "created_at": "2026-09-28T10:00:00Z",
- "started_at": "2026-09-28T10:00:00Z",
- "finished_at": "2026-09-28T10:00:00Z",
- "files": [
- {
- "name": "string",
- "bytes": 0,
- "sha256": "string"
}
], - "counts": {
- "rows": 0,
- "files": 0,
- "created": 0,
- "updated": 0,
- "unchanged": 0,
- "unpublished": 0,
- "errors": 0,
- "warnings": 0
}, - "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "errors_preview": [
- {
- "file": "string",
- "row": 1,
- "column": "string",
- "severity": "error",
- "obx_error": "invalid_request",
- "detail": "string",
- "value": "string"
}
]
}, - "next_run_at": "2026-09-28T10:00:00Z",
- "created_at": "2026-09-28T10:00:00Z",
- "updated_at": "2026-09-28T10:00:00Z"
}
]
}| X-CSRF-Token required | string |
| name | string |
| kind | string Enum: "https_url" "sftp" "s3" |
| enabled | boolean |
| schedule | object |
| mode | string Enum: "upsert" "mirror" |
| allow_mass_unpublish | boolean |
| config | object |
| credentials | object or null |
{- "name": "string",
- "kind": "https_url",
- "enabled": true,
- "schedule": { },
- "mode": "upsert",
- "allow_mass_unpublish": true,
- "config": { },
- "credentials": { }
}{- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "kind": "https_url",
- "enabled": true,
- "schedule": {
- "frequency": "manual",
- "time": "string",
- "weekday": 1,
- "timezone": "Europe/Amsterdam"
}, - "mode": "upsert",
- "allow_mass_unpublish": true,
- "credentials": {
- "password": "string",
- "private_key": "string",
- "access_key_id": "string",
- "secret_access_key": "string",
- "headers": {
- "property1": "string",
- "property2": "string"
}
}, - "credentials_set": {
- "password": true,
- "private_key": true,
- "access_key_id": true,
- "secret_access_key": true,
- "headers": [
- "string"
]
}, - "last_run": {
- "id": "prd_01J9ZK3Q7T5W",
- "source_id": "prd_01J9ZK3Q7T5W",
- "trigger": "upload",
- "status": "queued",
- "mode": "upsert",
- "dry_run": true,
- "created_at": "2026-09-28T10:00:00Z",
- "started_at": "2026-09-28T10:00:00Z",
- "finished_at": "2026-09-28T10:00:00Z",
- "files": [
- {
- "name": "string",
- "bytes": 0,
- "sha256": "string"
}
], - "counts": {
- "rows": 0,
- "files": 0,
- "created": 0,
- "updated": 0,
- "unchanged": 0,
- "unpublished": 0,
- "errors": 0,
- "warnings": 0
}, - "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "errors_preview": [
- {
- "file": "string",
- "row": 1,
- "column": "string",
- "severity": "error",
- "obx_error": "invalid_request",
- "detail": "string",
- "value": "string"
}
]
}, - "next_run_at": "2026-09-28T10:00:00Z",
- "created_at": "2026-09-28T10:00:00Z",
- "updated_at": "2026-09-28T10:00:00Z"
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
{- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "kind": "https_url",
- "enabled": true,
- "schedule": {
- "frequency": "manual",
- "time": "string",
- "weekday": 1,
- "timezone": "Europe/Amsterdam"
}, - "mode": "upsert",
- "allow_mass_unpublish": true,
- "credentials": {
- "password": "string",
- "private_key": "string",
- "access_key_id": "string",
- "secret_access_key": "string",
- "headers": {
- "property1": "string",
- "property2": "string"
}
}, - "credentials_set": {
- "password": true,
- "private_key": true,
- "access_key_id": true,
- "secret_access_key": true,
- "headers": [
- "string"
]
}, - "last_run": {
- "id": "prd_01J9ZK3Q7T5W",
- "source_id": "prd_01J9ZK3Q7T5W",
- "trigger": "upload",
- "status": "queued",
- "mode": "upsert",
- "dry_run": true,
- "created_at": "2026-09-28T10:00:00Z",
- "started_at": "2026-09-28T10:00:00Z",
- "finished_at": "2026-09-28T10:00:00Z",
- "files": [
- {
- "name": "string",
- "bytes": 0,
- "sha256": "string"
}
], - "counts": {
- "rows": 0,
- "files": 0,
- "created": 0,
- "updated": 0,
- "unchanged": 0,
- "unpublished": 0,
- "errors": 0,
- "warnings": 0
}, - "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "errors_preview": [
- {
- "file": "string",
- "row": 1,
- "column": "string",
- "severity": "error",
- "obx_error": "invalid_request",
- "detail": "string",
- "value": "string"
}
]
}, - "next_run_at": "2026-09-28T10:00:00Z",
- "created_at": "2026-09-28T10:00:00Z",
- "updated_at": "2026-09-28T10:00:00Z"
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
| name | string |
| kind | string Enum: "https_url" "sftp" "s3" |
| enabled | boolean |
| schedule | object |
| mode | string Enum: "upsert" "mirror" |
| allow_mass_unpublish | boolean |
| config | object |
| credentials | object or null |
{- "name": "string",
- "kind": "https_url",
- "enabled": true,
- "schedule": { },
- "mode": "upsert",
- "allow_mass_unpublish": true,
- "config": { },
- "credentials": { }
}{- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "kind": "https_url",
- "enabled": true,
- "schedule": {
- "frequency": "manual",
- "time": "string",
- "weekday": 1,
- "timezone": "Europe/Amsterdam"
}, - "mode": "upsert",
- "allow_mass_unpublish": true,
- "credentials": {
- "password": "string",
- "private_key": "string",
- "access_key_id": "string",
- "secret_access_key": "string",
- "headers": {
- "property1": "string",
- "property2": "string"
}
}, - "credentials_set": {
- "password": true,
- "private_key": true,
- "access_key_id": true,
- "secret_access_key": true,
- "headers": [
- "string"
]
}, - "last_run": {
- "id": "prd_01J9ZK3Q7T5W",
- "source_id": "prd_01J9ZK3Q7T5W",
- "trigger": "upload",
- "status": "queued",
- "mode": "upsert",
- "dry_run": true,
- "created_at": "2026-09-28T10:00:00Z",
- "started_at": "2026-09-28T10:00:00Z",
- "finished_at": "2026-09-28T10:00:00Z",
- "files": [
- {
- "name": "string",
- "bytes": 0,
- "sha256": "string"
}
], - "counts": {
- "rows": 0,
- "files": 0,
- "created": 0,
- "updated": 0,
- "unchanged": 0,
- "unpublished": 0,
- "errors": 0,
- "warnings": 0
}, - "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "errors_preview": [
- {
- "file": "string",
- "row": 1,
- "column": "string",
- "severity": "error",
- "obx_error": "invalid_request",
- "detail": "string",
- "value": "string"
}
]
}, - "next_run_at": "2026-09-28T10:00:00Z",
- "created_at": "2026-09-28T10:00:00Z",
- "updated_at": "2026-09-28T10:00:00Z"
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
| dry_run | boolean Default: false |
| force | boolean Default: false Import even if the remote files did not change. |
{- "dry_run": false,
- "force": false
}{- "id": "prd_01J9ZK3Q7T5W",
- "source_id": "prd_01J9ZK3Q7T5W",
- "trigger": "upload",
- "status": "queued",
- "mode": "upsert",
- "dry_run": true,
- "created_at": "2026-09-28T10:00:00Z",
- "started_at": "2026-09-28T10:00:00Z",
- "finished_at": "2026-09-28T10:00:00Z",
- "files": [
- {
- "name": "string",
- "bytes": 0,
- "sha256": "string"
}
], - "counts": {
- "rows": 0,
- "files": 0,
- "created": 0,
- "updated": 0,
- "unchanged": 0,
- "unpublished": 0,
- "errors": 0,
- "warnings": 0
}, - "error": {
- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}, - "errors_preview": [
- {
- "file": "string",
- "row": 1,
- "column": "string",
- "severity": "error",
- "obx_error": "invalid_request",
- "detail": "string",
- "value": "string"
}
]
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "ok": true,
- "message": "string",
- "host_key_fingerprint": "string",
- "files": [
- {
- "name": "string",
- "bytes": 0,
- "modified_at": "2019-08-24T14:15:22Z"
}
]
}| q | string <= 200 characters |
| status | string Enum: "active" "blocked" |
| cursor | string (Cursor) [ 1 .. 4096 ] characters Opaque pagination or feed cursor. Clients MUST NOT parse or construct it. |
| limit | integer [ 1 .. 200 ] Default: 50 |
{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "reference": "string",
- "website": "string",
- "vat_number": "string",
- "country": "string",
- "notes": "string",
- "status": "active",
- "brand_ids": [
- "string"
], - "allow_original": true,
- "user_count": 0,
- "api_client_count": 0,
- "last_activity_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string"
}| X-CSRF-Token required | string |
| name | string [ 1 .. 200 ] characters |
| reference | string or null <= 100 characters |
| website | string or null |
| vat_number | string or null |
| country | string or null^[A-Z]{2}$ |
| notes | string or null <= 5000 characters |
| status | string Enum: "active" "blocked" |
| brand_ids | Array of strings or null |
| allow_original | boolean or null |
{- "name": "string",
- "reference": "string",
- "website": "string",
- "vat_number": "string",
- "country": "string",
- "notes": "string",
- "status": "active",
- "brand_ids": [
- "string"
], - "allow_original": true
}{- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "reference": "string",
- "website": "string",
- "vat_number": "string",
- "country": "string",
- "notes": "string",
- "status": "active",
- "brand_ids": [
- "string"
], - "allow_original": true,
- "user_count": 0,
- "api_client_count": 0,
- "last_activity_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
{- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "reference": "string",
- "website": "string",
- "vat_number": "string",
- "country": "string",
- "notes": "string",
- "status": "active",
- "brand_ids": [
- "string"
], - "allow_original": true,
- "user_count": 0,
- "api_client_count": 0,
- "last_activity_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}Blocking ends all its sessions and invalidates its API tokens immediately (access_revoked). Grant changes emit a grant change with resync for its consumers.
| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
| name | string [ 1 .. 200 ] characters |
| reference | string or null <= 100 characters |
| website | string or null |
| vat_number | string or null |
| country | string or null^[A-Z]{2}$ |
| notes | string or null <= 5000 characters |
| status | string Enum: "active" "blocked" |
| brand_ids | Array of strings or null |
| allow_original | boolean or null |
{- "name": "string",
- "reference": "string",
- "website": "string",
- "vat_number": "string",
- "country": "string",
- "notes": "string",
- "status": "active",
- "brand_ids": [
- "string"
], - "allow_original": true
}{- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "reference": "string",
- "website": "string",
- "vat_number": "string",
- "country": "string",
- "notes": "string",
- "status": "active",
- "brand_ids": [
- "string"
], - "allow_original": true,
- "user_count": 0,
- "api_client_count": 0,
- "last_activity_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}| status | string Enum: "pending" "approved" "rejected" |
| cursor | string (Cursor) [ 1 .. 4096 ] characters Opaque pagination or feed cursor. Clients MUST NOT parse or construct it. |
| limit | integer [ 1 .. 200 ] Default: 50 |
{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "status": "pending",
- "created_at": "2019-08-24T14:15:22Z",
- "decided_at": "2019-08-24T14:15:22Z",
- "reason": "string",
- "retailer": {
- "name": "string",
- "reference": "string",
- "website": "string",
- "vat_number": "string",
- "country": "string"
}, - "contact": {
- "name": "string",
- "email": "string",
- "phone": "string",
- "language": "string"
}, - "access": [
- "portal"
], - "requested_brand_ids": [
- "string"
], - "message": "string",
- "retailer_id": "string",
- "source_ip_country": "string"
}
], - "next_cursor": "string"
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
{- "id": "prd_01J9ZK3Q7T5W",
- "status": "pending",
- "created_at": "2019-08-24T14:15:22Z",
- "decided_at": "2019-08-24T14:15:22Z",
- "reason": "string",
- "retailer": {
- "name": "string",
- "reference": "string",
- "website": "string",
- "vat_number": "string",
- "country": "string"
}, - "contact": {
- "name": "string",
- "email": "string",
- "phone": "string",
- "language": "string"
}, - "access": [
- "portal"
], - "requested_brand_ids": [
- "string"
], - "message": "string",
- "retailer_id": "string",
- "source_ip_country": "string"
}Creates (or links) the retailer, optionally invites the contact as a portal user
(e-mail with a one-time link) and optionally creates an API client whose secret is
handed to the requester exactly once via the protocol status endpoint. 409 conflict
if not pending.
| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
| retailer_id | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Link to an existing retailer instead of creating one. |
| brand_ids | Array of strings or null (Id) [ items^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ ] Grant; null/omitted = the requested brands, or all when none requested. |
| invite_portal_user | boolean Default true when 'portal' was requested. |
| create_api_client | boolean Default true when 'api' was requested. |
{- "retailer_id": "prd_01J9ZK3Q7T5W",
- "brand_ids": [
- "prd_01J9ZK3Q7T5W"
], - "invite_portal_user": true,
- "create_api_client": true
}{- "access_request": {
- "id": "prd_01J9ZK3Q7T5W",
- "status": "pending",
- "created_at": "2019-08-24T14:15:22Z",
- "decided_at": "2019-08-24T14:15:22Z",
- "reason": "string",
- "retailer": {
- "name": "string",
- "reference": "string",
- "website": "string",
- "vat_number": "string",
- "country": "string"
}, - "contact": {
- "name": "string",
- "email": "string",
- "phone": "string",
- "language": "string"
}, - "access": [
- "portal"
], - "requested_brand_ids": [
- "string"
], - "message": "string",
- "retailer_id": "string",
- "source_ip_country": "string"
}, - "retailer": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "reference": "string",
- "website": "string",
- "vat_number": "string",
- "country": "string",
- "notes": "string",
- "status": "active",
- "brand_ids": [
- "string"
], - "allow_original": true,
- "user_count": 0,
- "api_client_count": 0,
- "last_activity_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}, - "invite": {
- "user": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "status": "invited",
- "language": "nl",
- "last_login_at": "2019-08-24T14:15:22Z",
- "invite_expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}, - "expires_at": "2019-08-24T14:15:22Z",
- "email_sent": true
}, - "api_client": {
- "id": "prd_01J9ZK3Q7T5W",
- "client_id": "string",
- "name": "string",
- "retailer_id": "string",
- "scopes": [
- "catalog:read"
], - "status": "active",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
| reason | string or null <= 2000 characters |
{- "reason": "string"
}{- "id": "prd_01J9ZK3Q7T5W",
- "status": "pending",
- "created_at": "2019-08-24T14:15:22Z",
- "decided_at": "2019-08-24T14:15:22Z",
- "reason": "string",
- "retailer": {
- "name": "string",
- "reference": "string",
- "website": "string",
- "vat_number": "string",
- "country": "string"
}, - "contact": {
- "name": "string",
- "email": "string",
- "phone": "string",
- "language": "string"
}, - "access": [
- "portal"
], - "requested_brand_ids": [
- "string"
], - "message": "string",
- "retailer_id": "string",
- "source_ip_country": "string"
}| role | string Enum: "admin" "retailer" |
| retailer_id | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: retailer_id=prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| cursor | string (Cursor) [ 1 .. 4096 ] characters Opaque pagination or feed cursor. Clients MUST NOT parse or construct it. |
| limit | integer [ 1 .. 200 ] Default: 50 |
{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "status": "invited",
- "language": "nl",
- "last_login_at": "2019-08-24T14:15:22Z",
- "invite_expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string"
}409 conflict when the e-mail already has an account on this node. When e-mail is not configured, email_sent is false and the admin copies invite_url manually.
| X-CSRF-Token required | string |
| email required | string <email> (Email) <= 254 characters E-mail address. |
| name | string <= 200 characters |
| role required | string Enum: "admin" "retailer" |
| retailer_id | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Required for role retailer. |
| language | string (LanguageTag) ^[a-z]{2,3}(-[A-Z]{2})?$ BCP 47 language tag, restricted to language or language-REGION. |
{- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "language": "nl"
}{- "user": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "status": "invited",
- "language": "nl",
- "last_login_at": "2019-08-24T14:15:22Z",
- "invite_expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}, - "expires_at": "2019-08-24T14:15:22Z",
- "email_sent": true
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
| name | string <= 200 characters |
| status | string Enum: "active" "blocked" |
{- "name": "string",
- "status": "active"
}{- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "status": "invited",
- "language": "nl",
- "last_login_at": "2019-08-24T14:15:22Z",
- "invite_expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "user": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "role": "admin",
- "retailer_id": "prd_01J9ZK3Q7T5W",
- "status": "invited",
- "language": "nl",
- "last_login_at": "2019-08-24T14:15:22Z",
- "invite_expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}, - "expires_at": "2019-08-24T14:15:22Z",
- "email_sent": true
}| retailer_id | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: retailer_id=prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "client_id": "string",
- "name": "string",
- "retailer_id": "string",
- "scopes": [
- "catalog:read"
], - "status": "active",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}
]
}| X-CSRF-Token required | string |
| retailer_id required | string |
| name required | string [ 1 .. 200 ] characters |
| scopes | Array of strings (Scope) Items Enum: "catalog:read" "media:read" "media:original" "usage:write" Omitted: |
{- "retailer_id": "string",
- "name": "string",
- "scopes": [
- "catalog:read"
]
}{- "client": {
- "id": "prd_01J9ZK3Q7T5W",
- "client_id": "string",
- "name": "string",
- "retailer_id": "string",
- "scopes": [
- "catalog:read"
], - "status": "active",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}, - "client_secret": "string",
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "client": {
- "id": "prd_01J9ZK3Q7T5W",
- "client_id": "string",
- "name": "string",
- "retailer_id": "string",
- "scopes": [
- "catalog:read"
], - "status": "active",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}, - "client_secret": "string",
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "prefix": "string",
- "scopes": [
- "ingest:read"
], - "brand_external_ids": [
- "string"
], - "status": "active",
- "expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}
]
}| X-CSRF-Token required | string |
| name required | string [ 1 .. 200 ] characters |
| scopes required | Array of strings (IngestScope) non-empty Items Enum: "ingest:read" "ingest:write" "ingest:delete" |
| brand_external_ids | Array of strings or null (ExternalId) [ items [ 1 .. 200 ] characters ^[^\x00-\x1F\x7F/]+$ ] |
DateTime (string) or null |
{- "name": "string",
- "scopes": [
- "ingest:read"
], - "brand_external_ids": [
- "KO-1001"
], - "expires_at": "2026-09-28T10:00:00Z"
}{- "token": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "prefix": "string",
- "scopes": [
- "ingest:read"
], - "brand_external_ids": [
- "string"
], - "status": "active",
- "expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}, - "secret": "string",
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "token": {
- "id": "prd_01J9ZK3Q7T5W",
- "name": "string",
- "prefix": "string",
- "scopes": [
- "ingest:read"
], - "brand_external_ids": [
- "string"
], - "status": "active",
- "expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}, - "secret": "string",
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "events": [
- "string"
], - "secret": "string",
- "status": "active",
- "created_at": "2026-09-28T10:00:00Z",
- "last_delivery_at": "2026-09-28T10:00:00Z",
- "last_status": 0
}
]
}Events access_request.created, import_run.completed, ingest_job.completed. Same signing scheme as protocol webhooks. The secret is returned once.
| X-CSRF-Token required | string |
| url required | string <uri> (Url) <= 2048 characters ^https?:// Absolute http(s) URL. |
| events required | Array of strings non-empty Items Enum: "access_request.created" "import_run.completed" "ingest_job.completed" |
{- "events": [
- "access_request.created"
]
}{- "id": "prd_01J9ZK3Q7T5W",
- "events": [
- "string"
], - "secret": "string",
- "status": "active",
- "created_at": "2026-09-28T10:00:00Z",
- "last_delivery_at": "2026-09-28T10:00:00Z",
- "last_status": 0
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
| events | Array of strings |
| status | string Enum: "active" "disabled" |
{- "events": [
- "string"
], - "status": "active"
}{- "id": "prd_01J9ZK3Q7T5W",
- "events": [
- "string"
], - "secret": "string",
- "status": "active",
- "created_at": "2026-09-28T10:00:00Z",
- "last_delivery_at": "2026-09-28T10:00:00Z",
- "last_status": 0
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "id": "string",
- "event_id": "string",
- "event_type": "string",
- "at": "2019-08-24T14:15:22Z",
- "status_code": 0,
- "duration_ms": 0,
- "attempt": 0,
- "success": true,
- "error": "string"
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| cursor | string (Cursor) [ 1 .. 4096 ] characters Opaque pagination or feed cursor. Clients MUST NOT parse or construct it. |
| limit | integer [ 1 .. 200 ] Default: 50 |
{- "items": [
- {
- "id": "string",
- "event_id": "string",
- "event_type": "string",
- "at": "2019-08-24T14:15:22Z",
- "status_code": 0,
- "duration_ms": 0,
- "attempt": 0,
- "success": true,
- "error": "string"
}
], - "next_cursor": "string"
}| days | integer Default: 30 Enum: 7 30 90 365 |
{- "days": 0,
- "totals": {
- "downloads": 0,
- "images": 0,
- "zips": 0,
- "csv_exports": 0,
- "api_downloads": 0,
- "usage_events": 0,
- "active_retailers": 0
}, - "by_day": [
- {
- "date": "2019-08-24",
- "downloads": 0,
- "images": 0
}
], - "top_retailers": [
- {
- "retailer_id": "string",
- "name": "string",
- "downloads": 0,
- "images": 0,
- "last_activity_at": "2019-08-24T14:15:22Z"
}
], - "top_products": [
- {
- "product_id": "string",
- "style_number": "string",
- "name": { },
- "downloads": 0
}
]
}| retailer_id | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: retailer_id=prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| kind | string (DownloadKind) Enum: "image" "product_zip" "selection_zip" "bulk_zip" "csv" "api_rendition" "api_export" "usage" |
| cursor | string (Cursor) [ 1 .. 4096 ] characters Opaque pagination or feed cursor. Clients MUST NOT parse or construct it. |
| limit | integer [ 1 .. 200 ] Default: 50 |
{- "items": [
- {
- "id": "string",
- "at": "2019-08-24T14:15:22Z",
- "kind": "image",
- "retailer_id": "string",
- "retailer_name": "string",
- "actor_type": "user",
- "actor_name": "string",
- "variant": "original",
- "product_id": "string",
- "asset_id": "string",
- "usage_event": "string",
- "files": 0,
- "bytes": 0
}
], - "next_cursor": "string"
}{- "preview": true,
- "retailer": {
- "id": "string",
- "name": "string"
}, - "brands": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "name": "string",
- "description": { },
- "updated_at": "2026-09-28T10:00:00Z"
}
], - "permissions": {
- "original_download": true,
- "article_data_export": true,
- "api_self_service": true
}, - "branding": {
- "name": "string",
- "logo_url": "string",
- "accent_color": "string",
- "welcome_text": { },
- "portal_name": { },
- "languages": [
- "nl"
], - "default_language": "nl",
- "access_requests_enabled": true,
- "setup_required": true,
- "brands": [
- {
- "id": "string",
- "name": "string"
}
]
}, - "languages": [
- "nl"
], - "selection_count": 0,
- "limits": {
- "selection_max_products": 1000,
- "sync_zip_max_images": 400,
- "gtin_lookup_max": 2000
}
}| q | string <= 200 characters Style number, name, colour, GTIN or SKU. |
| brand_id | Array of strings |
| item_type | Array of strings |
| color | Array of strings Colour code. |
| season | Array of strings |
| collection | Array of strings |
| target_group | Array of strings |
| updated_since | string <date-time> "New since": products that got new/changed data or images since this time. |
{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "style_number": "string",
- "name": { },
- "brand": {
- "id": "string",
- "name": "string"
}, - "item_type": "string",
- "target_group": "string",
- "season": "string",
- "collection": "string",
- "image_count": 0,
- "variant_count": 0,
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string",
- "total": 0
}| q | string <= 200 characters Style number, name, colour, GTIN or SKU. |
| brand_id | Array of strings |
| item_type | Array of strings |
| color | Array of strings Colour code. |
| season | Array of strings |
| collection | Array of strings |
| target_group | Array of strings |
| updated_since | string <date-time> "New since": products that got new/changed data or images since this time. |
{- "brands": [
- {
- "value": "string",
- "label": "string",
- "count": 0
}
], - "item_types": [
- {
- "value": "string",
- "label": "string",
- "count": 0
}
], - "colors": [
- {
- "value": "string",
- "label": "string",
- "count": 0
}
], - "seasons": [
- {
- "value": "string",
- "label": "string",
- "count": 0
}
], - "collections": [
- {
- "value": "string",
- "label": "string",
- "count": 0
}
], - "target_groups": [
- {
- "value": "string",
- "label": "string",
- "count": 0
}
]
}Rendition URLs are signed and usable directly in an <img> element. original only when the viewer may download originals.
| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
{- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "brand_id": "prd_01J9ZK3Q7T5W",
- "style_number": "string",
- "name": { },
- "description": { },
- "item_type": "string",
- "gpc_brick": "string",
- "target_group": "string",
- "season": "string",
- "collection": "string",
- "materials": [
- {
- "part": "main",
- "fibers": [
- {
- "fiber": "string",
- "percentage": 1
}
]
}
], - "care": [
- {
- "code": "string",
- "text": { }
}
], - "country_of_origin": "NL",
- "attributes": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-09-28T10:00:00Z",
- "updated_at": "2026-09-28T10:00:00Z",
- "variants": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "product_id": "prd_01J9ZK3Q7T5W",
- "brand_id": "prd_01J9ZK3Q7T5W",
- "gtin": "02000010010011",
- "gtin_original": "2000010010011",
- "sku": "string",
- "color": {
- "code": "string",
- "name": { },
- "supplier_color": "string"
}, - "size": "string",
- "size_system": "string",
- "updated_at": "2026-09-28T10:00:00Z"
}
], - "assets": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "product_id": "prd_01J9ZK3Q7T5W",
- "brand_id": "prd_01J9ZK3Q7T5W",
- "media_type": "image",
- "color_code": "string",
- "variant_ids": [
- "prd_01J9ZK3Q7T5W"
], - "role": "packshot",
- "view": "front",
- "position": 1,
- "filename": "string",
- "alt_text": { },
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string",
- "rights": {
- "license": "retailer-use",
- "license_text": "string",
- "channels": [
- "webshop"
], - "territories": [
- "NL"
], - "embargo_until": "2026-09-28T10:00:00Z",
- "expires_at": "2026-09-28T10:00:00Z",
- "credit": "string",
- "model_release": true
}, - "provenance": {
- "ai_generated": true,
- "ai_edited": true,
- "source": "photo",
- "c2pa": "embedded",
- "generator": "string"
}, - "renditions": {
- "original": {
- "name": "original",
- "url_expires_at": "2026-09-28T10:00:00Z",
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string"
}, - "web": {
- "name": "original",
- "url_expires_at": "2026-09-28T10:00:00Z",
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string"
}, - "square": {
- "name": "original",
- "url_expires_at": "2026-09-28T10:00:00Z",
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string"
}, - "thumb": {
- "name": "original",
- "url_expires_at": "2026-09-28T10:00:00Z",
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string"
}
}, - "updated_at": "2026-09-28T10:00:00Z"
}
]
}text is split on anything that is not a digit (newlines, commas, semicolons, tabs, spaces between codes are all fine) - or send gtins. Same result shape and matching rules as the protocol by-GTIN lookup.
| X-CSRF-Token required | string |
| text | string <= 100000 characters |
| gtins | Array of strings <= 2000 items [ items <= 64 characters ] |
{- "text": "string",
- "gtins": [
- "string"
]
}{- "results": [
- {
- "input": "string",
- "gtin": "02000010010011",
- "status": "matched",
- "product_id": "prd_01J9ZK3Q7T5W",
- "variant_id": "prd_01J9ZK3Q7T5W"
}
], - "products": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "brand_id": "prd_01J9ZK3Q7T5W",
- "style_number": "string",
- "name": { },
- "description": { },
- "item_type": "string",
- "gpc_brick": "string",
- "target_group": "string",
- "season": "string",
- "collection": "string",
- "materials": [
- {
- "part": "main",
- "fibers": [
- {
- "fiber": "string",
- "percentage": 1
}
]
}
], - "care": [
- {
- "code": "string",
- "text": { }
}
], - "country_of_origin": "NL",
- "attributes": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-09-28T10:00:00Z",
- "updated_at": "2026-09-28T10:00:00Z",
- "variants": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "product_id": "prd_01J9ZK3Q7T5W",
- "brand_id": "prd_01J9ZK3Q7T5W",
- "gtin": "02000010010011",
- "gtin_original": "2000010010011",
- "sku": "string",
- "color": {
- "code": "string",
- "name": { },
- "supplier_color": "string"
}, - "size": "string",
- "size_system": "string",
- "updated_at": "2026-09-28T10:00:00Z"
}
], - "assets": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "external_id": "KO-1001",
- "product_id": "prd_01J9ZK3Q7T5W",
- "brand_id": "prd_01J9ZK3Q7T5W",
- "media_type": "image",
- "color_code": "string",
- "variant_ids": [
- "prd_01J9ZK3Q7T5W"
], - "role": "packshot",
- "view": "front",
- "position": 1,
- "filename": "string",
- "alt_text": { },
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string",
- "rights": {
- "license": "retailer-use",
- "license_text": "string",
- "channels": [
- "webshop"
], - "territories": [
- "NL"
], - "embargo_until": "2026-09-28T10:00:00Z",
- "expires_at": "2026-09-28T10:00:00Z",
- "credit": "string",
- "model_release": true
}, - "provenance": {
- "ai_generated": true,
- "ai_edited": true,
- "source": "photo",
- "c2pa": "embedded",
- "generator": "string"
}, - "renditions": {
- "original": {
- "name": "original",
- "url_expires_at": "2026-09-28T10:00:00Z",
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string"
}, - "web": {
- "name": "original",
- "url_expires_at": "2026-09-28T10:00:00Z",
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string"
}, - "square": {
- "name": "original",
- "url_expires_at": "2026-09-28T10:00:00Z",
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string"
}, - "thumb": {
- "name": "original",
- "url_expires_at": "2026-09-28T10:00:00Z",
- "content_type": "image/jpeg",
- "width": 1,
- "height": 1,
- "bytes": 1,
- "sha256": "string"
}
}, - "updated_at": "2026-09-28T10:00:00Z"
}
]
}
]
}| X-CSRF-Token required | string |
| product_ids required | Array of strings (Id) <= 1000 items unique [ items^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ ] |
{- "product_ids": [
- "prd_01J9ZK3Q7T5W"
]
}{- "product_ids": [
- "prd_01J9ZK3Q7T5W"
], - "image_count": 0,
- "updated_at": "2019-08-24T14:15:22Z"
}{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}Content-Disposition: attachment. 403 original_not_allowed for original when not permitted.
| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| variant | string Enum: "original" "web" "square" Default original when allowed, else web. |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| variant | string Enum: "original" "web" "square" Default original when allowed, else web. |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}| variant | string Enum: "original" "web" "square" Default original when allowed, else web. |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}Canonical CSV columns (docs/import-format.md) plus image_files. 403 when the brand disabled article data export.
| delimiter | string Default: "comma" Enum: "comma" "semicolon" The UI uses semicolon for Dutch users (Excel), comma otherwise. |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}| q | string |
| brand_id | Array of strings |
| updated_since | string <date-time> |
| delimiter | string Default: "comma" Enum: "comma" "semicolon" The UI uses semicolon for Dutch users (Excel), comma otherwise. |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "status": "queued",
- "source": "selection",
- "variant": "original",
- "include_data_csv": true,
- "created_at": "2019-08-24T14:15:22Z",
- "finished_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z",
- "progress": {
- "done": 0,
- "total": 0
}, - "file_url": "string",
- "bytes": 0,
- "files": 0,
- "error": "string"
}
]
}Max 2 running jobs per user (409). When finished the node e-mails the user (if mail is configured) and the job shows a download link. Files are kept 7 days.
| X-CSRF-Token required | string |
| source required | string Enum: "selection" "products" "filter" |
| product_ids | Array of strings <= 10000 items For source products (e.g. matches of an EAN list). |
object For source filter; same keys as the portal product filters. | |
| variant required | string Enum: "original" "web" "square" |
| include_data_csv | boolean Default: true |
{- "source": "selection",
- "product_ids": [
- "string"
], - "filter": {
- "q": "string",
- "brand_id": [
- "string"
], - "item_type": [
- "string"
], - "color": [
- "string"
], - "season": [
- "string"
], - "collection": [
- "string"
], - "target_group": [
- "string"
], - "updated_since": "2019-08-24T14:15:22Z"
}, - "variant": "original",
- "include_data_csv": true
}{- "id": "prd_01J9ZK3Q7T5W",
- "status": "queued",
- "source": "selection",
- "variant": "original",
- "include_data_csv": true,
- "created_at": "2019-08-24T14:15:22Z",
- "finished_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z",
- "progress": {
- "done": 0,
- "total": 0
}, - "file_url": "string",
- "bytes": 0,
- "files": 0,
- "error": "string"
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
{- "id": "prd_01J9ZK3Q7T5W",
- "status": "queued",
- "source": "selection",
- "variant": "original",
- "include_data_csv": true,
- "created_at": "2019-08-24T14:15:22Z",
- "finished_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z",
- "progress": {
- "done": 0,
- "total": 0
}, - "file_url": "string",
- "bytes": 0,
- "files": 0,
- "error": "string"
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}{- "items": [
- {
- "id": "prd_01J9ZK3Q7T5W",
- "client_id": "string",
- "name": "string",
- "retailer_id": "string",
- "scopes": [
- "catalog:read"
], - "status": "active",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}
]
}403 forbidden when portal.retailer_api_self_service is off. Scopes are limited to the retailer's grant. Max 5 active clients per retailer.
| X-CSRF-Token required | string |
| name required | string [ 1 .. 200 ] characters |
| scopes | Array of strings (Scope) Items Enum: "catalog:read" "media:read" "media:original" "usage:write" Omitted = the same defaults as ApiClientInput.scopes. |
{- "name": "string",
- "scopes": [
- "catalog:read"
]
}{- "client": {
- "id": "prd_01J9ZK3Q7T5W",
- "client_id": "string",
- "name": "string",
- "retailer_id": "string",
- "scopes": [
- "catalog:read"
], - "status": "active",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}, - "client_secret": "string",
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "client": {
- "id": "prd_01J9ZK3Q7T5W",
- "client_id": "string",
- "name": "string",
- "retailer_id": "string",
- "scopes": [
- "catalog:read"
], - "status": "active",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}, - "client_secret": "string",
}| id required | string (Id) ^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$ Examples: prd_01J9ZK3Q7T5W Opaque, node-assigned identifier. Stable for the life of the object. Consumers MUST treat it as opaque. |
| X-CSRF-Token required | string |
{- "title": "string",
- "status": 400,
- "detail": "string",
- "instance": "string",
- "obx_error": "invalid_request",
- "errors": [
- {
- "pointer": "string",
- "obx_error": "invalid_request",
- "detail": "string"
}
], - "retry_after": 0
}