Skip to main content

API

The xPage API lets you read and write resources on a user's hosting. All requests are scoped to a single installation via a restricted token.

Base URL: https://.../api/apps/v1

All endpoints (except auth) require:

Authorization: Bearer <token>

Pagination

List endpoints share a common set of query parameters:

ParamDefaultDescription
page1Page number
page_size20Results per page (max 200)
order_byresource-specificField to sort by (see each endpoint)
order_directionDESCASC or DESC

Paginated response shape:

{
"data": {
"<resource>": [...],
"pagination": {
"total": 100,
"per_page": 20,
"current_page": 1,
"last_page": 5
}
}
}

Products

List products

GET /product

Permission: product:view

Query params:

ParamDescription
searchFull-text search on title, description, slug (min 2 chars)
titleExact title match
statusactive or inactive
is_digitaltrue or false
out_of_stocktrue returns products with no stock; false returns products with stock
categoryFilter by category ID
order_bytitle, category, created_at

Response:

{
"data": {
"products": [
{
"id": "uuid",
"slug": "string",
"title": "string",
"description": "string|null",
"page_title": "string|null",
"meta_description": "string|null",
"is_digital": false,
"status": "active|inactive",
"stock_tracked": true,
"allow_order_when_oos": false,
"created_at": "2024-01-01T00:00:00Z",
"image": { "...file" },
"images": [{ "...file" }],
"ugc_videos": [{ "...file" }],
"options": [{ "...option" }],
"variants": [{ "...variant" }],
"category": { "id": "uuid", "name": "string" },
"default": { "...variant" },
"properties": [{ "id": "uuid", "name": "string", "value": "string" }]
}
],
"pagination": { "..." }
}
}

Get product

GET /product/{id}

Permission: product:view

Response:

{
"data": {
"product": { "...product" }
}
}

Create product

POST /product

Permission: product:create

Request must be multipart/form-data. Product fields are sent as a JSON string in the metadata field. Image and file uploads are sent as separate multipart parts.

Body:

FieldTypeRequiredDescription
metadataJSON stringYesProduct data (see structure below)
images[]fileNoNew image files to upload (jpeg, png, webp, gif — max 5 MB each)
files[]fileNoDigital product files (pdf, mp3, mp4, zip, etc.)

metadata structure:

{
"title": "string",
"slug": "string",
"description": "string|null",
"page_title": "string|null",
"meta_description": "string|null",
"status": "active|inactive",
"is_digital": false,
"category_id": "uuid|null",
"images": [
{ "id": "uuid", "order": 0 }
],
"options": [
{
"order": 0,
"name": "string",
"values": [
{ "order": 0, "value": "string" }
]
}
],
"variants": [
{
"price": 29.99,
"compare_price": 39.99,
"sku": "string|null",
"quantity": 100,
"image": "file_uuid|null",
"file": "file_uuid|null",
"values": [{ "order": 0, "value": "string" }]
}
],
"default": {
"price": 29.99,
"compare_price": 39.99,
"sku": "string|null",
"quantity": 100,
"file": "file_uuid|null"
},
"properties": [
{ "name": "string", "value": "string" }
],
"ugc_videos": [
{ "id": "file_uuid", "order": 0 }
]
}
info

images and ugc_videos reference file UUIDs from previously uploaded files (via POST /file). The variants.*.image and variants.*.file fields also reference file UUIDs. Use metadata.default for simple products with no variants, or metadata.variants for products with options.

Response:

{
"data": {
"product": { "...product" }
}
}

Update product

POST /product/{id}/update

Permission: product:update

Same request structure as create. All fields are optional — only provided fields are updated.

For options and variants, pass the existing id field to update an item, or omit it to create a new one.

Response:

{
"data": {
"product": { "...product" }
}
}

Orders

List orders

GET /order

Permission: order:view

Query params:

ParamDescription
searchSearch by order ID, ref, customer name, email, phone, address
refExact match on order reference number
statuspending, paid, or abandoned
delivery_statusunfulfilled, fulfilled, shipped, delivered, or cancelled. Comma-separated or array for multiple
return_statusFilter by return delivery status (same values as delivery_status)
refund_statuspending or refunded. Comma-separated or array for multiple
exclude_delivery_statusExclude orders with this delivery status
exclude_return_statusExclude orders with this return status
exclude_refund_statusExclude orders with this refund status
customer_idFilter by customer UUID
product_idFilter by product UUID (comma-separated or array for multiple)
landing_page_idFilter by landing page UUID
is_cancelledtrue or false
is_archivedtrue or false
fromCreated at — ISO date or Unix timestamp lower bound
toCreated at — ISO date or Unix timestamp upper bound
updated_fromUpdated at lower bound
updated_toUpdated at upper bound
order_bytotal, quantity, date, status

Response:

{
"data": {
"orders": [
{
"id": "uuid",
"ref": "string",
"status": "pending|paid|abandoned",
"currency": "string",
"customer_first_name": "string",
"customer_last_name": "string",
"customer_name": "string",
"customer_email": "string",
"customer_phone": "string",
"customer_address": "string",
"customer_city": "string",
"customer_state": "string",
"customer_postal_code": "string",
"customer_id": "uuid|null",
"customer_country": { "...country" },
"billing_first_name": "string",
"billing_last_name": "string",
"billing_name": "string",
"billing_email": "string",
"billing_phone": "string",
"billing_address": "string",
"billing_city": "string",
"billing_state": "string",
"billing_postal_code": "string",
"card_brand": "string|null",
"card_last4": "string|null",
"shipping_rate": 5.00,
"shipping_name": "string|null",
"discount": 10,
"discount_code": "string|null",
"tip": 0,
"tip_type": "string|null",
"tip_value": 0,
"bundle_name": "string|null",
"bundle_option_name": "string|null",
"bundle_price": null,
"fee": 0,
"subtotal": 29.99,
"total": 34.99,
"quantity": 1,
"is_archived": false,
"is_cancelled": false,
"cancelled_at": "datetime|null",
"paid_at": "datetime|null",
"created_at": "datetime",
"meta_data": {},
"payment_method": {
"id": "uuid",
"name": "string",
"status": "string",
"payment_types": [],
"connected": true
},
"variants": [
{
"id": "uuid",
"quantity": 1,
"price": 29.99,
"sku": "string|null",
"title": "string",
"is_digital": false,
"options": {},
"variant": { "...variant" },
"image_url": "string|null"
}
],
"deliveries": [
{
"id": "uuid",
"status": "unfulfilled|fulfilled|shipped|delivered|cancelled",
"tracking_number": "string|null",
"tracking_link": "string|null",
"shipping_carrier": { "id": "uuid", "name": "string", "code": "string", "status": "string" },
"order_variants": [{ "...order_variant" }]
}
],
"returns": [
{
"id": "uuid",
"order_id": "uuid",
"reason": "string|null",
"return_variants": [{ "..." }],
"delivery": { "...delivery" }
}
],
"refunds": [
{
"id": "uuid",
"order_id": "uuid",
"status": "pending|refunded",
"amount": 29.99,
"reason": "string|null",
"return": { "...return" },
"refund_variants": [{ "..." }]
}
],
"landing_page": { "...landing_page" },
"source_link": "string|null",
"checkout_link": "string",
"thank_you_link": "string"
}
],
"pagination": { "..." }
}
}

Get order

GET /order/{id}

Permission: order:view

Response:

{
"data": {
"order": { "...order" }
}
}

Create order

POST /order

Permission: order:create

Used to sync orders created outside of xPage (e.g. from an external checkout).

Body:

FieldTypeRequiredDescription
statusstringNopending, paid, or abandoned
customer_first_namestringNo
customer_last_namestringNo
customer_emailstringNo
customer_phonestringNo
customer_addressstringNo
customer_citystringNo
customer_statestringNo
customer_postal_codestringNo
billing_first_namestringNo
billing_last_namestringNo
billing_emailstringNo
billing_phonestringNo
billing_addressstringNo
billing_citystringNo
billing_statestringNo
billing_postal_codestringNo
country_idstringNoCountry ID
is_archivedbooleanNo
is_cancelledbooleanNo

Response:

{
"data": {
"order": { "...order" }
}
}

Update delivery

PUT /order/delivery/{deliveryId}

Permission: order:update

Body:

FieldTypeRequiredDescription
statusstringNounfulfilled, fulfilled, shipped, delivered, or cancelled
tracking_numberstringNoCarrier tracking number
shipping_carrierstringNoShipping carrier ID (required if tracking_number is set)

Response:

{
"data": {
"delivery": { "...delivery" }
}
}

Export orders

GET /order/export

Permission: order:export

Accepts the same filter params as GET /order. Returns a downloadable CSV file.

ParamDescription
formatExport format — currently csv (default)

Response is a file download (Content-Type: text/csv), not JSON.


Customers

List customers

GET /customer

Permission: customer:view

Query params:

ParamDescription
searchFull-text search on name, email, phone, address, city, postal code
countryFilter by country ID
order_byamount_spent, order_count, name, email, phone, address, city, postal_code, created_at, subscription_status

Response:

{
"data": {
"customers": [
{
"id": "uuid",
"name": "string",
"email": "string",
"phone": "string|null",
"address": "string|null",
"city": "string|null",
"country_id": "string|null",
"postal_code": "string|null",
"created_at": "datetime",
"updated_at": "datetime",
"country": { "...country" },
"order_count": 3,
"amount_spent": 89.97,
"latest_order": { "...order" },
"subscription_status": "subscribed|not_subscribed"
}
],
"pagination": { "..." }
}
}

Get customer

GET /customer/{id}

Permission: customer:view

Response:

{
"data": {
"customer": { "...customer" }
}
}

Create customer

POST /customer

Permission: customer:create

Body:

FieldTypeRequiredDescription
emailstringYes
namestringNo
phonestringNo
addressstringNo
citystringNo
postal_codestringNo
country_idstringNoCountry ID
subscription_statusstringNosubscribed or not_subscribed

Response:

{
"data": {
"customer": { "...customer" }
}
}

Reviews

List reviews

GET /review

Permission: review:view

Query params:

ParamDescription
product_idFilter by product UUID
statuspending, hidden, or published
ratingMinimum rating (integer 1–5)
order_byproduct_id, rating, created_at

Response:

{
"data": {
"reviews": [
{
"id": "uuid",
"content": "string",
"status": "pending|hidden|published",
"rating": 5,
"reviewer_name": "string",
"reviewer_email": "string|null",
"created_at": "datetime",
"images": [{ "...file" }],
"product": { "...product" }
}
],
"pagination": { "..." }
}
}

Get review

GET /review/{id}

Permission: review:view

Response:

{
"data": {
"review": { "...review" }
}
}

Create review

POST /review

Permission: review:create

Request must be multipart/form-data.

Body:

FieldTypeRequiredDescription
metadataJSON stringYesReview data (see structure below)
images[]fileNoImage files to upload (max 5 MB each)

metadata structure:

{
"product_id": "uuid",
"content": "string",
"rating": 5,
"reviewer_name": "string",
"reviewer_email": "string",
"status": "pending|hidden|published",
"image_ids": ["uuid"]
}
FieldRequiredDescription
product_idYesUUID of the product being reviewed
contentYesReview text
ratingYesInteger 1–5
reviewer_nameYes
reviewer_emailNo
statusNoDefaults to pending
image_idsNoUUIDs of previously uploaded files to attach

Response:

{
"data": {
"review": { "...review" }
}
}

Landing pages

List landing pages

GET /landing-page

Permission: landing_page:view

Query params:

ParamDescription
product_idFilter by product UUID (comma-separated for multiple)
domain_idFilter by domain UUID
cod_typecheckout, popup, or embedded
order_bycreated_at, updated_at

Response:

{
"data": {
"landingPages": [
{
"id": "uuid",
"title": "string",
"slug": "string",
"meta_description": "string|null",
"product_id": "uuid",
"domain_id": "uuid|null",
"created_at": "datetime",
"updated_at": "datetime",
"product": { "...product" },
"url": "string",
"screenshot_url": "string|null",
"lang": "string|null",
"cod_type": "checkout|popup|embedded"
}
],
"pagination": { "..." }
}
}

Get landing page

GET /landing-page/{id}

Permission: landing_page:view

Response:

{
"data": {
"landing_page": { "...landing_page" }
}
}

Shipping carriers

List carriers

GET /shipping-carrier

No permission required. Returns active shipping carriers available on the platform.

Response:

{
"data": {
"carriers": [
{
"id": "uuid",
"name": "string",
"code": "string",
"status": "string"
}
]
}
}

Files

List files

GET /file

Query params:

ParamDescription
fileable_typeproduct, variant, landing_page, review
fileable_idUUID of the associated resource
mime_typeExact MIME type or pattern with wildcard (e.g. image/*). Comma-separated for multiple
fromCreated at lower bound
toCreated at upper bound
order_bycreated_at

Response:

{
"data": {
"files": [
{
"id": "uuid",
"name": "string",
"size": 204800,
"alt": "string",
"mime_type": "image/webp",
"created_at": "datetime",
"url": "string",
"permanent_url": "string",
"thumbnail": "string|null"
}
],
"pagination": { "..." }
}
}

Get file

GET /file/{id}

Response:

{
"data": {
"file": { "...file" }
}
}

Upload file

POST /file

Request must be multipart/form-data.

Body:

FieldTypeRequiredDescription
filefileYesThe file to upload
fileable_typestringNo (required with fileable_id)product, variant, landing_page, review
fileable_idstringNo (required with fileable_type)UUID of the resource to link the file to
rolestringNoproduct_images, variant_image, digital_product, landing_page_images, review_images, ugc_video
orderintegerNoSort order when linked to a resource
altstringNoAlt text

Response:

{
"data": {
"file": { "...file" }
}
}

Delete file

POST /file/{id}

Deletes the file and unlinks it from all associated resources.

Response:

{
"data": {}
}

DELETE /file/{id}/link/{fileable_type}/{fileable_id}

Removes the association between a file and a resource without deleting the file itself.

Path paramDescription
fileable_typeproduct, variant, landing_page, review
fileable_idUUID of the resource to unlink from

Response:

{
"data": {
"file": { "...file" }
}
}

Permissions

List available permissions

GET /permission

Returns all permission subjects and their available actions. No authentication required.

Response:

{
"data": {
"permissions": {
"product": ["view", "create", "update", "delete"],
"order": ["view", "create", "update", "delete", "export"],
"customer": ["view", "create", "update", "delete"],
"review": ["view", "create", "update", "delete"],
"landing_page": ["view", "create", "update", "delete", "publish"],
"shipping": ["view", "create", "update", "delete"],
"setting": ["view", "update"],
"payment_method": ["view", "update"],
"analytic": ["view"],
"domain": ["view", "create", "update", "delete"],
"bundle": ["view", "create", "update", "delete"],
"policy": ["view", "create", "update", "delete"],
"plan": ["switch"],
"invoice": ["view", "pay"],
"file": ["browse", "upload", "delete"],
"app": ["install", "uninstall", "boot"]
}
}
}

If a required permission is not granted to your app, the API returns 403 Forbidden.


Response format

Success:

{
"data": { "..." }
}

Error:

{
"code": "ERROR_CODE",
"message": "Human-readable description",
"errors": {
"field": ["validation message"]
}
}