Skip to main content

Content Requests

What is a content request?

A content request is your proposal to create or update a product, a brand or a manufacturer in the catalog. You submit it with the createContentRequest mutation.

  • The request is created in a pending state and is reviewed by the marketplace team before any catalog change is applied.
  • The mutation returns 202 Accepted — it does not change the catalog immediately.
  • The id you send is also the idempotency key: sending the same id again will not create a duplicate.

The mutation

mutation CreateContentRequest($input: CreateContentRequestInput!) {
createContentRequest(input: $input) {
code
message
}
}

The input has four fields:

FieldRequiredDescription
idA UUID you generate. Also the idempotency key.
resourceType"product", "brand" or "manufacturer".
operation"create" or "update".
payloadThe resource fields. See the payload sections below.

⚠️ Important rules — please read

  • Use only the field names listed for each resource. Do not invent fields — anything that is not in the contract will not be processed.
  • On create you must include every mandatory field (marked ✅ below).
  • On update send only the identifier (ean for a product, brand_id for a brand, manufacturer_id for a manufacturer) plus the fields you want to change.
  • A brand cannot exist without a manufacturer: a brand create requires manufacturer_id. If the manufacturer does not exist yet, create the manufacturer first with its own content request, wait for its approval, then create the brand.
  • A manufacturer create must NOT include manufacturer_id — sending one means an update.
  • Field names and shapes must match exactly (e.g. category_id, not main_category).

Errors

When a content request is not accepted, the mutation does not return code/message — the response contains a GraphQL errors entry with extensions.code: "BAD_REQUEST" and a descriptive message:

{
"errors": [
{
"message": "There is already an identical pending content request",
"extensions": { "code": "BAD_REQUEST" }
}
],
"data": null
}

These are the two most common rejections:

There is already an identical pending content request

You already have a pending content request with the same resourceType, the same operation and an identical payload. The new request is not created.

  • Wait for the pending request to be reviewed, or change the payload if you actually want to submit something different.
  • This is different from resending the same id: resending an id you already used is idempotent and simply returns 202 Accepted without creating anything.

You have submitted too many changes for product 4262493171667 today

You can submit one content request per resource per day (today is the calendar day in German time, Europe/Berlin). The resource is identified by the product EAN, the brand or the manufacturer, per resourceType — so on the same day you can still submit requests for other products, brands or manufacturers, or for the same EAN as a different resource type.

  • The message includes the resource type and identifier, e.g. You have submitted too many changes for brand Premium Healthcare today.
  • Requests that were automatically rejected (for example with rejection reason unsupported_video) do not count towards the limit: you can fix the payload and resubmit the same day.
  • If you hit the limit, batch your changes into a single request and resubmit the next day.

Product payload fields

For resourceType: "product". The fields are grouped by what they affect: Product, Enrichment (descriptive texts) and Media. For brand and manufacturer requests see the Brand content requests and Manufacturer content requests sections below.

Product

FieldRequired on createTypeAllowed values / notes
eanstringProduct EAN. Identifies the product.
product_namestringMust not contain dosage or size information
sales_typestringBPC or OTC
brand_idstring (UUID)
manufacturer_idstring (UUID)
category_idstring (UUID)
vatarrayInform { vat_country, vat_type }. vat_type: for VAT 0% inform ZERO, for VAT 7% inform R1, for VAT 19% inform GENERAL
recommended_pricesarrayInform { value, rrp_currency, rrp_origin }. For rrp_origin, the value must be entered in uppercase. If the value has been provided by an official source inform OFFICIAL, otherwise inform UNKNOWN
net_weightnumberValue in grams (gr)
net_volumenumberValue in millilitres (ml)
alternative_package_size_quantitystring
alternative_package_size_unitstringcm, Fl, g, kg, l, m, mg, ml, P, Sp, St, µg, Set
alternative_dose_formstring
food_supplementboolean
is_cosmetic_productboolean
is_cbdboolean
dangerous_goodsboolean
is_electronic_deviceboolean
uses_batteriesboolean

Enrichment (descriptive texts — all optional)

FieldTypeNotes
sub_headlinestringShort subtitle shown under the product name
marketingstringHTML allowed
how_to_usestringHTML allowed
compositionstringHTML allowed
advicestringHTML allowed
safety_informationstringHTML allowed
usp_onestringMax 150 characters
usp_twostringMax 150 characters
usp_threestringMax 150 characters
keywordsarray of stringsMax 15 keywords, 50 chars each

When you send a descriptive text (for example a sub_headline), its content source is recorded as marketplace.

Media (optional)

medias is an array (up to 12 entries). If you include it, every item must have all three fields:

FieldRequired (per item)TypeAllowed values / notes
typestringimage, video, leaflet, biocide, lmiv
resourcestring (URL)Public URL we can download. For video, it must be a YouTube link (youtube.com, youtu.be or youtube-nocookie.com).
positioninteger0 = main image, 17 = additional images; non-image types use 0; only one video
Videos must be hosted on YouTube

If a video entry points to any other host, the content request is automatically rejected with rejection reason unsupported_video. You will see it as REJECTED in the sellerContentRequests query.

Mandatory on create (quick summary)

ean, product_name, sales_type, brand_id, manufacturer_id, category_id, vat (with a vat_type), recommended_prices (with value, rrp_currency). If you send medias, each item needs type, resource and position.

On update: only ean + the fields you change.

Examples

Create

mutation CreateContentRequest($input: CreateContentRequestInput!) {
createContentRequest(input: $input) {
code
message
}
}

Variables:

{
"input": {
"id": "b3f1c2a4-5d6e-4f70-8a91-2c3d4e5f6071",
"resourceType": "product",
"operation": "create",
"payload": {
"ean": "4262493171667",
"product_name": "supplenatura® Citicolin",
"sales_type": "BPC",
"brand_id": "507f5e47-363e-4206-a42c-c3cafb61a31c",
"manufacturer_id": "cd45a842-4f4d-4580-8e63-fb81100e95a6",
"category_id": "0c2a1b3c-4d5e-6f70-8a91-2c3d4e5f6071",
"vat": [
{ "vat_country": "DE", "vat_type": "GENERAL" }
],
"recommended_prices": [
{ "value": 29.99, "rrp_currency": "EUR", "rrp_origin": "OFFICIAL" }
],
"net_weight": 189,
"alternative_package_size_quantity": "540",
"alternative_package_size_unit": "St",
"alternative_dose_form": "Kapseln",
"food_supplement": true,
"is_cosmetic_product": false,
"is_cbd": false,
"dangerous_goods": false,
"is_electronic_device": false,
"uses_batteries": false,
"sub_headline": "Nahrungsergänzungsmittel mit Citicolin",
"marketing": "Citicolin – biochemisch bekannt als CDP-Cholin …",
"how_to_use": "Täglich 1 Kapsel mit Wasser einnehmen.",
"composition": "Citicolin (CDP-Cholin), Kapselhülle …",
"usp_one": "250 mg CDP-Cholin pro Kapsel",
"usp_two": "6 Monate Vorrat",
"usp_three": "Nur 2 Zutaten",
"keywords": ["Citicolin", "CDP-Cholin", "Citicoline Kapseln"],
"medias": [
{ "type": "image", "resource": "https://cdn.seller.com/citicolin/main.jpg", "position": 0 },
{ "type": "image", "resource": "https://cdn.seller.com/citicolin/front.jpg", "position": 1 },
{ "type": "video", "resource": "https://www.youtube.com/watch?v=aBcDeFgHiJk", "position": 0 },
{ "type": "leaflet", "resource": "https://cdn.seller.com/citicolin/otc.pdf", "position": 0 }
]
}
}
}

Update

Send ean to identify the product, then only the fields you want to change:

{
"input": {
"id": "9b2d7e10-3a4b-4c5d-8e9f-1a2b3c4d5e6f",
"resourceType": "product",
"operation": "update",
"payload": {
"ean": "4262493171667",
"product_name": "supplenatura® Citicolin Kapseln",
"recommended_prices": [
{ "value": 27.99, "rrp_currency": "EUR", "rrp_origin": "OFFICIAL" }
]
}
}
}

Response

{
"data": {
"createContentRequest": {
"code": 202,
"message": "Accepted"
}
}
}

Brand content requests

Create

Propose a new brand. Set resourceType: "brand" and operation: "create". A brand cannot exist without a manufacturer, so manufacturer_id is mandatory — if the manufacturer does not exist yet, create it first with its own content request.

FieldRequiredTypeNotes
brand_namestringThe name of the new brand.
manufacturer_idstring (UUID)The brand's manufacturer. It must already exist.
brand_logostring (URL)Public image URL (jpg, jpeg, png). Applied right after the brand is created.

Example

{
"input": {
"id": "6c2c2509-8190-4c3e-9d4f-708192030415",
"resourceType": "brand",
"operation": "create",
"payload": {
"brand_name": "Premium Healthcare",
"manufacturer_id": "cd45a842-4f4d-4580-8e63-fb81100e95a6",
"brand_logo": "https://cdn.seller.com/brands/premium-healthcare.png"
}
}
}

Update

Propose an update to an existing brand. Set resourceType: "brand" and operation: "update"; the brand is identified by brand_id. Send brand_id plus at least one field you want to change.

FieldRequiredTypeNotes
brand_idstring (UUID)The brand to update.
brand_namestring
manufacturer_idstring (UUID)Link the brand to this manufacturer.
brand_logostring (URL)Public image URL (jpg, jpeg, png). Send #DELETE# to remove it.

Example

{
"input": {
"id": "3f7c1a90-2b4d-4e6f-8a01-b2c3d4e5f601",
"resourceType": "brand",
"operation": "update",
"payload": {
"brand_id": "44d9212d-0c27-4289-802e-4f07b6576694",
"brand_name": "Premium Healthcare",
"manufacturer_id": "cd45a842-4f4d-4580-8e63-fb81100e95a6",
"brand_logo": "https://cdn.seller.com/brands/premium-healthcare.png"
}
}
}

Manufacturer content requests

Create

Propose a new manufacturer. Set resourceType: "manufacturer" and operation: "create". Do not include manufacturer_id — the id is assigned when the request is approved (you can read it from affectedResourceId in sellerContentRequests). A manufacturer create must include its address: street, zip code, city, country and a contact email.

FieldRequiredTypeNotes
manufacturer_namestringThe name of the new manufacturer.
address_streetstringe.g. Luise-Ullrich-Str
address_street_numberstringe.g. 20
address_zip_codestringe.g. 10789
address_citystringe.g. Berlin
address_countrystringe.g. Germany
address_contact_personstringe.g. Dr. Mueller
address_emailstringe.g. berlin@isdin.com
address_phone_numberstringe.g. +49 30 12345678
address_websitestringe.g. https://www.isdin.com
address_imprint_urlstringe.g. https://www.isdin.com/de/kontakt

The address source is recorded as marketplace.

Example

{
"input": {
"id": "8e4e472b-a3b2-4e50-9f61-920304152637",
"resourceType": "manufacturer",
"operation": "create",
"payload": {
"manufacturer_name": "ISDIN GmbH",
"address_street": "Luise-Ullrich-Str",
"address_street_number": "20",
"address_zip_code": "10789",
"address_city": "Berlin",
"address_country": "Germany",
"address_email": "berlin@isdin.com"
}
}
}

Update

Propose an update to an existing manufacturer. Set resourceType: "manufacturer" and operation: "update"; the manufacturer is identified by manufacturer_id. Send manufacturer_id plus at least one field you want to change.

FieldRequiredTypeNotes
manufacturer_idstring (UUID)The manufacturer to update.
manufacturer_namestring
address_streetstring
address_street_numberstring
address_zip_codestring
address_citystring
address_countrystring
address_contact_personstring
address_emailstring
address_phone_numberstring
address_websitestring
address_imprint_urlstring

If you send any address_* field, the address source is recorded as marketplace.

Example

{
"input": {
"id": "5b1b14f8-708f-4b2d-8c3e-6f7081920304",
"resourceType": "manufacturer",
"operation": "update",
"payload": {
"manufacturer_id": "0d780958-8176-4e20-8e8d-ce2af1a5dd32",
"manufacturer_name": "ISDIN GmbH",
"address_street": "Luise-Ullrich-Str",
"address_street_number": "20",
"address_zip_code": "10789",
"address_city": "Berlin",
"address_country": "Germany"
}
}
}

Checking your content requests

Use the sellerContentRequests query to retrieve the content requests you have submitted, with their full detail in a single call — status, review date, rejection reason, the id of the product created on approval, and the original payload. There is no need to fetch each request separately.

query SellerContentRequests($status: ContentRequestStatus, $page: Int, $size: Int) {
sellerContentRequests(status: $status, sortDirection: DESC, page: $page, size: $size) {
metadata {
totalItems
totalPages
currentPage
}
collection {
id
resourceType
operation
status
referenceCode
referenceName
requestDate
reviewDate
rejectionReason
affectedResourceId
payload
}
}
}

Arguments

ArgumentRequiredDescription
statusFilter by status: PENDING, APPROVED or REJECTED. Omit to get all yours.
sortDirectionASC or DESC by request date (default DESC).
pageThe page to fetch (default 1).
sizeThe page size.

Item fields

FieldDescription
idThe content request id (the UUID you supplied on create).
operationCREATE or UPDATE.
statusPENDING, APPROVED or REJECTED.
referenceCodeThe resource identifier: product EAN, or brand_id / manufacturer_id.
referenceNameThe resource name: product name, or brand / manufacturer name.
requestDateWhen you submitted the request.
reviewDateWhen it was reviewed (null while pending).
rejectionReasonWhy it was rejected (only present when REJECTED). See Rejection reasons.
affectedResourceIdThe id of the product, brand or manufacturer created/updated on approval (null otherwise).
payloadThe payload exactly as you submitted it.

Example response

{
"data": {
"sellerContentRequests": {
"metadata": { "totalItems": 2, "totalPages": 1, "currentPage": 1 },
"collection": [
{
"id": "b3f1c2a4-5d6e-4f70-8a91-2c3d4e5f6071",
"resourceType": "product",
"operation": "CREATE",
"status": "APPROVED",
"referenceCode": "4262493171667",
"referenceName": "supplenatura® Citicolin",
"requestDate": "2026-06-30 12:22:39",
"reviewDate": "2026-07-01 12:21:17",
"rejectionReason": null,
"affectedResourceId": "c7f46fb9-b396-423c-90b6-d4cad26694cb",
"payload": { "ean": "4262493171667", "product_name": "supplenatura® Citicolin" }
}
]
}
}
}

Rejection reasons

When a content request is REJECTED, the rejectionReason field tells you why:

Rejection reasonDescription
duplicated_requestThe same request has already been submitted by this or another seller.
forbidden_productThe product is inappropriate for the marketplace (for example: sexually explicit).
incorrect_manufacturer_or_brandThe manufacturer and the brand informed do not match.
incorrect_categoryThe category informed does not match.
inconsistent_contentThe product's name, image and texts are not coherent.
wrong_languageThe content is not in German language.
bad_quality_imageThe image does not meet the minimum image quality requirements.
unsupported_videoThe video link does not belong to YouTube.
assortmentThe product does not fit the DocMorris assortment.
otherMost common: wrong recommended price, net weight/volume, alternative_package_size_quantity.
note

In case of doubt, reach out to the Marketplace Catalog Team (marktplatzkatalog@docmorris.de) and they will provide further details on rejections.