Skip to content

Create, update and restore records

Create CRM records, verify field changes, and recover a record moved to trash.

Use these operations to keep an external system in sync with Lightfield accounts, contacts, opportunities, notes, tasks and custom objects. For choosing the right record type, start with Object types. Meetings have a narrower write contract; use Manage meeting records.

Use an API key with the selected resource’s read scope and the create, update or delete scope needed for your operation. Restore and listing trashed records require the resource’s :restore scope. Custom objects use custom_objects:* scopes, including custom_objects:restore, and their configured slug.

Find custom object slugs with List object definitions, then read the object’s field and relationship definitions. Writes take bare values; reads return fields[key].value. Use the returned IDs for relationships, not display names. The examples below use fictional IDs; replace them with records in your workspace.

For imports, look for an existing record with a stable identifier before creating one. A find-then-create check alone is not atomic: serialize writes for the same source record and reuse its idempotency key when retrying.

This request creates an account without starting enrichment. Set skipEnrichment to true for imports whose data is already complete; omit it when you want Lightfield to enrich the new account.

Terminal window
curl https://api.lightfield.app/v1/accounts \
-H "Authorization: Bearer $LIGHTFIELD_API_KEY" \
-H "Lightfield-Version: 2026-03-01" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: import-northwind-account-001" \
-d '{"fields":{"$name":"Northwind","$website":["https://northwind.example"]},"skipEnrichment":true}'

Save id from the response. An account response includes a value such as fields.$name.value: "Northwind"; use that returned id for the next request.

Use the same headers with the appropriate path and JSON body below. Each linked operation defines its complete writable fields.

Create operationPathExample body and difference
Account/v1/accountsThe request above requires $name; enrichment is optional.
Contact/v1/contacts{"fields":{"$name":{"firstName":"Ada","lastName":"Chen"},"$email":["ada@northwind.example"]},"skipEnrichment":true}. A contact name is an object; email is an array.
Opportunity/v1/opportunities{"fields":{"$name":"Northwind renewal"},"relationships":{"$account":"acc_northwind"}}. The account relationship is required; Stage is optional.
Note/v1/notes{"fields":{"$title":"Renewal call","$content":"Ada wants a proposal by Friday."},"relationships":{"$account":"acc_northwind"}}. The author is set from the caller.
Task/v1/tasks{"fields":{"$title":"Send renewal proposal","$status":"TODO"},"relationships":{"$assignedTo":"mem_ada","$account":"acc_northwind"}}. Resolve the assignee with Members.
Custom object record/v1/objects/subscriptions/values{"fields":{"name":"Northwind annual subscription"}}, only if your subscriptions definition has a writable text field named name; choose your actual slug and fields from definitions.

Retrieve by ID to verify a write immediately. Search-backed lists can lag. For an account:

Terminal window
curl "https://api.lightfield.app/v1/accounts/$RECORD_ID" \
-H "Authorization: Bearer $LIGHTFIELD_API_KEY" \
-H "Lightfield-Version: 2026-03-01"
curl "https://api.lightfield.app/v1/accounts/$RECORD_ID" \
-X POST \
-H "Authorization: Bearer $LIGHTFIELD_API_KEY" \
-H "Lightfield-Version: 2026-03-01" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: rename-northwind-001" \
-d '{"fields":{"$name":"Northwind Europe"}}'

Confirm the same id and the new fields.$name.value in the response. Only supplied fields change. Omission preserves a value; null clears it only where the schema permits null. Relationship updates use add, remove or replace as explained in Fields and relationships.

ResourceRetrieveUpdateExample update body
AccountGET /v1/accounts/{id}POST same path{"fields":{"$name":"Northwind Europe"}}
ContactGET /v1/contacts/{id}POST same path{"fields":{"$name":{"firstName":"Ada","lastName":"Chen"}}}
OpportunityGET /v1/opportunities/{id}POST same path{"fields":{"$name":"Northwind expansion"}}
NoteGET /v1/notes/{id}POST same path{"fields":{"$content":"Proposal sent; follow up Friday."}}
TaskGET /v1/tasks/{id}POST same path{"fields":{"$status":"COMPLETE"}}
Custom objectGET /v1/objects/{entitySlug}/values/{id}POST same path{"fields":{"name":"Northwind renewal"}}, using an actual writable field.

Use list methods to discover IDs: accounts, contacts, opportunities, notes, tasks or custom objects. Custom-object listing uses /v1/objects/{entitySlug}, without /values.

Deletion moves the record to trash. Keep its ID so you can restore it; do not create a replacement to undo a deletion. Deleting an account through the API does not delete its associated contacts, tasks or notes.

Terminal window
curl "https://api.lightfield.app/v1/accounts/$RECORD_ID" \
-X DELETE \
-H "Authorization: Bearer $LIGHTFIELD_API_KEY" \
-H "Lightfield-Version: 2026-03-01"
curl "https://api.lightfield.app/v1/accounts/$RECORD_ID/restore" \
-X POST \
-H "Authorization: Bearer $LIGHTFIELD_API_KEY" \
-H "Lightfield-Version: 2026-03-01"

For each resource below, DELETE uses its retrieve path from the table above; restore uses POST to that path plus /restore.

ResourceDelete contractRestore contract
AccountDeleteRestore
ContactDeleteRestore
OpportunityDeleteRestore
NoteDeleteRestore
TaskDeleteRestore
Custom objectDeleteRestore

Check the deletion response for the same ID, then use the list endpoint with status=trashed to locate it. After restoration, retrieve it again. Deleting an already-trashed record and restoring an active record are no-ops for these resources. Custom-object restore must name the object’s actual slug.

  • 400: check field keys, value types and writable fields against definitions. For a task, use a supported status and a member ID for the assignee.
  • 403: check the operation’s scopes and the caller’s role. A read-only role cannot write, even with a write scope.
  • 404: check the workspace, record type and ID before creating anything new. An unavailable record is not evidence that a duplicate should be created.
  • 409 or uncertain network result: follow the operation’s retry rules; reuse the original key for supported writes.

Use Merge duplicate records when two existing IDs represent the same entity. Product users can manage the same records through Lightfield basics and Deleted items.