← All documentationContents ↓

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

PropertyTypeDescription
dataCollectionSimplyIdstringRequired. Collection to search.
querystringOptional keyword search over record display names (max 128 characters).
filtersarrayUp to 25 { field, operator, value } conditions, combined with AND.
fieldsstring[]Optional array of field simplyIds to include in each result's fields object.
limit / offsetintegerlimit 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. The in operator takes an array of up to 100 scalar values.
  • calculatedName: eq, ne, contains, startsWith.
  • createdAt / updatedAt: gt, lt, gte, lte with ISO 8601 date values.
  • isArchived: pass true to 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 MethodEndpointReturns
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}/conversationsConversations linked to the record.
listCommunications(dataRecordSimplyId, params?)GET /v1/data-records/{dataRecordSimplyId}/communicationsSafe canonical cross-channel metadata for everything sent to the constituent.
listOutgoingMessages(dataRecordSimplyId, params?)GET /v1/data-records/{dataRecordSimplyId}/outgoing-messagesDeprecated compatibility alias for listCommunications; returns the same metadata projection.
listCardGroups(dataRecordSimplyId)GET /v1/data-records/{dataRecordSimplyId}/card-groupsReadable data card groups configured for the record.
renderCardGroup(dataRecordSimplyId, dataCardGroupSimplyId, params?)GET /v1/data-records/{dataRecordSimplyId}/card-groups/{dataCardGroupSimplyId}/renderRender-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 fields object are always the field's simplyId, not the field label.
  • Batch operations report per-item success/failure — an individual failure does not roll back the whole batch.
  • Use the fields query parameter (list/get) or fields array (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-delete operation.