Skip to content
Guides
API essentials

Write records safely

Create and update records with idempotency and optimistic concurrency.

Test writes in a disposable workspace. Discover property metadata first, then create a record with POST /v2/prism/{teamId}/{objectType}.

export IDEMPOTENCY_KEY="$(uuidgen)"
curl --request POST \
  "https://developers.micro.so/v2/prism/${MICRO_TEAM_ID}/contact" \
  --header "content-type: application/json" \
  --header "x-api-key: ${MICRO_API_KEY}" \
  --header "idempotency-key: ${IDEMPOTENCY_KEY}" \
  --data '{"default":{"full_name":"Sarah Chen","email":"sarah@example.com"}}'

Generate one key per logical operation. After a timeout or retryable error, resend the same method, path, body, and key. Completed non-5xx responses are retained for 24 hours and replayed with idempotent-replay: true. A changed request with the same unexpired key returns 409 idempotency_key_mismatch; an expired key returns 409 idempotency_key_stale.

For updates, capture the record's etag response header and send it as If-Match. A concurrent change then produces 412 precondition_failed instead of being overwritten.

Never automatically retry a destructive operation without checking its documented semantics and requiring appropriate user confirmation.

Update without overwriting a newer value

Read the record and save its ETag, then patch with If-Match:

curl --silent --dump-header headers.txt \
  "https://developers.micro.so/v2/prism/${MICRO_TEAM_ID}/contact/${CONTACT_ID}" \
  --header "x-api-key: ${MICRO_API_KEY}"

# Copy the etag header value from headers.txt.
export RECORD_ETAG='"replace-with-etag"'

curl --request PATCH \
  "https://developers.micro.so/v2/prism/${MICRO_TEAM_ID}/contact/${CONTACT_ID}" \
  --header "content-type: application/json" \
  --header "x-api-key: ${MICRO_API_KEY}" \
  --header "if-match: ${RECORD_ETAG}" \
  --header "idempotency-key: $(uuidgen)" \
  --data '{"default":{"full_name":"Sarah Chen-Goldstein"}}'

A successful create returns 201 and the new record. A successful patch returns 200, the updated record, and a new ETag. On 412, re-read the record and reconcile the user's intended change; do not blindly overwrite it.

Handle partial success

Bulk update and bulk delete can return HTTP 200 while individual items fail. Inspect every entry in results and the response summary. Retry only failed items whose error is transient, using a new bulk request and an idempotency key appropriate to that new logical operation. Do not replay successful items as part of a changed request under the old key.

{
  "results": [
    {"id": "11111111-1111-4111-8111-111111111111", "status": "ok", "record": {}},
    {"id": "22222222-2222-4222-8222-222222222222", "status": "error", "error": {"code": "invalid_request", "message": "Invalid property value"}}
  ],
  "summary": {"total": 2, "succeeded": 1, "failed": 1}
}

id can be null when an input item cannot be parsed. Treat summary.failed > 0 or any results[].status === "error" as a partially failed job even though the HTTP request succeeded.

micro.so