Ingestion API (1.0.0-dev)

Download OpenAPI specification:

License: Propietary

Ingestion API is used to upload ONIX metadata and supporting resources for distribution.

Authentication

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.

Suggested flow

  • Using Publizon's sample generator:

    1. Upload ONIX and request signed links to upload supporting resources: POST /onix/upload
    2. Upload supporting resources: PUT {supporting resource upload signed link}
    3. Poll ingestion status endpoint until supporting resource validation is done (or failed): GET /status/{isbn}
    4. Generate sample: POST /sample/generate
    5. Poll ingestion status endpoint until sample generation is done (or failed): GET /status/{isbn}
  • Uploading custom sample:

    1. Upload ONIX and request signed links to upload supporting resources (including 15: sample content): POST /onix/upload
    2. Upload supporting resources: PUT {supporting resource upload signed link}
    3. Poll ingestion status endpoint until the ingestion process is done (or failed): GET /status/{isbn}

Validate Onix

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:

  • details: Error messages for each product
  • validProducts: List of identifiers for valid products
  • invalidProducts: List of identifiers for invalid products Using per product validation takes significantly more time than batch validation.

Custom validation

Besides validation against editeur XSD files, the following custom rules are validated:

Identifier

Ebooks and Audiobooks must contain either an ISBN13 or a GTIN13 identifier. This is, a ProductIdentifier element with ProductIDType 15 or 03.

PrimaryContentType

When creating/updating products, it is required to provide a PrimaryContentType tag for each product with one of the following values (codelist 81):

  • Ebooks: 10 or 49
  • Audiobooks: 01
  • Podcasts: 13

Author

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).

PublisherName

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>

Distinctive title

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>

Default 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.

Authorizations:
(api_keybearer_auth)
query Parameters
disableStrictValidation
boolean
enablePerProductValidation
boolean

Responses

Response samples

Content type
application/json
Example
{
  • "valid": true,
  • "details": {
    },
  • "validProducts": [
    ],
  • "invalidProducts": [ ]
}

Upload onix

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.

ONIX

Supported Notification Types and their usage:

  • NotificationType 01: Early notification. Use for a complete record issued earlier than approximately six months before publication.
  • NotificationType 02: Advance notification. Use for a complete record issued to confirm advance information approximately six months before publication; or for a complete record issued after that date and before information has been confirmed from the book-in-hand
  • NotificationType 03: Notification confirmed on publication. Use for a complete record issued to confirm advance information at or just before actual publication date; or for a complete record issued at any later date
  • NotificationType 04: Partial update. Use when sending a "block update" record. It can only be used to update existing products. Only the metadata blocks that must be updated are required. There is no need to send the whole onix file.
  • NotificationType 05: Delete. Use when sending an instruction to delete a record which was previously issued. This will send a take down notification to all the receivers.

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).

Active/Inactive content

Content is considered "active" only if Publishing Status is set to one of: "02" (Forthcoming) or "04" (Active) and NotificationType is not 05.

PrimaryContentType

When creating/updating products, it is required to provide a PrimaryContentType tag for each product with one of the following values (codelist 81):

  • Ebooks: 10 or 49
  • Audiobooks: 01
  • Podcasts: 13

Identifier

Ebooks and Audiobooks must contain either an ISBN13 or a GTIN13 identifier. This is, a ProductIdentifier element with ProductIDType 15 or 03.

Author

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).

PublisherName

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>

Distinctive title

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>

Metadata for specific receivers

In order to set dates, prices or activate/deactivate content for a specific receiver, the ProductSupply element must be used.

  • Receivers are identified using ONIX Retail sales outlet ID.
  • For each receiver, there must be a ProductSupply element. The receiver ID is defined in ProductSupply > Market > SalesRestriction > SalesOutlet > SalesOutletIdentifier.
  • Make sure that SalesOutletIDType is set to '03' (ONIX retail sales outlet ID code).
  • The publishing status for the receiver is defined in: ProductSupply > MarketPublishingDetail > MarketPublishingStatus. Only the values '04' (active) and '02' (forthcoming) will activate the product for the receiver. Any other value will deactivate it.
  • When a product was active for a receiver and is later deactivated, a takedown notification (NotificationType=05) will be sent to the receiver.
  • Prices for the receiver must be defined in: ProductSupply > SupplyDetail.
  • Optionally, specific dates for the receiver can be defined in: 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>
  • When sending NotificationType 01, 02 or 03, all the active receivers must be present in the onix metadata. If a product was active for a receiver, but later new onix metadata with NotificationType 01, 02 or 03 is received without a ProductSupply block for the receiver, the receiver will be set to inactive.
  • When sending NotificationType 04 (partial update), all the active receivers must be present in the onix metadata ONLY if the ProductSupply block is updated. If the ProductSupply block is updated, the receivers that are not longer defined in the onix file as active will be deactivated.
  • When sending NotificationType 05 (Delete), all the receivers are set to inactive.

Default net price

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.

Request

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.
    • The keys must be ISBN-13 identifiers.
    • The values must be lists of ResourceContentType ONIX codelist.
    • Signed links will only be created if the ISBN-13 is defined in resourceContentTypes AND ONIX metadata with NotificationType=01/02/03/04. Example:
    "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.

Response

When ONIX metadata is uploaded, the response includes the following data for each product:

status

  • 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.

completeForDistribution

A product is considered complete for distribution when:

  • NotificationType is 01 or 02: The product is immediately complete, with or without supporting resources.
  • NotificationType is 03: The product metadata, FullContent, and FrontCover supporting resources must be uploaded.

uploadSignedUrls

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.

activeReceivers and inactiveReceivers

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.

Using signed URLs to upload supporting resources

Before uploading a file using a signed URL, consider the following:

  • Signed URL expiration: Signed URLs are valid for 30 minutes. After that time, a new URL can be requested. Signed URLs can also be generated using the /supporting-resources/generate-upload-signed-url endpoint.
  • File processing starts immediately after upload.
    • While a file is being processed, uploading a new file for the same ISBN and ResourceContentType is not allowed until processing is complete.
    • A 412 Precondition Failed response will be returned if an upload is attempted while the previous file is still being processed.
  • Method: Signed URLs must be used with a PUT request.
  • Required header: When uploading a file via a signed URL, the x-goog-if-generation-match header with a value of 0 is required.

File format restrictions

  • Ebook "Full Content" file (ResourceContentType=28): Must be epub / pdf
  • Audiobook "Full Content" file (ResourceContentType=28):
    • Must be a zip file containing .mp3 files (bitrate >= 96 kb/s) and up to 1 .json file (manifest https://www.w3.org/TR/audiobooks/).
    • There must not be subdirectories in the zip file. Mp3 files must follow the naming convention: part001.mp3, part002.mp3, ... , partNNN.mp3 or del001.mp3, del002.mp3, ... , delNNN.mp3.
    • Each mp3 file must contain ID3v2 or ID3v1 tags.
    • The metadata of each mp3 file must include the following required tags: title, album, artist, genre, year, track number and a cover image
  • Audiobook sample files (ResourceContentType=15) must be .mp3
  • Ebook sample files (ResourceContentType=15) must be epub / pdf
Authorizations:
(api_keybearer_auth)
query Parameters
disableStrictValidation
boolean
enablePerProductValidation
boolean
Request Body schema: application/json
required
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

Responses

Request samples

Content type
application/json
{
  • "onixProducts": "<ONIXMessage release=\"3.0\" xmlns=\"http://ns.editeur.org/onix/3.0/reference\">...</ONIXMessage>",
  • "resourceContentTypes": {
    }
}

Response samples

Content type
application/json
{
  • "9780801003608": {
    },
  • "9788743518310": {
    },
  • "9788743518341": {
    }
}

Supporting resources upload signed urls.

Get signed urls to upload supporting resources for existing content.

Using signed URLs to upload supporting resources

Before uploading a file using a signed URL, consider the following:

  • Signed URL expiration: Signed URLs are valid for 30 minutes. After that time, a new URL can be requested.
  • File processing starts immediately after upload.
    • While a file is being processed, uploading a new file for the same ISBN and ResourceContentType is not allowed until processing is complete.
    • A 412 Precondition Failed response will be returned if an upload is attempted while the previous file is still being processed.
  • Method: Signed URLs must be used with a PUT request.
  • Required header: When uploading a file via a signed URL, the x-goog-if-generation-match header with a value of 0 is required.

File format restrictions

  • Ebook "Full Content" file (ResourceContentType=28): Must be epub / pdf
  • Audiobook "Full Content" file (ResourceContentType=28):
    • Must be a zip file containing .mp3 files (bitrate >= 96 kb/s) and up to 1 .json file (manifest https://www.w3.org/TR/audiobooks/).
    • There must not be subdirectories in the zip file. Mp3 files must follow the naming convention: part001.mp3, part002.mp3, ... , partNNN.mp3 or del001.mp3, del002.mp3, ... , delNNN.mp3.
    • Each mp3 file must contain ID3v2 or ID3v1 tags.
    • The metadata of each mp3 file must include the following required tags: title, album, artist, genre, year, track number and a cover image
  • Audiobook sample files (ResourceContentType=15) must be .mp3
  • Ebook sample files (ResourceContentType=15) must be epub / pdf
Authorizations:
(api_keybearer_auth)
Request Body schema: application/json
required
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"

Responses

Request samples

Content type
application/json
{
  • "9780394320069": [
    ],
  • "9780394320066": [
    ]
}

Trigger sample generator for ebook.

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
Authorizations:
(api_keybearer_auth)
Request Body schema: application/json
required
Any of
identifier
required
string
fraction
required
number <float> [ 0.03 .. 0.2 ]

Responses

Request samples

Content type
application/json
Example
{
  • "identifier": "9780394320069",
  • "fraction": 0.1
}

Trigger sample generator for audiobook.

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.

Authorizations:
(api_keybearer_auth)
Request Body schema: application/json
required
identifier
required
string
fraction
number <float> [ 0.05 .. 0.2 ]

Responses

Request samples

Content type
application/json
{
  • "identifier": "9780394320069",
  • "fraction": 0.05
}

Ingestion status

Since supporting resource processing is asynchronous, this endpoint can be used to check the files validation and processing status.

  • Validation status: This is the files validation status. Every file uploaded to the system is validated before being ingested.
  • Files processing status: After validation, files may be processed to generate samples and/or encrypted versions.

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.

  • Status code 202: Files are being processed
  • Status code 200: File processing successfully finished
  • Status code 422: File validation error. Find details in response body
  • Status code 500: Internal server error.
Authorizations:
(api_keybearer_auth)
path Parameters
isbn
required
string
query Parameters
statusType
string (StatusType)
Enum: "Validation" "FilesProcessing"

Responses

Response samples

Content type
application/json
{
  • "supporting_resource_ingestion_status": {
    },
  • "streaming_file_production_status": {
    },
  • "sample_file_production_status": {
    }
}