API Reference: Data Records
List, get, create, update, replace, delete, search, and batch-process Data Records via the Simply360 API.
Overview
Data Records are the core unit of data in Simply360. Each record belongs to a Data Collection and carries a set of field values defined by that collection's schema. Records are identified by a unique simplyId with format XXXX-XXXX-XXXX. The CRUD, search, and batch endpoints on this page are standard-tier: they work with API keys and scoped session tokens, subject to the caller's Data Role permissions.
Key Concepts
- simplyId — The unique public identifier for every record. Use it in all API calls. Internal integer IDs are never exposed by the public API.
- dataCollectionSimplyId — The Simply ID of the collection a record belongs to. Required when creating or listing records.
- fields — A key/value object where each key is a field simplyId and the value is the field's content. Field types determine accepted formats; see API Reference: Data Collections.
- name — A computed display label derived from the collection's display-name configuration. Read-only.
- Batch operations — Create, update, or delete up to 100 records in one request for higher throughput.
Record Shape
Every record response uses the same shape:
{
"dataRecordSimplyId": "WXYZ-5678-IJKL",
"id": "WXYZ-5678-IJKL",
"dataCollectionSimplyId": "XXXX-XXXX-XXXX",
"name": "Jane Doe",
"fields": { "FLDS-FRST-NAME": "Jane", "FLDS-EMAL-ADDR": "jane@example.com" },
"isArchived": false,
"createdAt": "2026-03-06T14:30:00.000Z",
"updatedAt": "2026-03-06T14:30:00.000Z"
}
List Records
Retrieve records from a collection with pagination, sorting, and field selection. dataCollectionSimplyId is required. limit accepts 1–100 (default 25); sortable fields are createdAt, updatedAt, and calculatedName (prefix with - for descending).
TypeScript SDK
const response = await s360.dataRecords.list({
dataCollectionSimplyId: 'XXXX-XXXX-XXXX',
limit: 25,
offset: 0,
sort: '-createdAt',
fields: 'FLDS-FRST-NAME,FLDS-LAST-NAME',
});
for (const record of response.data) {
console.log(record.dataRecordSimplyId, record.fields);
}
cURL
curl -s "https://api.simply360.app/v1/data-records?dataCollectionSimplyId=XXXX-XXXX-XXXX&limit=25&sort=-createdAt" \
-H "Authorization: Bearer $S360_API_KEY"
Get a Record
Retrieve a single record by its simplyId. The fields query parameter selects specific field simplyIds; expand accepts collection and/or fieldDefinitions, and the expansions are returned under meta.expanded.
TypeScript SDK
const record = await s360.dataRecords.get('WXYZ-5678-IJKL', {
expand: 'collection,fieldDefinitions',
});
console.log(record.data.dataRecordSimplyId, record.data.fields);
console.log(record.meta.expanded?.collection);
cURL
curl -s "https://api.simply360.app/v1/data-records/WXYZ-5678-IJKL?expand=collection,fieldDefinitions" \
-H "Authorization: Bearer $S360_API_KEY"
Create a Record
Create a new record by providing the collection Simply ID and field values. Field keys must be the field's simplyId. Returns 201 with the created record; unknown field keys are skipped and reported in meta.warnings.
TypeScript SDK
const created = await s360.dataRecords.create({
dataCollectionSimplyId: 'XXXX-XXXX-XXXX',
fields: {
'FLDS-FRST-NAME': 'Jane',
'FLDS-LAST-NAME': 'Doe',
'FLDS-EMAL-ADDR': 'jane@example.com',
},
});
console.log(`Created: ${created.data.dataRecordSimplyId}`);
cURL
curl -s -X POST "https://api.simply360.app/v1/data-records" \
-H "Authorization: Bearer $S360_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dataCollectionSimplyId": "XXXX-XXXX-XXXX",
"fields": {
"FLDS-FRST-NAME": "Jane",
"FLDS-LAST-NAME": "Doe",
"FLDS-EMAL-ADDR": "jane@example.com"
}
}'
Update a Record (PATCH and PUT)
Two write methods are available, and both take the same body: a fields object keyed by field simplyId.
PATCH /v1/data-records/{dataRecordSimplyId}— Partial update: only the fields present in the request body are written. SDK:s360.dataRecords.update(dataRecordSimplyId, { fields }).PUT /v1/data-records/{dataRecordSimplyId}— Replace field values: writes the provided field values. Fields omitted from the body are currently left unchanged (the same merge semantics as PATCH), so include every field you intend to change. SDK:s360.dataRecords.replace(dataRecordSimplyId, { fields }).
// Partial update — only updates email, leaves other fields alone
await s360.dataRecords.update('WXYZ-5678-IJKL', {
fields: { 'FLDS-EMAL-ADDR': 'jane.doe@newdomain.com' },
});
To clear a field, set it explicitly to null in the fields object.
Delete a Record
Deletes are soft: the record is flagged deleted and disappears from list, get, and search responses.
await s360.dataRecords.delete('WXYZ-5678-IJKL');
curl -s -X DELETE "https://api.simply360.app/v1/data-records/WXYZ-5678-IJKL" \
-H "Authorization: Bearer $S360_API_KEY"
Search Records
Use the search endpoint for keyword search over record names plus structured field-level filters.
TypeScript SDK
const results = await s360.dataRecords.search({
dataCollectionSimplyId: 'XXXX-XXXX-XXXX',
query: 'Jane',
filters: [
{ field: 'FLDS-EMAL-ADDR', operator: 'contains', value: '@example.com' },
],
limit: 10,
});
cURL
curl -s -X POST "https://api.simply360.app/v1/data-records/search" \
-H "Authorization: Bearer $S360_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dataCollectionSimplyId": "XXXX-XXXX-XXXX",
"query": "Jane",
"filters": [
{ "field": "FLDS-EMAL-ADDR", "operator": "contains", "value": "@example.com" }
],
"limit": 10
}'
Request Body
| Property | Type | Description |
|---|---|---|
dataCollectionSimplyId | string | Required. Collection to search. |
query | string | Optional keyword search over record display names (max 128 characters). |
filters | array | Up to 25 { field, operator, value } conditions, combined with AND. |
fields | string[] | Optional array of field simplyIds to include in each result's fields object. |
limit / offset | integer | limit 1–100 (default 25); offset up to 5,000. |
Filter Operators
A filter's field is either a field simplyId or one of the metadata fields calculatedName, createdAt, updatedAt, isArchived.
- Custom fields:
eq,ne,gt,lt,gte,lte,in,contains,startsWith. Theinoperator takes an array of up to 100 scalar values. calculatedName:eq,ne,contains,startsWith.createdAt/updatedAt:gt,lt,gte,ltewith ISO 8601 date values.isArchived: passtrueto search archived memberships instead of active ones.
Batch Operations
The Data Records API offers three batch endpoints on /v1/data-records/batch, one per write semantic. Each accepts up to 100 items per request and reports per-item results.
Batch Create
const result = await s360.dataRecords.batchCreate({
dataCollectionSimplyId: 'XXXX-XXXX-XXXX',
records: [
{ fields: { 'FLDS-FRST-NAME': 'Alice' } },
{ fields: { 'FLDS-FRST-NAME': 'Bob' } },
],
});
console.log(`Created: ${result.data.created}, Failed: ${result.data.failed}`);
Batch Update
await s360.dataRecords.batchUpdate({
records: [
{ dataRecordSimplyId: 'WXYZ-5678-IJKL', fields: { 'FLDS-FRST-NAME': 'Bob' } },
{ dataRecordSimplyId: 'MNOP-9012-QRST', fields: { 'FLDS-FRST-NAME': 'Carol' } },
],
});
Batch Delete
await s360.dataRecords.batchDelete({
dataRecordSimplyIds: ['WXYZ-5678-IJKL', 'MNOP-9012-QRST'],
});
Related Endpoints on a Record
These standard-tier endpoints read data associated with a record:
| SDK Method | Endpoint | Returns |
|---|---|---|
getAuditLog(dataRecordSimplyId, params?) | GET /v1/audit-log/records/DataRecord/{recordSimplyId} | Audit-log entries for the record. See API Reference: Audit Log. |
listConversations(dataRecordSimplyId, params?) | GET /v1/data-records/{dataRecordSimplyId}/conversations | Conversations linked to the record. |
listCommunications(dataRecordSimplyId, params?) | GET /v1/data-records/{dataRecordSimplyId}/communications | Safe canonical cross-channel metadata for everything sent to the constituent. |
listOutgoingMessages(dataRecordSimplyId, params?) | GET /v1/data-records/{dataRecordSimplyId}/outgoing-messages | Deprecated compatibility alias for listCommunications; returns the same metadata projection. |
listCardGroups(dataRecordSimplyId) | GET /v1/data-records/{dataRecordSimplyId}/card-groups | Readable data card groups configured for the record. |
renderCardGroup(dataRecordSimplyId, dataCardGroupSimplyId, params?) | GET /v1/data-records/{dataRecordSimplyId}/card-groups/{dataCardGroupSimplyId}/render | Render-ready content for one card group. |
Constituent Communications
Record Communications are the canonical history of constituent-facing sends across Message Studio, Conversations, Automations, Wizards, Views, constituent authentication, reports, commerce, and supported historical external-provider evidence. OutgoingMessage is an optional coordinating source for some deliveries, not a second timeline. Reading the endpoint requires records:read, CONSTITUENT_MESSAGE_HISTORY_VIEW, and read access to the record.
listCommunications supports limit (1–100), opaque keyset cursor, channelId, and currentStateId. Each item includes public delivery/constituent/source IDs, channel/state/timestamps, attachment count, protected-content presence, and a completeness value of EXACT, PARTIAL, or METADATA_ONLY. A partial or metadata-only legacy row includes a gap reason; consumers must not infer facts that were not retained. The response metadata identifies archived/deleted state, the requested and surviving record Simply IDs, and all merged constituent identities included in the timeline.
The Public API, SDK integration path, MCP, and TeamAgent expose only this safe metadata. They structurally exclude exact recipient/sender addresses and numbers, rendered subjects/bodies, attachment bytes or storage coordinates, bearer credentials, provider payloads, and numeric IDs. The SDK also defines listCommunicationsProtected and getCommunicationAttachmentDownload for the Simply360 first-party clients, but the service accepts those operations only from authenticated Team users and allowlisted Simply Anywhere OAuth clients. Ordinary API keys and integration OAuth clients cannot use them.
const history = await s360.dataRecords.listCommunications('WXYZ-5678-IJKL', {
channelId: 'SMS',
limit: 25,
});
for (const delivery of history.data) {
console.log(delivery.sourceType, delivery.currentStateId, delivery.completeness);
}
if (history.meta.nextCursor) {
await s360.dataRecords.listCommunications('WXYZ-5678-IJKL', {
limit: 25,
cursor: history.meta.nextCursor,
});
}
renderCardGroup TABLE cards that are backed by a relationship field may include multiDataRecordContext.creationAvailability. When canCreate is false, clients should hide new-record creation for that related Collection. Reasons include NO_EDITABLE_FIELDS, REQUIRED_FIELDS_READ_ONLY, and TARGET_COLLECTION_NOT_FOUND; blockingFields lists required read-only fields that prevent a create form from being usable. Reverse SINGLE_DATA_RECORD contexts can also include fieldSettings.prePopulateFieldSimplyId and fieldSettings.prePopulateFieldCompositeKey so clients can lock the prefilled relationship field.
POST /v1/create-menu/data-records (standard tier) creates a record from create-menu form data — the same path the dashboard's create menu uses.
Administrative Operations
A larger privileged-tier surface backs the Simply360 webapp's record tooling: bulk operations (bulk-update, bulk-delete, bulk-archive, bulk-link, bulk-unlink, bulk-approval), duplicate detection and merging (duplicate-rules, duplicate-review, merge, unmerge), approval workflows, archive/unarchive with impact previews, undo-delete, collection links, record variants, kanban and timeline queries, and the AI graph composer. These require admin-level feature permissions, are reserved for first-party Simply360 clients, and are not included in the public (standard-tier) OpenAPI contract; the operations above remain the supported integration surface.
Usage Notes
- Field keys in the
fieldsobject are always the field'ssimplyId, not the field label. - Batch operations report per-item success/failure — an individual failure does not roll back the whole batch.
- Use the
fieldsquery parameter (list/get) orfieldsarray (search) to select specific fields and reduce payload size. See Pagination, Sorting & Field Selection. - Writes respect field-level permissions: attempting to write a field your Data Role cannot edit returns
403 PERMISSION_DENIED. - Record creates and updates fire matching automations and webhook events (
DATA_RECORD_CREATED,DATA_RECORD_UPDATED). See API Reference: Webhooks. - Deletes are soft. Recently deleted records can be restored from the dashboard, which uses the privileged
undo-deleteoperation.