Workspace endpoints

List and create workspaces, list the people in a workspace, invite someone by email, and manage roles and invites through the REST API.

Updated

Paths are relative to https://api.fishcamp.space/api/v1. See the REST API overview for authentication, the X-Workspace-Id header and errors.

List workspaces

GET /workspaces

People. The workspaces of the signed-in person, oldest first, with their role in each. No X-Workspace-Id needed. An API key gets 403: it belongs to one workspace and can't see the others of the person who created it.

[
  {
    "id": "9b2f6c1d-3e4a-4f5b-8c7d-1a2b3c4d5e6f",
    "name": "Northstar Studio",
    "slug": "northstar-studio",
    "role": "OWNER",
    "lastChannelId": "0b6f3c55-2a51-4e0a-a3d6-6a3f1f2e9d10"
  }
]

role is OWNER, ADMIN or MEMBER. lastChannelId is the channel the person had open last, or null.

Create a workspace

POST /workspaces
FieldTypeRequiredDescription
namestringYesWorkspace name, 2 to 60 characters.
curl -X POST "https://api.fishcamp.space/api/v1/workspaces" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Northstar Studio"}'

People. Returns 201 Created with the workspace, in the same shape as the list. The person who creates it becomes its owner, and Fishcamp creates a public #general channel in it. The address (slug) comes from the name. Limit: 10 per minute.

List members

GET /workspace/members

Everyone in the workspace, oldest member first.

[
  {
    "membershipId": "5d0e7a2c-9b1f-4c3e-8a6d-2f4b7c9e1a0d",
    "role": "ADMIN",
    "joinedAt": "2026-11-02T13:05:11.000Z",
    "profile": {
      "id": "7a1c2e3f-4b5d-4e6f-8a9b-0c1d2e3f4a5b",
      "name": "Maya Lopes",
      "email": "maya@northstar.studio",
      "avatarUrl": null
    }
  }
]

Use profile.id wherever an endpoint asks for a profileId (direct messages, adding someone to a private channel) and membershipId to change a role or remove someone.

Invite someone

POST /workspace/invites

Admins. Sends an invite email and returns the invite.

FieldTypeRequiredDescription
emailstringYesEmail address of the person to invite.
roleMEMBER or ADMINNoRole they get when they accept. Default: MEMBER.
localeen, pt or esNoLanguage of the invite email. Default: en. Any other value gets 422. New in November 2026
curl -X POST "https://api.fishcamp.space/api/v1/workspace/invites" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{"email": "theo@northstar.studio", "role": "MEMBER", "locale": "pt"}'
{
  "id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
  "email": "theo@northstar.studio",
  "role": "MEMBER",
  "status": "PENDING",
  "createdAt": "2026-11-05T14:00:00.000Z",
  "expiresAt": "2026-11-12T14:00:00.000Z",
  "acceptUrl": "https://fishcamp.space/invite/inv_…",
  "emailSent": true
}
  • The invite only works for that email address and expires after 7 days.
  • acceptUrl is returned only here, so you can send it yourself, for example when emailSent is false.
  • Inviting the same address again renews the invite with a new link; the old link stops working.
  • Someone who is already in the workspace gets 409 conflict. Limit: 20 per minute.

To share one link with many people, to the workspace or straight to a channel, use an invite link instead. New in November 2026

More endpoints

Method and pathWhoWhat it does
GET /workspace/invitesAdminsPending invites.
DELETE /workspace/invites/:inviteIdAdminsRevokes a pending invite. 204.
PATCH /workspace/members/:membershipIdAdminsChanges a role: body { "role": "MEMBER" }. Only owners can give or take away OWNER.
DELETE /workspace/members/:membershipIdAdmins, or yourselfRemoves someone, or lets you leave. 204. Only owners can remove an owner.
PATCH /workspaceAdminsRenames the workspace: body { "name": "…" }.
GET /meAnyone signed inYour profile: id, email, name, avatarUrl.

The last owner can't be demoted, removed or leave: those requests get 409 conflict until someone else is an owner. See People and roles.

On this page