Download OpenAPI specification:
Ingestion API is used to upload ONIX metadata and supporting resources for distribution.
An API key and a set of credentials (email and password) must be used to authenticate. Use the auth api to get the short-lived token needed to call the ingestion api endpoints.
Using Publizon's sample generator:
POST /onix/uploadPUT {supporting resource upload signed link}GET /status/{isbn}POST /sample/generateGET /status/{isbn}Uploading custom sample:
POST /onix/uploadPUT {supporting resource upload signed link}GET /status/{isbn}Validate onix 3.0 file against official editeur xsd schemas.
The maximum number of products allowed per request is 50.
https://www.editeur.org/93/release-3.0-downloads/#Specifications
By default, strict onix validation is performed. In order to disable strict validation, the query param disableStrictValidation must be set to true: /onix/validate?disableStrictValidation=true.
If a detailed per-product validation is needed, the query param enablePerProductValidation must be set to true. When enablePerProductValidation is true the following information is included in the response:
Besides validation against editeur XSD files, the following custom rules are validated:
Ebooks and Audiobooks must contain either an ISBN13 or a GTIN13 identifier. This is, a ProductIdentifier element with ProductIDType 15 or 03.
When creating/updating products, it is required to provide a PrimaryContentType tag for each product with one of the following values (codelist 81):
10 or 490113It is required to define an author for each onix product with NotificationType 01, 02 or 03. The author may be a person, corporate name or even an unnamed person(s).
One Publisher with PublishingRole 01 and PublisherName is required for each product with NotificationType 01, 02 or 03. For example:
<Publisher>
<PublishingRole>01</PublishingRole>
<PublisherName>Publisher name</PublisherName>
</Publisher>
It is required to define a distinctive title for each product at product level. This is, a TitleDetail element with TitleType = 01 and TitleElementLevel = 01. For example:
<TitleDetail>
<TitleType>01</TitleType>
<TitleElement>
<TitleElementLevel>01</TitleElementLevel>
<TitlePrefix>The</TitlePrefix>
<TitleWithoutPrefix>Princess Who Fixed the Bridge</TitleWithoutPrefix>
</TitleElement>
</TitleDetail>
A ProductSupply that includes a market definition with SalesRestrictionType 03 is treated as the default ProductSupply. There can be at most one default ProductSupply per product.
| disableStrictValidation | boolean |
| enablePerProductValidation | boolean |
{- "valid": true,
- "details": {
- "9780566622083": [ ],
- "9788740039030": [ ],
- "9788727110622": [ ],
- "9788727147437": [ ],
- "9788775937578": [ ],
- "9788702431353": [ ],
- "9788711791769": [ ]
}, - "validProducts": [
- "9780566622083",
- "9788740039030",
- "9788727110622",
- "9788727147437",
- "9788775937578",
- "9788702431353",
- "9788711791769"
], - "invalidProducts": [ ]
}Upload ONIX 3.0 products metadata and optionally request signed URLs to upload supporting resources. This endpoint can be used to create new products or update existing ones.
The maximum number of products allowed per request is 50.
By default, strict onix validation is performed. In order to disable strict validation, the query param disableStrictValidation must be set to true: `/onix/validate?disableStrictValidation=true.
Additionally, by default, the entire onix file is validated as a whole. If any single product in the batch is invalid, the entire import is aborted and a 422 Unprocessable Entity status is returned.
To change this behavior, set the query parameter enablePerProductValidation to true. When this is enabled, invalid products will be skipped, and only the valid ones will be imported. The response will include
detailed information about which products were successfully created, which were skipped, and the specific validation errors for each failed product.
Note: Enabling per-product validation can significantly increase the processing time of the request.
When NotificationType is 01 or 02, the product may be distributed without any supporting resource. When the NotificationType is 03, the product will not be distributed until is complete (FullContent and FrontCover files are uploaded).
Content is considered "active" only if Publishing Status is set to one of: "02" (Forthcoming) or "04" (Active) and NotificationType is not 05.
When creating/updating products, it is required to provide a PrimaryContentType tag for each product with one of the following values (codelist 81):
10 or 490113Ebooks and Audiobooks must contain either an ISBN13 or a GTIN13 identifier. This is, a ProductIdentifier element with ProductIDType 15 or 03.
It is required to define an author for each onix product with NotificationType 01, 02 or 03. The author may be a person, corporate name or even an unnamed person(s).
One Publisher with PublishingRole 01 and PublisherName is required for each product with NotificationType 01, 02 or 03. For example:
<Publisher>
<PublishingRole>01</PublishingRole>
<PublisherName>Publisher name</PublisherName>
</Publisher>
It is required to define a distinctive title for each product at product level. This is, a TitleDetail element with TitleType = 01 and TitleElementLevel = 01. For example:
<TitleDetail>
<TitleType>01</TitleType>
<TitleElement>
<TitleElementLevel>01</TitleElementLevel>
<TitlePrefix>The</TitlePrefix>
<TitleWithoutPrefix>Princess Who Fixed the Bridge</TitleWithoutPrefix>
</TitleElement>
</TitleDetail>
In order to set dates, prices or activate/deactivate content for a specific receiver, the ProductSupply element must be used.
ProductSupply element. The receiver ID is defined in ProductSupply > Market > SalesRestriction > SalesOutlet > SalesOutletIdentifier.SalesOutletIDType is set to '03' (ONIX retail sales outlet ID code).ProductSupply > MarketPublishingDetail > MarketPublishingStatus. Only the values '04' (active) and '02' (forthcoming) will activate the product for the receiver. Any other value will deactivate it.NotificationType=05) will be sent to the receiver.ProductSupply > SupplyDetail.ProductSupply > MarketPublishingDetail > MarketDate. If there are no specific dates for the receiver, global dates must be defined in the ONIX metadata. Global dates are defined in the PublishingDetail block.
Only the dates that differ from "global" dates must be defined for the receiver. There is no need to define specific dates for the receiver when they are the same as the global dates.Example active ProductSupply for receiver BMA with specific prices and dates:
<ProductSupply>
<Market>
<Territory>
<RegionsIncluded>WORLD</RegionsIncluded>
</Territory>
<SalesRestriction>
<SalesRestrictionType>01</SalesRestrictionType>
<SalesOutlet>
<SalesOutletIdentifier>
<SalesOutletIDType>03</SalesOutletIDType>
<IDValue>BMA</IDValue>
</SalesOutletIdentifier>
</SalesOutlet>
</SalesRestriction>
</Market>
<MarketPublishingDetail>
<MarketPublishingStatus>04</MarketPublishingStatus> <!-- ACTIVE -->
<MarketDate>
<MarketDateRole>02</MarketDateRole>
<Date dateformat="00">20241009</Date> <!-- THIS DATE IS ONLY FOR THIS RECEIVER -->
</MarketDate>
</MarketPublishingDetail>
<SupplyDetail>
<Supplier>
<SupplierRole>00</SupplierRole>
<SupplierName>Supplier</SupplierName>
</Supplier>
<ProductAvailability>20</ProductAvailability>
<Price>
<PriceType>01</PriceType>
<PriceAmount>15</PriceAmount>
<CurrencyCode>USD</CurrencyCode>
</Price>
<Price>
<PriceType>05</PriceType>
<PriceAmount>100.00</PriceAmount>
<CurrencyCode>DKK</CurrencyCode>
</Price>
</SupplyDetail>
</ProductSupply>
A ProductSupply that includes a market definition with SalesRestrictionType 03 is treated as the default ProductSupply. There can be at most one default ProductSupply per product.
This default ProductSupply may define a default net price (Price element with PriceType '05'), but it is not distributed to receivers and is intended for internal use only.
The default net price can be combined with automation rules in the UI to set prices for different receivers. For example, if a product has a net price of 10, and there is an automation rule that applies a markup factor of 1.5 for sales channel X, then sales channel X will receive a price of 15.
Example:
<ProductSupply>
<Market>
<Territory>
<RegionsIncluded>WORLD</RegionsIncluded>
</Territory>
<SalesRestriction>
<SalesRestrictionType>03</SalesRestrictionType>
</SalesRestriction>
</Market>
<SupplyDetail>
<Supplier>
<SupplierRole>00</SupplierRole>
<SupplierName>Default Supplier</SupplierName>
</Supplier>
<ProductAvailability>20</ProductAvailability>
<Price>
<PriceType>05</PriceType> <!-- Publisher's net price, excluding tax -->
<PriceAmount>120.00</PriceAmount>
<CurrencyCode>DKK</CurrencyCode>
</Price>
</SupplyDetail>
</ProductSupply>
There can be up to 1 default product supply per product. Validation will not pass otherwise.
The request body must be a JSON with the following keys:
onixProducts: A string containing the ONIX metadata.resourceContentTypes: An optional map used to request signed URLs for uploading supporting resources for the products present in the uploaded ONIX metadata."resourceContentTypes": {
"9780801003608": ["01", "02", "28"],
"9788743518310": ["01"],
"9788743518327": ["01", "28"],
"9788743518334": ["01", "28"],
"9788743518358": ["28"],
"9788743517849": ["01"],
"9788743518228": ["15"]
},
It is not mandatory to specify a list of ResourceContentType for every product in the ONIX metadata, only for those products requiring a supporting resource upload.
Signed links can also be generated later using the /supporting-resources/generate-upload-signed-url endpoint.
When ONIX metadata is uploaded, the response includes the following data for each product:
WaitingForFiles: Product created/updated but not ready for distribution until FullContent and FrontCover supporting resources are uploaded.Created: A new product has been created and it is complete for distribution.Updated: An existing Product has been updated.Failed: The product update or creation failed.A product is considered complete for distribution when:
FullContent, and FrontCover supporting resources must be uploaded.A map where the keys correspond to ResourceContentType ONIX codelist, and the values are signed URLs that can be used to upload the supporting resources. This map includes only the resource content types for the ISBNs specified in the request.
A list of ONIX Retail sales outlet ID to identify active/inactive receivers after the metadata update. Active receivers will get an onix file with the NotificationType 01,02 or 03 depending on the uploaded ONIX metadata. Inactive receivers will get a NotificationType 05 meaning they must delete the product from their system.
Before uploading a file using a signed URL, consider the following:
/supporting-resources/generate-upload-signed-url endpoint.ResourceContentType is not allowed until processing is complete.412 Precondition Failed response will be returned if an upload is attempted while the previous file is still being processed.PUT request.x-goog-if-generation-match header with a value of 0 is required.part001.mp3, part002.mp3, ... , partNNN.mp3 or del001.mp3, del002.mp3, ... , delNNN.mp3.| disableStrictValidation | boolean |
| enablePerProductValidation | boolean |
| onixProducts required | string |
| resourceContentTypes | object (Record_string.ResourceContentTypeEnum-Array_) Construct a type with a set of properties K of type T |
| customIds | object (Record_string.string_) Construct a type with a set of properties K of type T |
{- "onixProducts": "<ONIXMessage release=\"3.0\" xmlns=\"http://ns.editeur.org/onix/3.0/reference\">...</ONIXMessage>",
- "resourceContentTypes": {
- "9780394320069": [
- "01",
- "02"
], - "9780394320061": [
- "01",
- "28"
]
}
}{- "9780801003608": {
- "status": "Updated",
- "message": "Updated product metadata. NotificationType 03",
- "completeForDistribution": true,
- "uploadSignedUrls": {
- "28": "signedUrl",
- "01": "signedUrl",
- "02": "signedUrl"
}, - "activeReceivers": [
- "SAX",
- "KBO"
], - "inactiveReceivers": [
- "APC"
]
}, - "9788743518310": {
- "status": "Failed",
- "message": "Detailed error message",
- "completeForDistribution": false,
- "activeReceivers": [ ],
- "inactiveReceivers": [ ]
}, - "9788743518341": {
- "status": "WaitingForFiles",
- "message": "Product will not be distributed until front cover and full content files are uploaded (NotificationType 03).",
- "completeForDistribution": false,
- "activeReceivers": [ ],
- "inactiveReceivers": [ ]
}
}Get signed urls to upload supporting resources for existing content.
Before uploading a file using a signed URL, consider the following:
ResourceContentType is not allowed until processing is complete.412 Precondition Failed response will be returned if an upload is attempted while the previous file is still being processed.PUT request.x-goog-if-generation-match header with a value of 0 is required.part001.mp3, part002.mp3, ... , partNNN.mp3 or del001.mp3, del002.mp3, ... , delNNN.mp3.| property name* additional property | Array of strings (ResourceContentTypeEnum) Items Enum: "01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" "50" "51" "52" "53" "99" |
{- "9780394320069": [
- "01",
- "15",
- "28"
], - "9780394320066": [
- "01",
- "28"
]
}{- "9780801003608": {
}, - "9788743518310": {
}, - "9788743518341": {
}
}Generate sample for existing audiobook. A valid full content file must exist before triggering sample generation.
Use GET /ingestion-status/{isbn}?statusType=Validation to retrieve the full content file ingestion status. Only when this endpoint returns an HTTP status code 200 will it be possible to generate a sample.
Either fraction or fromPage and toPage query params may be provided. If no params are provided, default values will be used:
fraction: 0.1| identifier required | string |
| fraction required | number <float> [ 0.03 .. 0.2 ] |
{- "identifier": "9780394320069",
- "fraction": 0.1
}Generate sample for existing audiobook. A valid full content file must exist before triggering sample generation.
Use GET /ingestion-status/{isbn}?statusType=Validation to retrieve the full content file ingestion status. Only when this endpoint returns an HTTP status code 200 will it be possible to generate a sample.
If no fraction is provided, a sample using 10% of the audiobook (min 30 sec and max 5 minutes) will be generated.
| identifier required | string |
| fraction | number <float> [ 0.05 .. 0.2 ] |
{- "identifier": "9780394320069",
- "fraction": 0.05
}Since supporting resource processing is asynchronous, this endpoint can be used to check the files validation and processing status.
In order to request only validation status: Query param ?statusType=Validation must be provided.
In order to request only files processing status, Query param ?statusType=FilesProcessing must be provided.
If no query param is provided, both statuses are included in the response.
Corresponding http status code will be returned depending on the ingestion status. Detailed error messages can be found in response body.
202: Files are being processed200: File processing successfully finished422: File validation error. Find details in response body500: Internal server error.| isbn required | string |
| statusType | string (StatusType) Enum: "Validation" "FilesProcessing" |
{- "supporting_resource_ingestion_status": {
- "28": {
- "ingestion_status": "Failed",
- "last_update": "2025-02-07T10:58:01.193Z",
- "details": "Invalid file. Audio full content must be a zip file. Received image/png"
}, - "01": {
- "ingestion_status": "Done",
- "last_update": "2025-02-06T14:31:57.659Z"
}
}, - "streaming_file_production_status": {
- "ingestion_status": "Done",
- "last_update": "2025-02-06T14:40:50.554+00:00Z"
}, - "sample_file_production_status": {
- "ingestion_status": "Done",
- "last_update": "2025-02-06T14:40:50.554+00:00Z"
}
}