On this page
bookmarkConstruct
mutation · in the family Your own session
What it does
Bookmark any record so it joins your Profile feed (or a team’s shared feed).
Bookmark ANY same-tenant construct: the target gates existence + same-rootId + non-doomed (its declared type IS the key namespace — the read proves it; a NOTE bookmarks by its OWN note id); teamId ABSENT = a personal bookmark, PRESENT = the team's shared set (the caller must be a MEMBER of that ACTIVE team; createdBy stamps the acting member — provenance). One row per (subject, target) — a duplicate refuses CONFLICT/BOOKMARK_EXISTS; the per-subject cap refuses CONFLICT/BOOKMARK_CAP. Requires authentication. Template class (universal staff work — the addNote kinship).
What happens
A personal subscription — it never changes the record itself.
Who may call it
Capability area: Your own session — What every signed-in person may do for themselves — their session, their profile and their own work.
- Owner
- System Administrator
- Manager
- Associate Manager
- Warehouse Associate
- Sales Associate
- Cashier
- An API key whose scope allows
api:bookmarkConstruct
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
targetType | String String! | yes | No further notes. |
targetId | ID ID! | yes | No further notes. |
teamId | ID | no | No further notes. |
Returns
BookmarkRef BookmarkRef! — One raw bookmark row.
Example request
mutation ExampleBookmarkConstruct($targetType: String!, $targetId: ID!, $teamId: ID) {
bookmarkConstruct(targetType: $targetType, targetId: $targetId, teamId: $teamId) {
subjectKind
ownerId
targetType
targetId
createdAt
createdBy
boostedAt
popAt
highlightedAt
}
}
Variables:
{
"targetType": "<target type>",
"targetId": "01900000-0000-7000-8000-446adfd50000",
"teamId": "01900000-0000-7000-8000-3c35d4210000"
}
Send it with the envelope naming the version: "extensions": {"at": {"version": {"name":"genesis","number":0}}}.
Example response
{
"data": {
"bookmarkConstruct": {
"subjectKind": "USER",
"ownerId": "01900000-0000-7000-8000-e51b6a790000",
"targetType": "<target type>",
"targetId": "01900000-0000-7000-8000-446adfd50000",
"createdAt": "2027-01-31T00:00:00.000Z",
"createdBy": "01900000-0000-7000-8000-0b14e5a60000",
"boostedAt": "2027-01-31T00:00:00.000Z",
"popAt": "2027-01-31T00:00:00.000Z",
"highlightedAt": "2027-01-31T00:00:00.000Z"
}
},
"extensions": {
"at": {
"callId": "01EXAMPLE-CALL-ID",
"version": {
"requested": {
"name": "genesis",
"number": 0
},
"serviced": {
"name": "genesis",
"number": 0
}
}
}
}
}
Errors this call can answer
VALIDATION/INVALID— Something in the request is not valid. (VALIDATION)AUTHN/REQUIRED— Sign in to do this. (AUTHN)AUTHZ/FORBIDDEN— Your role does not allow this action. (AUTHZ)RATE_LIMIT/THROTTLED— Too many requests in a short time. (RATE_LIMIT)NOT_FOUND/*— That record could not be found. (NOT_FOUND)CONFLICT/*— The record’s state, or a change made in the meantime, does not allow this; the codes are on the CONFLICT page. (CONFLICT)VALIDATION/VERSION_REQUIRED— The request did not say which app version it came from. (VALIDATION)