Guestbook & poll
Interact with guestbook and poll widgets on your social profile. Widgets are created via the Social profile API (type: guestbook or type: poll); these routes handle messages and votes.
Base path: /api/v1/social/widgets/{widgetId}. Scopes: guestbook and poll (separate keys): read for GET, read_write for POST / DELETE. See Authentication and Scopes.
REST routes treat the API key holder as both owner and viewer. They operate on your widgets only (widgetId must belong to your account).
Concepts
- Widget id: UUID of a guestbook or poll row in your social section (from GET /api/v1/social or widget create response).
- Guestbook threads: top-level messages plus one level of replies nested under each thread. No deeper threading.
- Anonymous posts: allowed only when widget config allowAnonymous: true. Owner sees real author; REST list as owner shows authorUserId even when postedAnonymously.
- Poll votes: one ballot per API key user per widget. POST replaces prior votes. Single-choice polls require exactly one index; multi-select allows 0–N indices (empty array clears your vote).
- Option indices: zero-based, matching config.options order on the widget (2–8 options).
Endpoint index
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/social/widgets/{widgetId}/guestbook | guestbook: read |
| POST | /api/v1/social/widgets/{widgetId}/guestbook | guestbook: read_write |
| DELETE | .../guestbook/messages/{messageId} | guestbook: read_write |
| POST | .../guestbook/block-author | guestbook: read_write |
| GET | /api/v1/social/widgets/{widgetId}/poll | poll: read |
| POST | /api/v1/social/widgets/{widgetId}/poll | poll: read_write |
List guestbook messages
GET/api/v1/social/widgets/{widgetId}/guestbook
200: 200: paginated threads. Default limit 25 (max 100). Cursor is createdAt (ms) of the oldest thread in the page; pass as cursor for the next page. nextCursor is null when done.
| Query | Notes |
|---|---|
limit | 1–100, optional |
cursor | positive int (ms), optional |
As owner, messages with hiddenByOwner: true are included.
curl -sS \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://api.floralitys.com/api/v1/social/widgets/WIDGET_UUID/guestbook?limit=25"{
"threads": [
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"ownerUserId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
"parentMessageId": null,
"authorUserId": "b0b0b0b0-b0b0-b0b0-b0b0-b0b0b0b0b0b0",
"authorDisplayName": "River",
"postedAnonymously": false,
"body": "Lovely profile!",
"createdAt": 1714237200000,
"hiddenByOwner": false,
"displayName": "River",
"authorAvatarUrl": "https://img.clerk.com/…",
"authorStatus": {
"isAdmin": false,
"planKey": "pro",
"donorSupporterUnlocked": true,
"closedBetaParticipantAt": null
},
"replies": [
{
"id": "c47ac10b-58cc-4372-a567-0e02b2c3d480",
"parentMessageId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"body": "Thank you!",
"displayName": "Alex",
"replies": []
}
]
}
],
"nextCursor": 1714233600000
}Post guestbook message
POST/api/v1/social/widgets/{widgetId}/guestbook
201: 201: created message (same shape as thread items, without nested replies).
| Field | Required | Notes |
|---|---|---|
body | yes | 1–500 chars (trimmed) |
postAnonymously | no | default false; needs allowAnonymous on widget |
parentMessageId | no | UUID of top-level message for a one-level reply |
curl -sS -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"body": "Lovely profile!",
"postAnonymously": false
}' \
"https://api.floralitys.com/api/v1/social/widgets/WIDGET_UUID/guestbook"curl -sS -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"body": "Thank you!",
"parentMessageId": "MESSAGE_UUID"
}' \
"https://api.floralitys.com/api/v1/social/widgets/WIDGET_UUID/guestbook"{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"ownerUserId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
"parentMessageId": null,
"authorUserId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
"authorDisplayName": "Alex",
"postedAnonymously": false,
"body": "Lovely profile!",
"createdAt": 1714237200000,
"hiddenByOwner": false,
"displayName": "Alex",
"authorAvatarUrl": "https://img.clerk.com/…",
"authorStatus": { "isAdmin": false, "planKey": "free", "donorSupporterUnlocked": false, "closedBetaParticipantAt": null }
}Delete guestbook message
DELETE/api/v1/social/widgets/{widgetId}/guestbook/messages/{messageId}
204: 204: hard delete. Allowed if you are the profile owner or the message author. widgetId in path is validated but delete is by messageId globally.
curl -sS -X DELETE \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://api.floralitys.com/api/v1/social/widgets/WIDGET_UUID/guestbook/messages/MESSAGE_UUID"// 204 No Content: empty response bodyBlock message author
POST/api/v1/social/widgets/{widgetId}/guestbook/block-author
204: blocks the author via friends block list (Friends API block). Cannot block yourself. Anonymous authors: only the guestbook owner may block (REST caller is owner).).
| Field | Required |
|---|---|
messageId | yes: UUID |
reason | no: max 280 chars |
curl -sS -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messageId": "MESSAGE_UUID",
"reason": "Spam"
}' \
"https://api.floralitys.com/api/v1/social/widgets/WIDGET_UUID/guestbook/block-author"// 204 No Content: empty response bodyGet poll state
GET/api/v1/social/widgets/{widgetId}/poll
200: 200: question, options, counts, and your current vote. No query parameters.
curl -sS \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://api.floralitys.com/api/v1/social/widgets/WIDGET_UUID/poll"{
"question": "Favourite season?",
"options": ["Spring", "Summer", "Autumn", "Winter"],
"allowMultipleSelections": false,
"optionCounts": [3, 12, 8, 5],
"distinctVoterCount": 28,
"myOptionIndices": [1]
}Cast poll vote
POST/api/v1/social/widgets/{widgetId}/poll
200: 200: updated poll state (same shape as GET). Replaces any prior vote from your account on this widget.
| Field | Notes |
|---|---|
optionIndices | Array of ints 0–7, max 8 entries. Single-choice: exactly one valid index. Multi-select: 0+ indices, or [] to clear vote. |
curl -sS -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "optionIndices": [1] }' \
"https://api.floralitys.com/api/v1/social/widgets/WIDGET_UUID/poll"{
"question": "Favourite season?",
"options": ["Spring", "Summer", "Autumn", "Winter"],
"allowMultipleSelections": false,
"optionCounts": [3, 12, 8, 5],
"distinctVoterCount": 28,
"myOptionIndices": [1]
}Errors
JSON { code, message }:
UNAUTHORIZED (401): missing/invalid API keyFORBIDDEN (403): wrong scope; cannot delete others' messages; cannot block anonymous author as non-ownerBAD_REQUEST (400): validation, empty body, anonymous disallowed, invalid reply parent, poll option rulesNOT_FOUND (404): invalid UUID; widget wrong type or not yours; message missingPRECONDITION_FAILED (503): DATABASE_URL not configured
See Errors.
{
"code": "NOT_FOUND",
"message": "Guestbook widget not found."
}