[{"data":1,"prerenderedAt":174},["ShallowReactive",2],{"cds-site:languages":3,"cds-site:style":5,"cds-site:globals":48,"cds-site:menu":54,"page-en-/guide/pagination-and-filtering":152},[4],"en",{"id":6,"name":7,"template":8,"logo":9,"logoMark":10,"favicon":11,"values":12,"cssProperties":14},"style_docs","Documentation","@checkin247/template-docs","hotelplatform-logo","hotelplatform-mark","favicon",{"icon_background":13},"#0B1B33",{"--color-ink":13,"--color-deep":15,"--color-signal":16,"--color-signal-deep":17,"--color-signal-light":18,"--color-canvas":19,"--color-error":20,"--color-brand-50":19,"--color-brand-100":21,"--color-brand-200":22,"--color-brand-300":23,"--color-brand-400":24,"--color-brand-500":25,"--color-brand-600":26,"--color-brand-700":15,"--color-brand-800":27,"--color-brand-900":13,"--color-brand-950":28,"--color-neutral-50":29,"--color-neutral-100":30,"--color-neutral-200":31,"--color-neutral-300":32,"--color-neutral-400":33,"--color-neutral-500":34,"--color-neutral-600":35,"--color-neutral-700":36,"--color-neutral-800":37,"--color-neutral-900":38,"--color-neutral-950":13,"--color-primary":25,"--color-primary-hover":15,"--color-surface":39,"--color-background-default":19,"--color-background-dark":13,"--color-text-strong":38,"--color-text-dark":38,"--color-text-body":36,"--color-text-default":36,"--color-text-muted":40,"--color-text-on-dark":41,"--color-border":31,"--color-border-default":31,"--font-heading":42,"--font-body":43,"--font-mono":44,"--radius-control":45,"--radius-card":46,"--radius":45,"--container-content":47},"#14306E","#4FC3B0","#136558","#8FE0D2","#F6F9FC","#B4442F","#EAF0F9","#CBD9F0","#A3BCE4","#6389C8","#2A56A8","#204487","#0F2452","#071223","#F8FAFC","#F1F5FA","#E3E9F2","#CFD8E6","#A6B3C6","#8494AB","#6C7C93","#5A6A80","#3B4A61","#12233F","#FFFFFF","#5D6C82","#D5E1F2","\"Outfit\", ui-sans-serif, system-ui, sans-serif","\"IBM Plex Sans\", ui-sans-serif, system-ui, sans-serif","\"IBM Plex Mono\", ui-monospace, monospace","10px","16px","780px",{"id":49,"siteName":50,"copyright":51,"footerText":52,"defaultLanguage":4,"vimeo":53,"linkedin":53,"youtube":53,"github":53,"logo":53,"logoMark":53,"favicon":53,"ogImage":53},"site","HotelPlatform.io Documentation","© 2026 key-card / HotelPlatform","API documentation of the HotelPlatform.",null,[55,64,70,77,83,90,96,103,110,117,124,131,138,145],{"id":56,"label":57,"description":53,"icon":53,"trailing_icon":53,"href":58,"sort":59,"status":60,"parent_item":53,"target":53,"isCanonical":53,"translations":61,"to":53,"menu":62},"m_main_api","API Documentation","/api-reference",1,"published",[],{"position":63},"main",{"id":65,"label":66,"description":53,"icon":53,"trailing_icon":53,"href":67,"sort":59,"status":60,"parent_item":56,"target":53,"isCanonical":53,"translations":68,"to":53,"menu":69},"m_main_api_AccessControl","AccessControl","/api-reference/AccessControl/latest",[],{"position":63},{"id":71,"label":72,"description":53,"icon":53,"trailing_icon":53,"href":73,"sort":74,"status":60,"parent_item":56,"target":53,"isCanonical":53,"translations":75,"to":53,"menu":76},"m_main_api_Configuration","Configuration","/api-reference/Configuration/latest",2,[],{"position":63},{"id":78,"label":79,"description":53,"icon":53,"trailing_icon":53,"href":80,"sort":74,"status":60,"parent_item":53,"target":53,"isCanonical":53,"translations":81,"to":53,"menu":82},"m_main_guide","Guide","/guide",[],{"position":63},{"id":84,"label":85,"description":53,"icon":53,"trailing_icon":53,"href":86,"sort":87,"status":60,"parent_item":56,"target":53,"isCanonical":53,"translations":88,"to":53,"menu":89},"m_main_api_HotelApi","HotelApi","/api-reference/HotelApi/latest",3,[],{"position":63},{"id":91,"label":92,"description":53,"icon":53,"trailing_icon":53,"href":93,"sort":87,"status":60,"parent_item":53,"target":53,"isCanonical":53,"translations":94,"to":53,"menu":95},"m_main_about","About","/about",[],{"position":63},{"id":97,"label":98,"description":53,"icon":53,"trailing_icon":53,"href":80,"sort":99,"status":60,"parent_item":53,"target":53,"isCanonical":53,"translations":100,"to":53,"menu":101},"m_sb_overview","Overview",4,[],{"position":102},"sidebar",{"id":104,"label":105,"description":53,"icon":53,"trailing_icon":53,"href":106,"sort":107,"status":60,"parent_item":53,"target":53,"isCanonical":53,"translations":108,"to":53,"menu":109},"m_sb_introduction","Introduction","/guide/introduction",5,[],{"position":102},{"id":111,"label":112,"description":53,"icon":53,"trailing_icon":53,"href":113,"sort":114,"status":60,"parent_item":53,"target":53,"isCanonical":53,"translations":115,"to":53,"menu":116},"m_sb_getting_started","Getting started","/guide/getting-started",6,[],{"position":102},{"id":118,"label":119,"description":53,"icon":53,"trailing_icon":53,"href":120,"sort":121,"status":60,"parent_item":53,"target":53,"isCanonical":53,"translations":122,"to":53,"menu":123},"m_sb_pagination","Pagination & Filtering","/guide/pagination-and-filtering",7,[],{"position":102},{"id":125,"label":126,"description":53,"icon":53,"trailing_icon":53,"href":127,"sort":128,"status":60,"parent_item":53,"target":53,"isCanonical":53,"translations":129,"to":53,"menu":130},"m_sb_changelogs","Changelogs","/guide/changelogs",12,[],{"position":102},{"id":132,"label":133,"description":53,"icon":53,"trailing_icon":53,"href":134,"sort":135,"status":60,"parent_item":125,"target":53,"isCanonical":53,"translations":136,"to":53,"menu":137},"m_sb_changelog_AccessControl","AccessControl Changelog","/guide/changelogs/AccessControl",13,[],{"position":102},{"id":139,"label":140,"description":53,"icon":53,"trailing_icon":53,"href":141,"sort":142,"status":60,"parent_item":125,"target":53,"isCanonical":53,"translations":143,"to":53,"menu":144},"m_sb_changelog_Configuration","Configuration Changelog","/guide/changelogs/Configuration",14,[],{"position":102},{"id":146,"label":147,"description":53,"icon":53,"trailing_icon":53,"href":148,"sort":149,"status":60,"parent_item":125,"target":53,"isCanonical":53,"translations":150,"to":53,"menu":151},"m_sb_changelog_HotelApi","HotelApi Changelog","/guide/changelogs/HotelApi",15,[],{"position":102},{"id":153,"slug":154,"title":119,"description":155,"blocks":156,"contentBlocks":167,"seo":173},"p_pagination-and-filtering","pagination-and-filtering","Filtering, sorting and cursor-based pagination, shared by every collection endpoint of the HotelPlatform APIs.",[157],{"id":158,"type":159,"title":53,"subtitle":53,"content":160,"image":53,"ctaText":53,"ctaUrl":53,"module":161,"alignment":53,"ratio":53,"colorScheme":162,"settings":163,"items":164,"texts":165},"b_guide-pagination-and-filtering","markdown","\u003Ch1>Pagination &amp; Filtering\u003C/h1>\n\u003Cp>Every collection endpoint in the HotelPlatform APIs (for example \u003Ccode>GET /reservations\u003C/code>,\n\u003Ccode>GET /units\u003C/code>, \u003Ccode>GET /configurations\u003C/code>) accepts the same query-string conventions for\n\u003Cstrong>filtering\u003C/strong>, \u003Cstrong>sorting\u003C/strong> and \u003Cstrong>cursor-based pagination\u003C/strong>. They follow the\n\u003Ca href=\"https://jsonapi.org/\">JSON:API\u003C/a> bracket syntax and are parsed centrally by the shared\nSDK, so the behaviour is identical across services.\u003C/p>\n\u003Cp>All examples assume the JSON:API media type:\u003C/p>\n\u003Cpre>\u003Ccode>Accept: application/vnd.api+json\n\u003C/code>\u003C/pre>\n\u003Ch2 id=\"filtering\" tabindex=\"-1\">Filtering\u003C/h2>\n\u003Cp>Filter a collection with one or more \u003Ccode>filter[...]\u003C/code> parameters. Multiple filters are\ncombined with logical \u003Cstrong>AND\u003C/strong>.\u003C/p>\n\u003Cpre>\u003Ccode>filter[&lt;field&gt;]=&lt;value&gt;            # implicit equality\nfilter[&lt;field&gt;][&lt;operator&gt;]=&lt;value&gt; # explicit operator\n\u003C/code>\u003C/pre>\n\u003Cp>\u003Ccode>filter[code]=WL\u003C/code> is therefore identical to \u003Ccode>filter[code][eq]=WL\u003C/code>.\u003C/p>\n\u003Ch3 id=\"supported-operators\" tabindex=\"-1\">Supported operators\u003C/h3>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\u003Cthead>\n\u003Ctr>\n\u003Cth>Operator\u003C/th>\n\u003Cth>Meaning\u003C/th>\n\u003Cth>Example\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>eq\u003C/code>\u003C/td>\n\u003Ctd>equals (default)\u003C/td>\n\u003Ctd>\u003Ccode>filter[status][eq]=confirmed\u003C/code>\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>ne\u003C/code>\u003C/td>\n\u003Ctd>not equal\u003C/td>\n\u003Ctd>\u003Ccode>filter[status][ne]=cancelled\u003C/code>\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>lt\u003C/code>\u003C/td>\n\u003Ctd>less than\u003C/td>\n\u003Ctd>\u003Ccode>filter[arrival][lt]=2026-06-01\u003C/code>\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>lte\u003C/code>\u003C/td>\n\u003Ctd>less than or equal\u003C/td>\n\u003Ctd>\u003Ccode>filter[arrival][lte]=2026-06-01\u003C/code>\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>gt\u003C/code>\u003C/td>\n\u003Ctd>greater than\u003C/td>\n\u003Ctd>\u003Ccode>filter[departure][gt]=2026-06-10\u003C/code>\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>gte\u003C/code>\u003C/td>\n\u003Ctd>greater than or equal\u003C/td>\n\u003Ctd>\u003Ccode>filter[departure][gte]=2026-06-10\u003C/code>\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>like\u003C/code>\u003C/td>\n\u003Ctd>case-insensitive contains\u003C/td>\n\u003Ctd>\u003Ccode>filter[lastName][like]=mei\u003C/code>\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>isnull\u003C/code>\u003C/td>\n\u003Ctd>field is null\u003C/td>\n\u003Ctd>\u003Ccode>filter[unitId][isnull]=true\u003C/code>\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>notnull\u003C/code>\u003C/td>\n\u003Ctd>field is not null\u003C/td>\n\u003Ctd>\u003Ccode>filter[unitId][notnull]=true\u003C/code>\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\u003C/div>\u003Cp>A few rules to keep in mind:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Nested fields\u003C/strong> use dot notation, e.g. \u003Ccode>filter[profile.lastName][like]=smith\u003C/code>.\u003C/li>\n\u003Cli>Fields the resource marks as non-filterable are rejected with \u003Ccode>400 Bad Request\u003C/code>.\u003C/li>\n\u003Cli>An unknown operator is rejected with \u003Ccode>400 Bad Request\u003C/code>; the error lists the\nsupported operators.\u003C/li>\n\u003Cli>For \u003Ccode>isnull\u003C/code> / \u003Ccode>notnull\u003C/code> the value is only a placeholder (any value works); the\npresence of the operator is what matters.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"sorting\" tabindex=\"-1\">Sorting\u003C/h2>\n\u003Cp>Use \u003Ccode>sort\u003C/code> with a comma-separated list of fields. Prefix a field with \u003Ccode>-\u003C/code> for\ndescending order.\u003C/p>\n\u003Cpre>\u003Ccode>sort=externalId            # ascending\nsort=-createdAt            # descending\nsort=-createdAt,externalId # multiple keys, evaluated left to right\n\u003C/code>\u003C/pre>\n\u003Ch2 id=\"cursor-pagination\" tabindex=\"-1\">Cursor pagination\u003C/h2>\n\u003Cp>The platform uses \u003Cstrong>cursor-based\u003C/strong> pagination rather than page numbers. A cursor is\nsimply the \u003Ccode>id\u003C/code> (UUID) of a resource you already received; you ask for the rows that\ncome \u003Cem>after\u003C/em> or \u003Cem>before\u003C/em> it.\u003C/p>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\u003Cthead>\n\u003Ctr>\n\u003Cth>Parameter\u003C/th>\n\u003Cth>Description\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>page[size]\u003C/code>\u003C/td>\n\u003Ctd>Number of items per page. Defaults to \u003Ccode>10\u003C/code>; values above the service maximum (or \u003Ccode>&lt;= 0\u003C/code>) are rejected with \u003Ccode>400\u003C/code>.\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>page[after]\u003C/code>\u003C/td>\n\u003Ctd>Return the page of items \u003Cstrong>after\u003C/strong> the resource with this \u003Ccode>id\u003C/code>.\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>page[before]\u003C/code>\u003C/td>\n\u003Ctd>Return the page of items \u003Cstrong>before\u003C/strong> the resource with this \u003Ccode>id\u003C/code>.\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\u003C/div>\u003Cblockquote>\n\u003Cp>Offset parameters such as \u003Ccode>page[number]\u003C/code> and a \u003Ccode>page[total]\u003C/code> count are \u003Cstrong>not\u003C/strong>\nsupported. Cursor pagination deliberately trades a total record count for stable,\nefficient paging over large tables.\u003C/p>\n\u003C/blockquote>\n\u003Cp>You normally never build cursors by hand — list responses carry the links to follow:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>links.self\u003C/code> — the current page.\u003C/li>\n\u003Cli>\u003Ccode>links.next\u003C/code> — the next page. \u003Cstrong>Only present when more rows exist.\u003C/strong>\u003C/li>\n\u003Cli>\u003Ccode>links.prev\u003C/code> — the previous page. \u003Cstrong>Only present when the request itself used a cursor.\u003C/strong>\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"walking-through-a-collection\" tabindex=\"-1\">Walking through a collection\u003C/h3>\n\u003Cp>Request the first page:\u003C/p>\n\u003Cpre class=\"shiki github-light\" style=\"background-color:#fff;color:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49\">GET\u003C/span>\u003Cspan style=\"color:#24292E\"> /reservations?page[size]=2&#x26;sort=-createdAt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#22863A\">Accept\u003C/span>\u003Cspan style=\"color:#D73A49\">:\u003C/span>\u003Cspan style=\"color:#032F62\"> application/vnd.api+json\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cpre class=\"shiki github-light\" style=\"background-color:#fff;color:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">  \"data\"\u003C/span>\u003Cspan style=\"color:#24292E\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">    { \u003C/span>\u003Cspan style=\"color:#005CC5\">\"type\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"reservation\"\u003C/span>\u003Cspan style=\"color:#24292E\">, \u003C/span>\u003Cspan style=\"color:#005CC5\">\"id\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"9f1c2d3e-0001-4a00-9b00-000000000001\"\u003C/span>\u003Cspan style=\"color:#24292E\">, \u003C/span>\u003Cspan style=\"color:#005CC5\">\"externalId\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"res-852963-1\"\u003C/span>\u003Cspan style=\"color:#24292E\"> },\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">    { \u003C/span>\u003Cspan style=\"color:#005CC5\">\"type\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"reservation\"\u003C/span>\u003Cspan style=\"color:#24292E\">, \u003C/span>\u003Cspan style=\"color:#005CC5\">\"id\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"9f1c2d3e-0002-4a00-9b00-000000000002\"\u003C/span>\u003Cspan style=\"color:#24292E\">, \u003C/span>\u003Cspan style=\"color:#005CC5\">\"externalId\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"res-852963-2\"\u003C/span>\u003Cspan style=\"color:#24292E\"> }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">  ],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">  \"links\"\u003C/span>\u003Cspan style=\"color:#24292E\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">    \"self\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"/reservations?page[size]=2&#x26;sort=-createdAt\"\u003C/span>\u003Cspan style=\"color:#24292E\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">    \"next\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"/reservations?page[size]=2&#x26;sort=-createdAt&#x26;page[after]=9f1c2d3e-0002-4a00-9b00-000000000002\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Follow \u003Ccode>links.next\u003C/code> to get the next page. When \u003Ccode>links.next\u003C/code> is absent you have\nreached the end of the collection.\u003C/p>\n\u003Ch2 id=\"example-fetch-a-reservation-by-its-pms-reservation-id\" tabindex=\"-1\">Example: fetch a reservation by its PMS reservation id\u003C/h2>\n\u003Cp>Reservations that originate in (or are mirrored from) a Property Management System\ncarry the third-party identifier in the \u003Cstrong>\u003Ccode>externalId\u003C/code>\u003C/strong> attribute — for example\n\u003Ccode>res-852963-1\u003C/code>. To look a reservation up by that id, filter the collection on\n\u003Ccode>externalId\u003C/code>:\u003C/p>\n\u003Cpre class=\"shiki github-light\" style=\"background-color:#fff;color:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49\">GET\u003C/span>\u003Cspan style=\"color:#24292E\"> /reservations?filter[externalId]=res-852963-1\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#22863A\">Accept\u003C/span>\u003Cspan style=\"color:#D73A49\">:\u003C/span>\u003Cspan style=\"color:#032F62\"> application/vnd.api+json\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cpre class=\"shiki github-light\" style=\"background-color:#fff;color:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6F42C1\">curl\u003C/span>\u003Cspan style=\"color:#005CC5\"> -G\u003C/span>\u003Cspan style=\"color:#032F62\"> 'https://hotelplatform.io/api/v2/reservations'\u003C/span>\u003Cspan style=\"color:#005CC5\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">  --data-urlencode\u003C/span>\u003Cspan style=\"color:#032F62\"> 'filter[externalId]=res-852963-1'\u003C/span>\u003Cspan style=\"color:#005CC5\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">  -H\u003C/span>\u003Cspan style=\"color:#032F62\"> 'Accept: application/vnd.api+json'\u003C/span>\u003Cspan style=\"color:#005CC5\"> \\\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">  -H\u003C/span>\u003Cspan style=\"color:#032F62\"> 'X-Tenant-ID: &#x3C;your-tenant>'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>The response is a JSON:API \u003Cstrong>list\u003C/strong> document. \u003Ccode>externalId\u003C/code> is unique per integration,\nso you normally get exactly one item — read \u003Ccode>data[0]\u003C/code>:\u003C/p>\n\u003Cpre class=\"shiki github-light\" style=\"background-color:#fff;color:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">{\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">  \"data\"\u003C/span>\u003Cspan style=\"color:#24292E\">: [\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">    {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">      \"type\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"reservation\"\u003C/span>\u003Cspan style=\"color:#24292E\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">      \"id\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"558112a0-c6e0-11eb-b8bc-0242ac130003\"\u003C/span>\u003Cspan style=\"color:#24292E\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">      \"externalId\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"res-852963-1\"\u003C/span>\u003Cspan style=\"color:#24292E\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">      \"stays\"\u003C/span>\u003Cspan style=\"color:#24292E\">: [ { \u003C/span>\u003Cspan style=\"color:#005CC5\">\"type\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"stay\"\u003C/span>\u003Cspan style=\"color:#24292E\">, \u003C/span>\u003Cspan style=\"color:#005CC5\">\"id\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"...\"\u003C/span>\u003Cspan style=\"color:#24292E\"> } ],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">      \"profiles\"\u003C/span>\u003Cspan style=\"color:#24292E\">: [ { \u003C/span>\u003Cspan style=\"color:#005CC5\">\"type\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"profile\"\u003C/span>\u003Cspan style=\"color:#24292E\">, \u003C/span>\u003Cspan style=\"color:#005CC5\">\"id\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"...\"\u003C/span>\u003Cspan style=\"color:#24292E\"> } ]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">    }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">  ],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">  \"links\"\u003C/span>\u003Cspan style=\"color:#24292E\">: {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5\">    \"self\"\u003C/span>\u003Cspan style=\"color:#24292E\">: \u003C/span>\u003Cspan style=\"color:#032F62\">\"/reservations?filter[externalId]=res-852963-1\"\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Once you have the HotelPlatform \u003Ccode>id\u003C/code>, fetch the full resource (with its related stays\nand profiles) directly:\u003C/p>\n\u003Cpre class=\"shiki github-light\" style=\"background-color:#fff;color:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#D73A49\">GET\u003C/span>\u003Cspan style=\"color:#24292E\"> /reservations/558112a0-c6e0-11eb-b8bc-0242ac130003\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#22863A\">Accept\u003C/span>\u003Cspan style=\"color:#D73A49\">:\u003C/span>\u003Cspan style=\"color:#032F62\"> application/vnd.api+json\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Tip:\u003C/strong> if you integrate more than one channel or PMS, the same \u003Ccode>externalId\u003C/code> value\ncan in theory appear for different upstreams. Combine the filter with another\nattribute (for example the channel) to disambiguate, and always iterate \u003Ccode>data\u003C/code>\nrather than assuming a single result.\u003C/p>\n\u003C/blockquote>\n",[],"default",{},[],{"body":166},"# Pagination & Filtering\n\nEvery collection endpoint in the HotelPlatform APIs (for example `GET /reservations`,\n`GET /units`, `GET /configurations`) accepts the same query-string conventions for\n**filtering**, **sorting** and **cursor-based pagination**. They follow the\n[JSON:API](https://jsonapi.org/) bracket syntax and are parsed centrally by the shared\nSDK, so the behaviour is identical across services.\n\nAll examples assume the JSON:API media type:\n\n```\nAccept: application/vnd.api+json\n```\n\n## Filtering\n\nFilter a collection with one or more `filter[...]` parameters. Multiple filters are\ncombined with logical **AND**.\n\n```\nfilter[\u003Cfield>]=\u003Cvalue>            # implicit equality\nfilter[\u003Cfield>][\u003Coperator>]=\u003Cvalue> # explicit operator\n```\n\n`filter[code]=WL` is therefore identical to `filter[code][eq]=WL`.\n\n### Supported operators\n\n| Operator | Meaning                  | Example                                  |\n|----------|--------------------------|------------------------------------------|\n| `eq`     | equals (default)         | `filter[status][eq]=confirmed`           |\n| `ne`     | not equal                | `filter[status][ne]=cancelled`           |\n| `lt`     | less than                | `filter[arrival][lt]=2026-06-01`         |\n| `lte`    | less than or equal       | `filter[arrival][lte]=2026-06-01`        |\n| `gt`     | greater than             | `filter[departure][gt]=2026-06-10`       |\n| `gte`    | greater than or equal    | `filter[departure][gte]=2026-06-10`      |\n| `like`   | case-insensitive contains| `filter[lastName][like]=mei`             |\n| `isnull` | field is null            | `filter[unitId][isnull]=true`            |\n| `notnull`| field is not null        | `filter[unitId][notnull]=true`           |\n\nA few rules to keep in mind:\n\n- **Nested fields** use dot notation, e.g. `filter[profile.lastName][like]=smith`.\n- Fields the resource marks as non-filterable are rejected with `400 Bad Request`.\n- An unknown operator is rejected with `400 Bad Request`; the error lists the\n  supported operators.\n- For `isnull` / `notnull` the value is only a placeholder (any value works); the\n  presence of the operator is what matters.\n\n## Sorting\n\nUse `sort` with a comma-separated list of fields. Prefix a field with `-` for\ndescending order.\n\n```\nsort=externalId            # ascending\nsort=-createdAt            # descending\nsort=-createdAt,externalId # multiple keys, evaluated left to right\n```\n\n## Cursor pagination\n\nThe platform uses **cursor-based** pagination rather than page numbers. A cursor is\nsimply the `id` (UUID) of a resource you already received; you ask for the rows that\ncome *after* or *before* it.\n\n| Parameter      | Description                                                        |\n|----------------|--------------------------------------------------------------------|\n| `page[size]`   | Number of items per page. Defaults to `10`; values above the service maximum (or `\u003C= 0`) are rejected with `400`. |\n| `page[after]`  | Return the page of items **after** the resource with this `id`.    |\n| `page[before]` | Return the page of items **before** the resource with this `id`.   |\n\n> Offset parameters such as `page[number]` and a `page[total]` count are **not**\n> supported. Cursor pagination deliberately trades a total record count for stable,\n> efficient paging over large tables.\n\nYou normally never build cursors by hand — list responses carry the links to follow:\n\n- `links.self` — the current page.\n- `links.next` — the next page. **Only present when more rows exist.**\n- `links.prev` — the previous page. **Only present when the request itself used a cursor.**\n\n### Walking through a collection\n\nRequest the first page:\n\n```http\nGET /reservations?page[size]=2&sort=-createdAt\nAccept: application/vnd.api+json\n```\n\n```json\n{\n  \"data\": [\n    { \"type\": \"reservation\", \"id\": \"9f1c2d3e-0001-4a00-9b00-000000000001\", \"externalId\": \"res-852963-1\" },\n    { \"type\": \"reservation\", \"id\": \"9f1c2d3e-0002-4a00-9b00-000000000002\", \"externalId\": \"res-852963-2\" }\n  ],\n  \"links\": {\n    \"self\": \"/reservations?page[size]=2&sort=-createdAt\",\n    \"next\": \"/reservations?page[size]=2&sort=-createdAt&page[after]=9f1c2d3e-0002-4a00-9b00-000000000002\"\n  }\n}\n```\n\nFollow `links.next` to get the next page. When `links.next` is absent you have\nreached the end of the collection.\n\n## Example: fetch a reservation by its PMS reservation id\n\nReservations that originate in (or are mirrored from) a Property Management System\ncarry the third-party identifier in the **`externalId`** attribute — for example\n`res-852963-1`. To look a reservation up by that id, filter the collection on\n`externalId`:\n\n```http\nGET /reservations?filter[externalId]=res-852963-1\nAccept: application/vnd.api+json\n```\n\n```bash\ncurl -G 'https://hotelplatform.io/api/v2/reservations' \\\n  --data-urlencode 'filter[externalId]=res-852963-1' \\\n  -H 'Accept: application/vnd.api+json' \\\n  -H 'X-Tenant-ID: \u003Cyour-tenant>'\n```\n\nThe response is a JSON:API **list** document. `externalId` is unique per integration,\nso you normally get exactly one item — read `data[0]`:\n\n```json\n{\n  \"data\": [\n    {\n      \"type\": \"reservation\",\n      \"id\": \"558112a0-c6e0-11eb-b8bc-0242ac130003\",\n      \"externalId\": \"res-852963-1\",\n      \"stays\": [ { \"type\": \"stay\", \"id\": \"...\" } ],\n      \"profiles\": [ { \"type\": \"profile\", \"id\": \"...\" } ]\n    }\n  ],\n  \"links\": {\n    \"self\": \"/reservations?filter[externalId]=res-852963-1\"\n  }\n}\n```\n\nOnce you have the HotelPlatform `id`, fetch the full resource (with its related stays\nand profiles) directly:\n\n```http\nGET /reservations/558112a0-c6e0-11eb-b8bc-0242ac130003\nAccept: application/vnd.api+json\n```\n\n> **Tip:** if you integrate more than one channel or PMS, the same `externalId` value\n> can in theory appear for different upstreams. Combine the filter with another\n> attribute (for example the channel) to disambiguate, and always iterate `data`\n> rather than assuming a single result.\n",[168],{"id":158,"type":159,"title":53,"subtitle":53,"content":160,"image":53,"ctaText":53,"ctaUrl":53,"module":169,"alignment":53,"ratio":53,"colorScheme":162,"settings":170,"items":171,"texts":172},[],{},[],{"body":166},{},1791403614939]