Skip to main content

Site Copy and Hierarchy Assignment API

Authentication

All endpoints use Bearer token authentication.

Authorization: Bearer <TOKEN>

Base URL

Use the environment-specific base URL provided to you (example below):

https://xprtbackend.xenial.com

Workflow

To use the Site Copy and Hierarchy Assignment API, follow this workflow:

For additional information, see Field Reference and Best Practices and Troubleshooting.

Create or Copy a New Site

Use the POST /v1/companies/{companyId}/sites endpoint to create a new site with the option to copy from a base site. Using this endpoint:

  • Creates a new site.

  • If the source_site_copy_id value is provided, the API copies selected entities from the source (base) site.

  • The copy_entities field controls which entities get copied. Send only what is needed.

Example curl

curl -X POST \
  "https://xprtbackend.xenial.com/v1/companies/{companyId}/sites" \
  -H "Authorization: Bearer {TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data-raw '{
    "name": "Site 3 (Copy)",
    "store_number": "4",
    "type": "Production",
    "environment": "Production",
    "business_type": "QSR",
    "timezone": "US/Eastern",
    "preferred_language": "en-US",
    "location": {
      "address_1": "4444",
      "address_2": "",
      "city": "444",
      "state": "AL",
      "zip": "44444",
      "country": "US"
    },
    "automatic_updates": false,
    "apps": [
      {
        "app_code": "XKS",
        "preferred_version": {
          "version": "4.0.444",
          "uri": "https://<official-host>/xks/4.0.444/"
        }
      },
      {
        "app_code": "XPOS",
        "preferred_version": {
          "version": "13131313131313",
          "uri": 
"https://pos-download.xenial.com/pos-app/13131313131313/"
        }
      }
    ],
    "subscriptions": [
      {
        "count": 1,
        "name": "Enterprise Kitchen",
        "product": "XKS",
        "is_active": true,
        "external_data": {
          "automatic_updates": false,
          "enable_encryption": false
        }
      },
      {
        "count": 1,
        "name": "Enterprise POS",
        "product": "XENIAL POS",
        "is_active": true,
        "external_data": {
          "automatic_updates": false
        }
      },
      {
        "count": 1,
        "name": "Genius Gateway",
        "product": "genius_transport",
        "is_active": true,
        "external_data": {
          "environment": "Production",
          "merchant_name": "merchant_name",
          "merchant_site_id": "merchant_site_id",
          "merchant_key": "merchant_key",
          "web_checkout_key": "web_checkout_key",
          "kount_fraud_detection": true,
          "applepay_merchant_id": "apple_merchant_id",
          "googlepay_merchant_id": "google_merchant_id"
        }
      }
    ],
    "source_site_copy_id": "{source_site_id}",
    "copy_entities": [
      "audio-file",
      "break-time",
      "bundle-component",
      "calendar",
      "configuration-group",
      "count-frequency",
      "country-state",
      "course",
      "currency-scheme",
      "custom-label-definition",
      "customer-survey",
      "date-range",
      "day-part",
      "day-part-type",
      "default-user",
      "discount-definition",
      "donation",
      "dynamic-matrix",
      "employee-status-change-reason",
      "employee-status-config",
      "event-type",
      "external-application",
      "fee-definition",
      "fixed-matrix",
      "floor-plan",
      "forecast-definition",
      "forecast-definition-mapping",
      "general-ledger-account",
      "gift-service",
      "history-definition",
      "house-account",
      "i9-document-class",
      "i9-status",
      "inventory-item-venue",
      "inventory-location",
      "job-change-reason",
      "job-code",
      "job-code-category",
      "job-code-rate",
      "labor-matrix",
      "load-balancing-rule",
      "main-variant-mix",
      "measure",
      "menu",
      "menu-category",
      "menu-item-group",
      "min-wage-config",
      "modifier-build",
      "modifier-collection",
      "modifier-group",
      "named-calculation",
      "notification-template",
      "online-ordering-settings",
      "order-destination",
      "order-lane",
      "order-screen",
      "order-source",
      "pay-type",
      "pay-type-scheme",
      "payroll-employee-status-mapping",
      "payroll-job-category-mapping",
      "payrule-group",
      "peripheral",
      "pos-job-code",
      "pos-pay-mapping",
      "pos-reason-code",
      "preferences",
      "product",
      "product-availability",
      "product-price",
      "punch-adjustment-reason",
      "receipt-message",
      "receipt-template",
      "report-options",
      "schedule-type",
      "service-point",
      "store-hours-config",
      "store-hours-config-group",
      "support-user",
      "tag-rule",
      "tare",
      "tax-definition",
      "tax-group",
      "tender-currency",
      "tender-mapping",
      "terminal",
      "terminal-scheme",
      "time-period",
      "tip-group",
      "validation-format",
      "variant-build",
      "vendor",
      "w4-filing-status",
      "web-meta-data",
      "workflow",
      "xks-bumpbar",
      "xks-display-definition",
      "xks-display-scheme",
      "xks-general-settings",
      "xks-station-config",
      "modifier"
    ]
  }'

App Version Definition

Use the GET /v1/apps endpoint to get a list of available applications and releases when these conditions apply:

  • Pinned versions of XKS/XPOS for the site are wanted.

  • The automatic_updates value is false.

  • The apps[] field with a preferred version for each managed app must be provided. This is required if the automatic_updates value is false.

Additional notes:

  • copy_entities should be minimal. Include only what the destination site requires.

  • The enable_encryption field is optional and defaults to false.

  • Genius Gateway is included in the example. If it is not used, omit that subscription object entirely.

  • Use only:

    • Non-EOL releases

    • Official download hosts

  • For most site subscriptions, send count: 1 at the site level, as shown in Example curl.

Assign the New Site to a Hierarchy

Use the PATCH /v1/companies/{companyId}/site-hierarchies/{siteHierarchyId} endpoint to add or move a site within a hierarchy level tree.

Note

This endpoint does not replace the entire hierarchy.

Key rules:

  • Every level object sent must include:

    • id

    • name

    • sites [array]

    • children [array] - can be empty []

      Note

      Sending children: [] does not mean delete all children. It only satisfies the schema requirement for the level object being patched.

  • Every site object must include:

    • id

    • name

  • Omitted nodes are not treated as deletions.

Add Site to a Top-level Level

Example curl

curl -X PATCH \
  "https://xprtbackend.xenial.com/v1/companies/{companyId}
/site-hierarchies/{siteHierarchyId}" \
  -H "Authorization: Bearer {TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data-raw '{
    "name": "Hierarchy name",
    "levels": [
      {
        "id": "{levelId}",
        "name": "Level name",
        "sites": [
          {
            "id": "{newSiteId}",
            "name": "4 (Copy)"
          }
        ],
        "children": []
      }
    ]
  }'

Add Site to a Nested Child Level

Example curl

curl -X PATCH \
  "https://xprtbackend.xenial.com/v1/companies/{companyId}
/site-hierarchies/{siteHierarchyId}?filter_by_assigned_sites=true" \
  -H "Authorization: Bearer {TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data-raw '{
    "name": "Second Hierarchy",
    "levels": [
      {
        "id": "{topLevelId}",
        "name": "Second Level",
        "sites": [],
        "children": [
          {
            "id": "{childLevelId}",
            "name": "Child level 1",
            "sites": [
              {
                "id": "{newSiteId}",
                "name": "Site 4 (Copy)"
              }
            ],
            "children": []
          }
        ]
      }
    ]
  }'

Find hierarchy + level Identifiers

If level identifiers (IDs) are not known, use the GET /v1/companies/{companyId}/site-hierarchies endpoint.

Example curl

curl -X GET \
  "https://xprtbackend.xenial.com/v1/companies/{companyId}
/site-hierarchies?filter_by_assigned_sites=true&%24skip=0&
no_mapping_hierarchy=false&%24top=10" \
  -H "Authorization: Bearer {TOKEN}" \
  -H "Accept: application/json"

From the response, look for:

  • items[].idsiteHierarchyId

  • items[].levels[].id → top-level levelId

  • items[].levels[].children[].id → nested child levelId

Field Reference and Best Practices

The following sections list and describe required and optional fields and site copying best practices.

Site Creation Fields (Core)

Field Name

Value Options

Guidance

type

  • Production

  • Site-Lab

  • QA-Test

  • Training

  • Gold-Standard

  • Warehouse

  • Vending Commissary

  • Suite Pantry

  • Production: Real/live store

  • Site-Lab / QA-Test: Validation and testing

  • Training: Training/demo operations

  • Gold-Standard: Reference/template site. Special rules may apply per company.

  • Warehouse / Vending Commissary / Suite Pantry: Specialized operational locations

environment

  • Production

  • Site-Lab

  • QA-Test

  • Training

  • Gold-Standard

The value usually aligns with the operational state, such as live vs test/training/reference.

business_type

  • QSR

  • TSR

  • Retail

  • Warehouse

  • Primary Warehouse

  • Vending Commissary

  • Suite Pantry

  • Suite

  • QSR / TSR: Restaurant models

  • Retail: Retail concept

  • Warehouse / Primary Warehouse: Logistics/inventory sites

  • Vending Commissary / Suite Pantry / Suite: Venue/commissary/suite operations

Practical default (typical restaurant store)

  • type : Production

  • environment : Production

  • business_type : QSR or TSR for table-service

Copy Behavior

source_site_copy_id: If set, the new site is created as a copy using the selected entities.

copy_entities:

  • Send only what is needed. Large copy sets increase runtime and risk.

  • Start with a minimal list and expand only when required.

Genius Gateway Subscription

product=genius_transport

  • Required fields (minimum):

    • count - Site-level should be 1

    • product : "genius_transport"

    • is_active : true

    • external_data.environment : "Production" or "Custom"

    • external_data.merchant_name

    • external_data.merchant_site_id

    • external_data.merchant_key

  • Optional fields (examples):

    • reporting_url

    • web_checkout_key

    • stage_url

    • void_url

    • applepay_merchant_id

    • googlepay_merchant_id

    • kount_fraud_detection

Troubleshooting

Common issues and errors with solutions are described below.

The PATCH endpoint does not treat missing nodes as deletions. It is add and move oriented:

  • If delete semantics are needed, request a dedicated endpoint/behavior. The delete operation is not supported by PATCH in this flow currently.

  • Always send children: [] only to satisfy the schema. Do not assume deletion behavior.

  • For every level object, send "children": []. This addresses the children needed response.

400 Validation Errors

These errors are typically caused by:

  • Missing required fields, such as id, name, sites, or children in a hierarchy level.

  • Missing id/name inside a sites[] item.

  • Using automatic_updates=false without supplying apps[].