Governed writes and actions
Use policy and operation state when external data can change
Write APIs combine operation scope, accountable actor, policy, resource grants and connector support. A data:write key cannot bypass the workspace write mode or a policy decision.
Policies
The write-policy collection supports listing and proposal. A proposal includes name, optional project boundary, policy contract, parent revision reference and reason. Decisions target a specific revision with approved/rejected/suspended/retired status and reason. Proposal, approval and management require the corresponding policy:* permission of the accountable member.
Upsert, update, replace and delete are classified as destructive policy operations. Approval requires the explicit destructive-approval flag when applicable. The bind action attaches an approved policy revision to a pipeline node draft; publishing/activation remain separate actions.
Endpoint source writes
Use a supported transactional source-write capability, currently the Iceberg path, with workspace mode read_write, an approved endpoint policy and a principal grant. This operation API is distinct from a generic pipeline connector write; PostgreSQL write capability alone does not imply this source-write protocol is available.
POST /data-endpoints/{endpointId}/source-writes requires data:write, a valid operation body and an Idempotency-Key header of at most 200 characters. Supported request operations include append, upsert, update and delete, with rows for append/upsert, where and set for update, and where for delete. Every request includes contractVersion 1 and expectedSourceSnapshot {id, version} from the immediately preceding source read. Identity is resolved from endpoint metadata and approved policy; the caller cannot override it.
A completed write returns 200; pending/uncertain work returns 202 with an operation. GET its source-write operation path to inspect state; POST its recover path to reconcile. Retain operation ID and the original request identity rather than submitting another mutation after a timeout.
Source-write grants select an api_key or user principal, allowed operations, writable fields and equality predicates. Grant updates replace that principal's grant. Empty writable fields grant no fields. Predicate restrictions also constrain appended/upserted rows; update/delete must satisfy the required equality predicates.
Actions and approvals
Project actions define governed contracts. Publish/list/detail routes manage action versions; request creation produces a tracked request, then review, execute and reconcile follow its lifecycle. data:write handles execution submissions, while review needs policy approval. A request accepted with 202 is not proof that the external effect completed.
Change delivery
Change-feed pull/ack/fail endpoints use data:read; dead-letter listing uses read access and retry uses data:write. Retain consumer and event identities. Acknowledge only after your consumer has handled the event, and expect retry/dead-letter paths to need deduplication in the downstream service.
The route catalog lists all policy, grant, operation, action and change-feed paths. Write controls and the Iceberg endpoint guides explain the contracts and installation prerequisites before an integration mutates records.
Source-write request example
After the preceding read, replace both snapshot values with its actual tokens. The endpoint must allow append of these exact fields and any required equality grant must match this row.
{"contractVersion":1,"operation":"append","expectedSourceSnapshot":{"id":"SNAPSHOT_ID_FROM_READ","version":"SNAPSHOT_VERSION_FROM_READ"},"rows":[{"equipment_id":"pump-17","condition":"inspection_required"}]}Save the body as source-write.json and submit it with the real endpoint UUID and a key with the approved grant:
curl --fail-with-body -X POST \
-H "Authorization: Bearer $SEMOGRAM_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: pump-17-inspection-001' \
--data-binary @source-write.json \
"https://platform.semogram.com/api/v1/data-endpoints/$SEMOGRAM_ENDPOINT_ID/source-writes"The literal placeholders are illustrative and must not be sent as a claimed current snapshot. A conflicting snapshot requires re-reading and reviewing the intended mutation, rather than forcing it with a new request key.