Idempotently creates or updates sub-location types (e.g. Fridge, Auditorium) and their attribute definitions in one call, keyed by your own externalId. Safe to re-run.
Up to 100 types per call, 50 attributes per type, 100 options per select attribute.
Type identity, in priority order: externalId → id → name (case-insensitive). If nothing matches, the type is created. A matched type is renamed to name.
Attribute identity (within the type): externalId → id → key → name (case-insensitive). If nothing matches, the attribute is created and gets a key derived from its name (returned in the response). key is match-only: it must name an existing attribute of the type. An externalId already used by an attribute of another type is rejected, as are two attributes in one row that match the same existing attribute.
Additive only. Attributes and options you leave out are kept, never deleted. Options are matched by id, else by label (case-insensitive): a match is updated (label, color), anything else is appended.
type is immutable. Sending a different type for an existing attribute is rejected with 400.
The response reports each type’s status, so a match against a type archived in the web app is visible (sub-locations cannot be created under an archived type).
The call is all-or-nothing: if any row fails, nothing is written and the error message names the row (e.g. types[1].attributes[0]).
Requires the Public API workspace feature, CAN_MANAGE_LOCATIONS, and Sub-Locations enabled for the workspace (contact Xenia to enable it; until then every sub-location endpoint returns 404).
One result per input type, in request order, with one entry per input attribute.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Xenia Team API","colors":{"primary":"#8e54e9","light":"#e1cfff","dark":"#e1cfff"},"logo":{"light":"https://mintcdn.com/xeniateam/r-j40vtdxuJKg0Zh/logo/logo-light.svg?fit=max\u0026auto=format\u0026n=r-j40vtdxuJKg0Zh\u0026q=85\u0026s=6e8f1d49ac9946b22863d3dd22346adf","dark":"https://mintcdn.com/xeniateam/r-j40vtdxuJKg0Zh/logo/logo-dark.svg?fit=max\u0026auto=format\u0026n=r-j40vtdxuJKg0Zh\u0026q=85\u0026s=d2260d84971fb9ba7fbe9d3334f9769c"},"favicon":"https://mintcdn.com/xeniateam/r-j40vtdxuJKg0Zh/favicon.ico?fit=max\u0026auto=format\u0026n=r-j40vtdxuJKg0Zh\u0026q=85\u0026s=1ec461628add23e7e21efd17a9c2dea9","navbar":{"links":[{"href":"mailto:support@xenia.team","label":"Support"}],"primary":{"type":"button","label":"Dashboard","href":"https://app.xenia.team/"}},"footer":{"socials":{"linkedin":"https://www.linkedin.com/company/xenia-app"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"xeniateam","hasAudioNarration":false,"actualSubdomain":"xeniateam","customDomains":["docs.xenia.team"],"gitSource":{"type":"github","owner":"xeniaengineering","repo":"docs","deployBranch":"production","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6af1a9b5ea8a9a7a2693706e","clientVersion":"0.0.4088","searchFilterCounts":[{"language":"default","tag":"API Reference","count":48},{"language":"default","tag":"Reporting","count":12},{"language":"default","tag":"Projects","count":11},{"language":"default","tag":"Guides","count":11},{"language":"default","tag":"Users","count":8},{"language":"default","tag":"Tasks","count":7},{"language":"default","tag":"Enterprise Locations","count":6},{"language":"default","tag":"Workflows","count":6},{"language":"default","tag":"Getting Started","count":3},{"language":"default","tag":"Integrations","count":2}]},"assistantConfig":{},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types","slug":"/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types","pageMetadata":{"title":"Bulk Upsert Sub-Location Types","openapi":"POST /api/v1/mgt/enterprise/workspaces/{workspaceId}/sub-location-types/bulk-upsert","description":"Idempotently creates or updates sub-location types (e.g. Fridge, Auditorium) and their attribute definitions in one call, keyed by your own `externalId`. Safe to re-run.\n\nUp to **100** types per call, **50** attributes per type, **100** options per select attribute.\n\n**Type identity**, in priority order: `externalId` → `id` → `name` (case-insensitive). If nothing matches, the type is created. A matched type is renamed to `name`.\n\n**Attribute identity** (within the type): `externalId` → `id` → `key` → `name` (case-insensitive). If nothing matches, the attribute is created and gets a `key` derived from its name (returned in the response). `key` is match-only: it must name an existing attribute of the type. An `externalId` already used by an attribute of another type is rejected, as are two attributes in one row that match the same existing attribute.\n\n**Additive only.** Attributes and options you leave out are kept, never deleted. Options are matched by `id`, else by `label` (case-insensitive): a match is updated (label, color), anything else is appended.\n\n**`type` is immutable.** Sending a different type for an existing attribute is rejected with `400`.\n\nThe response reports each type's `status`, so a match against a type archived in the web app is visible (sub-locations cannot be created under an archived type).\n\nThe call is all-or-nothing: if any row fails, nothing is written and the error message names the row (e.g. `types[1].attributes[0]`).\n\nRequires the **Public API** workspace feature, `CAN_MANAGE_LOCATIONS`, and **Sub-Locations** enabled for the workspace (contact Xenia to enable it; until then every sub-location endpoint returns `404`).","href":"/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types"},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n strong: \"strong\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"Idempotently creates or updates sub-location types (e.g. Fridge, Auditorium) and their attribute definitions in one call, keyed by your own \", _jsx(_components.code, {\n children: \"externalId\"\n }), \". Safe to re-run.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Up to \", _jsx(_components.strong, {\n children: \"100\"\n }), \" types per call, \", _jsx(_components.strong, {\n children: \"50\"\n }), \" attributes per type, \", _jsx(_components.strong, {\n children: \"100\"\n }), \" options per select attribute.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Type identity\"\n }), \", in priority order: \", _jsx(_components.code, {\n children: \"externalId\"\n }), \" → \", _jsx(_components.code, {\n children: \"id\"\n }), \" → \", _jsx(_components.code, {\n children: \"name\"\n }), \" (case-insensitive). If nothing matches, the type is created. A matched type is renamed to \", _jsx(_components.code, {\n children: \"name\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Attribute identity\"\n }), \" (within the type): \", _jsx(_components.code, {\n children: \"externalId\"\n }), \" → \", _jsx(_components.code, {\n children: \"id\"\n }), \" → \", _jsx(_components.code, {\n children: \"key\"\n }), \" → \", _jsx(_components.code, {\n children: \"name\"\n }), \" (case-insensitive). If nothing matches, the attribute is created and gets a \", _jsx(_components.code, {\n children: \"key\"\n }), \" derived from its name (returned in the response). \", _jsx(_components.code, {\n children: \"key\"\n }), \" is match-only: it must name an existing attribute of the type. An \", _jsx(_components.code, {\n children: \"externalId\"\n }), \" already used by an attribute of another type is rejected, as are two attributes in one row that match the same existing attribute.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Additive only.\"\n }), \" Attributes and options you leave out are kept, never deleted. Options are matched by \", _jsx(_components.code, {\n children: \"id\"\n }), \", else by \", _jsx(_components.code, {\n children: \"label\"\n }), \" (case-insensitive): a match is updated (label, color), anything else is appended.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsxs(_components.strong, {\n children: [_jsx(_components.code, {\n children: \"type\"\n }), \" is immutable.\"]\n }), \" Sending a different type for an existing attribute is rejected with \", _jsx(_components.code, {\n children: \"400\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The response reports each type’s \", _jsx(_components.code, {\n children: \"status\"\n }), \", so a match against a type archived in the web app is visible (sub-locations cannot be created under an archived type).\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The call is all-or-nothing: if any row fails, nothing is written and the error message names the row (e.g. \", _jsx(_components.code, {\n children: \"types[1].attributes[0]\"\n }), \").\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Requires the \", _jsx(_components.strong, {\n children: \"Public API\"\n }), \" workspace feature, \", _jsx(_components.code, {\n children: \"CAN_MANAGE_LOCATIONS\"\n }), \", and \", _jsx(_components.strong, {\n children: \"Sub-Locations\"\n }), \" enabled for the workspace (contact Xenia to enable it; until then every sub-location endpoint returns \", _jsx(_components.code, {\n children: \"404\"\n }), \").\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Bulk Upsert Sub-Location Types","openapi":"POST /api/v1/mgt/enterprise/workspaces/{workspaceId}/sub-location-types/bulk-upsert","description":"Idempotently creates or updates sub-location types (e.g. Fridge, Auditorium) and their attribute definitions in one call, keyed by your own `externalId`. Safe to re-run.\n\nUp to **100** types per call, **50** attributes per type, **100** options per select attribute.\n\n**Type identity**, in priority order: `externalId` → `id` → `name` (case-insensitive). If nothing matches, the type is created. A matched type is renamed to `name`.\n\n**Attribute identity** (within the type): `externalId` → `id` → `key` → `name` (case-insensitive). If nothing matches, the attribute is created and gets a `key` derived from its name (returned in the response). `key` is match-only: it must name an existing attribute of the type. An `externalId` already used by an attribute of another type is rejected, as are two attributes in one row that match the same existing attribute.\n\n**Additive only.** Attributes and options you leave out are kept, never deleted. Options are matched by `id`, else by `label` (case-insensitive): a match is updated (label, color), anything else is appended.\n\n**`type` is immutable.** Sending a different type for an existing attribute is rejected with `400`.\n\nThe response reports each type's `status`, so a match against a type archived in the web app is visible (sub-locations cannot be created under an archived type).\n\nThe call is all-or-nothing: if any row fails, nothing is written and the error message names the row (e.g. `types[1].attributes[0]`).\n\nRequires the **Public API** workspace feature, `CAN_MANAGE_LOCATIONS`, and **Sub-Locations** enabled for the workspace (contact Xenia to enable it; until then every sub-location endpoint returns `404`).","href":"/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"summary":"Bulk Upsert Sub-Location Types","description":"Idempotently creates or updates sub-location types (e.g. Fridge, Auditorium) and their attribute definitions in one call, keyed by your own `externalId`. Safe to re-run.\n\nUp to **100** types per call, **50** attributes per type, **100** options per select attribute.\n\n**Type identity**, in priority order: `externalId` → `id` → `name` (case-insensitive). If nothing matches, the type is created. A matched type is renamed to `name`.\n\n**Attribute identity** (within the type): `externalId` → `id` → `key` → `name` (case-insensitive). If nothing matches, the attribute is created and gets a `key` derived from its name (returned in the response). `key` is match-only: it must name an existing attribute of the type. An `externalId` already used by an attribute of another type is rejected, as are two attributes in one row that match the same existing attribute.\n\n**Additive only.** Attributes and options you leave out are kept, never deleted. Options are matched by `id`, else by `label` (case-insensitive): a match is updated (label, color), anything else is appended.\n\n**`type` is immutable.** Sending a different type for an existing attribute is rejected with `400`.\n\nThe response reports each type's `status`, so a match against a type archived in the web app is visible (sub-locations cannot be created under an archived type).\n\nThe call is all-or-nothing: if any row fails, nothing is written and the error message names the row (e.g. `types[1].attributes[0]`).\n\nRequires the **Public API** workspace feature, `CAN_MANAGE_LOCATIONS`, and **Sub-Locations** enabled for the workspace (contact Xenia to enable it; until then every sub-location endpoint returns `404`).","tags":["Enterprise Sub-Locations"],"parameters":["a1244657-bb05-4bc7-bde8-d6c499689585"],"requestBody":"42cfffbb-8d10-4e8b-a9e6-cf5f61687afd","responses":{"200":"fec1f031-88bf-4f15-b913-dd32a2c0379c","400":"18417341-6ce0-4b9a-946b-770e04706659","401":"c1a48467-838a-477a-b325-994403193889","403":"6ec8e0bb-1f3e-4447-b266-f79c4435707d","404":"c23b30ff-f6c9-447e-911f-ec4db780ecce","409":"68fcf746-61ae-43ea-bb12-64ddacdfec16","422":"a71c581a-3d58-4084-85ce-63e293f3c32a","500":"4d5aceaa-6667-431a-a4f3-eac8f2effb88"},"security":["2f480c80-d0fc-4425-a2ba-eb9d169e523a"],"method":"post","type":"path","servers":["1872f631-45f9-43be-a02b-fd206b4074de"],"path":"/api/v1/mgt/enterprise/workspaces/{workspaceId}/sub-location-types/bulk-upsert","baseUrlOptions":["https://api.xenia.team"],"title":"Bulk Upsert Sub-Location Types","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"a1244657-bb05-4bc7-bde8-d6c499689585":{"name":"workspaceId","in":"path","required":true,"description":"UUID of the workspace. Must be the workspace your API key is bound to.","schema":{"type":"string","format":"uuid","isRequired":true,"description":"UUID of the workspace. Must be the workspace your API key is bound to.","uniqueKey":"","typeLabel":"string\u003cuuid>"}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"types":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","properties":{"name":{"type":"string","maxLength":120,"isRequired":true,"uniqueKey":"types.items.[INDEX].name","typeLabel":"string"},"externalId":{"type":"string","maxLength":255,"description":"Your own stable key for this type. Strongly recommended.","uniqueKey":"types.items.[INDEX].externalId","typeLabel":"string"},"id":{"type":"string","format":"uuid","description":"Xenia type id, if you already know it.","uniqueKey":"types.items.[INDEX].id","typeLabel":"string\u003cuuid>"},"attributes":{"type":"array","maxItems":50,"items":{"type":"object","properties":{"name":{"type":"string","maxLength":120,"isRequired":true,"uniqueKey":"types.items.[INDEX].attributes.items.[INDEX].name","typeLabel":"string"},"type":{"type":"string","enum":["single_select","multi_select","number","boolean","text","date"],"description":"Immutable once the attribute exists.","isRequired":true,"uniqueKey":"types.items.[INDEX].attributes.items.[INDEX].type","typeLabel":"enum\u003cstring>"},"externalId":{"type":"string","maxLength":255,"description":"Your own stable key for this attribute.","uniqueKey":"types.items.[INDEX].attributes.items.[INDEX].externalId","typeLabel":"string"},"id":{"type":"string","format":"uuid","description":"Xenia attribute id.","uniqueKey":"types.items.[INDEX].attributes.items.[INDEX].id","typeLabel":"string\u003cuuid>"},"key":{"type":"string","maxLength":64,"description":"Match-only: the key of an existing attribute of this type (see List Sub-Location Types).","uniqueKey":"types.items.[INDEX].attributes.items.[INDEX].key","typeLabel":"string"},"options":{"type":"array","minItems":1,"maxItems":100,"description":"Required when creating a `single_select`/`multi_select` attribute, forbidden for other types.","items":{"type":"object","properties":{"label":{"type":"string","maxLength":60,"isRequired":true,"uniqueKey":"types.items.[INDEX].attributes.items.[INDEX].options.items.[INDEX].label","typeLabel":"string"},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","description":"Hex chip color, e.g. `#7C5CFC`.","isRequired":true,"uniqueKey":"types.items.[INDEX].attributes.items.[INDEX].options.items.[INDEX].color","typeLabel":"string"},"id":{"type":"string","format":"uuid","description":"Xenia option id.","uniqueKey":"types.items.[INDEX].attributes.items.[INDEX].options.items.[INDEX].id","typeLabel":"string\u003cuuid>"}},"required":["label","color"],"uniqueKey":"types.items.[INDEX].attributes.items.[INDEX].options.items.[INDEX]","typeLabel":"object"},"uniqueKey":"types.items.[INDEX].attributes.items.[INDEX].options","typeLabel":"object[]"},"isRequired":{"type":"boolean","description":"Whether the web app requires this attribute. Defaults to `false` on create; unchanged when omitted.","uniqueKey":"types.items.[INDEX].attributes.items.[INDEX].isRequired","typeLabel":"boolean"}},"required":["name","type"],"uniqueKey":"types.items.[INDEX].attributes.items.[INDEX]","typeLabel":"object"},"uniqueKey":"types.items.[INDEX].attributes","typeLabel":"object[]"}},"required":["name"],"uniqueKey":"types.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"types","typeLabel":"object[]"}},"required":["types"],"uniqueKey":"","typeLabel":"object"},"example":{"types":[{"externalId":"FRIDGE","name":"Fridge","attributes":[{"externalId":"ZONE","name":"Zone","type":"single_select","options":[{"label":"Front","color":"#7C5CFC"},{"label":"Back","color":"#22B8CF"}]},{"externalId":"CAPACITY","name":"Capacity","type":"number"}]}]},"examples":{"Example":{"title":"Example","value":{"types":[{"externalId":"FRIDGE","name":"Fridge","attributes":[{"externalId":"ZONE","name":"Zone","type":"single_select","options":[{"label":"Front","color":"#7C5CFC"},{"label":"Back","color":"#22B8CF"}]},{"externalId":"CAPACITY","name":"Capacity","type":"number"}]}]}}},"exampleType":"examples"}},"exampleType":"examples"},"responses":{"fec1f031-88bf-4f15-b913-dd32a2c0379c":{"description":"One result per input type, in request order, with one entry per input attribute.","content":{"application/json":{"example":{"data":[{"externalId":"FRIDGE","id":"5ea865b5-1503-4cc4-975d-101ecf67a5e4","name":"Fridge","status":"active","created":true,"attributes":[{"externalId":"ZONE","id":"8b1d2c3e-4f50-4a61-8b72-93a4b5c6d7e8","key":"zone","name":"Zone","created":true},{"externalId":"CAPACITY","id":"9c2e3d4f-5061-4b72-9c83-a4b5c6d7e8f9","key":"capacity","name":"Capacity","created":true}]}],"extra_meta":{"message":"Sub-location types upserted"}},"examples":{"Example":{"title":"Example","value":{"data":[{"externalId":"FRIDGE","id":"5ea865b5-1503-4cc4-975d-101ecf67a5e4","name":"Fridge","status":"active","created":true,"attributes":[{"externalId":"ZONE","id":"8b1d2c3e-4f50-4a61-8b72-93a4b5c6d7e8","key":"zone","name":"Zone","created":true},{"externalId":"CAPACITY","id":"9c2e3d4f-5061-4b72-9c83-a4b5c6d7e8f9","key":"capacity","name":"Capacity","created":true}]}],"extra_meta":{"message":"Sub-location types upserted"}}}},"exampleType":"examples"}},"exampleType":"examples"},"18417341-6ce0-4b9a-946b-770e04706659":{"description":"Bad Request - an attribute's `type` would change; an `id` or `key` does not resolve; an attribute `externalId` belongs to another type; two rows or attributes match the same record.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"c1a48467-838a-477a-b325-994403193889":{"description":"Unauthorized - invalid client credentials, or the `workspaceId` in the path is not the workspace your key is bound to (`Client does not belong to this workspace`).","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"6ec8e0bb-1f3e-4447-b266-f79c4435707d":{"description":"Forbidden - missing `CAN_MANAGE_LOCATIONS`, or the **Public API** feature is not enabled for the workspace.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"c23b30ff-f6c9-447e-911f-ec4db780ecce":{"description":"Not Found - Sub-Locations is not enabled for this workspace.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"68fcf746-61ae-43ea-bb12-64ddacdfec16":{"description":"Conflict - a rename would collide with another sub-location type's name.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"a71c581a-3d58-4084-85ce-63e293f3c32a":{"description":"Unprocessable Entity - body failed validation (missing `name`/`type`, `options` on a non-select type, color not `#RRGGBB`, limits exceeded).","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"4d5aceaa-6667-431a-a4f3-eac8f2effb88":{"description":"Internal Server Error.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}}},"security":{"2f480c80-d0fc-4425-a2ba-eb9d169e523a":{"clientKey":{"type":"apiKey","in":"header","name":"x-client-key","scopes":[],"schemeName":"clientKey"},"clientSecret":{"type":"apiKey","in":"header","name":"x-client-secret","scopes":[],"schemeName":"clientSecret"}}},"servers":{"1872f631-45f9-43be-a02b-fd206b4074de":{"url":"https://api.xenia.team"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"apiKey","in":"header","name":"x-client-key","scopes":[],"schemeName":"clientKey"},"schema":{"title":"x-client-key","type":"string","isRequired":true,"typeLabel":"string","deprecated":false},"schemeName":"clientKey","name":"x-client-key"},{"scheme":{"type":"apiKey","in":"header","name":"x-client-secret","scopes":[],"schemeName":"clientSecret"},"schema":{"title":"x-client-secret","type":"string","isRequired":true,"typeLabel":"string","deprecated":false},"schemeName":"clientSecret","name":"x-client-secret"}],"title":"clientKey \u0026 clientSecret"}]},"originalFileLocation":"api-reference/openapi/enterprise-sub-locations/bulk_upsert_sub_location_types.json"},"subdomain":"xeniateam","siteName":"Xenia Team API","title":"Bulk Upsert Sub-Location Types - Xenia Team API","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-09T11:08:50.278Z","originalFileLocation":"api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Idempotently creates or updates sub-location types (e.g. Fridge, Auditorium) and their attribute definitions in one call, keyed by your own externalId. Safe to re-run. Up to 100 types per call, 50 attributes per type, 100 options per select attribute. Type identity, in priority order: externalId → id → name (case-insensitive). If nothing matches, the type is created. A matched type is renamed to name. Attribute identity (within the type): externalId → id → key → name (case-insensitive). If nothing matches, the attribute is created and gets a key derived from its name (returned in the response). key is match-only: it must name an existing attribute of the type. An externalId already used by an attribute of another type is rejected, as are two attributes in one row that match the same existing attribute. Additive only. Attributes and options you leave out are kept, never deleted. Options are matched by id, else by label (case-insensitive): a match is updated (label, color), anything else is appended. type is immutable. Sending a different type for an existing attribute is rejected with 400. The response reports each type\u0026#x27;s status, so a match against a type archived in the web app is visible (sub-locations cannot be created under an archived type). The call is all-or-nothing: if any row fails, nothing is written and the error message names the row (e.g. types[1].attributes[0]). Requires the Public API workspace feature, CAN_MANAGE_LOCATIONS, and Sub-Locations enabled for the workspace (contact Xenia to enable it; until then every sub-location endpoint returns 404).\">\u003cmeta data-mint-head name=\"application-name\" content=\"Xenia Team API\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/xeniateam/1-R9L-rMXezXpRg2/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/xeniateam/1-R9L-rMXezXpRg2/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/xeniateam/1-R9L-rMXezXpRg2/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/xeniateam/1-R9L-rMXezXpRg2/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/xeniateam/1-R9L-rMXezXpRg2/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/xeniateam/1-R9L-rMXezXpRg2/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/xeniateam/1-R9L-rMXezXpRg2/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/xeniateam/1-R9L-rMXezXpRg2/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/xeniateam/1-R9L-rMXezXpRg2/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Bulk Upsert Sub-Location Types - Xenia Team API\">\u003cmeta data-mint-head property=\"og:description\" content=\"Idempotently creates or updates sub-location types (e.g. Fridge, Auditorium) and their attribute definitions in one call, keyed by your own externalId. Safe to re-run. Up to 100 types per call, 50 attributes per type, 100 options per select attribute. Type identity, in priority order: externalId → id → name (case-insensitive). If nothing matches, the type is created. A matched type is renamed to name. Attribute identity (within the type): externalId → id → key → name (case-insensitive). If nothing matches, the attribute is created and gets a key derived from its name (returned in the response). key is match-only: it must name an existing attribute of the type. An externalId already used by an attribute of another type is rejected, as are two attributes in one row that match the same existing attribute. Additive only. Attributes and options you leave out are kept, never deleted. Options are matched by id, else by label (case-insensitive): a match is updated (label, color), anything else is appended. type is immutable. Sending a different type for an existing attribute is rejected with 400. The response reports each type\u0026#x27;s status, so a match against a type archived in the web app is visible (sub-locations cannot be created under an archived type). The call is all-or-nothing: if any row fails, nothing is written and the error message names the row (e.g. types[1].attributes[0]). Requires the Public API workspace feature, CAN_MANAGE_LOCATIONS, and Sub-Locations enabled for the workspace (contact Xenia to enable it; until then every sub-location endpoint returns 404).\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Xenia Team API\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.xenia.team/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://xeniateam.mintlify.site/_mintlify/api/og/v2?division=Enterprise+Sub-Locations\u0026amp;title=Bulk+Upsert+Sub-Location+Types\u0026amp;description=Idempotently+creates+or+updates+sub-location+types+%28e.g.+Fridge%2C+Auditorium%29+and+their+attribute+definitions+in+one+call%2C+keyed+by+your+own+%60externalId%60.+Safe+t\u0026amp;theme=10a62aa493e86ee87dcc54c2\u0026amp;signature=8f1883a33556425ada2f5ecd12d79cb74f029432abc0c894476701c2d9cbd956\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Bulk Upsert Sub-Location Types - Xenia Team API\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Idempotently creates or updates sub-location types (e.g. Fridge, Auditorium) and their attribute definitions in one call, keyed by your own externalId. Safe to re-run. Up to 100 types per call, 50 attributes per type, 100 options per select attribute. Type identity, in priority order: externalId → id → name (case-insensitive). If nothing matches, the type is created. A matched type is renamed to name. Attribute identity (within the type): externalId → id → key → name (case-insensitive). If nothing matches, the attribute is created and gets a key derived from its name (returned in the response). key is match-only: it must name an existing attribute of the type. An externalId already used by an attribute of another type is rejected, as are two attributes in one row that match the same existing attribute. Additive only. Attributes and options you leave out are kept, never deleted. Options are matched by id, else by label (case-insensitive): a match is updated (label, color), anything else is appended. type is immutable. Sending a different type for an existing attribute is rejected with 400. The response reports each type\u0026#x27;s status, so a match against a type archived in the web app is visible (sub-locations cannot be created under an archived type). The call is all-or-nothing: if any row fails, nothing is written and the error message names the row (e.g. types[1].attributes[0]). Requires the Public API workspace feature, CAN_MANAGE_LOCATIONS, and Sub-Locations enabled for the workspace (contact Xenia to enable it; until then every sub-location endpoint returns 404).\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://xeniateam.mintlify.site/_mintlify/api/og/v2?division=Enterprise+Sub-Locations\u0026amp;title=Bulk+Upsert+Sub-Location+Types\u0026amp;description=Idempotently+creates+or+updates+sub-location+types+%28e.g.+Fridge%2C+Auditorium%29+and+their+attribute+definitions+in+one+call%2C+keyed+by+your+own+%60externalId%60.+Safe+t\u0026amp;theme=10a62aa493e86ee87dcc54c2\u0026amp;signature=8f1883a33556425ada2f5ecd12d79cb74f029432abc0c894476701c2d9cbd956\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/xeniateam/1-R9L-rMXezXpRg2/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Xenia Team API\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#8e54e9\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.xenia.team/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.xenia.team/#organization\",\"name\":\"Xenia Team API\",\"url\":\"https://docs.xenia.team\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/xeniateam/r-j40vtdxuJKg0Zh/logo/logo-light.svg?fit=max\u0026auto=format\u0026n=r-j40vtdxuJKg0Zh\u0026q=85\u0026s=6e8f1d49ac9946b22863d3dd22346adf\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.xenia.team#website\",\"name\":\"Xenia Team API\",\"url\":\"https://docs.xenia.team\",\"publisher\":{\"@id\":\"https://docs.xenia.team/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.xenia.team/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types#webpage\",\"url\":\"https://docs.xenia.team/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types\",\"name\":\"Bulk Upsert Sub-Location Types\",\"description\":\"Idempotently creates or updates sub-location types (e.g. Fridge, Auditorium) and their attribute definitions in one call, keyed by your own externalId. Safe to re-run. Up to 100 types per call, 50 attributes per type, 100 options per select attribute. Type identity, in priority order: externalId → id → name (case-insensitive). If nothing matches, the type is created. A matched type is renamed to name. Attribute identity (within the type): externalId → id → key → name (case-insensitive). If nothing matches, the attribute is created and gets a key derived from its name (returned in the response). key is match-only: it must name an existing attribute of the type. An externalId already used by an attribute of another type is rejected, as are two attributes in one row that match the same existing attribute. Additive only. Attributes and options you leave out are kept, never deleted. Options are matched by id, else by label (case-insensitive): a match is updated (label, color), anything else is appended. type is immutable. Sending a different type for an existing attribute is rejected with 400. The response reports each type's status, so a match against a type archived in the web app is visible (sub-locations cannot be created under an archived type). The call is all-or-nothing: if any row fails, nothing is written and the error message names the row (e.g. types[1].attributes[0]). Requires the Public API workspace feature, CAN_MANAGE_LOCATIONS, and Sub-Locations enabled for the workspace (contact Xenia to enable it; until then every sub-location endpoint returns 404).\",\"dateModified\":\"2026-11-09T11:08:50.278Z\",\"isPartOf\":{\"@id\":\"https://docs.xenia.team#website\"},\"breadcrumb\":{\"@id\":\"https://docs.xenia.team/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.xenia.team/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Xenia Team API\",\"item\":\"https://docs.xenia.team\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Bulk Upsert Sub-Location Types\",\"item\":\"https://docs.xenia.team/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.xenia.team/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types#apireference\",\"headline\":\"Bulk Upsert Sub-Location Types\",\"name\":\"Bulk Upsert Sub-Location Types\",\"description\":\"Idempotently creates or updates sub-location types (e.g. Fridge, Auditorium) and their attribute definitions in one call, keyed by your own externalId. Safe to re-run. Up to 100 types per call, 50 attributes per type, 100 options per select attribute. Type identity, in priority order: externalId → id → name (case-insensitive). If nothing matches, the type is created. A matched type is renamed to name. Attribute identity (within the type): externalId → id → key → name (case-insensitive). If nothing matches, the attribute is created and gets a key derived from its name (returned in the response). key is match-only: it must name an existing attribute of the type. An externalId already used by an attribute of another type is rejected, as are two attributes in one row that match the same existing attribute. Additive only. Attributes and options you leave out are kept, never deleted. Options are matched by id, else by label (case-insensitive): a match is updated (label, color), anything else is appended. type is immutable. Sending a different type for an existing attribute is rejected with 400. The response reports each type's status, so a match against a type archived in the web app is visible (sub-locations cannot be created under an archived type). The call is all-or-nothing: if any row fails, nothing is written and the error message names the row (e.g. types[1].attributes[0]). Requires the Public API workspace feature, CAN_MANAGE_LOCATIONS, and Sub-Locations enabled for the workspace (contact Xenia to enable it; until then every sub-location endpoint returns 404).\",\"url\":\"https://docs.xenia.team/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types\",\"mainEntityOfPage\":{\"@id\":\"https://docs.xenia.team/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types#webpage\"},\"dateModified\":\"2026-11-09T11:08:50.278Z\",\"publisher\":{\"@id\":\"https://docs.xenia.team/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.xenia.team#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Xenia Team API\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Xenia Team API","nav":{"global":null,"tabs":[{"tab":"Guides","pages":[{"title":"Guides","href":"/guides/getting-started"}]},{"tab":"API Reference","groups":[{"group":"Authentication","pages":[{"title":"Client Key Setup","href":"/api-reference/endpoints/authentication"}]},{"group":"Users","pages":[{"title":"Provision Users","openapi":"POST /api/v1/mgt/users/provision","href":"/api-reference/endpoints/users/provision-users"},{"title":"Get Users","openapi":"GET /api/v1/mgt/workspaces/{workspaceId}/users","href":"/api-reference/endpoints/users/get-users"},{"title":"Get User Context","openapi":"GET /api/v1/mgt/user-context","href":"/api-reference/endpoints/users/user-context"},{"title":"Change User Role","openapi":"PATCH /api/v1/mgt/workspaces/{workspaceId}/users/{userId}/role","href":"/api-reference/endpoints/users/change-user-role"},{"title":"Replace User Locations","openapi":"PUT /api/v1/mgt/workspaces/{workspaceId}/users/{userId}/locations","href":"/api-reference/endpoints/users/replace-user-locations"},{"title":"Set User Password","openapi":"PATCH /api/v1/mgt/workspaces/{workspaceId}/set-password","href":"/api-reference/endpoints/users/set-password"},{"title":"Set User Login Pin","openapi":"PUT /api/v1/mgt/set-login-pin","href":"/api-reference/endpoints/users/set-login-pin"},{"title":"Delete User","openapi":"DELETE /api/v1/mgt/workspaces/{workspaceId}/users/{userId}","href":"/api-reference/endpoints/users/delete-user"}]},{"group":"Locations","pages":[{"title":"Get Locations - Sub Locations Hierarchy","openapi":"GET /api/v1/mgt/workspaces/{workspaceId}/locations","href":"/api-reference/endpoints/locations/get-locations"}]},{"group":"Enterprise Locations","pages":[{"title":"Bulk Upsert Hierarchies","openapi":"POST /api/v1/mgt/enterprise/workspaces/{workspaceId}/hierarchy/bulk-upsert","href":"/api-reference/endpoints/enterprise-locations/bulk-upsert-hierarchy"},{"title":"Bulk Upsert Locations","openapi":"POST /api/v1/mgt/enterprise/workspaces/{workspaceId}/locations/bulk-upsert","href":"/api-reference/endpoints/enterprise-locations/bulk-upsert-locations"},{"title":"List Locations with External IDs","openapi":"GET /api/v1/mgt/enterprise/workspaces/{workspaceId}/locations","href":"/api-reference/endpoints/enterprise-locations/list-locations"},{"title":"Bulk Upsert Location Attributes","openapi":"POST /api/v1/mgt/enterprise/workspaces/{workspaceId}/location-attributes/bulk-upsert","href":"/api-reference/endpoints/enterprise-locations/bulk-upsert-attributes"},{"title":"List Location Attributes","openapi":"GET /api/v1/mgt/enterprise/workspaces/{workspaceId}/location-attributes","href":"/api-reference/endpoints/enterprise-locations/list-attributes"},{"title":"Bulk Upsert Attribute Values","openapi":"POST /api/v1/mgt/enterprise/workspaces/{workspaceId}/location-attribute-values/bulk-upsert","description":"Writes up to **2,000** location/attribute values per call. This is the endpoint an HRIS or store-master system calls on a schedule to keep Xenia's location profile in sync.\n\n**Addressing the location:** exactly one of `locationExternalId` or `locationId`.\n\n**Addressing the attribute:** at least one of `attributeExternalId`, `attributeId`, or `attributeName` (resolved in that order).\n\n**The value** must match the attribute's declared type, and for select types every option id must exist on the definition — otherwise the call fails with `400`.\n\nThe whole batch is applied in a **single version-guarded write**: if any row fails, nothing is written. Setting a value replaces any previous value for that location/attribute pair. There is no \"clear\" variant on this endpoint — an attribute simply has no entry for a location until you set one.\n\nRequires the **Public API** and **Location Attributes** workspace features plus `CAN_MANAGE_LOCATIONS`.","href":"/api-reference/endpoints/enterprise-locations/bulk-upsert-attribute-values"}]},{"group":"Enterprise Sub-Locations","pages":[{"title":"Bulk Upsert Sub-Location Types","openapi":"POST /api/v1/mgt/enterprise/workspaces/{workspaceId}/sub-location-types/bulk-upsert","href":"/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-types"},{"title":"List Sub-Location Types","openapi":"GET /api/v1/mgt/enterprise/workspaces/{workspaceId}/sub-location-types","description":"Returns every sub-location type in the workspace with its attribute definitions and the `externalId` you mapped to each type and attribute (or `null`). Use it to reconcile your own ids and to look up attribute `key`s and option ids.\n\nRequires the **Public API** workspace feature, `CAN_MANAGE_LOCATIONS`, and **Sub-Locations** enabled for the workspace (contact Xenia to enable it; until then every sub-location endpoint returns `404`).","href":"/api-reference/endpoints/enterprise-sub-locations/list-sub-location-types"},{"title":"Bulk Upsert Sub-Locations","openapi":"POST /api/v1/mgt/enterprise/workspaces/{workspaceId}/sub-locations/bulk-upsert","href":"/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-locations"},{"title":"List Sub-Locations","openapi":"GET /api/v1/mgt/enterprise/workspaces/{workspaceId}/sub-locations","href":"/api-reference/endpoints/enterprise-sub-locations/list-sub-locations"},{"title":"Bulk Upsert Sub-Location Attribute Values","openapi":"POST /api/v1/mgt/enterprise/workspaces/{workspaceId}/sub-location-attribute-values/bulk-upsert","href":"/api-reference/endpoints/enterprise-sub-locations/bulk-upsert-sub-location-attribute-values"}]},{"group":"Roles","pages":[{"title":"Get Roles","openapi":"GET /api/v1/mgt/workspaces/{workspaceId}/roles","href":"/api-reference/endpoints/roles/get"}]},{"group":"Teams","pages":[{"title":"List Teams","openapi":"GET /api/v1/mgt/workspaces/{workspaceId}/teams","href":"/api-reference/endpoints/teams/get-teams"}]},{"group":"Tasks","pages":[{"title":"Get Tasks","openapi":"POST /api/v1/ops/workspaces/{workspaceId}/tasks/catalog","href":"/api-reference/endpoints/tasks/get-tasks"},{"title":"Get Task","openapi":"GET /api/v1/ops/workspaces/{workspaceId}/tasks/{taskId}/details","href":"/api-reference/endpoints/tasks/get-task-by-id"},{"title":"Get Task List","openapi":"POST /api/v1/ops/workspaces/{workspaceId}/tasks/list","href":"/api-reference/endpoints/tasks/get-task-list"},{"title":"Create Task","openapi":"POST /api/v1/ops/workspaces/{workspaceId}/tasks","href":"/api-reference/endpoints/tasks/create-task"},{"title":"Edit Task","openapi":"POST /api/v1/ops/workspaces/{workspaceId}/tasks/{taskId}/edit","href":"/api-reference/endpoints/tasks/edit-task"},{"title":"Change Task Status","openapi":"PATCH /api/v1/ops/workspaces/{workspaceId}/tasks/{taskId}/status","href":"/api-reference/endpoints/tasks/set-task-status"},{"title":"Delete Task","openapi":"DELETE /api/v1/ops/workspaces/{workspaceId}/tasks/{taskId}","href":"/api-reference/endpoints/tasks/delete-task"}]},{"group":"Projects","pages":[{"title":"Create Project","href":"/api-reference/endpoints/projects/create-project"},{"title":"List Projects","openapi":"GET /api/v1/ops/workspaces/{workspaceId}/projects","href":"/api-reference/endpoints/projects/list-projects"},{"title":"Search Projects","openapi":"POST /api/v1/ops/workspaces/{workspaceId}/projects","href":"/api-reference/endpoints/projects/search-projects"},{"title":"Get Project","openapi":"GET /api/v1/ops/workspaces/{workspaceId}/projects/{projectId}","href":"/api-reference/endpoints/projects/get-project-by-id"},{"title":"Get Project Active Tasks","openapi":"GET /api/v1/ops/workspaces/{workspaceId}/projects/{projectId}/active/tasks","href":"/api-reference/endpoints/projects/get-project-active-tasks"},{"title":"Get Project Schedule Analytics","openapi":"POST /api/v1/ops/workspaces/{workspaceId}/projects/{projectId}/schedules/analytics","href":"/api-reference/endpoints/projects/project-schedule-analytics"},{"title":"Get Project Task Analytics","openapi":"POST /api/v1/ops/workspaces/{workspaceId}/projects/{projectId}/tasks/analytics","href":"/api-reference/endpoints/projects/project-task-analytics"},{"title":"Edit Project","openapi":"PATCH /api/v1/ops/workspaces/{workspaceId}/projects/{projectId}/edit","href":"/api-reference/endpoints/projects/edit-project"},{"title":"Pause or Resume Project","openapi":"GET /api/v1/ops/workspaces/{workspaceId}/projects/{projectId}/toggle-pause","href":"/api-reference/endpoints/projects/pause-resume-project"},{"title":"End Project","openapi":"PUT /api/v1/ops/workspaces/{workspaceId}/projects/{projectId}/end","href":"/api-reference/endpoints/projects/end-project"},{"title":"Delete Project","openapi":"DELETE /api/v1/ops/workspaces/{workspaceId}/projects/{projectId}","href":"/api-reference/endpoints/projects/delete-project"}]},{"group":"Reporting","pages":[{"title":"Submission Records","openapi":"POST /api/v1/ops/template-submissions","href":"/api-reference/endpoints/reporting/submission-records"},{"title":"Get Submission","openapi":"GET /api/v1/ops/workspaces/{workspaceId}/logs/{logId}","href":"/api-reference/endpoints/reporting/submission-record"},{"title":"Submission Counts by Status","openapi":"POST /api/v1/ops/submissions-count-by-status","href":"/api-reference/endpoints/reporting/submission-counts-by-status"},{"title":"Task Count by Status","openapi":"POST /api/v1/ops/reports/tasks/count-by-status","href":"/api-reference/endpoints/reporting/task-count-by-status"},{"title":"Task Count by Assignees","openapi":"POST /api/v1/ops/reports/tasks/count-by-assignees","href":"/api-reference/endpoints/reporting/task-count-by-assignees"},{"title":"Task Count by Categories","openapi":"POST /api/v1/ops/reports/tasks/count-by-categories","href":"/api-reference/endpoints/reporting/task-count-by-categories"},{"title":"Weekly Completion","openapi":"POST /api/v1/ops/reports/tasks/weekly-completion","href":"/api-reference/endpoints/reporting/weekly-completion"},{"title":"Schedule Completion by Location","openapi":"POST /api/v1/ops/reports/tasks/schedule-completion-by-location","href":"/api-reference/endpoints/reporting/schedule-completion-by-location"},{"title":"On-Time / Late Submission by Location","openapi":"POST /api/v1/ops/reports/tasks/on-time-late-submission-by-location","href":"/api-reference/endpoints/reporting/on-time-late-submission-by-location"},{"title":"Daily Compliance","openapi":"POST /api/v1/ops/reports/tasks/daily-compliance","href":"/api-reference/endpoints/reporting/daily-compliance"},{"title":"List Grid Reports","openapi":"GET /api/v1/mgt/grid-reports","href":"/api-reference/endpoints/reporting/grid-reports-list"},{"title":"Grid Report View Spreadsheet","openapi":"GET /api/v1/mgt/grid-report-views/{viewId}/spreadsheet","href":"/api-reference/endpoints/reporting/grid-report-spreadsheet"}]}]}]},"basePath":"","title":"Bulk Upsert Sub-Location Types - Xenia Team API","buildId":"dpl_DTau1J5HqS9UTgVSDwGksstFWtPa","deploymentId":"dpl_DTau1J5HqS9UTgVSDwGksstFWtPa","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-5FCzAcfS.js","utils-SLtAG4EZ.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-2DZi8ZMu.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-D7J3nkzE.js","snippetPresets-D0Alv0AH.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-BI4qNJ2c.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BD3uyr8j.js","shallow-D8iEBr5z.js","getApiPlaygroundDisplay-CgNP4lzR.js","CodeSnippet-CX-QHuMs.js","CodeSnippets-VlXE-ZUf.js","Page-D9ithiIZ.js","getPastedJson-DYNQkZ1M.js","icon-CzacdwOi.js","MethodPill-2JVqoYKi.js","DuplicateIcon-_xVXs-U8.js","createIcon-BRHrweLo.js","DynamicMarkdown-mQG_iQiE.js","SectionHeading-DMpJzv8f.js","axios-vUo_bRtp.js","Markdown-5FGIym-8.js","clsx-D-TRO5q5.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CdrJecqK.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-CHlcWBLM.js"]}