{"openapi":"3.0.0","info":{"title":"Afineo Webservices API — publishing","description":"Module `publishing` of the Afineo API v3 (22 endpoints).\n\nManage publication projects for catalog and document generation: create publications, manage pages, place products in blocks, assign themes, and control page layout. This is the complete print/digital publishing workflow.\n\nFull specification: https://api.afineo.io/openapi.json","version":"3.0.0","contact":{"name":"Afineo Solutions","url":"https://www.afineo.com"},"x-logo":{"url":"./logo.png","altText":"Afineo - Powerful Data, Powerful People"}},"servers":[{"url":"https://{instance}.afineo.io","description":"Afineo instance","variables":{"instance":{"description":"Your Afineo instance name","default":"client"}}}],"tags":[{"name":"publishing","description":"Manage publication projects for catalog and document generation: create publications, manage pages, place products in blocks, assign themes, and control page layout. This is the complete print/digital publishing workflow."}],"paths":{"/api/v3/publishing/add-block-to-page/":{"post":{"tags":["publishing"],"summary":"Add a single content block to a page","description":"## Purpose\n\nAdds a single content block to a specific publication page. Simplified alternative to add-blocks-to-pages for single block operations.\n\n## Important\n\n`product_block` type creates a block with a template and optional form data, but does NOT assign a product. To assign a product to a block, use POST /api/v3/publishing/place-product-in-page/.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Single block addition response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Block created successfully","description":"Status message"},"result":{"type":"object","properties":{"block_id":{"type":"integer","example":12345,"description":"ID of the created block"},"page_num":{"type":"integer","example":1,"description":"Page number where the block was added"}},"required":["block_id","page_num"],"description":"Created block information"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error, 3 = system error)"},"status_message":{"type":"string","enum":["Page does not exist","Block already exists at this position","Not authorized to modify this page","Block could not be created"],"example":"Page does not exist","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"page_num":{"type":"integer","description":"Page number (1-based). Use POST /api/v3/publishing/pages to list available pages.","example":1},"block":{"type":"object","description":"Block information object with type, position, dimensions. product_block creates a block with template/form but no product — use place-product-in-page to assign a product afterwards.","example":{"type":"product_block","x_position":10,"y_position":20,"width":60,"height":40,"asset_template_id":22,"rank":3,"form_datas":{"123":"Cuisine","456":"Promo","789":"P1"}},"properties":{"type":{"type":"string","description":"Block type. product_block creates a block with a template and optional form data (no product assignment — use place-product-in-page for that). Other types: empty_block, text_block, image_block, or notepad types.","enum":["product_block","empty_block","text_block","image_block","image_note","square_note","text_note","attention_pin_note","question_pin_note","information_pin_note","simple_note"]},"x_position":{"type":"integer","description":"Block X position in mm from the left edge of the page"},"y_position":{"type":"integer","description":"Block Y position in mm from the top edge of the page"},"width":{"type":"integer","description":"Block width in mm. Must be a positive value"},"height":{"type":"integer","description":"Block height in mm. Must be a positive value"},"rank":{"type":"integer","description":"Block z-index position for layering. Higher values display on top of lower values. Default: 0."},"html_content":{"type":"string","description":"HTML content (required for text_block and notepad types) **⚠️ Required when:** `type` = `text_block` | `image_note` | `square_note` | `text_note` | `attention_pin_note` | `question_pin_note` | `information_pin_note` | `simple_note`","x-conditional-required":{"type":["text_block","image_note","square_note","text_note","attention_pin_note","question_pin_note","information_pin_note","simple_note"]}},"asset_template_id":{"type":"integer","description":"Product template ID for rendering (applicable to product_block type). If omitted, uses the publication default, then the library default. There is no dedicated API endpoint to list templates; inspect existing blocks via POST /api/v3/publishing/page-details (profil_id and profil_label fields)."},"section_id":{"type":"integer","description":"Section ID for text categorization (applicable to text_block type). Sections are configured at library administration level. There is no API endpoint to list sections; contact your administrator."},"form_datas":{"type":"object","description":"Form data as {attribute_id: \"value\"} pairs (applicable to product_block type). All values must be strings. Use POST /api/v3/attributes/list with class_id to get available attribute IDs."}},"required":["type","x_position","y_position","width","height"]}},"required":["class_id","project_node_id","page_num","block"]}}}}}},"/api/v3/publishing/add-blocks-to-pages/":{"post":{"tags":["publishing"],"summary":"Add content blocks to pages","description":"## Purpose\n\nDefines page layout by adding content blocks to publication pages. Configure block positioning and content for print catalog production.\n\n## Important\n\n`product_block` type creates a block with a template and optional form data, but does NOT assign a product. To assign a product to a block, use POST /api/v3/publishing/place-product-in-page/ or POST /api/v3/publishing/place-products-in-pages/.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Publication blocks addition response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"OK - but 2 existing blocks","description":"Status message (empty string for success)"},"result":{"type":"object","properties":{"nb_pages_modified":{"type":"integer","example":1,"description":"Number of pages that were modified"},"nb_blocks_created":{"type":"integer","example":3,"description":"Number of new blocks created"},"nb_blocks_updated":{"type":"integer","example":1,"description":"Number of existing blocks updated via attribute_key UPSERT"},"created_blocks":{"type":"array","nullable":true,"items":{"type":"integer"},"example":[12345,12346],"description":"List of created block IDs (only present if blocks were created). Use these IDs with place-product-in-page block_id parameter."},"updated_blocks":{"type":"array","nullable":true,"items":{"type":"integer"},"example":[456],"description":"List of updated block IDs (only present if blocks were updated via UPSERT)"},"pages_not_exist":{"type":"array","nullable":true,"items":{"type":"integer"},"example":[2,3],"description":"List of page numbers that do not exist (optional)"},"existing_blocks":{"type":"array","nullable":true,"items":{"type":"object"},"example":[],"description":"List of blocks that already exist at the same position (optional)"},"pages_unauthorized":{"type":"array","nullable":true,"items":{"type":"integer"},"example":[4],"description":"List of page numbers where user is not authorized (optional)"}},"required":["nb_pages_modified","nb_blocks_created","nb_blocks_updated"],"description":"Block addition result with statistics"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":3,"description":"Status code (3 = error, 0 = validation failed)"},"status_message":{"type":"string","example":"Invalid block type or missing required parameters","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"pages":{"type":"array","description":"List of pages with blocks. A page can contain multiple blocks. Each block requires: \"type\" (use enum values: empty_block, text_block, image_block, or notepad types), \"x_position\", \"y_position\", \"width\", \"height\". Additional fields by type: text_block supports \"html_content\" and \"section_id\"; notepad types support \"html_content\". For product blocks, use POST /api/v3/publishing/place-product-in-page/ or place-products-in-pages/ instead. (Array of objects - see example for structure)","example":[{"page_num":1,"blocks":[{"type":"empty_block","x_position":10,"y_position":20,"width":60,"height":40,"rank":2},{"type":"text_block","x_position":16,"y_position":178,"width":60,"height":40,"html_content":"Advertising block","section_id":10},{"type":"product_block","x_position":10,"y_position":80,"width":60,"height":40,"asset_template_id":22,"rank":3,"form_datas":{"123":"Cuisine","456":"Promo","789":"P1"}}]}],"items":{"type":"object","properties":{"page_num":{"type":"integer","description":"Page number (1-based index). First page is 1"},"blocks":{"type":"array","description":"List of blocks on the page with their properties and positions. (Array of objects - see example for structure)","items":{"type":"object","properties":{"type":{"type":"string","description":"Block type. product_block creates a block with a template and optional form data (no product assignment — use place-product-in-page for that). Other types: empty_block, text_block, image_block, or notepad types.","enum":["product_block","empty_block","text_block","image_block","image_note","square_note","text_note","attention_pin_note","question_pin_note","information_pin_note","simple_note"]},"x_position":{"type":"integer","description":"Block X position in mm from the left edge of the page"},"y_position":{"type":"integer","description":"Block Y position in mm from the top edge of the page"},"width":{"type":"integer","description":"Block width in mm. Must be a positive value"},"height":{"type":"integer","description":"Block height in mm. Must be a positive value"},"rank":{"type":"integer","description":"Block z-index position for layering. Higher values display on top of lower values. Default: 0."},"html_content":{"type":"string","description":"HTML content (required for text_block and notepad types) **⚠️ Required when:** `type` = `text_block` | `image_note` | `square_note` | `text_note` | `attention_pin_note` | `question_pin_note` | `information_pin_note` | `simple_note`","x-conditional-required":{"type":["text_block","image_note","square_note","text_note","attention_pin_note","question_pin_note","information_pin_note","simple_note"]}},"asset_template_id":{"type":"integer","description":"Product template ID for rendering (applicable to product_block type). If omitted, uses the publication default, then the library default. There is no dedicated API endpoint to list templates; inspect existing blocks via POST /api/v3/publishing/page-details (profil_id and profil_label fields)."},"section_id":{"type":"integer","description":"Section ID for text categorization (applicable to text_block type). Sections are configured at library administration level. There is no API endpoint to list sections; contact your administrator."},"attribute_key":{"type":"integer","description":"Attribute ID used as lookup key for UPSERT mode. If a block already exists in the project with this attribute value (from form_datas), it will be updated instead of creating a new one. The attribute must be indexed. Use POST /api/v3/attributes/list with class_id to get attribute IDs."},"form_datas":{"type":"object","description":"Form data as {attribute_id: \"value\"} pairs. All values must be strings, even for numeric attributes. Use POST /api/v3/attributes/list with class_id to get available attribute IDs."}},"required":["type","x_position","y_position","width","height"],"title":"Item"}}},"required":["page_num","blocks"],"title":"Item"}}},"required":["class_id","project_node_id","pages"]}}}}}},"/api/v3/publishing/add-empty-block/":{"post":{"tags":["publishing"],"summary":"Add an empty block to a page","description":"## Purpose\n\nCreates an empty placeholder block on a publication page. Empty blocks reserve space for future product placement.\n\n## When to use\n\nUse this endpoint to create placeholder blocks that will later receive products via place-product-in-page.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Empty block creation response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Block created successfully","description":"Status message"},"result":{"type":"object","properties":{"block_id":{"type":"integer","example":12345,"description":"ID of the created block"},"page_num":{"type":"integer","example":1,"description":"Page number where the block was added"}},"required":["block_id","page_num"],"description":"Created block information"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error, 3 = system error)"},"status_message":{"type":"string","enum":["Page does not exist","Block already exists at this position","Not authorized to modify this page","Block could not be created"],"example":"Page does not exist","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"page_num":{"type":"integer","description":"Page number (1-based). Use POST /api/v3/publishing/pages to list available pages.","example":1},"x_position":{"type":"integer","description":"X position in mm from the left edge of the page.","example":10},"y_position":{"type":"integer","description":"Y position in mm from the top edge of the page.","example":20},"width":{"type":"integer","description":"Block width in mm. Must be a positive value.","example":80},"height":{"type":"integer","description":"Block height in mm. Must be a positive value.","example":100},"rank":{"type":"integer","description":"Block placement order (z-index). Higher values display on top. Default: 0.","example":0}},"required":["class_id","project_node_id","page_num","x_position","y_position","width","height"]}}}}}},"/api/v3/publishing/add-notepad/":{"post":{"tags":["publishing"],"summary":"Add a notepad to a page","description":"## Purpose\n\nCreates a notepad element on a publication page. Notepads are annotation elements for collaboration (pins, simple notes).\n\n## Notepad Types\n\n- `attention_pin_note`: Orange pin marker for attention items\n- `question_pin_note`: Blue pin marker for questions\n- `information_pin_note`: Green pin marker for information\n- `simple_note`: Full-page simple note (positions ignored)\n\n## Position Requirements\n\nFor all pin types, x_position, y_position, width, and height are required.\nFor `simple_note` type, these parameters are ignored as simple notes are page-level annotations.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Notepad creation response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Notepad created successfully","description":"Status message"},"result":{"type":"object","properties":{"block_id":{"type":"integer","example":12345,"description":"ID of the created notepad block"},"page_num":{"type":"integer","example":1,"description":"Page number where the notepad was added"},"notepad_type":{"type":"string","example":"attention_pin","description":"Type of notepad created"}},"required":["block_id","page_num","notepad_type"],"description":"Created notepad information"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error, 3 = system error)"},"status_message":{"type":"string","enum":["Page does not exist","Not authorized to modify this page","Notepad could not be created","Parameter 'x_position' is required for notepad type 'attention_pin'"],"example":"Page does not exist","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"page_num":{"type":"integer","description":"Page number (1-based). Use POST /api/v3/publishing/pages to list available pages.","example":1},"notepad_type":{"type":"string","description":"Notepad type. For \"simple_note\", positions are ignored.","enum":["attention_pin_note","question_pin_note","information_pin_note","simple_note"],"example":"attention_pin_note"},"html_content":{"type":"string","description":"HTML content for the notepad block. Supports basic formatting tags.","example":"<p>Please review this section</p>"},"x_position":{"type":"integer","description":"X position in mm (required except for simple_note type)","example":50},"y_position":{"type":"integer","description":"Y position in mm (required except for simple_note type)","example":100},"width":{"type":"integer","description":"Width in mm (required except for simple_note type)","example":8},"height":{"type":"integer","description":"Height in mm (required except for simple_note type)","example":8}},"required":["class_id","project_node_id","page_num","notepad_type","html_content"]}}}}}},"/api/v3/publishing/add-product-to-page/":{"post":{"tags":["publishing"],"summary":"Add a product to a publication page tree","description":"## Purpose\n\nAdds a product from the repository to a publication page tree. The product becomes a child of the page, making it available for block placement via place-product-in-page.\n\n## When to use\n\nUse this endpoint to populate a page with products before placing them in blocks. This is the first step in the product placement workflow.\n\n## When NOT to use\n\n- To place a product in a block (with coordinates or block_id) → use POST /api/v3/publishing/place-product-in-page/\n- If the product is already in the page tree → this endpoint will return the existing node_id without duplicating\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Product addition response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Product added to page successfully","description":"Status message"},"result":{"type":"object","properties":{"node_id":{"type":"integer","example":12345,"description":"Node ID of the product in the page tree. Use this value as node_id in place-product-in-page."},"page_num":{"type":"integer","example":1,"description":"Page number"},"already_in_page":{"type":"boolean","example":false,"description":"Whether the product was already present in the page tree (true) or newly added (false)"}},"required":["node_id","page_num","already_in_page"],"description":"Product addition result"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error)"},"status_message":{"type":"string","enum":["Publication not found","Page does not exist","Product asset not found","Could not add product to page tree"],"example":"Product asset not found","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"page_num":{"type":"integer","description":"Page number (1-based). Use POST /api/v3/publishing/pages to list available pages.","example":1},"asset_id":{"type":"integer","description":"Product asset ID from the repository (unique database identifier). Use POST /api/v3/get-asset/by-search/ to find product asset IDs.","example":638116}},"required":["class_id","project_node_id","page_num","asset_id"]}}}}}},"/api/v3/publishing/add-products-to-pages/":{"post":{"tags":["publishing"],"summary":"Add products to publication pages (batch)","description":"## Purpose\n\nBatch endpoint for adding products from the repository to multiple publication pages. Each product becomes a child of its target page.\n\n## When to use\n\nUse this endpoint to populate multiple pages with products in a single call. More efficient than calling add-product-to-page repeatedly.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Batch product addition response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"","description":"Status message (empty for full success)"},"result":{"type":"object","properties":{"nb_pages_modified":{"type":"integer","example":2,"description":"Number of pages that received products"},"nb_products_added":{"type":"integer","example":5,"description":"Number of products added"},"products":{"type":"array","items":{"type":"object","properties":{"node_id":{"type":"integer","example":12345,"description":"Node ID of the product in the page tree"},"page_num":{"type":"integer","example":1,"description":"Page number where the product was added"},"already_in_page":{"type":"boolean","example":false,"description":"Whether the product was already in the page (true) or newly added (false)"}}},"description":"List of added products with node IDs"},"errors":{"type":"array","nullable":true,"items":{"type":"object","properties":{"page_num":{"type":"integer","description":"Page number where the error occurred"},"asset_id":{"type":"integer","description":"Asset ID that caused the error"},"message":{"type":"string","description":"Error message"}}},"description":"List of errors for individual products (optional, present on partial success)"}},"required":["nb_pages_modified","nb_products_added","products"],"description":"Batch addition result"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error)"},"status_message":{"type":"string","example":"The parameter \"pages\" must be not empty","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"pages":{"type":"array","description":"List of pages with products to add. Each entry requires a page_num (1-based) and an asset_ids array of product asset IDs from the repository. (Array of objects - see example for structure)","example":[{"page_num":1,"asset_ids":[638116,638117,638118]},{"page_num":2,"asset_ids":[638200,638201]}],"items":{"type":"object","properties":{"page_num":{"type":"integer","description":"Page number (1-based index). First page is 1"},"asset_ids":{"type":"array","description":"List of product asset IDs to add to this page. Use POST /api/v3/get-asset/by-search/ to find asset IDs.","items":{"type":"integer"}}},"required":["page_num","asset_ids"],"title":"Item"}}},"required":["class_id","project_node_id","pages"]}}}}}},"/api/v3/publishing/add-text-block/":{"post":{"tags":["publishing"],"summary":"Add a text block to a page","description":"## Purpose\n\nCreates a text block with HTML content on a publication page. Text blocks display formatted content independently of products.\n\n## When to use\n\nUse this endpoint for adding titles, descriptions, promotional text, or any standalone HTML content to a page.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Text block creation response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Block created successfully","description":"Status message"},"result":{"type":"object","properties":{"block_id":{"type":"integer","example":12345,"description":"ID of the created block"},"page_num":{"type":"integer","example":1,"description":"Page number where the block was added"}},"required":["block_id","page_num"],"description":"Created block information"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error, 3 = system error)"},"status_message":{"type":"string","enum":["Page does not exist","Block already exists at this position","Not authorized to modify this page","Block could not be created"],"example":"Page does not exist","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"page_num":{"type":"integer","description":"Page number (1-based). Use POST /api/v3/publishing/pages to list available pages.","example":1},"x_position":{"type":"integer","description":"X position in mm from the left edge of the page.","example":10},"y_position":{"type":"integer","description":"Y position in mm from the top edge of the page.","example":20},"width":{"type":"integer","description":"Block width in mm. Must be a positive value.","example":80},"height":{"type":"integer","description":"Block height in mm. Must be a positive value.","example":30},"html_content":{"type":"string","description":"HTML content for the text block. Supports basic formatting tags.","example":"<h1>Section Title</h1><p>Description text</p>"},"section_id":{"type":"integer","description":"Section ID for text block categorization. Sections are configured at library administration level. There is no API endpoint to list sections; contact your administrator.","example":10}},"required":["class_id","project_node_id","page_num","x_position","y_position","width","height","html_content"]}}}}}},"/api/v3/publishing/add-theme-to-page/":{"post":{"tags":["publishing"],"summary":"Associate a single theme to a single page","description":"## Purpose\n\nAssigns a single theme to a specific publication page. Simplified alternative to add-themes-to-pages for single operations.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Single theme to page association response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Theme associated successfully","description":"Status message"},"result":{"type":"object","properties":{"page_num":{"type":"integer","example":4,"description":"Page number where the theme was added"},"theme":{"type":"string","example":"Music","description":"Theme name that was associated"}},"required":["page_num","theme"],"description":"Theme association result"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error, 3 = system error)"},"status_message":{"type":"string","enum":["Page does not exist","Theme does not exist","Theme is already associated to this page","Not authorized to modify this page"],"example":"Page does not exist","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"page_num":{"type":"integer","description":"Page number (1-based). Use POST /api/v3/publishing/pages to list available pages.","example":4},"theme":{"type":"string","description":"Theme name to associate. Themes are configured at publication level.","example":"Music"}},"required":["class_id","project_node_id","page_num","theme"]}}}}}},"/api/v3/publishing/add-themes-to-pages/":{"post":{"tags":["publishing"],"summary":"Associate themes to pages","description":"## Purpose\n\nAssigns thematic categories to publication pages. Use for organizing print catalog content by themes (seasonal, product families, promotional sections).\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Publication themes addition response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"OK - but 4 unauthorized pages (2, 3)","description":"Status message"},"result":{"type":"object","properties":{"nb_pages_modified":{"type":"integer","example":1,"description":"Number of pages that were modified"},"themes_not_exist":{"type":"array","nullable":true,"items":{"type":"string"},"example":["Music","Board games"],"description":"List of themes that do not exist (optional)"},"pages_not_exist":{"type":"array","nullable":true,"items":{"type":"integer"},"example":[2,3],"description":"List of page numbers that do not exist (optional)"},"pages_unauthorized":{"type":"array","nullable":true,"items":{"type":"integer"},"example":[2,3],"description":"List of page numbers that are not allowed (optional)"}},"required":["nb_pages_modified"],"description":"Theme addition result with statistics"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":3,"description":"Status code (3 = error, 0 = validation failed)"},"status_message":{"type":"string","example":"Project not found or invalid parameters","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"pages":{"type":"array","description":"List of pages with theme names. A page can contain multiple themes. Format : array(array(\"page_num\" => 1, \"themes\" => array(theme_name_1, theme_name_2)), ...) (Array of objects - see example for structure)","example":[{"page_num":4,"themes":["Music"]},{"page_num":6,"themes":["Music","Board games"]}],"items":{"type":"object","properties":{"page_num":{"type":"integer","description":"Page number (1-based index). First page is 1"},"themes":{"type":"array","description":"List of theme names. Themes are configured at publication level","items":{"type":"string"}}},"required":["page_num","themes"],"title":"Item"}}},"required":["class_id","project_node_id","pages"]}}}}}},"/api/v3/publishing/create/":{"post":{"tags":["publishing"],"summary":"Create new project","description":"## Purpose\n\nCreates a new publication or catalog project within a project group. Configure project type, page dimensions, and initial settings.\n\n## Project Types\n\n- `publication`: Print publication with page layout and blocks\n- `catalog_with_pagination`: Digital catalog with pagination support\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Project creation response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"","description":"Status message (empty string for success)"},"result":{"type":"object","properties":{"id":{"type":"integer","example":956408,"description":"Node ID of the created project"},"node_id":{"type":"integer","example":956408,"description":"Node ID of the created project"},"asset_id":{"type":"integer","example":24923,"description":"Asset ID of the created project"}},"required":["id","node_id","asset_id"],"description":"Created project information - simplified structure"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","enum":[2,3],"example":2,"description":"Status code (2 = validation error/business logic error, 3 = system error)"},"status_message":{"type":"string","enum":["The parameter \"template_id\" must be a valid integer","There is an issue with the data sent in the parameter \"versions_id\" : one of the items in the array is not a valid integer.","There is an issue with the data sent in the parameter \"start_date\" : the value is invalid, expected ISO 8601 date format (2025-11-06T10:00:00Z or 2025-11-06T10:00:00Z+02:00).","There is an issue with the data sent in the parameter \"end_date\" : the value is invalid, expected ISO 8601 date format (2025-11-06T10:00:00Z or 2025-11-06T10:00:00Z+02:00).","There is an issue with the data sent in the parameter \"themes_configuration\" : each key must be a valid string and not empty.","There is an issue with the data sent in the parameter \"themes_configuration\" : each value must be a valid string and not empty and must match a hexadecimal code (with or without #).","Parent workspace does not exist","Project could not be created","Publication could not be created"],"example":"The parameter \"template_id\" must be a valid integer","description":"Specific error message describing the validation or business logic failure"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"workspace_node_id":{"type":"integer","description":"Workspace node ID (project group). Use POST /api/v3/publishing/list with class_id to find workspace nodes.","example":6726},"label":{"type":"string","description":"Label/name for the new publication project.","example":"Christmas 2025"},"project_type":{"type":"string","description":"Project type: \"publication\" (paginated document with layout) or \"catalog_with_pagination\" (catalog with automatic pagination).","enum":["publication","catalog_with_pagination"],"example":"publication"},"template_id":{"type":"integer","description":"Project template ID (optional). Creates a blank project if omitted. There is currently no API endpoint to list project templates. You can inspect existing projects via POST /api/v3/publishing/list as reference.","example":25},"default_version_id":{"type":"integer","description":"Default version ID for the project. Use POST /api/v3/administration/versions/list with class_id to get available versions.","example":1},"versions_id":{"type":"array","description":"List of version IDs for the project. Use POST /api/v3/administration/versions/list to get versions.","example":[1,2,3],"items":{"type":"integer"}},"tree_default_display":{"type":"string","description":"Default tree to display : \"dynamic\" or \"virtual\"","enum":["dynamic","virtual"],"example":"virtual"},"start_date":{"type":"string","description":"Project start date in ISO 8601 format (e.g., 2025-01-01T00:00:00Z).","example":"2025-01-01T00:00:00Z"},"end_date":{"type":"string","description":"Project end date in ISO 8601 format (e.g., 2025-12-31T23:59:59Z).","example":"2025-12-31T23:59:59Z"},"page_width":{"type":"integer","description":"Page width in mm for publication layout **⚠️ Required when:** `project_type` = `publication`","example":210,"x-conditional-required":{"project_type":["publication"]}},"page_height":{"type":"integer","description":"Page height in mm for publication layout **⚠️ Required when:** `project_type` = `publication`","example":297,"x-conditional-required":{"project_type":["publication"]}},"page_margin":{"type":"array","description":"Page margin information (for publication) (Array of objects - see example for structure)","example":{"top":5,"left":5,"right":5,"bottom":5},"items":{"type":"object","properties":{"top":{"type":"integer","description":"Top page margin in millimeters. Default value: 0"},"left":{"type":"integer","description":"Left page margin in millimeters. Default value: 0"},"right":{"type":"integer","description":"Right page margin in millimeters. Default value: 0"},"bottom":{"type":"integer","description":"Bottom page margin in millimeters. Default value: 0"}},"title":"Item"}},"number_of_pages":{"type":"integer","description":"Number of pages to create (for publication)","example":10},"easycatalog_export_mapping_id":{"type":"integer","description":"Export mapping ID for EasyCatalog. Use POST /api/v3/mappings/list with type=\"export\" to get mappings.","example":251},"page_start_number":{"type":"integer","description":"Starting page numbering (for publication)","example":1},"themes_configuration":{"type":"object","description":"List of theme configurations for publication layout organization. Color values accept hexadecimal codes with or without # prefix (e.g. \"4169e1\" or \"#4169e1\").","example":{"Music":"4169e1","Board games":"#228b22"}},"attribute_list":{"type":"array","description":"List of attributes to update on the project asset. List of properties to apply : \"attribute_id\", \"value\" (Array of objects - see example for structure)","example":[{"attribute_id":231,"value":"Christmas 2025 Edition"},{"attribute_id":658,"value":"1234"}],"items":{"type":"object","properties":{"attribute_id":{"type":"integer","description":"Attribute ID. Use POST /api/v3/attributes/list with class_id to get available attributes."},"value":{"type":"string","description":"Value to set. Format depends on attribute type (text, date, list)"}},"required":["attribute_id","value"],"title":"Item"}},"start_workflow":{"type":"boolean","description":"If true, automatically starts the project workflow after creation. Requires the project to be created from a template containing workflows (template_id must be set and the template must define workflows). Default: false (workflow must be started manually).","example":true}},"required":["class_id","workspace_node_id","label","project_type"]}}}}}},"/api/v3/publishing/delete-block-to-page/":{"post":{"tags":["publishing"],"summary":"Remove a content block from a page","description":"## Purpose\n\nDeletes a content block from a publication page. Also removes any associated form data.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Block deletion response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Block deleted successfully","description":"Status message"},"result":{"type":"object","properties":{"block_id":{"type":"integer","example":12345,"description":"ID of the deleted block"}},"required":["block_id"],"description":"Deleted block information"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error, 3 = system error)"},"status_message":{"type":"string","enum":["Block not found","No form data in block","Not authorized to delete the block"],"example":"Block not found","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"block_id":{"type":"integer","description":"Block ID to delete. Use POST /api/v3/publishing/page-details with project_node_id and page_num to get block IDs.","example":12345}},"required":["block_id"]}}}}}},"/api/v3/publishing/delete-theme-to-page/":{"post":{"tags":["publishing"],"summary":"Remove a theme from a page","description":"## Purpose\n\nRemoves a theme from a specific publication page. Reverse operation of add-theme-to-page.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Theme removal from page response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Theme removed successfully","description":"Status message"},"result":{"type":"object","properties":{"page_num":{"type":"integer","example":4,"description":"Page number from which the theme was removed"},"theme":{"type":"string","example":"Music","description":"Theme name that was removed"}},"required":["page_num","theme"],"description":"Theme removal result"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error, 3 = system error)"},"status_message":{"type":"string","enum":["Page does not exist","Theme does not exist","Theme is not associated to this page","Not authorized to modify this page"],"example":"Page does not exist","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"page_num":{"type":"integer","description":"Page number (1-based). Use POST /api/v3/publishing/pages to list available pages.","example":4},"theme":{"type":"string","description":"Theme name to remove. Use POST /api/v3/publishing/page-details with project_node_id and page_num to see current page themes.","example":"Music"}},"required":["class_id","project_node_id","page_num","theme"]}}}}}},"/api/v3/publishing/details/":{"post":{"tags":["publishing"],"summary":"Get publication details","description":"## Purpose\n\nReturns complete details of a publication including dimensions, page count, display mode, and associated themes.\n\n## When to use\n\nUse this endpoint to:\n- Get an overview of a publication before working with its pages\n- Retrieve publication metadata (dimensions, page count)\n- List all themes configured for a publication\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Publication details response","content":{"application/json":{"schema":{"type":"object","properties":{"status_code":{"type":"integer","example":1},"status_message":{"type":"string","example":"Success"},"result":{"type":"object","properties":{"id":{"type":"integer","description":"Publication ID"},"node_id":{"type":"integer","description":"Publication node ID"},"label":{"type":"string","description":"Publication name"},"project_type":{"type":"string","enum":["publication","catalog_with_pagination"],"description":"Project type"},"nb_pages":{"type":"integer","description":"Total number of pages"},"page_width":{"type":"integer","description":"Page width in mm"},"page_height":{"type":"integer","description":"Page height in mm"},"display_mode":{"type":"string","enum":["single","double"],"description":"Page display mode: single (one page at a time) or double (two-page spread)"},"created_at":{"type":"string","description":"Creation date"},"themes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"label":{"type":"string"},"color":{"type":"string"}}}}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556}},"required":["class_id","project_node_id"]}}}}}},"/api/v3/publishing/get-block-form-by-attribute/":{"post":{"tags":["publishing"],"summary":"Get forms in a project by attribute value","description":"## Purpose\n\nRetrieves all forms in a publication project matching a specific attribute value. Useful for finding forms based on their content.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Forms search response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"","description":"Status message"},"result":{"type":"object","properties":{"results_total":{"type":"integer","example":2,"description":"Total number of forms found"},"items":{"type":"array","items":{"type":"object","properties":{"form_id":{"type":"integer","example":12345,"description":"Form asset ID"},"block":{"type":"object","properties":{"id":{"type":"integer","example":456,"description":"Block ID"},"type":{"type":"string","example":"product_block","description":"Block type: product_block, empty_block, text_block, image_block, or notepad types (image_note, etc.)"},"x_position":{"type":"integer","example":10,"description":"Block X position in mm from the left edge of the page"},"y_position":{"type":"integer","example":20,"description":"Block Y position in mm from the top edge of the page"},"width":{"type":"integer","example":60,"description":"Block width in mm. Must be a positive value"},"height":{"type":"integer","example":40,"description":"Block height in mm. Must be a positive value"},"node_id":{"type":"integer","example":789,"description":"Product node ID"},"asset_template_id":{"type":"integer","example":22,"description":"Asset template ID"}},"description":"Block information"},"page":{"type":"object","properties":{"page_num":{"type":"integer","example":1,"description":"Page number"},"node_id":{"type":"integer","example":555,"description":"Page node ID"}},"description":"Page information"}},"required":["form_id","block","page"]},"description":"List of forms found"}},"required":["results_total","items"],"description":"Search results"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error, 3 = system error)"},"status_message":{"type":"string","enum":["Project not found","No form type configured","Attribute not found","Attribute is not indexed","No forms found"],"example":"No forms found","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"attribute_id":{"type":"integer","description":"Attribute ID to search on (must be indexed). Use POST /api/v3/attributes/list with class_id to get attributes.","example":730},"value":{"type":"string","description":"Value to search for in the specified attribute.","example":"REF-12345"}},"required":["class_id","project_node_id","attribute_id","value"]}}}}}},"/api/v3/publishing/list/":{"post":{"tags":["publishing"],"summary":"List publication projects","description":"## Purpose\n\nReturns publication projects grouped by workspace.\n\n## When to Use\n\n- Use this endpoint first to discover available publication projects and their node_id values\n- The returned node_id is used as project_node_id in all other publishing endpoints\n- The returned workspace_id values can be used as workspace_node_id when creating new projects with POST /api/v3/publishing/create\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Publications list response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"","description":"Status message"},"result":{"type":"object","properties":{"results_total":{"type":"integer","example":5,"description":"Total number of publications"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","example":213855,"description":"Publication node ID"},"node_id":{"type":"integer","example":213855,"description":"Publication node ID"},"label":{"type":"string","example":"Christmas Catalog 2025","description":"Publication label"},"workspace_id":{"type":"integer","example":1982,"description":"Parent workspace node ID"},"workspace_label":{"type":"string","example":"Catalogs 2025","description":"Parent workspace label"},"description":{"type":"string","nullable":true,"example":null,"description":"Publication description"},"active":{"type":"boolean","example":true,"description":"Whether the publication is active"},"project_type":{"type":"string","example":"publication","description":"Project type (always \"publication\" or \"catalog_with_pagination\")"},"project_type_description":{"type":"string","example":"Publication - Brief","description":"Human-readable project type"},"path":{"type":"string","example":"0/1978/1982/213855","description":"Publication path in hierarchy"},"class_id":{"type":"integer","example":4,"description":"Associated library ID"},"start_date":{"type":"string","nullable":true,"example":"2025-01-01T00:00:00+01:00","description":"Publication start date"},"end_date":{"type":"string","nullable":true,"example":"2025-12-31T23:59:59+01:00","description":"Publication end date"}},"required":["id","node_id","label","workspace_id","workspace_label","active","project_type","project_type_description","path","class_id"]},"description":"List of publications"}},"required":["results_total","items"]}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":3,"description":"Status code (3 = error)"},"status_message":{"type":"string","example":"No publications found","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"include_inactive":{"type":"boolean","description":"Include inactive publications. By default, inactive publications are excluded.","example":false}},"required":["class_id"]}}}}}},"/api/v3/publishing/page-details/":{"post":{"tags":["publishing"],"summary":"Get page details with blocks","description":"## Purpose\n\nReturns complete details of a publication page including themes and all blocks with their positions, content, and metadata.\n\n## When to use\n\nUse this endpoint to:\n- Get all blocks on a specific page with their complete details\n- View block positions and dimensions for layout analysis\n- See which products are assigned to blocks with their templates and forms\n- Access form data values for product blocks\n- Track modification history (user, date, version)\n- Retrieve HTML content for text blocks and notes\n- Identify note hierarchies (parent-child relationships for replies)\n- Get page themes and status\n\n## Block type specificity\n\nDifferent block types return different fields:\n- **product_block**: includes node_id, template_id, template_label, form_id, form_datas\n- **text_block**: includes html_content\n- **note types**: includes html_content and parent_id (if reply to another note)\n- **empty_block**: basic positioning fields only\n\nOnly relevant fields are returned for each block type (no null values for unsupported fields).\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Page details response","content":{"application/json":{"schema":{"type":"object","properties":{"status_code":{"type":"integer","example":1},"status_message":{"type":"string","example":"Success"},"result":{"type":"object","properties":{"page_number":{"type":"integer"},"node_id":{"type":"integer"},"asset_id":{"type":"integer"},"status_id":{"type":"integer"},"status_label":{"type":"string"},"themes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"label":{"type":"string"},"color":{"type":"string"}}}},"blocks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","description":"Unique identifier of the block in the publication page"},"type":{"type":"string","description":"Block type: product_block (contains product), empty_block (placeholder), text_block (HTML content), or note types (annotations with possible replies)"},"x_position":{"type":"integer","description":"Horizontal position of the block on the page in millimeters from the left edge"},"y_position":{"type":"integer","description":"Vertical position of the block on the page in millimeters from the top edge"},"width":{"type":"integer","description":"Width of the block in millimeters"},"height":{"type":"integer","description":"Height of the block in millimeters"},"user_id":{"type":"integer","description":"ID of the user who last modified the block. Use POST /api/v3/assets/read/ with class_id=99 to get user details."},"user_label":{"type":"string","description":"Display name of the user who last modified the block"},"modification_date":{"type":"string","description":"Last modification date in ISO 8601 format (YYYY-MM-DD HH:MM:SS)"},"history_id":{"type":"integer","description":"Version ID in the block history, used for tracking changes and rollback operations"},"node_id":{"type":"integer","description":"Product node ID (only for product_block type). Use POST /api/v3/repository/node-content/ to get product details."},"template_id":{"type":"integer","description":"Product template/gabarit ID (only for product_block type). Use POST /api/v3/templates/list/ to get available templates."},"template_label":{"type":"string","description":"Product template/gabarit display name (only for product_block type with template assigned)"},"form_id":{"type":"integer","description":"Form instance ID containing attribute values (only for product_block type with form assigned)"},"form_datas":{"type":"object","description":"Form attribute values as key-value pairs where keys are attribute IDs and values are their content (only for product_block type with form assigned). Use POST /api/v3/attributes/list to get attribute definitions."},"html_content":{"type":"string","description":"HTML content of the block (only for text_block type and note types)"},"parent_id":{"type":"integer","description":"ID of the parent note block if this is a reply to another note (only for note types with parent)"}}}}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"page_num":{"type":"integer","description":"Page number (1-based). Use POST /api/v3/publishing/pages to list available pages.","example":1}},"required":["class_id","project_node_id","page_num"]}}}}}},"/api/v3/publishing/pages/":{"post":{"tags":["publishing"],"summary":"Get publication pages list","description":"## Purpose\n\nReturns a paginated list of pages in a publication with their status and block count.\n\n## When to use\n\nUse this endpoint to:\n- List all pages of a publication\n- Get page status and block counts\n- Navigate through a publication structure\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Pages list response","content":{"application/json":{"schema":{"type":"object","properties":{"status_code":{"type":"integer","example":1},"status_message":{"type":"string","example":"Success"},"result":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of pages"},"page":{"type":"integer","description":"Current pagination page"},"limit":{"type":"integer","description":"Results per page"},"pages":{"type":"array","items":{"type":"object","properties":{"page_number":{"type":"integer"},"node_id":{"type":"integer"},"asset_id":{"type":"integer"},"status_id":{"type":"integer"},"status_label":{"type":"string"},"blocks_count":{"type":"integer"},"themes":{"type":"array","items":{"type":"object"}}}}}}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"page":{"type":"integer","description":"Pagination page number for API results (NOT the publication page number). Default: 1. Use together with the \"limit\" parameter to paginate through the list of publication pages.","example":1},"limit":{"type":"integer","description":"Results per page (default: 20, max: 100)","example":20},"include_themes":{"type":"boolean","description":"Include themes for each page (default: false)","example":false}},"required":["class_id","project_node_id"]}}}}}},"/api/v3/publishing/place-product-in-page/":{"post":{"tags":["publishing"],"summary":"Place a product on a publication page","description":"## Purpose\n\nIntelligent endpoint for placing a product on a publication page. Handles the full workflow: adding the product from the repository to the page tree if needed, then creating a new product block or assigning the product to an existing block.\n\n## When to use\n\nUse this endpoint when you need to place a product on a publication page. It replaces the former `add-product-block` endpoint with added capabilities:\n- Place a product already present in the page tree (via `node_id`)\n- Place a product from the repository (via `asset_id`) — will be added to the page tree automatically\n- Create a new block OR assign to an existing block (via `block_id`)\n\n## Parameter rules\n\n- Provide either `node_id` OR `asset_id` (mutually exclusive, one is required)\n- If `block_id` is not provided, `x_position`, `y_position`, `width`, `height` are required to create a new block\n- If `block_id` is provided, the product will be assigned to the existing block\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Product placement response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Product placed in page successfully","description":"Status message"},"result":{"type":"object","properties":{"node_id":{"type":"integer","example":12345,"description":"Node ID of the product in the page tree"},"block_id":{"type":"integer","example":6789,"description":"ID of the block (created or existing)"},"page_num":{"type":"integer","example":1,"description":"Page number"},"added_from_repository":{"type":"boolean","example":true,"description":"Whether the product was added from the repository (true) or was already in the page (false)"}},"required":["node_id","block_id","page_num","added_from_repository"],"description":"Product placement result"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error, 3 = system error)"},"status_message":{"type":"string","enum":["You must provide either node_id or asset_id (not both)","Publication not found","Page does not exist","Product not found in page","Product asset not found","Could not add product to page tree","Parameters x_position, y_position, width, height are required when block_id is not provided","Not authorized to modify this page","Block could not be created"],"example":"You must provide either node_id or asset_id (not both)","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"page_num":{"type":"integer","description":"Page number (1-based). Use POST /api/v3/publishing/pages to list available pages.","example":1},"node_id":{"type":"integer","description":"Product node ID already present as a child of the page. Mutually exclusive with asset_id — provide one or the other. Use POST /api/v3/publishing/page-details/ with project_node_id and page_num to list products already in the page (see blocks[].node_id).","example":12345},"asset_id":{"type":"integer","description":"Product asset ID from the repository (unique database identifier). If the product is not already in the page tree, it will be added automatically. Mutually exclusive with node_id. Use POST /api/v3/get-asset/by-search/ to find product asset IDs.","example":638116},"block_id":{"type":"integer","description":"ID of an existing block (empty_block or product_block) to assign the product to. If omitted, a new block is created using x_position, y_position, width, height parameters. Use POST /api/v3/publishing/page-details/ to list existing blocks and their IDs (see blocks[].id).","example":789},"asset_template_id":{"type":"integer","description":"Product template ID for rendering. If omitted, uses the default template configured on the publication project; if none, falls back to the library default template. There is no dedicated API endpoint to list templates; inspect existing blocks via POST /api/v3/publishing/page-details (profil_id and profil_label fields).","example":22},"x_position":{"type":"integer","description":"X position in mm from the left edge of the page. Must be a positive value. Required if block_id is not provided.","example":10},"y_position":{"type":"integer","description":"Y position in mm from the top edge of the page. Must be a positive value. Required if block_id is not provided.","example":20},"width":{"type":"integer","description":"Block width in mm. Must be a positive value. Required if block_id is not provided.","example":60},"height":{"type":"integer","description":"Block height in mm. Must be a positive value. Required if block_id is not provided.","example":40},"rank":{"type":"integer","description":"Block placement order (z-index). Higher values display on top of lower values. Default: 0.","example":3},"form_datas":{"type":"object","description":"Form data as {attribute_id: \"value\"} pairs. All values must be strings, even for numeric attributes. Use POST /api/v3/attributes/list with class_id to get available attribute IDs.","example":{"123":"Cuisine","456":"Promo"}}},"required":["class_id","project_node_id","page_num"]}}}}}},"/api/v3/publishing/place-products-in-pages/":{"post":{"tags":["publishing"],"summary":"Place products on publication pages (batch)","description":"## Purpose\n\nBatch endpoint for placing multiple products on multiple publication pages. Each product follows the same workflow as place-product-in-page: adding from repository if needed, then creating or assigning blocks.\n\n## When to use\n\nUse this endpoint when you need to place multiple products across one or more pages in a single call. More efficient than calling place-product-in-page repeatedly.\n\n## Parameter rules (per product)\n\n- Provide either `node_id` OR `asset_id` (mutually exclusive, one is required)\n- If `block_id` is not provided, `x_position`, `y_position`, `width`, `height` are required to create a new block\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Batch product placement response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"","description":"Status message (empty for full success, details on partial success)"},"result":{"type":"object","properties":{"nb_pages_modified":{"type":"integer","example":1,"description":"Number of pages that were modified"},"nb_products_placed":{"type":"integer","example":3,"description":"Number of products successfully placed"},"products":{"type":"array","items":{"type":"object","properties":{"node_id":{"type":"integer","example":12345,"description":"Node ID of the product in the page tree"},"block_id":{"type":"integer","example":6789,"description":"ID of the block (created or existing)"},"page_num":{"type":"integer","example":1,"description":"Page number where the product was placed"},"added_from_repository":{"type":"boolean","example":true,"description":"Whether the product was added from the repository (true) or was already in the page (false)"}}},"description":"List of placed products with details"},"errors":{"type":"array","nullable":true,"items":{"type":"object","properties":{"page_num":{"type":"integer","description":"Page number where the error occurred"},"message":{"type":"string","description":"Error message"}}},"description":"List of errors encountered during processing (optional, present on partial success)"}},"required":["nb_pages_modified","nb_products_placed","products"],"description":"Batch placement result"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error)"},"status_message":{"type":"string","example":"The parameter \"pages\" must be not empty","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"pages":{"type":"array","description":"List of pages with products to place. Each page contains a page_num and a list of products. (Array of objects - see example for structure)","example":[{"page_num":1,"products":[{"asset_id":638116,"x_position":10,"y_position":20,"width":60,"height":40,"asset_template_id":22},{"node_id":12345,"block_id":789}]}],"items":{"type":"object","properties":{"page_num":{"type":"integer","description":"Page number (1-based index). First page is 1"},"products":{"type":"array","description":"List of products to place on this page. (Array of objects - see example for structure)","items":{"type":"object","properties":{"node_id":{"type":"integer","description":"Product node ID already present as a child of the page. Mutually exclusive with asset_id — provide one or the other. Use POST /api/v3/publishing/page-details/ to list products in the page (see blocks[].node_id).","example":12345},"asset_id":{"type":"integer","description":"Product asset ID from the repository (unique database identifier). If the product is not already in the page tree, it will be added automatically. Mutually exclusive with node_id. Use POST /api/v3/get-asset/by-search/ to find product asset IDs.","example":638116},"block_id":{"type":"integer","description":"ID of an existing block (empty_block or product_block) to assign the product to. If omitted, a new block is created using x_position, y_position, width, height parameters. Use POST /api/v3/publishing/page-details/ to list existing blocks and their IDs (see blocks[].id).","example":789},"asset_template_id":{"type":"integer","description":"Product template ID for rendering. If omitted, uses the default template configured on the publication project; if none, falls back to the library default template. There is no dedicated API endpoint to list templates; inspect existing blocks via POST /api/v3/publishing/page-details (profil_id and profil_label fields).","example":22},"x_position":{"type":"integer","description":"X position in mm from the left edge of the page. Must be a positive value. Required if block_id is not provided."},"y_position":{"type":"integer","description":"Y position in mm from the top edge of the page. Must be a positive value. Required if block_id is not provided."},"width":{"type":"integer","description":"Block width in mm. Must be a positive value. Required if block_id is not provided."},"height":{"type":"integer","description":"Block height in mm. Must be a positive value. Required if block_id is not provided."},"rank":{"type":"integer","description":"Block placement order (z-index). Higher values display on top of lower values. Default: 0."},"form_datas":{"type":"object","description":"Form data as {attribute_id: \"value\"} pairs. All values must be strings, even for numeric attributes. Use POST /api/v3/attributes/list with class_id to get available attribute IDs."}},"title":"Item"}}},"required":["page_num","products"],"title":"Item"}}},"required":["class_id","project_node_id","pages"]}}}}}},"/api/v3/publishing/unassign-product-from-block/":{"post":{"tags":["publishing"],"summary":"Remove a product from a block","description":"## Purpose\n\nRemoves the product assignment from a product block, converting it back to an empty block. Associated form data is preserved.\n\n## When to use\n\nUse this endpoint to:\n- Clear a product block without deleting it\n- Convert a product block back to a placeholder\n- Prepare a block for a different product assignment\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Product unassignment response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Product unassigned from block successfully","description":"Status message"},"result":{"type":"object","properties":{"block_id":{"type":"integer","example":12345,"description":"Block ID"},"previous_type":{"type":"string","example":"product_block","description":"Previous block type before unassignment"},"new_type":{"type":"string","example":"empty_block","description":"New block type after unassignment"},"previous_node_id":{"type":"integer","example":5678,"description":"Previously assigned product node ID"}},"required":["block_id","previous_type","new_type"],"description":"Unassignment result"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error, 3 = system error)"},"status_message":{"type":"string","enum":["Block not found","Block is not a product block","Block has no product assigned","Not authorized to modify this block"],"example":"Block not found","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"block_id":{"type":"integer","description":"Block ID to unassign product from. Use POST /api/v3/publishing/page-details with project_node_id and page_num to get block IDs.","example":12345}},"required":["class_id","project_node_id","block_id"]}}}}}},"/api/v3/publishing/update-block-to-page/":{"post":{"tags":["publishing"],"summary":"Update a content block on a page","description":"## Purpose\n\nUpdates an existing content block on a publication page. Modify position, dimensions, content, or associated data. Only provided properties are updated.\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Block update response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Block updated successfully","description":"Status message"},"result":{"type":"object","properties":{"block_id":{"type":"integer","example":12345,"description":"ID of the updated block"},"page_num":{"type":"integer","example":1,"description":"Page number where the block was updated"},"messages":{"type":"array","items":{"type":"string"},"example":["Updated block","Updated form data"],"description":"List of operations performed"}},"required":["block_id","page_num"],"description":"Updated block information"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = validation error, 3 = system error)"},"status_message":{"type":"string","enum":["Page does not exist","Block not found","Not authorized to update the block","Project not found","Block could not be updated"],"example":"Block not found","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"page_num":{"type":"integer","description":"Page number (1-based). Use POST /api/v3/publishing/pages to list available pages.","example":1},"block_id":{"type":"integer","description":"Block ID to update. Use POST /api/v3/publishing/page-details with project_node_id and page_num to get block IDs.","example":12345},"block":{"type":"object","description":"Block information to update. All properties are optional - only provided properties will be updated.","example":{"x_position":15,"y_position":25,"width":70,"height":50},"properties":{"type":{"type":"string","description":"Block type: product_block, empty_block, text_block, image_block, or notepad types (image_note, etc.)","enum":["product_block","empty_block","text_block","image_block","image_note","square_note","text_note","attention_pin_note","question_pin_note","information_pin_note","simple_note"]},"x_position":{"type":"integer","description":"Block X position in mm from the left edge of the page"},"y_position":{"type":"integer","description":"Block Y position in mm from the top edge of the page"},"width":{"type":"integer","description":"Block width in mm. Must be a positive value"},"height":{"type":"integer","description":"Block height in mm. Must be a positive value"},"node_id":{"type":"integer","description":"Product node ID for product_block. Use POST /api/v3/get-asset/by-search/node to find products"},"asset_template_id":{"type":"integer","description":"Product template ID for rendering. If omitted, uses the publication default, then the library default. There is no dedicated API endpoint to list templates; inspect existing blocks via POST /api/v3/publishing/page-details (profil_id and profil_label fields)."},"rank":{"type":"integer","description":"Block position for product placement (for product_block and empty_block)"},"html_content":{"type":"string","description":"HTML content (for text_block and notepad types)"},"section_id":{"type":"integer","description":"Section ID for text categorization (applicable to text_block type). Sections are configured at library administration level. There is no API endpoint to list sections; contact your administrator."},"form_datas":{"type":"object","description":"Form data as key-value pairs where key is attribute_id and value is the content (for product_block)"}}}},"required":["class_id","project_node_id","page_num","block_id","block"]}}}}}},"/api/v3/publishing/update-status/node/":{"post":{"tags":["publishing"],"summary":"Update page status in publication project","description":"## Purpose\n\nUpdates the access control status (LCA) of a publication page by page number. This endpoint operates in the project/node context (not repository).\n\n## Note on URL\n\nThe `/node/` suffix indicates this operates in a project context (as opposed to repository). This is consistent with other Afineo endpoints that distinguish between `/node/` (project-specific) and `/repository/` (master data).\n\n## When to Use\n\n- Use to change the validation status of a specific page in a publication project\n- The `page_num` refers to the publication page number (1-based), not the internal node ID\n- Use POST /api/v3/publishing/pages with class_id and project_node_id to get available page numbers\n- Use POST /api/v3/permissions/statuses/list to get available status IDs\n","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Update status by page response","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Success Response","properties":{"status_code":{"type":"integer","example":1,"description":"Status code (1 = success)"},"status_message":{"type":"string","example":"Status updated","description":"Status message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array"}},"required":["status_code","status_message","result"]},{"type":"object","title":"Error Response","properties":{"status_code":{"type":"integer","example":2,"description":"Status code (2 = error)"},"status_message":{"type":"string","enum":["Page does not exist","Asset does not exist or has been deleted","The status of the asset is already the same as the one you want to set","You don't have the rights to update the status of this asset"],"example":"Page does not exist","description":"Error message"},"result":{"type":"array","items":{"type":"object"},"example":[],"description":"Empty array on error"}},"required":["status_code","status_message","result"]}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"page_num":{"type":"integer","description":"Page number (1-based). Use POST /api/v3/publishing/pages to list available pages.","example":1},"class_id":{"type":"integer","description":"Library ID. Use POST /api/v3/administration/classes/list to get available libraries.","example":4},"project_node_id":{"type":"integer","description":"Publication project node ID. Use POST /api/v3/publishing/list with class_id to get available publication projects.","example":556},"status_id":{"type":"integer","description":"Status ID. Use POST /api/v3/permissions/statuses/list to get available statuses.","example":102}},"required":["page_num","class_id","project_node_id","status_id"]}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token generated with /api/v3/token/get/"}}}}