Product Texts v4
Sub-resource of products holding the descriptive copy that goes with a title: the main blurb, the short annotation used in feeds, the table of contents, the author biography, review quotes and endorsements, cover copy, excerpts. Each entry is one text, in one language, with a type tag and an optional distribution-channel scope. A product carries as many entries as it needs — one blurb per language, one biography per contributor, one entry per review quote.
The model follows the ONIX 3 <TextContent> composite, with this API's own lowercase-slug
vocabulary in type rather than raw ONIX codes; the matching
ONIX Codelist 153 code is derived by the server into
type_onix.
Endpoints
GET /resource/v4/products/{product_id}/texts
Retrieve texts for a product
Description
Returns every text entry for the product, paginated. type is the only field that
can be filtered on — ?type=description for the blurbs, for example; language and
channel have to be filtered client-side. Results cannot be sorted. See
Resource Queries for the filter, sort and pagination syntax.
An unknown product_id returns 404. A product belonging to another realm returns
403.
Input parameters
Path parameters
| Parameter | Type | Default | Nullable | Description |
|---|---|---|---|---|
product_id |
string | No | UUID of the product. |
Query parameters
| Parameter | Type | Default | Nullable | Description |
|---|---|---|---|---|
page |
integer | No | Page number, starting at 1. | |
page_size |
integer | No | Entries per page; defaults to 100. `display` is accepted as a legacy alias. | |
type |
string | No | Filter by text type slug, e.g. `description`, `biographical-note`, `table-of-contents`. The only filterable field; any other name returns 400. Operator suffixes are supported — see [Resource Queries](/resource_queries/). |
Responses
{
"_links": {},
"_pagination": {},
"items": [
{
"_id": "3d5a9c14-7b02-4e88-9a61-0c7f2e4d8b35",
"_version": "4.0",
"_legacy_id": 4180231,
"_links": {},
"text": "Marit Sallenberg arbeitete als Lektorin und Kulturjournalistin, bevor sie ihren ersten Roman veroeffentlichte. Sie schreibt Gesellschaftsromane und lebt als freie Autorin in Rheinbergen.",
"channels": [],
"language": "ger",
"type": "biographical-note",
"type_onix": "12",
"mime_type": "text/plain"
}
]
}
Schema of the response body
{
"type": "object",
"additionalProperties": false,
"properties": {
"_links": {
"type": "object"
},
"_pagination": {
"type": "object"
},
"items": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"description": "One piece of descriptive copy attached to a product, in a single language, tagged by text type.",
"properties": {
"_id": {
"type": "string",
"description": "Unique identifier (UUID) for the product text.",
"example": "3d5a9c14-7b02-4e88-9a61-0c7f2e4d8b35"
},
"_version": {
"type": "string",
"description": "API Version.",
"example": "4.0"
},
"_legacy_id": {
"type": "integer",
"description": "Legacy integer identifier of this resource, kept so existing integrations can correlate their own records. This is the `_id` the same record has on the v3 endpoint.",
"example": 4180231
},
"_links": {
"type": "object"
},
"text": {
"type": "string",
"description": "The text itself. Its interpretation follows `mime_type`: with `text/plain` it is\nliteral characters and line breaks; with `text/html` it is a fragment of markup\n(typically `<p>` paragraphs) that a storefront can drop into a page.\n\nMust not be empty — a create or update that would leave `text` empty is rejected\nwith `400 Bad Request`.\n\nThere is no business length limit: an entry comfortably holds a full table of contents\nor a sample chapter, and the practical ceiling comes from the receiving channel rather\nthan from this API. Characters outside the Basic Multilingual Plane — emoji, and some\nrarely used CJK and historic scripts — are not supported.\n\n**This sub-resource is a standalone store.** It is independent of the legacy\ndescriptive fields carried directly on the v3 product record (`abstract`,\n`abstract_prefix`, `biographical_note`, `table_of_content`): a text written here does\nnot update those, and reading them does not surface entries created here. An entry is\nreachable through this sub-resource and its v3 equivalent, and nowhere else in the\nAPI.\n",
"example": "Marit Sallenberg arbeitete als Lektorin und Kulturjournalistin, bevor sie ihren ersten Roman veroeffentlichte. Sie schreibt Gesellschaftsromane und lebt als freie Autorin in Rheinbergen."
},
"channels": {
"type": "array",
"description": "Distribution channels this text is intended for. An **empty list means the text\napplies to every channel** and is the normal case; it is populated only when a partner\nneeds different copy from everyone else — for example a shortened blurb for a\nretailer with a character limit, or a description that omits a competitor's name.\n\nValues are the platform's distribution-channel slugs. Those in common use are:\n\n- `google`\n- `amazon`\n- `kobo`\n- `spotify`\n- `libri`\n- `ciando`\n- `divibib`\n- `overdrive`\n- `scribd`\n- `bookwire`\n\nThe list is open-ended — a realm distributes through whichever partners it has\ncontracts with. **They are not validated against the channel list** — any string of lowercase letters and\nhyphens is accepted, so a typo silently produces a text that no channel will ever\nmatch. Note that channel slugs containing digits or underscores (`24symbols`,\n`manual_sale`, `zeitfracht_sa02e`) are valid channels elsewhere in the API but are\n**rejected** here, because this field allows only `[a-z-]`.\n\nThe list is normalised on write: values are lower-cased, de-duplicated and sorted\nalphabetically. Sending `[\"Google\", \"amazon\", \"google\"]` stores and returns\n`[\"amazon\", \"google\"]`. On update the list is replaced wholesale, never merged.\n\nThis endpoint applies no fallback logic of its own: it returns the entries exactly as\nstored, so selecting copy for one channel means preferring an entry that names that\nchannel and otherwise taking the unscoped one.\n\n**`channels` is the only scoping axis this resource has, and it is narrower than\nONIX.** An ONIX 3 `<TextContent>` is also scoped by content audience\n([Codelist 154](https://ns.editeur.org/onix/en/154) — booktrade, end-customers,\nlibrarians, press, …) and by text source and validity dates; none of those fields\nexist here. `channels` names distribution partners, not classes of reader.\n\n**Storefronts are a separate axis and are not handled here.** Per-shop copy — HTML\ntitle, meta description, meta keywords — belongs to the\n`/resource/v4/products/{product_id}/storefronts` sub-resource.\n",
"items": {
"type": "string"
},
"example": []
},
"language": {
"type": "string",
"description": "Language of `text`, as a three-letter ISO 639-2/B (bibliographic) code — `ger` for\nGerman, `eng` for English, `fre` for French. Note the B-codes: German is `ger`, not\n`deu`. Case is normalised to lower case on write; an unknown code is rejected with\n`400 Bad Request`.\n\n`null` when the language is unknown or not meaningful. A product carrying the same\n`type` in several languages holds one entry per language — nothing prevents\nduplicates, so a consumer picking \"the description\" should filter by the language it\nwants and fall back to the product's own `language`.\n\nNote that a language once set cannot be cleared: sending `\"language\": null` is\nrejected with `400 Bad Request`.\n",
"nullable": true,
"example": "ger"
},
"type": {
"type": "string",
"description": "What kind of text this is. **Not a closed enumeration** — any non-empty string of\nlowercase letters and hyphens (`[a-z-]`, up to 255 characters) is accepted. Digits,\nunderscores, spaces and upper case are rejected with `400 Bad Request`, as is an\nempty value.\n\n37 slugs are recognised as equivalents of [ONIX Codelist\n153](https://ns.editeur.org/onix/en/153) values; for those the server derives\n`type_onix`. Anything else is stored as given with `type_onix: null`, which is the\nsupported way to carry copy that ONIX has no code for.\n\nA few of the distinctions in the list are easy to get wrong:\n\n- `description` (03) is the main long-form selling copy;\n `short-description-annotation` (02) is the abridged version for listings and feeds\n with a length budget. They are separate entries, not two renderings of one.\n- `biographical-note` (12) is about the author, not about the book, and takes one entry\n per contributor where there are several.\n- `review-quote` (06) is a quotation from a published review of *this* edition;\n `review-quote-previous-edition` (07) and `review-quote-previous-work` (08) exist for\n quotes that refer to something else.\n- `endorsement` (09) is a commendation solicited by the publisher, as distinct from a\n review published independently.\n- `abstract` (30) is the scholarly abstract, not a marketing blurb.\n- `table-of-contents` (04) is conventionally `text/plain` with one heading per line.\n\nThe complete set of recognised slugs, with the [Codelist\n153](https://ns.editeur.org/onix/en/153) code each one derives:\n\n| `type` | `type_onix` | Meaning |\n|---|---|---|\n| `sender-defined-text` | `01` | Sender-defined text |\n| `short-description-annotation` | `02` | Short description / annotation — the abridged blurb for listings and feeds |\n| `description` | `03` | Description — the main long-form selling copy |\n| `table-of-contents` | `04` | Table of contents |\n| `primary-cover-copy` | `05` | Primary cover copy — text printed on the cover or jacket |\n| `review-quote` | `06` | Review quote |\n| `review-quote-previous-edition` | `07` | Review quote, previous edition |\n| `review-quote-previous-work` | `08` | Review quote, previous work |\n| `endorsement` | `09` | Endorsement — solicited by the publisher, unlike a review |\n| `promotional-headline` | `10` | Promotional headline |\n| `feature` | `11` | Feature — a single selling point |\n| `biographical-note` | `12` | Biographical note about a contributor |\n| `publishers-notive` | `13` | Publisher's notice *(slug misspelled — send it exactly as shown)* |\n| `excerpt` | `14` | Excerpt |\n| `index` | `15` | Index |\n| `short-description-annotiation-for-collation` | `16` | Short description for the collection *(slug misspelled — send it exactly as shown)* |\n| `description-for-collection` | `17` | Description for the collection (series) |\n| `new-feature` | `18` | New feature — what changed in this edition |\n| `version-history` | `19` | Version history |\n| `open-access-statement` | `20` | Open access statement |\n| `digital-exclusivity-statement` | `21` | Digital exclusivity statement |\n| `official-recommendation` | `22` | Official recommendation |\n| `jbpa-description` | `23` | JBPA description |\n| `schema-org-snippet` | `24` | schema.org snippet |\n| `errata` | `25` | Errata |\n| `intriduction` | `26` | Introduction *(slug misspelled — send it exactly as shown)* |\n| `secondary-cover-copy` | `27` | Secondary cover copy |\n| `full-cast-and-credit-list` | `28` | Full cast and credit list |\n| `bibliography` | `29` | Bibliography |\n| `abstract` | `30` | Abstract — the scholarly summary, not a marketing blurb |\n| `rules-or-instructions` | `31` | Rules or instructions |\n| `list-of-contents` | `32` | List of contents — components of a multi-item product |\n| `short-description-annotation-for-imprint` | `33` | Short description for the imprint |\n| `description-for-imprint` | `34` | Description for the imprint |\n| `short-description-annotation-for-publisher` | `35` | Short description for the publisher |\n| `description-for-publisher` | `36` | Description for the publisher |\n| `cover-line` | `37` | Cover line |\n\nThree of those slugs — `publishers-notive`, `short-description-annotiation-for-collation`\nand `intriduction` — are misspelled, and the table lists them as they must be sent to\nobtain a code. The correctly spelled forms `publishers-notice`,\n`short-description-annotation-for-collection` and `introduction` are accepted as well,\nbut they are not recognised and yield `type_onix: null`.\n\n**This is the only field the collection endpoint can filter on**, with the operators\ndescribed under [Resource Queries](/resource_queries/). Any other field name is\nrejected with `400 Bad Request`, as is an unknown operator suffix, so `language` and\n`channels` have to be narrowed down client-side. Results cannot be sorted: a `sort`\nparameter is accepted and applied to nothing, which leaves the order of results\nunspecified. Pagination is standard, with a default page size of 100.\n",
"example": "biographical-note",
"x-enum-descriptions": {
"sender-defined-text": "ONIX 153 code 01 — Sender-defined text.",
"short-description-annotation": "ONIX 153 code 02 — Short description/annotation; the abridged blurb for listings and feeds.",
"description": "ONIX 153 code 03 — Description; the main long-form selling copy.",
"table-of-contents": "ONIX 153 code 04 — Table of contents.",
"primary-cover-copy": "ONIX 153 code 05 — Primary cover copy; the text printed on the cover or jacket.",
"review-quote": "ONIX 153 code 06 — Review quote for this edition.",
"review-quote-previous-edition": "ONIX 153 code 07 — Review quote taken from a review of a previous edition.",
"review-quote-previous-work": "ONIX 153 code 08 — Review quote taken from a review of a previous work by the same author.",
"endorsement": "ONIX 153 code 09 — Endorsement; a commendation solicited by the publisher.",
"promotional-headline": "ONIX 153 code 10 — Promotional headline; the one-line hook.",
"feature": "ONIX 153 code 11 — Feature; a single selling point, usually one of a set of bullets.",
"biographical-note": "ONIX 153 code 12 — Biographical note about a contributor.",
"publishers-notive": "ONIX 153 code 13 — Publisher's notice. The slug is misspelled; send it exactly as shown.",
"excerpt": "ONIX 153 code 14 — Excerpt; a sample passage from the work.",
"index": "ONIX 153 code 15 — Index.",
"short-description-annotiation-for-collation": "ONIX 153 code 16 — Short description/annotation for the collection (series) this product belongs to. The slug is misspelled; send it exactly as shown.",
"description-for-collection": "ONIX 153 code 17 — Description of the collection (series) this product belongs to.",
"new-feature": "ONIX 153 code 18 — New feature; what changed in this edition.",
"version-history": "ONIX 153 code 19 — Version history.",
"open-access-statement": "ONIX 153 code 20 — Open access statement; the licence and access terms.",
"digital-exclusivity-statement": "ONIX 153 code 21 — Digital exclusivity statement.",
"official-recommendation": "ONIX 153 code 22 — Official recommendation, e.g. by an educational authority.",
"jbpa-description": "ONIX 153 code 23 — JBPA description (Japanese Book Publishers Association).",
"schema-org-snippet": "ONIX 153 code 24 — schema.org snippet for search-engine markup.",
"errata": "ONIX 153 code 25 — Errata.",
"intriduction": "ONIX 153 code 26 — Introduction. The slug is misspelled; send it exactly as shown.",
"secondary-cover-copy": "ONIX 153 code 27 — Secondary cover copy, e.g. back cover as opposed to front.",
"full-cast-and-credit-list": "ONIX 153 code 28 — Full cast and credit list; used for audiobooks and dramatisations.",
"bibliography": "ONIX 153 code 29 — Bibliography.",
"abstract": "ONIX 153 code 30 — Abstract; the scholarly summary, distinct from a marketing blurb.",
"rules-or-instructions": "ONIX 153 code 31 — Rules or instructions, e.g. for a game or kit.",
"list-of-contents": "ONIX 153 code 32 — List of contents; the components of a multi-item product.",
"short-description-annotation-for-imprint": "ONIX 153 code 33 — Short description/annotation for the imprint.",
"description-for-imprint": "ONIX 153 code 34 — Description of the imprint.",
"short-description-annotation-for-publisher": "ONIX 153 code 35 — Short description/annotation for the publisher.",
"description-for-publisher": "ONIX 153 code 36 — Description of the publisher.",
"cover-line": "ONIX 153 code 37 — Cover line; a strapline carried on the cover."
}
},
"type_onix": {
"type": "string",
"description": "The [ONIX Codelist 153](https://ns.editeur.org/onix/en/153) text type code\ncorresponding to `type`, as a two-digit string (`\"03\"` description, `\"12\"`\nbiographical note, …). Present so that ONIX consumers do not have to reimplement the\nslug mapping.\n\n**Read-only in effect.** The field is accepted in a request body but the value is\ndiscarded: the server recomputes it from `type` on every write. It is `null` whenever\n`type` is not one of the 37 recognised slugs. To change it, change `type`.\n\nNote that this is Codelist **153** (ONIX 3 `<TextType>`), not the ONIX 2.1 Codelist 33\n(`<OtherText>` type) that earlier revisions of this schema named. The two lists assign\ndifferent codes to the same concepts — a biographical note is `12` in 153 and `13` in\n33 — so a consumer that reads these codes against Codelist 33 will mislabel them.\n",
"nullable": true,
"example": "12"
},
"mime_type": {
"type": "string",
"description": "How `text` is encoded. In practice two values are used:\n\n- `text/plain` — literal text; line breaks are significant and a consumer must escape\n it before putting it into a web page. The default when the field is omitted on\n create.\n- `text/html` — an HTML fragment, typically wrapped in `<p>` elements. The API stores\n it as sent and does not sanitise it, so a storefront rendering the value unescaped\n is trusting whoever wrote it.\n\nValidation is **syntactic only**: any well-formed `type/subtype[; parameters]` string\nup to 255 characters is accepted, so a misspelling such as `text/htlm` is stored\nwithout complaint and is only noticed when the value is used. A malformed value is\nrejected with `400 Bad Request`, as is an empty one.\n\nBook-trade descriptions are usually HTML, while biographies and tables of contents are\nusually plain text, but nothing in the API enforces that pairing — `mime_type` is\nrecorded independently of `type`.\n",
"example": "text/plain"
}
},
"required": []
}
}
},
"required": [
"_links",
"_pagination",
"items"
]
}
POST /resource/v4/products/{product_id}/texts
Create a new product text
Description
Creates one text entry on the product. text and type are required — both must be
non-empty, or the request is rejected with 400. Everything else may be omitted:
mime_type then defaults to text/plain, language to null, and channels to the
empty list (meaning all channels).
type_onix is ignored when sent; the server derives it from type.
The example creates a German author biography: plain text, no channel restriction, so every channel and storefront can use it.
Input parameters
Path parameters
| Parameter | Type | Default | Nullable | Description |
|---|---|---|---|---|
product_id |
string | No | UUID of the product. |
Request body
{
"type": "biographical-note",
"text": "Marit Sallenberg arbeitete als Lektorin und Kulturjournalistin, bevor sie ihren ersten Roman veroeffentlichte. Sie schreibt Gesellschaftsromane und lebt als freie Autorin in Rheinbergen.",
"mime_type": "text/plain",
"language": "ger",
"channels": []
}
Schema of the request body
{
"type": "object",
"additionalProperties": false,
"description": "One piece of descriptive copy attached to a product, in a single language, tagged by text type.",
"properties": {
"_id": {
"type": "string",
"description": "Unique identifier (UUID) for the product text.",
"example": "3d5a9c14-7b02-4e88-9a61-0c7f2e4d8b35"
},
"_version": {
"type": "string",
"description": "API Version.",
"example": "4.0"
},
"_legacy_id": {
"type": "integer",
"description": "Legacy integer identifier of this resource, kept so existing integrations can correlate their own records. This is the `_id` the same record has on the v3 endpoint.",
"example": 4180231
},
"_links": {
"type": "object"
},
"text": {
"type": "string",
"description": "The text itself. Its interpretation follows `mime_type`: with `text/plain` it is\nliteral characters and line breaks; with `text/html` it is a fragment of markup\n(typically `<p>` paragraphs) that a storefront can drop into a page.\n\nMust not be empty — a create or update that would leave `text` empty is rejected\nwith `400 Bad Request`.\n\nThere is no business length limit: an entry comfortably holds a full table of contents\nor a sample chapter, and the practical ceiling comes from the receiving channel rather\nthan from this API. Characters outside the Basic Multilingual Plane — emoji, and some\nrarely used CJK and historic scripts — are not supported.\n\n**This sub-resource is a standalone store.** It is independent of the legacy\ndescriptive fields carried directly on the v3 product record (`abstract`,\n`abstract_prefix`, `biographical_note`, `table_of_content`): a text written here does\nnot update those, and reading them does not surface entries created here. An entry is\nreachable through this sub-resource and its v3 equivalent, and nowhere else in the\nAPI.\n",
"example": "Marit Sallenberg arbeitete als Lektorin und Kulturjournalistin, bevor sie ihren ersten Roman veroeffentlichte. Sie schreibt Gesellschaftsromane und lebt als freie Autorin in Rheinbergen."
},
"channels": {
"type": "array",
"description": "Distribution channels this text is intended for. An **empty list means the text\napplies to every channel** and is the normal case; it is populated only when a partner\nneeds different copy from everyone else — for example a shortened blurb for a\nretailer with a character limit, or a description that omits a competitor's name.\n\nValues are the platform's distribution-channel slugs. Those in common use are:\n\n- `google`\n- `amazon`\n- `kobo`\n- `spotify`\n- `libri`\n- `ciando`\n- `divibib`\n- `overdrive`\n- `scribd`\n- `bookwire`\n\nThe list is open-ended — a realm distributes through whichever partners it has\ncontracts with. **They are not validated against the channel list** — any string of lowercase letters and\nhyphens is accepted, so a typo silently produces a text that no channel will ever\nmatch. Note that channel slugs containing digits or underscores (`24symbols`,\n`manual_sale`, `zeitfracht_sa02e`) are valid channels elsewhere in the API but are\n**rejected** here, because this field allows only `[a-z-]`.\n\nThe list is normalised on write: values are lower-cased, de-duplicated and sorted\nalphabetically. Sending `[\"Google\", \"amazon\", \"google\"]` stores and returns\n`[\"amazon\", \"google\"]`. On update the list is replaced wholesale, never merged.\n\nThis endpoint applies no fallback logic of its own: it returns the entries exactly as\nstored, so selecting copy for one channel means preferring an entry that names that\nchannel and otherwise taking the unscoped one.\n\n**`channels` is the only scoping axis this resource has, and it is narrower than\nONIX.** An ONIX 3 `<TextContent>` is also scoped by content audience\n([Codelist 154](https://ns.editeur.org/onix/en/154) — booktrade, end-customers,\nlibrarians, press, …) and by text source and validity dates; none of those fields\nexist here. `channels` names distribution partners, not classes of reader.\n\n**Storefronts are a separate axis and are not handled here.** Per-shop copy — HTML\ntitle, meta description, meta keywords — belongs to the\n`/resource/v4/products/{product_id}/storefronts` sub-resource.\n",
"items": {
"type": "string"
},
"example": []
},
"language": {
"type": "string",
"description": "Language of `text`, as a three-letter ISO 639-2/B (bibliographic) code — `ger` for\nGerman, `eng` for English, `fre` for French. Note the B-codes: German is `ger`, not\n`deu`. Case is normalised to lower case on write; an unknown code is rejected with\n`400 Bad Request`.\n\n`null` when the language is unknown or not meaningful. A product carrying the same\n`type` in several languages holds one entry per language — nothing prevents\nduplicates, so a consumer picking \"the description\" should filter by the language it\nwants and fall back to the product's own `language`.\n\nNote that a language once set cannot be cleared: sending `\"language\": null` is\nrejected with `400 Bad Request`.\n",
"nullable": true,
"example": "ger"
},
"type": {
"type": "string",
"description": "What kind of text this is. **Not a closed enumeration** — any non-empty string of\nlowercase letters and hyphens (`[a-z-]`, up to 255 characters) is accepted. Digits,\nunderscores, spaces and upper case are rejected with `400 Bad Request`, as is an\nempty value.\n\n37 slugs are recognised as equivalents of [ONIX Codelist\n153](https://ns.editeur.org/onix/en/153) values; for those the server derives\n`type_onix`. Anything else is stored as given with `type_onix: null`, which is the\nsupported way to carry copy that ONIX has no code for.\n\nA few of the distinctions in the list are easy to get wrong:\n\n- `description` (03) is the main long-form selling copy;\n `short-description-annotation` (02) is the abridged version for listings and feeds\n with a length budget. They are separate entries, not two renderings of one.\n- `biographical-note` (12) is about the author, not about the book, and takes one entry\n per contributor where there are several.\n- `review-quote` (06) is a quotation from a published review of *this* edition;\n `review-quote-previous-edition` (07) and `review-quote-previous-work` (08) exist for\n quotes that refer to something else.\n- `endorsement` (09) is a commendation solicited by the publisher, as distinct from a\n review published independently.\n- `abstract` (30) is the scholarly abstract, not a marketing blurb.\n- `table-of-contents` (04) is conventionally `text/plain` with one heading per line.\n\nThe complete set of recognised slugs, with the [Codelist\n153](https://ns.editeur.org/onix/en/153) code each one derives:\n\n| `type` | `type_onix` | Meaning |\n|---|---|---|\n| `sender-defined-text` | `01` | Sender-defined text |\n| `short-description-annotation` | `02` | Short description / annotation — the abridged blurb for listings and feeds |\n| `description` | `03` | Description — the main long-form selling copy |\n| `table-of-contents` | `04` | Table of contents |\n| `primary-cover-copy` | `05` | Primary cover copy — text printed on the cover or jacket |\n| `review-quote` | `06` | Review quote |\n| `review-quote-previous-edition` | `07` | Review quote, previous edition |\n| `review-quote-previous-work` | `08` | Review quote, previous work |\n| `endorsement` | `09` | Endorsement — solicited by the publisher, unlike a review |\n| `promotional-headline` | `10` | Promotional headline |\n| `feature` | `11` | Feature — a single selling point |\n| `biographical-note` | `12` | Biographical note about a contributor |\n| `publishers-notive` | `13` | Publisher's notice *(slug misspelled — send it exactly as shown)* |\n| `excerpt` | `14` | Excerpt |\n| `index` | `15` | Index |\n| `short-description-annotiation-for-collation` | `16` | Short description for the collection *(slug misspelled — send it exactly as shown)* |\n| `description-for-collection` | `17` | Description for the collection (series) |\n| `new-feature` | `18` | New feature — what changed in this edition |\n| `version-history` | `19` | Version history |\n| `open-access-statement` | `20` | Open access statement |\n| `digital-exclusivity-statement` | `21` | Digital exclusivity statement |\n| `official-recommendation` | `22` | Official recommendation |\n| `jbpa-description` | `23` | JBPA description |\n| `schema-org-snippet` | `24` | schema.org snippet |\n| `errata` | `25` | Errata |\n| `intriduction` | `26` | Introduction *(slug misspelled — send it exactly as shown)* |\n| `secondary-cover-copy` | `27` | Secondary cover copy |\n| `full-cast-and-credit-list` | `28` | Full cast and credit list |\n| `bibliography` | `29` | Bibliography |\n| `abstract` | `30` | Abstract — the scholarly summary, not a marketing blurb |\n| `rules-or-instructions` | `31` | Rules or instructions |\n| `list-of-contents` | `32` | List of contents — components of a multi-item product |\n| `short-description-annotation-for-imprint` | `33` | Short description for the imprint |\n| `description-for-imprint` | `34` | Description for the imprint |\n| `short-description-annotation-for-publisher` | `35` | Short description for the publisher |\n| `description-for-publisher` | `36` | Description for the publisher |\n| `cover-line` | `37` | Cover line |\n\nThree of those slugs — `publishers-notive`, `short-description-annotiation-for-collation`\nand `intriduction` — are misspelled, and the table lists them as they must be sent to\nobtain a code. The correctly spelled forms `publishers-notice`,\n`short-description-annotation-for-collection` and `introduction` are accepted as well,\nbut they are not recognised and yield `type_onix: null`.\n\n**This is the only field the collection endpoint can filter on**, with the operators\ndescribed under [Resource Queries](/resource_queries/). Any other field name is\nrejected with `400 Bad Request`, as is an unknown operator suffix, so `language` and\n`channels` have to be narrowed down client-side. Results cannot be sorted: a `sort`\nparameter is accepted and applied to nothing, which leaves the order of results\nunspecified. Pagination is standard, with a default page size of 100.\n",
"example": "biographical-note",
"x-enum-descriptions": {
"sender-defined-text": "ONIX 153 code 01 — Sender-defined text.",
"short-description-annotation": "ONIX 153 code 02 — Short description/annotation; the abridged blurb for listings and feeds.",
"description": "ONIX 153 code 03 — Description; the main long-form selling copy.",
"table-of-contents": "ONIX 153 code 04 — Table of contents.",
"primary-cover-copy": "ONIX 153 code 05 — Primary cover copy; the text printed on the cover or jacket.",
"review-quote": "ONIX 153 code 06 — Review quote for this edition.",
"review-quote-previous-edition": "ONIX 153 code 07 — Review quote taken from a review of a previous edition.",
"review-quote-previous-work": "ONIX 153 code 08 — Review quote taken from a review of a previous work by the same author.",
"endorsement": "ONIX 153 code 09 — Endorsement; a commendation solicited by the publisher.",
"promotional-headline": "ONIX 153 code 10 — Promotional headline; the one-line hook.",
"feature": "ONIX 153 code 11 — Feature; a single selling point, usually one of a set of bullets.",
"biographical-note": "ONIX 153 code 12 — Biographical note about a contributor.",
"publishers-notive": "ONIX 153 code 13 — Publisher's notice. The slug is misspelled; send it exactly as shown.",
"excerpt": "ONIX 153 code 14 — Excerpt; a sample passage from the work.",
"index": "ONIX 153 code 15 — Index.",
"short-description-annotiation-for-collation": "ONIX 153 code 16 — Short description/annotation for the collection (series) this product belongs to. The slug is misspelled; send it exactly as shown.",
"description-for-collection": "ONIX 153 code 17 — Description of the collection (series) this product belongs to.",
"new-feature": "ONIX 153 code 18 — New feature; what changed in this edition.",
"version-history": "ONIX 153 code 19 — Version history.",
"open-access-statement": "ONIX 153 code 20 — Open access statement; the licence and access terms.",
"digital-exclusivity-statement": "ONIX 153 code 21 — Digital exclusivity statement.",
"official-recommendation": "ONIX 153 code 22 — Official recommendation, e.g. by an educational authority.",
"jbpa-description": "ONIX 153 code 23 — JBPA description (Japanese Book Publishers Association).",
"schema-org-snippet": "ONIX 153 code 24 — schema.org snippet for search-engine markup.",
"errata": "ONIX 153 code 25 — Errata.",
"intriduction": "ONIX 153 code 26 — Introduction. The slug is misspelled; send it exactly as shown.",
"secondary-cover-copy": "ONIX 153 code 27 — Secondary cover copy, e.g. back cover as opposed to front.",
"full-cast-and-credit-list": "ONIX 153 code 28 — Full cast and credit list; used for audiobooks and dramatisations.",
"bibliography": "ONIX 153 code 29 — Bibliography.",
"abstract": "ONIX 153 code 30 — Abstract; the scholarly summary, distinct from a marketing blurb.",
"rules-or-instructions": "ONIX 153 code 31 — Rules or instructions, e.g. for a game or kit.",
"list-of-contents": "ONIX 153 code 32 — List of contents; the components of a multi-item product.",
"short-description-annotation-for-imprint": "ONIX 153 code 33 — Short description/annotation for the imprint.",
"description-for-imprint": "ONIX 153 code 34 — Description of the imprint.",
"short-description-annotation-for-publisher": "ONIX 153 code 35 — Short description/annotation for the publisher.",
"description-for-publisher": "ONIX 153 code 36 — Description of the publisher.",
"cover-line": "ONIX 153 code 37 — Cover line; a strapline carried on the cover."
}
},
"type_onix": {
"type": "string",
"description": "The [ONIX Codelist 153](https://ns.editeur.org/onix/en/153) text type code\ncorresponding to `type`, as a two-digit string (`\"03\"` description, `\"12\"`\nbiographical note, …). Present so that ONIX consumers do not have to reimplement the\nslug mapping.\n\n**Read-only in effect.** The field is accepted in a request body but the value is\ndiscarded: the server recomputes it from `type` on every write. It is `null` whenever\n`type` is not one of the 37 recognised slugs. To change it, change `type`.\n\nNote that this is Codelist **153** (ONIX 3 `<TextType>`), not the ONIX 2.1 Codelist 33\n(`<OtherText>` type) that earlier revisions of this schema named. The two lists assign\ndifferent codes to the same concepts — a biographical note is `12` in 153 and `13` in\n33 — so a consumer that reads these codes against Codelist 33 will mislabel them.\n",
"nullable": true,
"example": "12"
},
"mime_type": {
"type": "string",
"description": "How `text` is encoded. In practice two values are used:\n\n- `text/plain` — literal text; line breaks are significant and a consumer must escape\n it before putting it into a web page. The default when the field is omitted on\n create.\n- `text/html` — an HTML fragment, typically wrapped in `<p>` elements. The API stores\n it as sent and does not sanitise it, so a storefront rendering the value unescaped\n is trusting whoever wrote it.\n\nValidation is **syntactic only**: any well-formed `type/subtype[; parameters]` string\nup to 255 characters is accepted, so a misspelling such as `text/htlm` is stored\nwithout complaint and is only noticed when the value is used. A malformed value is\nrejected with `400 Bad Request`, as is an empty one.\n\nBook-trade descriptions are usually HTML, while biographies and tables of contents are\nusually plain text, but nothing in the API enforces that pairing — `mime_type` is\nrecorded independently of `type`.\n",
"example": "text/plain"
}
},
"required": []
}
Responses
{
"_id": "3d5a9c14-7b02-4e88-9a61-0c7f2e4d8b35",
"_legacy_id": 4180231,
"_version": "4.0",
"_links": {
"self": "https://api.openpublishing.com/resource/v4/products/e8659334-e616-11ee-a221-00505699575c/texts/c6f34176-c138-47d7-9627-dce17b4a948d"
},
"type": "biographical-note",
"type_onix": "12",
"text": "Marit Sallenberg arbeitete als Lektorin und Kulturjournalistin, bevor sie ihren ersten Roman veroeffentlichte. Sie schreibt Gesellschaftsromane und lebt als freie Autorin in Rheinbergen.",
"mime_type": "text/plain",
"language": "ger",
"channels": []
}
Schema of the response body
{
"type": "object",
"additionalProperties": false,
"description": "One piece of descriptive copy attached to a product, in a single language, tagged by text type.",
"properties": {
"_id": {
"type": "string",
"description": "Unique identifier (UUID) for the product text.",
"example": "3d5a9c14-7b02-4e88-9a61-0c7f2e4d8b35"
},
"_version": {
"type": "string",
"description": "API Version.",
"example": "4.0"
},
"_legacy_id": {
"type": "integer",
"description": "Legacy integer identifier of this resource, kept so existing integrations can correlate their own records. This is the `_id` the same record has on the v3 endpoint.",
"example": 4180231
},
"_links": {
"type": "object"
},
"text": {
"type": "string",
"description": "The text itself. Its interpretation follows `mime_type`: with `text/plain` it is\nliteral characters and line breaks; with `text/html` it is a fragment of markup\n(typically `<p>` paragraphs) that a storefront can drop into a page.\n\nMust not be empty — a create or update that would leave `text` empty is rejected\nwith `400 Bad Request`.\n\nThere is no business length limit: an entry comfortably holds a full table of contents\nor a sample chapter, and the practical ceiling comes from the receiving channel rather\nthan from this API. Characters outside the Basic Multilingual Plane — emoji, and some\nrarely used CJK and historic scripts — are not supported.\n\n**This sub-resource is a standalone store.** It is independent of the legacy\ndescriptive fields carried directly on the v3 product record (`abstract`,\n`abstract_prefix`, `biographical_note`, `table_of_content`): a text written here does\nnot update those, and reading them does not surface entries created here. An entry is\nreachable through this sub-resource and its v3 equivalent, and nowhere else in the\nAPI.\n",
"example": "Marit Sallenberg arbeitete als Lektorin und Kulturjournalistin, bevor sie ihren ersten Roman veroeffentlichte. Sie schreibt Gesellschaftsromane und lebt als freie Autorin in Rheinbergen."
},
"channels": {
"type": "array",
"description": "Distribution channels this text is intended for. An **empty list means the text\napplies to every channel** and is the normal case; it is populated only when a partner\nneeds different copy from everyone else — for example a shortened blurb for a\nretailer with a character limit, or a description that omits a competitor's name.\n\nValues are the platform's distribution-channel slugs. Those in common use are:\n\n- `google`\n- `amazon`\n- `kobo`\n- `spotify`\n- `libri`\n- `ciando`\n- `divibib`\n- `overdrive`\n- `scribd`\n- `bookwire`\n\nThe list is open-ended — a realm distributes through whichever partners it has\ncontracts with. **They are not validated against the channel list** — any string of lowercase letters and\nhyphens is accepted, so a typo silently produces a text that no channel will ever\nmatch. Note that channel slugs containing digits or underscores (`24symbols`,\n`manual_sale`, `zeitfracht_sa02e`) are valid channels elsewhere in the API but are\n**rejected** here, because this field allows only `[a-z-]`.\n\nThe list is normalised on write: values are lower-cased, de-duplicated and sorted\nalphabetically. Sending `[\"Google\", \"amazon\", \"google\"]` stores and returns\n`[\"amazon\", \"google\"]`. On update the list is replaced wholesale, never merged.\n\nThis endpoint applies no fallback logic of its own: it returns the entries exactly as\nstored, so selecting copy for one channel means preferring an entry that names that\nchannel and otherwise taking the unscoped one.\n\n**`channels` is the only scoping axis this resource has, and it is narrower than\nONIX.** An ONIX 3 `<TextContent>` is also scoped by content audience\n([Codelist 154](https://ns.editeur.org/onix/en/154) — booktrade, end-customers,\nlibrarians, press, …) and by text source and validity dates; none of those fields\nexist here. `channels` names distribution partners, not classes of reader.\n\n**Storefronts are a separate axis and are not handled here.** Per-shop copy — HTML\ntitle, meta description, meta keywords — belongs to the\n`/resource/v4/products/{product_id}/storefronts` sub-resource.\n",
"items": {
"type": "string"
},
"example": []
},
"language": {
"type": "string",
"description": "Language of `text`, as a three-letter ISO 639-2/B (bibliographic) code — `ger` for\nGerman, `eng` for English, `fre` for French. Note the B-codes: German is `ger`, not\n`deu`. Case is normalised to lower case on write; an unknown code is rejected with\n`400 Bad Request`.\n\n`null` when the language is unknown or not meaningful. A product carrying the same\n`type` in several languages holds one entry per language — nothing prevents\nduplicates, so a consumer picking \"the description\" should filter by the language it\nwants and fall back to the product's own `language`.\n\nNote that a language once set cannot be cleared: sending `\"language\": null` is\nrejected with `400 Bad Request`.\n",
"nullable": true,
"example": "ger"
},
"type": {
"type": "string",
"description": "What kind of text this is. **Not a closed enumeration** — any non-empty string of\nlowercase letters and hyphens (`[a-z-]`, up to 255 characters) is accepted. Digits,\nunderscores, spaces and upper case are rejected with `400 Bad Request`, as is an\nempty value.\n\n37 slugs are recognised as equivalents of [ONIX Codelist\n153](https://ns.editeur.org/onix/en/153) values; for those the server derives\n`type_onix`. Anything else is stored as given with `type_onix: null`, which is the\nsupported way to carry copy that ONIX has no code for.\n\nA few of the distinctions in the list are easy to get wrong:\n\n- `description` (03) is the main long-form selling copy;\n `short-description-annotation` (02) is the abridged version for listings and feeds\n with a length budget. They are separate entries, not two renderings of one.\n- `biographical-note` (12) is about the author, not about the book, and takes one entry\n per contributor where there are several.\n- `review-quote` (06) is a quotation from a published review of *this* edition;\n `review-quote-previous-edition` (07) and `review-quote-previous-work` (08) exist for\n quotes that refer to something else.\n- `endorsement` (09) is a commendation solicited by the publisher, as distinct from a\n review published independently.\n- `abstract` (30) is the scholarly abstract, not a marketing blurb.\n- `table-of-contents` (04) is conventionally `text/plain` with one heading per line.\n\nThe complete set of recognised slugs, with the [Codelist\n153](https://ns.editeur.org/onix/en/153) code each one derives:\n\n| `type` | `type_onix` | Meaning |\n|---|---|---|\n| `sender-defined-text` | `01` | Sender-defined text |\n| `short-description-annotation` | `02` | Short description / annotation — the abridged blurb for listings and feeds |\n| `description` | `03` | Description — the main long-form selling copy |\n| `table-of-contents` | `04` | Table of contents |\n| `primary-cover-copy` | `05` | Primary cover copy — text printed on the cover or jacket |\n| `review-quote` | `06` | Review quote |\n| `review-quote-previous-edition` | `07` | Review quote, previous edition |\n| `review-quote-previous-work` | `08` | Review quote, previous work |\n| `endorsement` | `09` | Endorsement — solicited by the publisher, unlike a review |\n| `promotional-headline` | `10` | Promotional headline |\n| `feature` | `11` | Feature — a single selling point |\n| `biographical-note` | `12` | Biographical note about a contributor |\n| `publishers-notive` | `13` | Publisher's notice *(slug misspelled — send it exactly as shown)* |\n| `excerpt` | `14` | Excerpt |\n| `index` | `15` | Index |\n| `short-description-annotiation-for-collation` | `16` | Short description for the collection *(slug misspelled — send it exactly as shown)* |\n| `description-for-collection` | `17` | Description for the collection (series) |\n| `new-feature` | `18` | New feature — what changed in this edition |\n| `version-history` | `19` | Version history |\n| `open-access-statement` | `20` | Open access statement |\n| `digital-exclusivity-statement` | `21` | Digital exclusivity statement |\n| `official-recommendation` | `22` | Official recommendation |\n| `jbpa-description` | `23` | JBPA description |\n| `schema-org-snippet` | `24` | schema.org snippet |\n| `errata` | `25` | Errata |\n| `intriduction` | `26` | Introduction *(slug misspelled — send it exactly as shown)* |\n| `secondary-cover-copy` | `27` | Secondary cover copy |\n| `full-cast-and-credit-list` | `28` | Full cast and credit list |\n| `bibliography` | `29` | Bibliography |\n| `abstract` | `30` | Abstract — the scholarly summary, not a marketing blurb |\n| `rules-or-instructions` | `31` | Rules or instructions |\n| `list-of-contents` | `32` | List of contents — components of a multi-item product |\n| `short-description-annotation-for-imprint` | `33` | Short description for the imprint |\n| `description-for-imprint` | `34` | Description for the imprint |\n| `short-description-annotation-for-publisher` | `35` | Short description for the publisher |\n| `description-for-publisher` | `36` | Description for the publisher |\n| `cover-line` | `37` | Cover line |\n\nThree of those slugs — `publishers-notive`, `short-description-annotiation-for-collation`\nand `intriduction` — are misspelled, and the table lists them as they must be sent to\nobtain a code. The correctly spelled forms `publishers-notice`,\n`short-description-annotation-for-collection` and `introduction` are accepted as well,\nbut they are not recognised and yield `type_onix: null`.\n\n**This is the only field the collection endpoint can filter on**, with the operators\ndescribed under [Resource Queries](/resource_queries/). Any other field name is\nrejected with `400 Bad Request`, as is an unknown operator suffix, so `language` and\n`channels` have to be narrowed down client-side. Results cannot be sorted: a `sort`\nparameter is accepted and applied to nothing, which leaves the order of results\nunspecified. Pagination is standard, with a default page size of 100.\n",
"example": "biographical-note",
"x-enum-descriptions": {
"sender-defined-text": "ONIX 153 code 01 — Sender-defined text.",
"short-description-annotation": "ONIX 153 code 02 — Short description/annotation; the abridged blurb for listings and feeds.",
"description": "ONIX 153 code 03 — Description; the main long-form selling copy.",
"table-of-contents": "ONIX 153 code 04 — Table of contents.",
"primary-cover-copy": "ONIX 153 code 05 — Primary cover copy; the text printed on the cover or jacket.",
"review-quote": "ONIX 153 code 06 — Review quote for this edition.",
"review-quote-previous-edition": "ONIX 153 code 07 — Review quote taken from a review of a previous edition.",
"review-quote-previous-work": "ONIX 153 code 08 — Review quote taken from a review of a previous work by the same author.",
"endorsement": "ONIX 153 code 09 — Endorsement; a commendation solicited by the publisher.",
"promotional-headline": "ONIX 153 code 10 — Promotional headline; the one-line hook.",
"feature": "ONIX 153 code 11 — Feature; a single selling point, usually one of a set of bullets.",
"biographical-note": "ONIX 153 code 12 — Biographical note about a contributor.",
"publishers-notive": "ONIX 153 code 13 — Publisher's notice. The slug is misspelled; send it exactly as shown.",
"excerpt": "ONIX 153 code 14 — Excerpt; a sample passage from the work.",
"index": "ONIX 153 code 15 — Index.",
"short-description-annotiation-for-collation": "ONIX 153 code 16 — Short description/annotation for the collection (series) this product belongs to. The slug is misspelled; send it exactly as shown.",
"description-for-collection": "ONIX 153 code 17 — Description of the collection (series) this product belongs to.",
"new-feature": "ONIX 153 code 18 — New feature; what changed in this edition.",
"version-history": "ONIX 153 code 19 — Version history.",
"open-access-statement": "ONIX 153 code 20 — Open access statement; the licence and access terms.",
"digital-exclusivity-statement": "ONIX 153 code 21 — Digital exclusivity statement.",
"official-recommendation": "ONIX 153 code 22 — Official recommendation, e.g. by an educational authority.",
"jbpa-description": "ONIX 153 code 23 — JBPA description (Japanese Book Publishers Association).",
"schema-org-snippet": "ONIX 153 code 24 — schema.org snippet for search-engine markup.",
"errata": "ONIX 153 code 25 — Errata.",
"intriduction": "ONIX 153 code 26 — Introduction. The slug is misspelled; send it exactly as shown.",
"secondary-cover-copy": "ONIX 153 code 27 — Secondary cover copy, e.g. back cover as opposed to front.",
"full-cast-and-credit-list": "ONIX 153 code 28 — Full cast and credit list; used for audiobooks and dramatisations.",
"bibliography": "ONIX 153 code 29 — Bibliography.",
"abstract": "ONIX 153 code 30 — Abstract; the scholarly summary, distinct from a marketing blurb.",
"rules-or-instructions": "ONIX 153 code 31 — Rules or instructions, e.g. for a game or kit.",
"list-of-contents": "ONIX 153 code 32 — List of contents; the components of a multi-item product.",
"short-description-annotation-for-imprint": "ONIX 153 code 33 — Short description/annotation for the imprint.",
"description-for-imprint": "ONIX 153 code 34 — Description of the imprint.",
"short-description-annotation-for-publisher": "ONIX 153 code 35 — Short description/annotation for the publisher.",
"description-for-publisher": "ONIX 153 code 36 — Description of the publisher.",
"cover-line": "ONIX 153 code 37 — Cover line; a strapline carried on the cover."
}
},
"type_onix": {
"type": "string",
"description": "The [ONIX Codelist 153](https://ns.editeur.org/onix/en/153) text type code\ncorresponding to `type`, as a two-digit string (`\"03\"` description, `\"12\"`\nbiographical note, …). Present so that ONIX consumers do not have to reimplement the\nslug mapping.\n\n**Read-only in effect.** The field is accepted in a request body but the value is\ndiscarded: the server recomputes it from `type` on every write. It is `null` whenever\n`type` is not one of the 37 recognised slugs. To change it, change `type`.\n\nNote that this is Codelist **153** (ONIX 3 `<TextType>`), not the ONIX 2.1 Codelist 33\n(`<OtherText>` type) that earlier revisions of this schema named. The two lists assign\ndifferent codes to the same concepts — a biographical note is `12` in 153 and `13` in\n33 — so a consumer that reads these codes against Codelist 33 will mislabel them.\n",
"nullable": true,
"example": "12"
},
"mime_type": {
"type": "string",
"description": "How `text` is encoded. In practice two values are used:\n\n- `text/plain` — literal text; line breaks are significant and a consumer must escape\n it before putting it into a web page. The default when the field is omitted on\n create.\n- `text/html` — an HTML fragment, typically wrapped in `<p>` elements. The API stores\n it as sent and does not sanitise it, so a storefront rendering the value unescaped\n is trusting whoever wrote it.\n\nValidation is **syntactic only**: any well-formed `type/subtype[; parameters]` string\nup to 255 characters is accepted, so a misspelling such as `text/htlm` is stored\nwithout complaint and is only noticed when the value is used. A malformed value is\nrejected with `400 Bad Request`, as is an empty one.\n\nBook-trade descriptions are usually HTML, while biographies and tables of contents are\nusually plain text, but nothing in the API enforces that pairing — `mime_type` is\nrecorded independently of `type`.\n",
"example": "text/plain"
}
},
"required": []
}
{
"errors": [
{
"_id": "string",
"stack_trace": [
"string"
],
"message": "string",
"vars": {}
}
]
}
Schema of the response body
{
"type": "object",
"additionalProperties": false,
"required": [
"errors"
],
"properties": {
"errors": {
"type": "array",
"description": "List of errors occurred",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"_id",
"message",
"stack_trace",
"vars"
],
"properties": {
"_id": {
"type": "string",
"description": "The identifier of the error"
},
"stack_trace": {
"type": "array",
"description": "A stacktrace of the error occurred. Only for testing systems.",
"items": {
"type": "string"
}
},
"message": {
"type": "string",
"description": "A translated message of the error"
},
"vars": {
"type": "object",
"description": "A dict containing additional values of the context of the error."
}
}
}
}
}
}
GET /resource/v4/products/{product_id}/texts/{id}
Retrieve a single product text
Description
Returns one text entry. The example is a German blurb held as an HTML fragment and truncated here; a blurb may run to a thousand characters or more.
A text id that exists but belongs to a different product returns 403, not 404 — the record is real, it is simply not reachable through that parent. An id that exists nowhere returns 404.
Input parameters
Path parameters
| Parameter | Type | Default | Nullable | Description |
|---|---|---|---|---|
id |
string | No | UUID of the text entry. | |
product_id |
string | No | UUID of the product. |
Responses
{
"_id": "66a7ef3c-03ab-40ed-abff-4bb22bfa702d",
"_legacy_id": 4180232,
"_version": "4.0",
"_links": {
"self": "https://api.openpublishing.com/resource/v4/products/e86581a9-e616-11ee-a221-00505699575c/texts/66a7ef3c-03ab-40ed-abff-4bb22bfa702d"
},
"type": "description",
"type_onix": "03",
"text": "<p>Als die Restauratorin Juli Sanwald einen unsignierten Wandteppich aus dem Nachlass ihrer Grossmutter uebernimmt, beginnt sie eine Spur zu verfolgen, die drei Generationen zurueckreicht - und die ihre Familie lieber vergessen haette. […]</p>",
"mime_type": "text/html",
"language": "ger",
"channels": []
}
Schema of the response body
{
"type": "object",
"additionalProperties": false,
"description": "One piece of descriptive copy attached to a product, in a single language, tagged by text type.",
"properties": {
"_id": {
"type": "string",
"description": "Unique identifier (UUID) for the product text.",
"example": "3d5a9c14-7b02-4e88-9a61-0c7f2e4d8b35"
},
"_version": {
"type": "string",
"description": "API Version.",
"example": "4.0"
},
"_legacy_id": {
"type": "integer",
"description": "Legacy integer identifier of this resource, kept so existing integrations can correlate their own records. This is the `_id` the same record has on the v3 endpoint.",
"example": 4180231
},
"_links": {
"type": "object"
},
"text": {
"type": "string",
"description": "The text itself. Its interpretation follows `mime_type`: with `text/plain` it is\nliteral characters and line breaks; with `text/html` it is a fragment of markup\n(typically `<p>` paragraphs) that a storefront can drop into a page.\n\nMust not be empty — a create or update that would leave `text` empty is rejected\nwith `400 Bad Request`.\n\nThere is no business length limit: an entry comfortably holds a full table of contents\nor a sample chapter, and the practical ceiling comes from the receiving channel rather\nthan from this API. Characters outside the Basic Multilingual Plane — emoji, and some\nrarely used CJK and historic scripts — are not supported.\n\n**This sub-resource is a standalone store.** It is independent of the legacy\ndescriptive fields carried directly on the v3 product record (`abstract`,\n`abstract_prefix`, `biographical_note`, `table_of_content`): a text written here does\nnot update those, and reading them does not surface entries created here. An entry is\nreachable through this sub-resource and its v3 equivalent, and nowhere else in the\nAPI.\n",
"example": "Marit Sallenberg arbeitete als Lektorin und Kulturjournalistin, bevor sie ihren ersten Roman veroeffentlichte. Sie schreibt Gesellschaftsromane und lebt als freie Autorin in Rheinbergen."
},
"channels": {
"type": "array",
"description": "Distribution channels this text is intended for. An **empty list means the text\napplies to every channel** and is the normal case; it is populated only when a partner\nneeds different copy from everyone else — for example a shortened blurb for a\nretailer with a character limit, or a description that omits a competitor's name.\n\nValues are the platform's distribution-channel slugs. Those in common use are:\n\n- `google`\n- `amazon`\n- `kobo`\n- `spotify`\n- `libri`\n- `ciando`\n- `divibib`\n- `overdrive`\n- `scribd`\n- `bookwire`\n\nThe list is open-ended — a realm distributes through whichever partners it has\ncontracts with. **They are not validated against the channel list** — any string of lowercase letters and\nhyphens is accepted, so a typo silently produces a text that no channel will ever\nmatch. Note that channel slugs containing digits or underscores (`24symbols`,\n`manual_sale`, `zeitfracht_sa02e`) are valid channels elsewhere in the API but are\n**rejected** here, because this field allows only `[a-z-]`.\n\nThe list is normalised on write: values are lower-cased, de-duplicated and sorted\nalphabetically. Sending `[\"Google\", \"amazon\", \"google\"]` stores and returns\n`[\"amazon\", \"google\"]`. On update the list is replaced wholesale, never merged.\n\nThis endpoint applies no fallback logic of its own: it returns the entries exactly as\nstored, so selecting copy for one channel means preferring an entry that names that\nchannel and otherwise taking the unscoped one.\n\n**`channels` is the only scoping axis this resource has, and it is narrower than\nONIX.** An ONIX 3 `<TextContent>` is also scoped by content audience\n([Codelist 154](https://ns.editeur.org/onix/en/154) — booktrade, end-customers,\nlibrarians, press, …) and by text source and validity dates; none of those fields\nexist here. `channels` names distribution partners, not classes of reader.\n\n**Storefronts are a separate axis and are not handled here.** Per-shop copy — HTML\ntitle, meta description, meta keywords — belongs to the\n`/resource/v4/products/{product_id}/storefronts` sub-resource.\n",
"items": {
"type": "string"
},
"example": []
},
"language": {
"type": "string",
"description": "Language of `text`, as a three-letter ISO 639-2/B (bibliographic) code — `ger` for\nGerman, `eng` for English, `fre` for French. Note the B-codes: German is `ger`, not\n`deu`. Case is normalised to lower case on write; an unknown code is rejected with\n`400 Bad Request`.\n\n`null` when the language is unknown or not meaningful. A product carrying the same\n`type` in several languages holds one entry per language — nothing prevents\nduplicates, so a consumer picking \"the description\" should filter by the language it\nwants and fall back to the product's own `language`.\n\nNote that a language once set cannot be cleared: sending `\"language\": null` is\nrejected with `400 Bad Request`.\n",
"nullable": true,
"example": "ger"
},
"type": {
"type": "string",
"description": "What kind of text this is. **Not a closed enumeration** — any non-empty string of\nlowercase letters and hyphens (`[a-z-]`, up to 255 characters) is accepted. Digits,\nunderscores, spaces and upper case are rejected with `400 Bad Request`, as is an\nempty value.\n\n37 slugs are recognised as equivalents of [ONIX Codelist\n153](https://ns.editeur.org/onix/en/153) values; for those the server derives\n`type_onix`. Anything else is stored as given with `type_onix: null`, which is the\nsupported way to carry copy that ONIX has no code for.\n\nA few of the distinctions in the list are easy to get wrong:\n\n- `description` (03) is the main long-form selling copy;\n `short-description-annotation` (02) is the abridged version for listings and feeds\n with a length budget. They are separate entries, not two renderings of one.\n- `biographical-note` (12) is about the author, not about the book, and takes one entry\n per contributor where there are several.\n- `review-quote` (06) is a quotation from a published review of *this* edition;\n `review-quote-previous-edition` (07) and `review-quote-previous-work` (08) exist for\n quotes that refer to something else.\n- `endorsement` (09) is a commendation solicited by the publisher, as distinct from a\n review published independently.\n- `abstract` (30) is the scholarly abstract, not a marketing blurb.\n- `table-of-contents` (04) is conventionally `text/plain` with one heading per line.\n\nThe complete set of recognised slugs, with the [Codelist\n153](https://ns.editeur.org/onix/en/153) code each one derives:\n\n| `type` | `type_onix` | Meaning |\n|---|---|---|\n| `sender-defined-text` | `01` | Sender-defined text |\n| `short-description-annotation` | `02` | Short description / annotation — the abridged blurb for listings and feeds |\n| `description` | `03` | Description — the main long-form selling copy |\n| `table-of-contents` | `04` | Table of contents |\n| `primary-cover-copy` | `05` | Primary cover copy — text printed on the cover or jacket |\n| `review-quote` | `06` | Review quote |\n| `review-quote-previous-edition` | `07` | Review quote, previous edition |\n| `review-quote-previous-work` | `08` | Review quote, previous work |\n| `endorsement` | `09` | Endorsement — solicited by the publisher, unlike a review |\n| `promotional-headline` | `10` | Promotional headline |\n| `feature` | `11` | Feature — a single selling point |\n| `biographical-note` | `12` | Biographical note about a contributor |\n| `publishers-notive` | `13` | Publisher's notice *(slug misspelled — send it exactly as shown)* |\n| `excerpt` | `14` | Excerpt |\n| `index` | `15` | Index |\n| `short-description-annotiation-for-collation` | `16` | Short description for the collection *(slug misspelled — send it exactly as shown)* |\n| `description-for-collection` | `17` | Description for the collection (series) |\n| `new-feature` | `18` | New feature — what changed in this edition |\n| `version-history` | `19` | Version history |\n| `open-access-statement` | `20` | Open access statement |\n| `digital-exclusivity-statement` | `21` | Digital exclusivity statement |\n| `official-recommendation` | `22` | Official recommendation |\n| `jbpa-description` | `23` | JBPA description |\n| `schema-org-snippet` | `24` | schema.org snippet |\n| `errata` | `25` | Errata |\n| `intriduction` | `26` | Introduction *(slug misspelled — send it exactly as shown)* |\n| `secondary-cover-copy` | `27` | Secondary cover copy |\n| `full-cast-and-credit-list` | `28` | Full cast and credit list |\n| `bibliography` | `29` | Bibliography |\n| `abstract` | `30` | Abstract — the scholarly summary, not a marketing blurb |\n| `rules-or-instructions` | `31` | Rules or instructions |\n| `list-of-contents` | `32` | List of contents — components of a multi-item product |\n| `short-description-annotation-for-imprint` | `33` | Short description for the imprint |\n| `description-for-imprint` | `34` | Description for the imprint |\n| `short-description-annotation-for-publisher` | `35` | Short description for the publisher |\n| `description-for-publisher` | `36` | Description for the publisher |\n| `cover-line` | `37` | Cover line |\n\nThree of those slugs — `publishers-notive`, `short-description-annotiation-for-collation`\nand `intriduction` — are misspelled, and the table lists them as they must be sent to\nobtain a code. The correctly spelled forms `publishers-notice`,\n`short-description-annotation-for-collection` and `introduction` are accepted as well,\nbut they are not recognised and yield `type_onix: null`.\n\n**This is the only field the collection endpoint can filter on**, with the operators\ndescribed under [Resource Queries](/resource_queries/). Any other field name is\nrejected with `400 Bad Request`, as is an unknown operator suffix, so `language` and\n`channels` have to be narrowed down client-side. Results cannot be sorted: a `sort`\nparameter is accepted and applied to nothing, which leaves the order of results\nunspecified. Pagination is standard, with a default page size of 100.\n",
"example": "biographical-note",
"x-enum-descriptions": {
"sender-defined-text": "ONIX 153 code 01 — Sender-defined text.",
"short-description-annotation": "ONIX 153 code 02 — Short description/annotation; the abridged blurb for listings and feeds.",
"description": "ONIX 153 code 03 — Description; the main long-form selling copy.",
"table-of-contents": "ONIX 153 code 04 — Table of contents.",
"primary-cover-copy": "ONIX 153 code 05 — Primary cover copy; the text printed on the cover or jacket.",
"review-quote": "ONIX 153 code 06 — Review quote for this edition.",
"review-quote-previous-edition": "ONIX 153 code 07 — Review quote taken from a review of a previous edition.",
"review-quote-previous-work": "ONIX 153 code 08 — Review quote taken from a review of a previous work by the same author.",
"endorsement": "ONIX 153 code 09 — Endorsement; a commendation solicited by the publisher.",
"promotional-headline": "ONIX 153 code 10 — Promotional headline; the one-line hook.",
"feature": "ONIX 153 code 11 — Feature; a single selling point, usually one of a set of bullets.",
"biographical-note": "ONIX 153 code 12 — Biographical note about a contributor.",
"publishers-notive": "ONIX 153 code 13 — Publisher's notice. The slug is misspelled; send it exactly as shown.",
"excerpt": "ONIX 153 code 14 — Excerpt; a sample passage from the work.",
"index": "ONIX 153 code 15 — Index.",
"short-description-annotiation-for-collation": "ONIX 153 code 16 — Short description/annotation for the collection (series) this product belongs to. The slug is misspelled; send it exactly as shown.",
"description-for-collection": "ONIX 153 code 17 — Description of the collection (series) this product belongs to.",
"new-feature": "ONIX 153 code 18 — New feature; what changed in this edition.",
"version-history": "ONIX 153 code 19 — Version history.",
"open-access-statement": "ONIX 153 code 20 — Open access statement; the licence and access terms.",
"digital-exclusivity-statement": "ONIX 153 code 21 — Digital exclusivity statement.",
"official-recommendation": "ONIX 153 code 22 — Official recommendation, e.g. by an educational authority.",
"jbpa-description": "ONIX 153 code 23 — JBPA description (Japanese Book Publishers Association).",
"schema-org-snippet": "ONIX 153 code 24 — schema.org snippet for search-engine markup.",
"errata": "ONIX 153 code 25 — Errata.",
"intriduction": "ONIX 153 code 26 — Introduction. The slug is misspelled; send it exactly as shown.",
"secondary-cover-copy": "ONIX 153 code 27 — Secondary cover copy, e.g. back cover as opposed to front.",
"full-cast-and-credit-list": "ONIX 153 code 28 — Full cast and credit list; used for audiobooks and dramatisations.",
"bibliography": "ONIX 153 code 29 — Bibliography.",
"abstract": "ONIX 153 code 30 — Abstract; the scholarly summary, distinct from a marketing blurb.",
"rules-or-instructions": "ONIX 153 code 31 — Rules or instructions, e.g. for a game or kit.",
"list-of-contents": "ONIX 153 code 32 — List of contents; the components of a multi-item product.",
"short-description-annotation-for-imprint": "ONIX 153 code 33 — Short description/annotation for the imprint.",
"description-for-imprint": "ONIX 153 code 34 — Description of the imprint.",
"short-description-annotation-for-publisher": "ONIX 153 code 35 — Short description/annotation for the publisher.",
"description-for-publisher": "ONIX 153 code 36 — Description of the publisher.",
"cover-line": "ONIX 153 code 37 — Cover line; a strapline carried on the cover."
}
},
"type_onix": {
"type": "string",
"description": "The [ONIX Codelist 153](https://ns.editeur.org/onix/en/153) text type code\ncorresponding to `type`, as a two-digit string (`\"03\"` description, `\"12\"`\nbiographical note, …). Present so that ONIX consumers do not have to reimplement the\nslug mapping.\n\n**Read-only in effect.** The field is accepted in a request body but the value is\ndiscarded: the server recomputes it from `type` on every write. It is `null` whenever\n`type` is not one of the 37 recognised slugs. To change it, change `type`.\n\nNote that this is Codelist **153** (ONIX 3 `<TextType>`), not the ONIX 2.1 Codelist 33\n(`<OtherText>` type) that earlier revisions of this schema named. The two lists assign\ndifferent codes to the same concepts — a biographical note is `12` in 153 and `13` in\n33 — so a consumer that reads these codes against Codelist 33 will mislabel them.\n",
"nullable": true,
"example": "12"
},
"mime_type": {
"type": "string",
"description": "How `text` is encoded. In practice two values are used:\n\n- `text/plain` — literal text; line breaks are significant and a consumer must escape\n it before putting it into a web page. The default when the field is omitted on\n create.\n- `text/html` — an HTML fragment, typically wrapped in `<p>` elements. The API stores\n it as sent and does not sanitise it, so a storefront rendering the value unescaped\n is trusting whoever wrote it.\n\nValidation is **syntactic only**: any well-formed `type/subtype[; parameters]` string\nup to 255 characters is accepted, so a misspelling such as `text/htlm` is stored\nwithout complaint and is only noticed when the value is used. A malformed value is\nrejected with `400 Bad Request`, as is an empty one.\n\nBook-trade descriptions are usually HTML, while biographies and tables of contents are\nusually plain text, but nothing in the API enforces that pairing — `mime_type` is\nrecorded independently of `type`.\n",
"example": "text/plain"
}
},
"required": []
}
{
"errors": [
{
"_id": "string",
"stack_trace": [
"string"
],
"message": "string",
"vars": {}
}
]
}
Schema of the response body
{
"type": "object",
"additionalProperties": false,
"required": [
"errors"
],
"properties": {
"errors": {
"type": "array",
"description": "List of errors occurred",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"_id",
"message",
"stack_trace",
"vars"
],
"properties": {
"_id": {
"type": "string",
"description": "The identifier of the error"
},
"stack_trace": {
"type": "array",
"description": "A stacktrace of the error occurred. Only for testing systems.",
"items": {
"type": "string"
}
},
"message": {
"type": "string",
"description": "A translated message of the error"
},
"vars": {
"type": "object",
"description": "A dict containing additional values of the context of the error."
}
}
}
}
}
}
PUT /resource/v4/products/{product_id}/texts/{id}
Update product text
Description
Updates one text entry. Despite being a PUT this is a partial update: only the
keys present in the body are applied, and every omitted key keeps its current value,
so sending {} changes nothing, and a field cannot be cleared by leaving it out.
Sending an explicit null clears only type_onix — and that has no effect, since
the value is recomputed from type regardless. text, type, mime_type and
language reject null with 400 Bad Request.
channels is replaced wholesale, not merged, so the request must carry the complete
list.
The example replaces the body of an existing table of contents — that of a scholarly
title, truncated here — leaving type, mime_type, language and channels
untouched. The response returns the complete merged record.
Input parameters
Path parameters
| Parameter | Type | Default | Nullable | Description |
|---|---|---|---|---|
id |
string | No | UUID of the text entry. | |
product_id |
string | No | UUID of the product. |
Request body
{
"text": "1. Einleitung 2. Forschungsstand 3. Methodisches Vorgehen 3.1 Korpusauswahl 3.2 Auswertungsverfahren 4. Ergebnisse […] 7. Fazit"
}
Schema of the request body
{
"type": "object",
"additionalProperties": false,
"description": "One piece of descriptive copy attached to a product, in a single language, tagged by text type.",
"properties": {
"_id": {
"type": "string",
"description": "Unique identifier (UUID) for the product text.",
"example": "3d5a9c14-7b02-4e88-9a61-0c7f2e4d8b35"
},
"_version": {
"type": "string",
"description": "API Version.",
"example": "4.0"
},
"_legacy_id": {
"type": "integer",
"description": "Legacy integer identifier of this resource, kept so existing integrations can correlate their own records. This is the `_id` the same record has on the v3 endpoint.",
"example": 4180231
},
"_links": {
"type": "object"
},
"text": {
"type": "string",
"description": "The text itself. Its interpretation follows `mime_type`: with `text/plain` it is\nliteral characters and line breaks; with `text/html` it is a fragment of markup\n(typically `<p>` paragraphs) that a storefront can drop into a page.\n\nMust not be empty — a create or update that would leave `text` empty is rejected\nwith `400 Bad Request`.\n\nThere is no business length limit: an entry comfortably holds a full table of contents\nor a sample chapter, and the practical ceiling comes from the receiving channel rather\nthan from this API. Characters outside the Basic Multilingual Plane — emoji, and some\nrarely used CJK and historic scripts — are not supported.\n\n**This sub-resource is a standalone store.** It is independent of the legacy\ndescriptive fields carried directly on the v3 product record (`abstract`,\n`abstract_prefix`, `biographical_note`, `table_of_content`): a text written here does\nnot update those, and reading them does not surface entries created here. An entry is\nreachable through this sub-resource and its v3 equivalent, and nowhere else in the\nAPI.\n",
"example": "Marit Sallenberg arbeitete als Lektorin und Kulturjournalistin, bevor sie ihren ersten Roman veroeffentlichte. Sie schreibt Gesellschaftsromane und lebt als freie Autorin in Rheinbergen."
},
"channels": {
"type": "array",
"description": "Distribution channels this text is intended for. An **empty list means the text\napplies to every channel** and is the normal case; it is populated only when a partner\nneeds different copy from everyone else — for example a shortened blurb for a\nretailer with a character limit, or a description that omits a competitor's name.\n\nValues are the platform's distribution-channel slugs. Those in common use are:\n\n- `google`\n- `amazon`\n- `kobo`\n- `spotify`\n- `libri`\n- `ciando`\n- `divibib`\n- `overdrive`\n- `scribd`\n- `bookwire`\n\nThe list is open-ended — a realm distributes through whichever partners it has\ncontracts with. **They are not validated against the channel list** — any string of lowercase letters and\nhyphens is accepted, so a typo silently produces a text that no channel will ever\nmatch. Note that channel slugs containing digits or underscores (`24symbols`,\n`manual_sale`, `zeitfracht_sa02e`) are valid channels elsewhere in the API but are\n**rejected** here, because this field allows only `[a-z-]`.\n\nThe list is normalised on write: values are lower-cased, de-duplicated and sorted\nalphabetically. Sending `[\"Google\", \"amazon\", \"google\"]` stores and returns\n`[\"amazon\", \"google\"]`. On update the list is replaced wholesale, never merged.\n\nThis endpoint applies no fallback logic of its own: it returns the entries exactly as\nstored, so selecting copy for one channel means preferring an entry that names that\nchannel and otherwise taking the unscoped one.\n\n**`channels` is the only scoping axis this resource has, and it is narrower than\nONIX.** An ONIX 3 `<TextContent>` is also scoped by content audience\n([Codelist 154](https://ns.editeur.org/onix/en/154) — booktrade, end-customers,\nlibrarians, press, …) and by text source and validity dates; none of those fields\nexist here. `channels` names distribution partners, not classes of reader.\n\n**Storefronts are a separate axis and are not handled here.** Per-shop copy — HTML\ntitle, meta description, meta keywords — belongs to the\n`/resource/v4/products/{product_id}/storefronts` sub-resource.\n",
"items": {
"type": "string"
},
"example": []
},
"language": {
"type": "string",
"description": "Language of `text`, as a three-letter ISO 639-2/B (bibliographic) code — `ger` for\nGerman, `eng` for English, `fre` for French. Note the B-codes: German is `ger`, not\n`deu`. Case is normalised to lower case on write; an unknown code is rejected with\n`400 Bad Request`.\n\n`null` when the language is unknown or not meaningful. A product carrying the same\n`type` in several languages holds one entry per language — nothing prevents\nduplicates, so a consumer picking \"the description\" should filter by the language it\nwants and fall back to the product's own `language`.\n\nNote that a language once set cannot be cleared: sending `\"language\": null` is\nrejected with `400 Bad Request`.\n",
"nullable": true,
"example": "ger"
},
"type": {
"type": "string",
"description": "What kind of text this is. **Not a closed enumeration** — any non-empty string of\nlowercase letters and hyphens (`[a-z-]`, up to 255 characters) is accepted. Digits,\nunderscores, spaces and upper case are rejected with `400 Bad Request`, as is an\nempty value.\n\n37 slugs are recognised as equivalents of [ONIX Codelist\n153](https://ns.editeur.org/onix/en/153) values; for those the server derives\n`type_onix`. Anything else is stored as given with `type_onix: null`, which is the\nsupported way to carry copy that ONIX has no code for.\n\nA few of the distinctions in the list are easy to get wrong:\n\n- `description` (03) is the main long-form selling copy;\n `short-description-annotation` (02) is the abridged version for listings and feeds\n with a length budget. They are separate entries, not two renderings of one.\n- `biographical-note` (12) is about the author, not about the book, and takes one entry\n per contributor where there are several.\n- `review-quote` (06) is a quotation from a published review of *this* edition;\n `review-quote-previous-edition` (07) and `review-quote-previous-work` (08) exist for\n quotes that refer to something else.\n- `endorsement` (09) is a commendation solicited by the publisher, as distinct from a\n review published independently.\n- `abstract` (30) is the scholarly abstract, not a marketing blurb.\n- `table-of-contents` (04) is conventionally `text/plain` with one heading per line.\n\nThe complete set of recognised slugs, with the [Codelist\n153](https://ns.editeur.org/onix/en/153) code each one derives:\n\n| `type` | `type_onix` | Meaning |\n|---|---|---|\n| `sender-defined-text` | `01` | Sender-defined text |\n| `short-description-annotation` | `02` | Short description / annotation — the abridged blurb for listings and feeds |\n| `description` | `03` | Description — the main long-form selling copy |\n| `table-of-contents` | `04` | Table of contents |\n| `primary-cover-copy` | `05` | Primary cover copy — text printed on the cover or jacket |\n| `review-quote` | `06` | Review quote |\n| `review-quote-previous-edition` | `07` | Review quote, previous edition |\n| `review-quote-previous-work` | `08` | Review quote, previous work |\n| `endorsement` | `09` | Endorsement — solicited by the publisher, unlike a review |\n| `promotional-headline` | `10` | Promotional headline |\n| `feature` | `11` | Feature — a single selling point |\n| `biographical-note` | `12` | Biographical note about a contributor |\n| `publishers-notive` | `13` | Publisher's notice *(slug misspelled — send it exactly as shown)* |\n| `excerpt` | `14` | Excerpt |\n| `index` | `15` | Index |\n| `short-description-annotiation-for-collation` | `16` | Short description for the collection *(slug misspelled — send it exactly as shown)* |\n| `description-for-collection` | `17` | Description for the collection (series) |\n| `new-feature` | `18` | New feature — what changed in this edition |\n| `version-history` | `19` | Version history |\n| `open-access-statement` | `20` | Open access statement |\n| `digital-exclusivity-statement` | `21` | Digital exclusivity statement |\n| `official-recommendation` | `22` | Official recommendation |\n| `jbpa-description` | `23` | JBPA description |\n| `schema-org-snippet` | `24` | schema.org snippet |\n| `errata` | `25` | Errata |\n| `intriduction` | `26` | Introduction *(slug misspelled — send it exactly as shown)* |\n| `secondary-cover-copy` | `27` | Secondary cover copy |\n| `full-cast-and-credit-list` | `28` | Full cast and credit list |\n| `bibliography` | `29` | Bibliography |\n| `abstract` | `30` | Abstract — the scholarly summary, not a marketing blurb |\n| `rules-or-instructions` | `31` | Rules or instructions |\n| `list-of-contents` | `32` | List of contents — components of a multi-item product |\n| `short-description-annotation-for-imprint` | `33` | Short description for the imprint |\n| `description-for-imprint` | `34` | Description for the imprint |\n| `short-description-annotation-for-publisher` | `35` | Short description for the publisher |\n| `description-for-publisher` | `36` | Description for the publisher |\n| `cover-line` | `37` | Cover line |\n\nThree of those slugs — `publishers-notive`, `short-description-annotiation-for-collation`\nand `intriduction` — are misspelled, and the table lists them as they must be sent to\nobtain a code. The correctly spelled forms `publishers-notice`,\n`short-description-annotation-for-collection` and `introduction` are accepted as well,\nbut they are not recognised and yield `type_onix: null`.\n\n**This is the only field the collection endpoint can filter on**, with the operators\ndescribed under [Resource Queries](/resource_queries/). Any other field name is\nrejected with `400 Bad Request`, as is an unknown operator suffix, so `language` and\n`channels` have to be narrowed down client-side. Results cannot be sorted: a `sort`\nparameter is accepted and applied to nothing, which leaves the order of results\nunspecified. Pagination is standard, with a default page size of 100.\n",
"example": "biographical-note",
"x-enum-descriptions": {
"sender-defined-text": "ONIX 153 code 01 — Sender-defined text.",
"short-description-annotation": "ONIX 153 code 02 — Short description/annotation; the abridged blurb for listings and feeds.",
"description": "ONIX 153 code 03 — Description; the main long-form selling copy.",
"table-of-contents": "ONIX 153 code 04 — Table of contents.",
"primary-cover-copy": "ONIX 153 code 05 — Primary cover copy; the text printed on the cover or jacket.",
"review-quote": "ONIX 153 code 06 — Review quote for this edition.",
"review-quote-previous-edition": "ONIX 153 code 07 — Review quote taken from a review of a previous edition.",
"review-quote-previous-work": "ONIX 153 code 08 — Review quote taken from a review of a previous work by the same author.",
"endorsement": "ONIX 153 code 09 — Endorsement; a commendation solicited by the publisher.",
"promotional-headline": "ONIX 153 code 10 — Promotional headline; the one-line hook.",
"feature": "ONIX 153 code 11 — Feature; a single selling point, usually one of a set of bullets.",
"biographical-note": "ONIX 153 code 12 — Biographical note about a contributor.",
"publishers-notive": "ONIX 153 code 13 — Publisher's notice. The slug is misspelled; send it exactly as shown.",
"excerpt": "ONIX 153 code 14 — Excerpt; a sample passage from the work.",
"index": "ONIX 153 code 15 — Index.",
"short-description-annotiation-for-collation": "ONIX 153 code 16 — Short description/annotation for the collection (series) this product belongs to. The slug is misspelled; send it exactly as shown.",
"description-for-collection": "ONIX 153 code 17 — Description of the collection (series) this product belongs to.",
"new-feature": "ONIX 153 code 18 — New feature; what changed in this edition.",
"version-history": "ONIX 153 code 19 — Version history.",
"open-access-statement": "ONIX 153 code 20 — Open access statement; the licence and access terms.",
"digital-exclusivity-statement": "ONIX 153 code 21 — Digital exclusivity statement.",
"official-recommendation": "ONIX 153 code 22 — Official recommendation, e.g. by an educational authority.",
"jbpa-description": "ONIX 153 code 23 — JBPA description (Japanese Book Publishers Association).",
"schema-org-snippet": "ONIX 153 code 24 — schema.org snippet for search-engine markup.",
"errata": "ONIX 153 code 25 — Errata.",
"intriduction": "ONIX 153 code 26 — Introduction. The slug is misspelled; send it exactly as shown.",
"secondary-cover-copy": "ONIX 153 code 27 — Secondary cover copy, e.g. back cover as opposed to front.",
"full-cast-and-credit-list": "ONIX 153 code 28 — Full cast and credit list; used for audiobooks and dramatisations.",
"bibliography": "ONIX 153 code 29 — Bibliography.",
"abstract": "ONIX 153 code 30 — Abstract; the scholarly summary, distinct from a marketing blurb.",
"rules-or-instructions": "ONIX 153 code 31 — Rules or instructions, e.g. for a game or kit.",
"list-of-contents": "ONIX 153 code 32 — List of contents; the components of a multi-item product.",
"short-description-annotation-for-imprint": "ONIX 153 code 33 — Short description/annotation for the imprint.",
"description-for-imprint": "ONIX 153 code 34 — Description of the imprint.",
"short-description-annotation-for-publisher": "ONIX 153 code 35 — Short description/annotation for the publisher.",
"description-for-publisher": "ONIX 153 code 36 — Description of the publisher.",
"cover-line": "ONIX 153 code 37 — Cover line; a strapline carried on the cover."
}
},
"type_onix": {
"type": "string",
"description": "The [ONIX Codelist 153](https://ns.editeur.org/onix/en/153) text type code\ncorresponding to `type`, as a two-digit string (`\"03\"` description, `\"12\"`\nbiographical note, …). Present so that ONIX consumers do not have to reimplement the\nslug mapping.\n\n**Read-only in effect.** The field is accepted in a request body but the value is\ndiscarded: the server recomputes it from `type` on every write. It is `null` whenever\n`type` is not one of the 37 recognised slugs. To change it, change `type`.\n\nNote that this is Codelist **153** (ONIX 3 `<TextType>`), not the ONIX 2.1 Codelist 33\n(`<OtherText>` type) that earlier revisions of this schema named. The two lists assign\ndifferent codes to the same concepts — a biographical note is `12` in 153 and `13` in\n33 — so a consumer that reads these codes against Codelist 33 will mislabel them.\n",
"nullable": true,
"example": "12"
},
"mime_type": {
"type": "string",
"description": "How `text` is encoded. In practice two values are used:\n\n- `text/plain` — literal text; line breaks are significant and a consumer must escape\n it before putting it into a web page. The default when the field is omitted on\n create.\n- `text/html` — an HTML fragment, typically wrapped in `<p>` elements. The API stores\n it as sent and does not sanitise it, so a storefront rendering the value unescaped\n is trusting whoever wrote it.\n\nValidation is **syntactic only**: any well-formed `type/subtype[; parameters]` string\nup to 255 characters is accepted, so a misspelling such as `text/htlm` is stored\nwithout complaint and is only noticed when the value is used. A malformed value is\nrejected with `400 Bad Request`, as is an empty one.\n\nBook-trade descriptions are usually HTML, while biographies and tables of contents are\nusually plain text, but nothing in the API enforces that pairing — `mime_type` is\nrecorded independently of `type`.\n",
"example": "text/plain"
}
},
"required": []
}
Responses
{
"_id": "e29bb6c0-dd03-47df-87bd-4b3f3881878c",
"_legacy_id": 4180233,
"_version": "4.0",
"_links": {
"self": "https://api.openpublishing.com/resource/v4/products/a65e2e05-e616-11ee-a221-00505699575c/texts/e29bb6c0-dd03-47df-87bd-4b3f3881878c"
},
"type": "table-of-contents",
"type_onix": "04",
"text": "1. Einleitung 2. Forschungsstand 3. Methodisches Vorgehen 3.1 Korpusauswahl 3.2 Auswertungsverfahren 4. Ergebnisse […] 7. Fazit",
"mime_type": "text/plain",
"language": "ger",
"channels": []
}
Schema of the response body
{
"type": "object",
"additionalProperties": false,
"description": "One piece of descriptive copy attached to a product, in a single language, tagged by text type.",
"properties": {
"_id": {
"type": "string",
"description": "Unique identifier (UUID) for the product text.",
"example": "3d5a9c14-7b02-4e88-9a61-0c7f2e4d8b35"
},
"_version": {
"type": "string",
"description": "API Version.",
"example": "4.0"
},
"_legacy_id": {
"type": "integer",
"description": "Legacy integer identifier of this resource, kept so existing integrations can correlate their own records. This is the `_id` the same record has on the v3 endpoint.",
"example": 4180231
},
"_links": {
"type": "object"
},
"text": {
"type": "string",
"description": "The text itself. Its interpretation follows `mime_type`: with `text/plain` it is\nliteral characters and line breaks; with `text/html` it is a fragment of markup\n(typically `<p>` paragraphs) that a storefront can drop into a page.\n\nMust not be empty — a create or update that would leave `text` empty is rejected\nwith `400 Bad Request`.\n\nThere is no business length limit: an entry comfortably holds a full table of contents\nor a sample chapter, and the practical ceiling comes from the receiving channel rather\nthan from this API. Characters outside the Basic Multilingual Plane — emoji, and some\nrarely used CJK and historic scripts — are not supported.\n\n**This sub-resource is a standalone store.** It is independent of the legacy\ndescriptive fields carried directly on the v3 product record (`abstract`,\n`abstract_prefix`, `biographical_note`, `table_of_content`): a text written here does\nnot update those, and reading them does not surface entries created here. An entry is\nreachable through this sub-resource and its v3 equivalent, and nowhere else in the\nAPI.\n",
"example": "Marit Sallenberg arbeitete als Lektorin und Kulturjournalistin, bevor sie ihren ersten Roman veroeffentlichte. Sie schreibt Gesellschaftsromane und lebt als freie Autorin in Rheinbergen."
},
"channels": {
"type": "array",
"description": "Distribution channels this text is intended for. An **empty list means the text\napplies to every channel** and is the normal case; it is populated only when a partner\nneeds different copy from everyone else — for example a shortened blurb for a\nretailer with a character limit, or a description that omits a competitor's name.\n\nValues are the platform's distribution-channel slugs. Those in common use are:\n\n- `google`\n- `amazon`\n- `kobo`\n- `spotify`\n- `libri`\n- `ciando`\n- `divibib`\n- `overdrive`\n- `scribd`\n- `bookwire`\n\nThe list is open-ended — a realm distributes through whichever partners it has\ncontracts with. **They are not validated against the channel list** — any string of lowercase letters and\nhyphens is accepted, so a typo silently produces a text that no channel will ever\nmatch. Note that channel slugs containing digits or underscores (`24symbols`,\n`manual_sale`, `zeitfracht_sa02e`) are valid channels elsewhere in the API but are\n**rejected** here, because this field allows only `[a-z-]`.\n\nThe list is normalised on write: values are lower-cased, de-duplicated and sorted\nalphabetically. Sending `[\"Google\", \"amazon\", \"google\"]` stores and returns\n`[\"amazon\", \"google\"]`. On update the list is replaced wholesale, never merged.\n\nThis endpoint applies no fallback logic of its own: it returns the entries exactly as\nstored, so selecting copy for one channel means preferring an entry that names that\nchannel and otherwise taking the unscoped one.\n\n**`channels` is the only scoping axis this resource has, and it is narrower than\nONIX.** An ONIX 3 `<TextContent>` is also scoped by content audience\n([Codelist 154](https://ns.editeur.org/onix/en/154) — booktrade, end-customers,\nlibrarians, press, …) and by text source and validity dates; none of those fields\nexist here. `channels` names distribution partners, not classes of reader.\n\n**Storefronts are a separate axis and are not handled here.** Per-shop copy — HTML\ntitle, meta description, meta keywords — belongs to the\n`/resource/v4/products/{product_id}/storefronts` sub-resource.\n",
"items": {
"type": "string"
},
"example": []
},
"language": {
"type": "string",
"description": "Language of `text`, as a three-letter ISO 639-2/B (bibliographic) code — `ger` for\nGerman, `eng` for English, `fre` for French. Note the B-codes: German is `ger`, not\n`deu`. Case is normalised to lower case on write; an unknown code is rejected with\n`400 Bad Request`.\n\n`null` when the language is unknown or not meaningful. A product carrying the same\n`type` in several languages holds one entry per language — nothing prevents\nduplicates, so a consumer picking \"the description\" should filter by the language it\nwants and fall back to the product's own `language`.\n\nNote that a language once set cannot be cleared: sending `\"language\": null` is\nrejected with `400 Bad Request`.\n",
"nullable": true,
"example": "ger"
},
"type": {
"type": "string",
"description": "What kind of text this is. **Not a closed enumeration** — any non-empty string of\nlowercase letters and hyphens (`[a-z-]`, up to 255 characters) is accepted. Digits,\nunderscores, spaces and upper case are rejected with `400 Bad Request`, as is an\nempty value.\n\n37 slugs are recognised as equivalents of [ONIX Codelist\n153](https://ns.editeur.org/onix/en/153) values; for those the server derives\n`type_onix`. Anything else is stored as given with `type_onix: null`, which is the\nsupported way to carry copy that ONIX has no code for.\n\nA few of the distinctions in the list are easy to get wrong:\n\n- `description` (03) is the main long-form selling copy;\n `short-description-annotation` (02) is the abridged version for listings and feeds\n with a length budget. They are separate entries, not two renderings of one.\n- `biographical-note` (12) is about the author, not about the book, and takes one entry\n per contributor where there are several.\n- `review-quote` (06) is a quotation from a published review of *this* edition;\n `review-quote-previous-edition` (07) and `review-quote-previous-work` (08) exist for\n quotes that refer to something else.\n- `endorsement` (09) is a commendation solicited by the publisher, as distinct from a\n review published independently.\n- `abstract` (30) is the scholarly abstract, not a marketing blurb.\n- `table-of-contents` (04) is conventionally `text/plain` with one heading per line.\n\nThe complete set of recognised slugs, with the [Codelist\n153](https://ns.editeur.org/onix/en/153) code each one derives:\n\n| `type` | `type_onix` | Meaning |\n|---|---|---|\n| `sender-defined-text` | `01` | Sender-defined text |\n| `short-description-annotation` | `02` | Short description / annotation — the abridged blurb for listings and feeds |\n| `description` | `03` | Description — the main long-form selling copy |\n| `table-of-contents` | `04` | Table of contents |\n| `primary-cover-copy` | `05` | Primary cover copy — text printed on the cover or jacket |\n| `review-quote` | `06` | Review quote |\n| `review-quote-previous-edition` | `07` | Review quote, previous edition |\n| `review-quote-previous-work` | `08` | Review quote, previous work |\n| `endorsement` | `09` | Endorsement — solicited by the publisher, unlike a review |\n| `promotional-headline` | `10` | Promotional headline |\n| `feature` | `11` | Feature — a single selling point |\n| `biographical-note` | `12` | Biographical note about a contributor |\n| `publishers-notive` | `13` | Publisher's notice *(slug misspelled — send it exactly as shown)* |\n| `excerpt` | `14` | Excerpt |\n| `index` | `15` | Index |\n| `short-description-annotiation-for-collation` | `16` | Short description for the collection *(slug misspelled — send it exactly as shown)* |\n| `description-for-collection` | `17` | Description for the collection (series) |\n| `new-feature` | `18` | New feature — what changed in this edition |\n| `version-history` | `19` | Version history |\n| `open-access-statement` | `20` | Open access statement |\n| `digital-exclusivity-statement` | `21` | Digital exclusivity statement |\n| `official-recommendation` | `22` | Official recommendation |\n| `jbpa-description` | `23` | JBPA description |\n| `schema-org-snippet` | `24` | schema.org snippet |\n| `errata` | `25` | Errata |\n| `intriduction` | `26` | Introduction *(slug misspelled — send it exactly as shown)* |\n| `secondary-cover-copy` | `27` | Secondary cover copy |\n| `full-cast-and-credit-list` | `28` | Full cast and credit list |\n| `bibliography` | `29` | Bibliography |\n| `abstract` | `30` | Abstract — the scholarly summary, not a marketing blurb |\n| `rules-or-instructions` | `31` | Rules or instructions |\n| `list-of-contents` | `32` | List of contents — components of a multi-item product |\n| `short-description-annotation-for-imprint` | `33` | Short description for the imprint |\n| `description-for-imprint` | `34` | Description for the imprint |\n| `short-description-annotation-for-publisher` | `35` | Short description for the publisher |\n| `description-for-publisher` | `36` | Description for the publisher |\n| `cover-line` | `37` | Cover line |\n\nThree of those slugs — `publishers-notive`, `short-description-annotiation-for-collation`\nand `intriduction` — are misspelled, and the table lists them as they must be sent to\nobtain a code. The correctly spelled forms `publishers-notice`,\n`short-description-annotation-for-collection` and `introduction` are accepted as well,\nbut they are not recognised and yield `type_onix: null`.\n\n**This is the only field the collection endpoint can filter on**, with the operators\ndescribed under [Resource Queries](/resource_queries/). Any other field name is\nrejected with `400 Bad Request`, as is an unknown operator suffix, so `language` and\n`channels` have to be narrowed down client-side. Results cannot be sorted: a `sort`\nparameter is accepted and applied to nothing, which leaves the order of results\nunspecified. Pagination is standard, with a default page size of 100.\n",
"example": "biographical-note",
"x-enum-descriptions": {
"sender-defined-text": "ONIX 153 code 01 — Sender-defined text.",
"short-description-annotation": "ONIX 153 code 02 — Short description/annotation; the abridged blurb for listings and feeds.",
"description": "ONIX 153 code 03 — Description; the main long-form selling copy.",
"table-of-contents": "ONIX 153 code 04 — Table of contents.",
"primary-cover-copy": "ONIX 153 code 05 — Primary cover copy; the text printed on the cover or jacket.",
"review-quote": "ONIX 153 code 06 — Review quote for this edition.",
"review-quote-previous-edition": "ONIX 153 code 07 — Review quote taken from a review of a previous edition.",
"review-quote-previous-work": "ONIX 153 code 08 — Review quote taken from a review of a previous work by the same author.",
"endorsement": "ONIX 153 code 09 — Endorsement; a commendation solicited by the publisher.",
"promotional-headline": "ONIX 153 code 10 — Promotional headline; the one-line hook.",
"feature": "ONIX 153 code 11 — Feature; a single selling point, usually one of a set of bullets.",
"biographical-note": "ONIX 153 code 12 — Biographical note about a contributor.",
"publishers-notive": "ONIX 153 code 13 — Publisher's notice. The slug is misspelled; send it exactly as shown.",
"excerpt": "ONIX 153 code 14 — Excerpt; a sample passage from the work.",
"index": "ONIX 153 code 15 — Index.",
"short-description-annotiation-for-collation": "ONIX 153 code 16 — Short description/annotation for the collection (series) this product belongs to. The slug is misspelled; send it exactly as shown.",
"description-for-collection": "ONIX 153 code 17 — Description of the collection (series) this product belongs to.",
"new-feature": "ONIX 153 code 18 — New feature; what changed in this edition.",
"version-history": "ONIX 153 code 19 — Version history.",
"open-access-statement": "ONIX 153 code 20 — Open access statement; the licence and access terms.",
"digital-exclusivity-statement": "ONIX 153 code 21 — Digital exclusivity statement.",
"official-recommendation": "ONIX 153 code 22 — Official recommendation, e.g. by an educational authority.",
"jbpa-description": "ONIX 153 code 23 — JBPA description (Japanese Book Publishers Association).",
"schema-org-snippet": "ONIX 153 code 24 — schema.org snippet for search-engine markup.",
"errata": "ONIX 153 code 25 — Errata.",
"intriduction": "ONIX 153 code 26 — Introduction. The slug is misspelled; send it exactly as shown.",
"secondary-cover-copy": "ONIX 153 code 27 — Secondary cover copy, e.g. back cover as opposed to front.",
"full-cast-and-credit-list": "ONIX 153 code 28 — Full cast and credit list; used for audiobooks and dramatisations.",
"bibliography": "ONIX 153 code 29 — Bibliography.",
"abstract": "ONIX 153 code 30 — Abstract; the scholarly summary, distinct from a marketing blurb.",
"rules-or-instructions": "ONIX 153 code 31 — Rules or instructions, e.g. for a game or kit.",
"list-of-contents": "ONIX 153 code 32 — List of contents; the components of a multi-item product.",
"short-description-annotation-for-imprint": "ONIX 153 code 33 — Short description/annotation for the imprint.",
"description-for-imprint": "ONIX 153 code 34 — Description of the imprint.",
"short-description-annotation-for-publisher": "ONIX 153 code 35 — Short description/annotation for the publisher.",
"description-for-publisher": "ONIX 153 code 36 — Description of the publisher.",
"cover-line": "ONIX 153 code 37 — Cover line; a strapline carried on the cover."
}
},
"type_onix": {
"type": "string",
"description": "The [ONIX Codelist 153](https://ns.editeur.org/onix/en/153) text type code\ncorresponding to `type`, as a two-digit string (`\"03\"` description, `\"12\"`\nbiographical note, …). Present so that ONIX consumers do not have to reimplement the\nslug mapping.\n\n**Read-only in effect.** The field is accepted in a request body but the value is\ndiscarded: the server recomputes it from `type` on every write. It is `null` whenever\n`type` is not one of the 37 recognised slugs. To change it, change `type`.\n\nNote that this is Codelist **153** (ONIX 3 `<TextType>`), not the ONIX 2.1 Codelist 33\n(`<OtherText>` type) that earlier revisions of this schema named. The two lists assign\ndifferent codes to the same concepts — a biographical note is `12` in 153 and `13` in\n33 — so a consumer that reads these codes against Codelist 33 will mislabel them.\n",
"nullable": true,
"example": "12"
},
"mime_type": {
"type": "string",
"description": "How `text` is encoded. In practice two values are used:\n\n- `text/plain` — literal text; line breaks are significant and a consumer must escape\n it before putting it into a web page. The default when the field is omitted on\n create.\n- `text/html` — an HTML fragment, typically wrapped in `<p>` elements. The API stores\n it as sent and does not sanitise it, so a storefront rendering the value unescaped\n is trusting whoever wrote it.\n\nValidation is **syntactic only**: any well-formed `type/subtype[; parameters]` string\nup to 255 characters is accepted, so a misspelling such as `text/htlm` is stored\nwithout complaint and is only noticed when the value is used. A malformed value is\nrejected with `400 Bad Request`, as is an empty one.\n\nBook-trade descriptions are usually HTML, while biographies and tables of contents are\nusually plain text, but nothing in the API enforces that pairing — `mime_type` is\nrecorded independently of `type`.\n",
"example": "text/plain"
}
},
"required": []
}
{
"errors": [
{
"_id": "string",
"stack_trace": [
"string"
],
"message": "string",
"vars": {}
}
]
}
Schema of the response body
{
"type": "object",
"additionalProperties": false,
"required": [
"errors"
],
"properties": {
"errors": {
"type": "array",
"description": "List of errors occurred",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"_id",
"message",
"stack_trace",
"vars"
],
"properties": {
"_id": {
"type": "string",
"description": "The identifier of the error"
},
"stack_trace": {
"type": "array",
"description": "A stacktrace of the error occurred. Only for testing systems.",
"items": {
"type": "string"
}
},
"message": {
"type": "string",
"description": "A translated message of the error"
},
"vars": {
"type": "object",
"description": "A dict containing additional values of the context of the error."
}
}
}
}
}
}
{
"errors": [
{
"_id": "string",
"stack_trace": [
"string"
],
"message": "string",
"vars": {}
}
]
}
Schema of the response body
{
"type": "object",
"additionalProperties": false,
"required": [
"errors"
],
"properties": {
"errors": {
"type": "array",
"description": "List of errors occurred",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"_id",
"message",
"stack_trace",
"vars"
],
"properties": {
"_id": {
"type": "string",
"description": "The identifier of the error"
},
"stack_trace": {
"type": "array",
"description": "A stacktrace of the error occurred. Only for testing systems.",
"items": {
"type": "string"
}
},
"message": {
"type": "string",
"description": "A translated message of the error"
},
"vars": {
"type": "object",
"description": "A dict containing additional values of the context of the error."
}
}
}
}
}
}
DELETE /resource/v4/products/{product_id}/texts/{id}
Delete product text
Description
Removes the text entry permanently; there is no soft delete and no undo. Returns 204 with an empty body. A second delete of the same id returns 404.
Input parameters
Path parameters
| Parameter | Type | Default | Nullable | Description |
|---|---|---|---|---|
id |
string | No | UUID of the text entry. | |
product_id |
string | No | UUID of the product. |
Responses
{
"errors": [
{
"_id": "string",
"stack_trace": [
"string"
],
"message": "string",
"vars": {}
}
]
}
Schema of the response body
{
"type": "object",
"additionalProperties": false,
"required": [
"errors"
],
"properties": {
"errors": {
"type": "array",
"description": "List of errors occurred",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"_id",
"message",
"stack_trace",
"vars"
],
"properties": {
"_id": {
"type": "string",
"description": "The identifier of the error"
},
"stack_trace": {
"type": "array",
"description": "A stacktrace of the error occurred. Only for testing systems.",
"items": {
"type": "string"
}
},
"message": {
"type": "string",
"description": "A translated message of the error"
},
"vars": {
"type": "object",
"description": "A dict containing additional values of the context of the error."
}
}
}
}
}
}
{
"errors": [
{
"_id": "string",
"stack_trace": [
"string"
],
"message": "string",
"vars": {}
}
]
}
Schema of the response body
{
"type": "object",
"additionalProperties": false,
"required": [
"errors"
],
"properties": {
"errors": {
"type": "array",
"description": "List of errors occurred",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"_id",
"message",
"stack_trace",
"vars"
],
"properties": {
"_id": {
"type": "string",
"description": "The identifier of the error"
},
"stack_trace": {
"type": "array",
"description": "A stacktrace of the error occurred. Only for testing systems.",
"items": {
"type": "string"
}
},
"message": {
"type": "string",
"description": "A translated message of the error"
},
"vars": {
"type": "object",
"description": "A dict containing additional values of the context of the error."
}
}
}
}
}
}
Schemas
Product Text
| Name | Type | Description | Example | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
_id |
string |
Unique identifier (UUID) for the product text. |
3d5a9c14-7b02-4e88-9a61-0c7f2e4d8b35 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_legacy_id |
integer |
Legacy integer identifier of this resource, kept so existing integrations can correlate their own records. This is the |
4180231 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_links |
object | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_version |
string |
API Version. |
4.0 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
channels |
Array<string> |
Distribution channels this text is intended for. An empty list means the text applies to every channel and is the normal case; it is populated only when a partner needs different copy from everyone else — for example a shortened blurb for a retailer with a character limit, or a description that omits a competitor's name. Values are the platform's distribution-channel slugs. Those in common use are:
The list is open-ended — a realm distributes through whichever partners it has
contracts with. They are not validated against the channel list — any string of lowercase letters and
hyphens is accepted, so a typo silently produces a text that no channel will ever
match. Note that channel slugs containing digits or underscores ( The list is normalised on write: values are lower-cased, de-duplicated and sorted
alphabetically. Sending This endpoint applies no fallback logic of its own: it returns the entries exactly as stored, so selecting copy for one channel means preferring an entry that names that channel and otherwise taking the unscoped one.
Storefronts are a separate axis and are not handled here. Per-shop copy — HTML
title, meta description, meta keywords — belongs to the
|
[] |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
language |
string| null |
Language of
Note that a language once set cannot be cleared: sending |
ger |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mime_type |
string |
How
Validation is syntactic only: any well-formed Book-trade descriptions are usually HTML, while biographies and tables of contents are
usually plain text, but nothing in the API enforces that pairing — |
text/plain |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
text |
string |
The text itself. Its interpretation follows Must not be empty — a create or update that would leave There is no business length limit: an entry comfortably holds a full table of contents or a sample chapter, and the practical ceiling comes from the receiving channel rather than from this API. Characters outside the Basic Multilingual Plane — emoji, and some rarely used CJK and historic scripts — are not supported. This sub-resource is a standalone store. It is independent of the legacy
descriptive fields carried directly on the v3 product record ( |
Marit Sallenberg arbeitete als Lektorin und Kulturjournalistin, bevor sie ihren ersten Roman veroeffentlichte. Sie schreibt Gesellschaftsromane und lebt als freie Autorin in Rheinbergen. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type |
string |
What kind of text this is. Not a closed enumeration — any non-empty string of
lowercase letters and hyphens ( 37 slugs are recognised as equivalents of ONIX Codelist
153 values; for those the server derives
A few of the distinctions in the list are easy to get wrong:
The complete set of recognised slugs, with the Codelist 153 code each one derives:
Three of those slugs — This is the only field the collection endpoint can filter on, with the operators
described under Resource Queries. Any other field name is
rejected with |
biographical-note |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type_onix |
string| null |
The ONIX Codelist 153 text type code
corresponding to Read-only in effect. The field is accepted in a request body but the value is
discarded: the server recomputes it from Note that this is Codelist 153 (ONIX 3 |
12 |