API reference
Data Stores
11 endpoints. Add your API key in the authentication panel to send test requests from this page.
List data stores
/api/external/v1/applications/{appId}/storesReturns a list of all data stores (tables) available for a specific application. This includes built-in stores (customers, services, etc.) and any custom-defined schema tables.
Each entry in the returned array contains at minimum key (string store identifier),
label (human-readable name), and fields (list of field definitions).
Built-in store keys: customers, appointments, services, feedback,
personnel, promotions, campaigns, time-slots.
Parameters
appIdstring (uuid)pathRequiredThe unique UUID of the application
Responses
200List of data store configurations401Missing or invalid API key403Key is valid but lacks access to this resource404Requested resource not found
Get data store records
/api/external/v1/applications/{appId}/stores/{storeKey}Retrieves all records from a specific storage table (built-in or custom). The result structure depends on the schema of the requested store.
By default this endpoint keeps the legacy response shape and returns a plain JSON array.
When page, size, q, field, or field.<key> is provided, it returns a paginated object:
{content, currentPage, pageSize, totalItems, totalPages}.
Search/filter examples:
?q=acme&page=0&size=25searches across returned fields.?field=phoneNumber:+15551234567&page=0&size=1filters by one exact field.?field.phoneNumber=+15551234567&page=0&size=1is equivalent and easier for URL builders.- For massive custom stores, prefer
size=500and pass the returnednextCursorascursoron the next request instead of incrementingpage.
Built-in store keys and their record shapes:
customers—{id, name, email, phone, notes, createdAt, updatedAt, ...}appointments—{id, customerId, serviceId, personnelId, startTime, endTime, status, notes, createdAt, ...}services—{id, name, description, duration, price, createdAt, ...}feedback—{id, customerId, rating, comment, callId, createdAt, ...}personnel—{id, name, role, email, phone, createdAt, ...}promotions—{id, name, description, discount, validFrom, validTo, createdAt, ...}campaigns—{id, name, description, startDate, endDate, status, createdAt, ...}time-slots—{id, dayOfWeek, startTime, endTime, maxCapacity, createdAt, ...}- custom keys —
{id, createdAt, updatedAt, ...plus all custom fields defined in the store schema}
Parameters
appIdstring (uuid)pathRequiredThe unique UUID of the application
storeKeystringpathRequiredThe unique key of the store (e.g., 'customers' or a custom key)
pageinteger (int32)queryPage number (0-indexed). When omitted, the legacy array response is returned.
sizeinteger (int32)queryItems per page (max 500)
cursorstringqueryOpaque cursor returned as `nextCursor` from a previous custom-store response
qstringqueryCase-insensitive search across returned fields
fieldarray of stringqueryExact field filters as key:value. May be repeated.
requestParamsobjectqueryRequired
Responses
200Records from the requested store401Missing or invalid API key403Key is valid but lacks access to this resource404Requested resource not found
Create custom data store record
/api/external/v1/applications/{appId}/stores/{storeKey}Inserts one record into a custom application data store. Built-in stores are read-only through this external endpoint; use a custom store for integrator-managed customer datasets.
Send custom fields at the top level. Reserved fields are handled specially:
customerId/customer_idlinks the record to an existing customer in the application.metadata/metaData/meta_datastores machine-readable metadata beside the record.id,createdAt, andupdatedAtare ignored on write.
Parameters
appIdstring (uuid)pathRequiredstoreKeystringpathRequiredIdempotency-Keystringheader
Request body application/json
object
Responses
201Custom store record created401Missing or invalid API key403Key is valid but lacks access to this resource404Requested resource not found
Update custom data store record
/api/external/v1/applications/{appId}/stores/{storeKey}/{recordId}Replaces the custom-field payload for one record in a custom application data store. Built-in stores are read-only through this external endpoint.
Send the full desired custom-field object. If metadata is present it replaces the record
metadata; if customerId is present it relinks the record to that application customer.
Parameters
appIdstring (uuid)pathRequiredstoreKeystringpathRequiredrecordIdstring (uuid)pathRequiredIdempotency-Keystringheader
Request body application/json
object
Responses
200Custom store record updated401Missing or invalid API key403Key is valid but lacks access to this resource404Requested resource not found
Delete custom data store record
/api/external/v1/applications/{appId}/stores/{storeKey}/{recordId}Deletes one record from a custom application data store. Built-in stores are read-only through this external endpoint.
Parameters
appIdstring (uuid)pathRequiredstoreKeystringpathRequiredrecordIdstring (uuid)pathRequired
Responses
204Custom store record deleted401Missing or invalid API key403Key is valid but lacks access to this resource404Requested resource not found
Get custom data store index status
/api/external/v1/applications/{appId}/stores/{storeKey}/indexesReturns the configured custom fields for a custom data store and whether the backing Postgres
expression index exists for fields marked indexed.
Parameters
appIdstring (uuid)pathRequiredstoreKeystringpathRequired
Responses
401Missing or invalid API key403Key is valid but lacks access to this resource404Requested resource not found
Get custom data store ingestion stats
/api/external/v1/applications/{appId}/stores/{storeKey}/ingestion-statsReturns ingestion counters and recent ingestion events for a custom data store. Use this to monitor enterprise sync jobs and verify whether incoming customer-data feeds are creating, updating, failing, or slowing down.
Parameters
appIdstring (uuid)pathRequiredstoreKeystringpathRequiredstartDatestring (date-time)queryendDatestring (date-time)query
Responses
401Missing or invalid API key403Key is valid but lacks access to this resource404Requested resource not found
Bulk upsert custom data store records
/api/external/v1/applications/{appId}/stores/{storeKey}/records:bulk-upsertUpserts many records into a custom data store. Use this for CRM/customer sync jobs instead of
sending one HTTP request per row. Each row uses the same where/data/metadata shape as
the single-record upsert endpoint.
Maximum batch size is 1000 records. The response includes created, updated, unchanged, and error counts plus per-row errors.
Parameters
appIdstring (uuid)pathRequiredstoreKeystringpathRequiredIdempotency-Keystringheader
Request body application/json
recordsarray of ExternalCustomStoreUpsertRequestUpsert rows. Maximum 1000 records per request.
continueOnErrorbooleanContinue processing rows after a row-level error. Defaults to true.
Responses
401Missing or invalid API key403Key is valid but lacks access to this resource404Requested resource not found
Patch custom data store records by filter
/api/external/v1/applications/{appId}/stores/{storeKey}/records:patchUpdates matching custom-store records without first retrieving their ids.
Use this for operations such as: update rows where phoneNumber = +15551234567.
where fields must be configured as indexed fields. set is merged into each matched record.
Use limit to bound blast radius. Maximum limit is 1000. Set dryRun: true to count and sample
matches without writing.
Parameters
appIdstring (uuid)pathRequiredstoreKeystringpathRequiredIdempotency-Keystringheader
Request body application/json
whereobjectExact-match lookup fields. Every key must be configured as indexed.
setobjectCustom fields to merge into every matched row.
metadataobjectMetadata fields to merge into every matched row.
limitinteger (int32)Maximum rows to update. Defaults to 100, maximum 1000.
dryRunbooleanWhen true, returns matched count/sample without writing.
Responses
401Missing or invalid API key403Key is valid but lacks access to this resource404Requested resource not found
Upsert custom data store record
/api/external/v1/applications/{appId}/stores/{storeKey}/records:upsertCreates or updates one custom-store record by matching indexed custom fields in where.
This is the preferred enterprise ingestion endpoint for customer data keyed by phone number,
external CRM id, membership id, or similar identifiers.
where fields must be configured as indexed fields in the data-store settings.
By default the endpoint creates a record if no match exists and merges data into an existing
record if one match exists. Multiple matches return 409 to protect data quality.
Parameters
appIdstring (uuid)pathRequiredstoreKeystringpathRequiredIdempotency-Keystringheader
Request body application/json
whereobjectExact-match lookup fields. Every key must be configured as indexed in the custom data store.
dataobjectCustom fields to create or merge into the record.
metadataobjectMachine-readable metadata stored beside the record.
createIfMissingbooleanCreate a new row when no row matches `where`. Defaults to true.
mergebooleanMerge data into existing records instead of replacing all custom fields. Defaults to true.
Responses
401Missing or invalid API key403Key is valid but lacks access to this resource404Requested resource not found
Get data store schema
/api/external/v1/applications/{appId}/stores/{storeKey}/schemaReturns the detailed schema metadata for a specific store key. Includes field definitions, types, and labels used for rendering data.
Each schema object contains: key (string), label (string), and fields (array of field
definitions, each with key, label, type — one of text, number, boolean, date,
select, multiselect, textarea).
Parameters
appIdstring (uuid)pathRequiredThe unique UUID of the application
storeKeystringpathRequiredThe unique key of the store
Responses
200Store schema definition401Missing or invalid API key403Key is valid but lacks access to this resource404Requested resource not found