Florality
FeaturesPricingSecurityFAQAbout
Sign upSign in
Public REST APIv1

REST reference & guides

Public REST APIv1

REST reference & guides

Get started

  • Overview
  • Authentication
  • Scopes
  • Errors

API reference

  • Members
    • GETList members
    • POSTCreate member
    • GETGet member by id
    • PATCHUpdate member
    • DELETEDelete member
    • GETMember media (avatar or background)
  • Groups
  • Entries
  • Front
  • Appearance
  • Custom fields
  • Trash
  • Search
  • Member statuses
  • Systems
  • Messaging
  • Privacy buckets
  • Terminology
  • Friends
  • Subscriptions
  • Billing
  • Import
  • Social
  • Guestbook & poll
  • Group layout
  • Activity
  1. Documentation
  2. Members
API keys
Florality

Organise your system. One front at a time.

Get startedSign in

Product

  • Features
  • Pricing
  • Public REST API
  • Security

Company

  • About
  • Our team
  • Changelog
  • Contact

Resources

  • FAQ
  • Trust & Safety
  • Privacy Policy
  • Terms of Service
  • Refunds and cancellation

© 2026 Florality. All rights reserved.

Privacy·Terms·

Members

Base path: /api/v1/members. Read (GET list, get one, media bytes) needs members: read. Write (PATCH, DELETE) needs members: read_write.


List members

GET/api/v1/members

Behavior

Returns all active members for the authenticated account, sorted by name. Optional query sideSystemId and subSystemId list members in that system scope instead of the account default. The server may run a one-time schema guard before querying; clients should treat this as a normal list endpoint.

Response

JSON array of member objects. MinIO-backed avatars and backgrounds are exposed as same-origin URLs under /api/v1/members/…/media (same Bearer token), not the dashboard-only /api/storage/member-media path.

Member object fields

FieldTypeNotes
_idstringMember id (UUID)
userIdstringInternal account id
directoryIdstringCurrent folder / directory id
namestringLegal / system name
displayNamestring?Optional display name
pronounsstring?Optional
avatarstring?Raw stored avatar ref or URL (when present)
backgroundstring?Raw stored background ref or URL (when present)
aboutstring?Optional markdown or text
aboutTagsstring[]Labels for the About card
archivedAtnumber?Unix ms when archived, if set
createdAt / updatedAtnumber?Unix ms. createdAt is the formed date (when the member/alter came into existence); editable via dashboard or PATCH. updatedAt is last profile change.
deletedAt / purgeAtnumber?Soft-delete / purge scheduling
originalDirectoryIdstring?When moved from another folder
profileStyleobject | nullMember profile chrome (banner, fonts, tints, etc.)
avatarUrlstring | nullResolved URL for clients: embeddable legacy https URLs as absolute URLs; MinIO refs as /api/v1/members/{id}/media?kind=avatar&v=…
backgroundUrlstring | nullSame pattern for background

Response

200

Sorted JSON array of member objects.

JSON
[{
  "_id": "b1c2d3e4-f5a6-7890-abcd-ef1234567890",
  "userId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
  "directoryId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "name": "string",
  "displayName": "string",
  "pronouns": "they/them",
  "avatar": "bucket::key-or-url",
  "about": "markdown or null",
  "aboutTags": ["tag-one"],
  "background": null,
  "archivedAt": null,
  "createdAt": 1714233600000,
  "updatedAt": 1714237200000,
  "deletedAt": null,
  "purgeAt": null,
  "originalDirectoryId": null,
  "profileStyle": null,
  "avatarUrl": "/api/v1/members/b1c2d3e4-f5a6-7890-abcd-ef1234567890/media?kind=avatar&v=1714237200000",
  "backgroundUrl": null
}]

Examples

cURL

Shell
curl -sS \
  -H "Authorization: Bearer YOUR_TOKEN" \
  "https://api.floralitys.com/api/v1/members"

JavaScript (fetch)

JavaScript
const res = await fetch("https://api.floralitys.com/api/v1/members", {
  headers: { Authorization: "Bearer YOUR_TOKEN" },
});
if (!res.ok) throw new Error(await res.text());
const members = await res.json();

Status codes

  • 200: JSON array
  • 401 / 403: JSON error (see Errors)

Create member

POST/api/v1/members: scope members: read_write.

JSON body: required name; optional directoryId or homeGroupId, displayName, pronouns, avatar, about, background, createdAt (unix ms formed date; defaults to now; cannot be in the future), clientMutationId. Uses the account's active system scope when creating. Returns 201 with the member object.


Get member by id

GET/api/v1/members/{memberId}

Behavior

Returns one member object for the authenticated account. Same field shape as each element in List members (including avatarUrl / backgroundUrl with apiV1 media URLs). Includes archived (moved-out) members; trashed or unknown ids yield NOT_FOUND (JSON, 404).

Response

200

One member object (same fields as list rows).

JSON
{
  "_id": "b1c2d3e4-f5a6-7890-abcd-ef1234567890",
  "userId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
  "directoryId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "name": "string",
  "displayName": "string",
  "pronouns": "they/them",
  "avatar": "bucket::key-or-url",
  "about": "markdown or null",
  "aboutTags": ["tag-one"],
  "background": null,
  "archivedAt": null,
  "createdAt": 1714233600000,
  "updatedAt": 1714237200000,
  "deletedAt": null,
  "purgeAt": null,
  "originalDirectoryId": null,
  "profileStyle": null,
  "avatarUrl": "/api/v1/members/b1c2d3e4-f5a6-7890-abcd-ef1234567890/media?kind=avatar&v=1714237200000",
  "backgroundUrl": null
}

404

JSON
{
  "code": "NOT_FOUND",
  "message": "Member not found."
}

Examples

cURL

Shell
curl -sS \
  -H "Authorization: Bearer YOUR_TOKEN" \
  "https://api.floralitys.com/api/v1/members/MEMBER_ID"

JavaScript (fetch)

JavaScript
const res = await fetch(
  "https://api.floralitys.com/api/v1/members/MEMBER_ID",
  { headers: { Authorization: "Bearer YOUR_TOKEN" } },
);
if (!res.ok) throw new Error(await res.text());
const member = await res.json();

Status codes

  • 200: JSON object
  • 404: JSON NOT_FOUND (wrong user, trashed, or unknown id)
  • 400: JSON BAD_REQUEST if the path id is empty (edge case)
  • 401 / 403: JSON error (see Errors)

Update member

PATCH/api/v1/members/{memberId}

Body (JSON)

Send only fields to change. Unknown keys are rejected (400). Non-media fields must pass validation. Avatar and background go through the same plan limits and WebP pipeline as first-party imports: https URLs are fetched safely, transcoded to WebP, stored under your account, and GIF animation requires a plan that allows GIF avatars/banners. bucket::key storage refs must already belong to your Clerk asset prefix and cannot be an import-staging object (complete the upload flow or use an https URL instead).

FieldTypeNotes
namestring?Legal / system name
displayName, pronounsstring | null?null null clears; omit to leave unchanged
aboutstring | null?Non-empty strings rehost external markdown images when storage is configured; null / empty clears
avatarstring | null?https URL → server imports to WebP with subscription limits. Non-URL string → MinIO bucket::key you already own (final path only, not staging). null / empty clears
backgroundstring | null?Same rules as avatar for banner images
aboutTagsstring[] | null?Replaces About tags; null or [] clears
profileStyleobject | null?Member profile chrome JSON; null resets to defaults
createdAtnumber?Formed date (unix ms). Backdate when the member/alter actually appeared; cannot be in the future. Omit to leave unchanged on PATCH.
expectedVersionnumber?Optimistic concurrency on members.version
clientMutationIdUUID string?Optional idempotency / outbox correlation

Response

200

Updated member JSON (same shape as GET).

JSON
{
  "_id": "b1c2d3e4-f5a6-7890-abcd-ef1234567890",
  "userId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
  "directoryId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "name": "string",
  "displayName": "string",
  "pronouns": "they/them",
  "avatar": "bucket::key-or-url",
  "about": "markdown or null",
  "aboutTags": ["tag-one"],
  "background": null,
  "archivedAt": null,
  "createdAt": 1714233600000,
  "updatedAt": 1714237200000,
  "deletedAt": null,
  "purgeAt": null,
  "originalDirectoryId": null,
  "profileStyle": null,
  "avatarUrl": "/api/v1/members/b1c2d3e4-f5a6-7890-abcd-ef1234567890/media?kind=avatar&v=1714237200000",
  "backgroundUrl": null
}

404

JSON
{
  "code": "NOT_FOUND",
  "message": "Member not found."
}

409

When expectedVersion does not match the stored row (message text may vary).

JSON
{
  "code": "CONFLICT",
  "message": "Version conflict: member was modified by another client."
}

503

PRECONDITION_FAILED when storage is required (e.g. markdown image rehost) but not configured.

JSON
{
  "code": "PRECONDITION_FAILED",
  "message": "Object storage is not configured. …"
}

400

Validation, empty body, unknown keys, member in Trash, etc.

JSON
{
  "code": "BAD_REQUEST",
  "message": "Invalid request body"
}

Examples

cURL

Shell
curl -sS -X PATCH \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"displayName":"River","pronouns":"they/them"}' \
  "https://api.floralitys.com/api/v1/members/MEMBER_ID"

JavaScript (fetch)

JavaScript
const res = await fetch(
  "https://api.floralitys.com/api/v1/members/MEMBER_ID",
  {
    method: "PATCH",
    headers: {
      Authorization: "Bearer YOUR_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ displayName: "River", pronouns: "they/them" }),
  },
);
if (!res.ok) throw new Error(await res.text());
const member = await res.json();

Delete member

DELETE/api/v1/members/{memberId}

Query: soft vs hard

permanentBehavior
omitted, false, 0, or otherSoft delete: move to Trash (deletedAt set, retention purgeAt). Fails if the member is already trashed or is currently on the front ordering / active front session.
true, 1, or yes (case-insensitive)Hard delete: permanently remove the member and dependent rows. If the member is not yet trashed, the server soft-deletes then purges in sequence. If already trashed, purges only.

Response

204

Success: no JSON body.

Plain text
// 204 No Content: empty response body

404 / 400

JSON error when the handler returns a body (e.g. unknown id).

JSON
{
  "code": "NOT_FOUND",
  "message": "Member not found."
}

Examples

cURL (soft)

Shell
curl -sS -X DELETE \
  -H "Authorization: Bearer YOUR_TOKEN" \
  "https://api.floralitys.com/api/v1/members/MEMBER_ID"

cURL (hard)

Shell
curl -sS -X DELETE \
  -H "Authorization: Bearer YOUR_TOKEN" \
  "https://api.floralitys.com/api/v1/members/MEMBER_ID?permanent=true"

JavaScript (fetch, hard)

JavaScript
const url = new URL("https://api.floralitys.com/api/v1/members/MEMBER_ID");
url.searchParams.set("permanent", "true"); // omit or false for soft delete (trash)
const res = await fetch(url.toString(), {
  method: "DELETE",
  headers: { Authorization: "Bearer YOUR_TOKEN" },
});
if (res.status !== 204) throw new Error(await res.text());

Member media (avatar or background)

GET/api/v1/members/{memberId}/media

Query parameters

ParameterRequiredDescription
kindyesavatar or background
vnoCache-bust integer (list responses include a suitable v from member timestamps)

Response

200

Raw image bytes (not JSON). Typical headers: Content-Type from object metadata, Cache-Control: private, max-age=300, optional ETag.

Plain text
// binary body: not JSON

302

Redirect to a legacy public https URL when the stored value is an embeddable HTTP(S) URL. Follow with GET separately; no JSON body on the redirect response.

Plain text
// Location: https://…

401 / 403

Same JSON error object as other v1 routes.

JSON
{
  "code": "FORBIDDEN",
  "message": "Missing API key scope: members requires read"
}

400

JSON
{
  "code": "BAD_REQUEST",
  "message": "Missing or invalid kind (use avatar or background)."
}

404 / 503

Often an empty body (no JSON) for missing asset, wrong member, or storage not configured.

Plain text
// empty body

Status codes

  • MinIO ref: 200 with image bytes, Cache-Control: private, max-age=300, Content-Type from object metadata, optional ETag
  • Legacy HTTP(S) URL: 302 to the embeddable URL (upgraded to HTTPS when applicable)
  • 401 / 403: JSON error body
  • 400: JSON if kind is missing or invalid, or member id is empty
  • 404: empty body (wrong user, deleted member, missing field, invalid ref, or non-embeddable URL)
  • 503: empty body if object storage is not configured

Examples

cURL

Shell
curl -sS -o avatar.bin \
  -H "Authorization: Bearer YOUR_TOKEN" \
  "https://api.floralitys.com/api/v1/members/MEMBER_ID/media?kind=avatar&v=0"

JavaScript (fetch)

JavaScript
const url = new URL(
  "https://api.floralitys.com/api/v1/members/MEMBER_ID/media",
);
url.searchParams.set("kind", "avatar");
url.searchParams.set("v", "0");
const res = await fetch(url.toString(), {
  headers: { Authorization: "Bearer YOUR_TOKEN" },
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const blob = await res.blob();