xMatix
Sign in Request demo
xMatix
PRODUCTS
SalesField SalesCRMRewardsClaimsInventoryProcurementWarehouse ManagementField ServiceServiceSupportTelephony & MessagingFinance & AccountingPayrollExpense ManagementCommercePortalsAnalytics & ReportingData StudioMobile AppSee all products →
PLATFORM
Platform overviewApp BuilderAutomationIntegrationsSecurity & GovernanceChange ManagementDevelopers
SENSE AI
Sense AI overviewSense AssistSense ControlSense VisionAI StudioTrust & governanceIn Claude & ChatGPTUse cases
SOLUTIONS
FMCG & DistributionManufacturing & Dealer NetworksAutomotive & DealershipsPharma & HealthcareConsumer DurablesAgri-InputsBuilding MaterialsService NetworksWarehousing & 3PLFinancial AccountingERP SoftwareIndia GST ComplianceUAE VAT & e-InvoicingSaudi ZATCA & VATAll solutions →
RESOURCES
Knowledge CenterDeveloper & CLIBlogGuidesWhat is xMatix?Company facts
COMPANY
AboutCareersPartnersEventsContactAuthorsLegal
Sign in Request demo
Home/Docs/Developer/The data API
REFERENCE · Last reviewed

The data API

The data API is the REST surface the xMatix web and mobile clients themselves run on — there is no separate, lesser "integration API". Every entity in the tenant, standard or custom, is addressable by its logical name through one uniform set of endpoints under your organization's API base URL, with versioned routes (/api/v1/…) and JSON in both directions. Because it is the product's own API, two guarantees follow: requests execute as the authenticated user with the full security model applied on the server, and writes run the complete save pipeline — business rules, validations, scripts, workflows and approvals fire exactly as they do in the UI.

Authentication

Calls carry an OAuth 2.0 bearer token issued by your organization's sign-in authority — the same identity service that signs users into the product. The token identifies a user; the platform applies that user's security profiles, record security and restriction rules to every request. For an unattended integration, use a dedicated account granted exactly what the integration needs.

curl -H "Authorization: Bearer $TOKEN" \
  "https://<your-api-host>/api/v1/data/Account?pageSize=50"

Entity names in routes are logical names as they appear in the data model (for example Account, not the display label) — find them in Setup → Design Studio → Entities, via the CLI's metadata pull, or through the MCP endpoint's describe tool.

Reading records

EndpointWhat it returns
GET /api/v1/data/{entity}A page of records, with total count and paging echo
GET /api/v1/data/{entity}/{id}One record; ?relations= expands related records inline
GET /api/v1/data/{entity}/{id}/{relation}The records related through a named relation

List queries compose through query parameters:

ParameterMeaning
filterA filter expression over the entity's fields, evaluated in the database — the query-filter side of Expressions
searchFree-text term, matched across the entity's searchable fields and combined with filter
orderBySort expression
relationsRelated records to include inline
idsComma-separated record ids — fetch a known set in one call
additionalFieldsExtra fields to project beyond the default set; lookup fields included here are enriched with their display-name sibling
pageSize, pageNoPaging — pageSize defaults to 25, pageNo starts at 1

The response wraps the page: the records under data, the total count, and the page size and number echoed back — everything needed to iterate a large result set deterministically.

Writing records

EndpointWhat it does
POST /api/v1/data/{entity}Creates a record from a JSON body; returns 201 with the created record and its location
PATCH /api/v1/data/{entity}/{id}Partial update — send only the fields you are changing
DELETE /api/v1/data/{entity}/{id}Deletes the record (subject to the tenant's delete and recycle-bin behavior)
POST /api/v1/data/{entity}/previewMaterializes the record a create would produce — defaults, rules and calculations applied — without persisting anything
PATCH /api/v1/data/{entity}/{id}/previewThe same, for an update

The preview endpoints are the API twin of what a form shows before you press save — useful for validating input and showing computed outcomes in your own UI without committing. Updates and deletes also respect the platform's record edit locks: while another user holds a record open for editing, the API rejects the write with a message naming the holder, exactly as the product does.

Actions and bulk operations

EndpointWhat it does
POST /api/v1/data/{entity}/{id}/{action}Invokes a named entity action on one record — the same actions buttons invoke in the UI
POST /api/v1/data/bulk/{entity}/{action}Invokes an action across many records
POST /api/v1/data/bulk/{entity}Creates many records in one call
PATCH /api/v1/data/bulk/{entity}Updates many records in one call
GET /api/v1/data/bulk/{entity}/{ids}Fetches a set of records by id

Actions are how server-side behavior is exposed by name — an action backed by an automation script or built-in handler does its work; an action with no handler succeeds without effect, so wire the handler before relying on the call.

Delta sync

For consumers that mirror data — the pattern behind the platform's offline mobile clients — GET /api/v1/sync/{entity}?since=<cursor> returns records changed or soft-deleted since a cursor (deletions arrive as records carrying a deletion timestamp), along with the next cursor to store. POST /api/v1/sync/manifest answers, for a batch of entity/cursor pairs in one round-trip, whether each has anything new. Polling deltas is far cheaper than re-querying, and the cursor model makes catch-up after downtime automatic.

Metadata, read-only

The model itself — entities, fields, views, relations — is readable under /api/v1/metadata/…, which is the surface the CLI's metadata commands ride on. For programmatic discovery ("what fields does this entity have?"), prefer the metadata routes or the MCP describe tool over guessing from record payloads.

Common questions

Do API writes trigger the same automation as the UI?

Yes — identically. A record created through POST /api/v1/data/{entity} passes through the same lifecycle as a form save: defaults, validations, business rules, bound scripts, workflow triggers, approval gates. This cuts both ways: your integration gets the tenant's business logic for free, and a validation that blocks users blocks the API too — what runs when you save a record explains the order.

How should an integration page through large tables?

With pageSize/pageNo for one-off reads, and the delta-sync cursor for anything that mirrors data continuously. A nightly "fetch everything" job re-reads mostly unchanged rows; the same job on sync/{entity} reads only what changed, and the manifest endpoint tells it in one call which entities are even worth visiting.

Why does a filtered query return records my filter should exclude?

First check the field name — filters reference logical field names, and an unknown name will not match the way you expect. Then check the value form: picklists compare stored values rather than display labels, and lookups are ids. When a filter still misbehaves, reproduce it with a minimal query and compare against a saved view with the same condition in the product — the query-filter reference covers the semantics shared by both surfaces.