Skip to main content

Spaces API

The Spaces namespace provides comprehensive operations for creating spaces, managing membership, configuring access control, and handling invites and applications.

See Spaces concept doc for product-level details.

Key Endpoints

Create space - POST /spaces

Get space - GET /spaces/{id}

Update space - PUT /spaces/{id}

Delete space - DELETE /spaces/{id}

Set public config - PUT /spaces/{id}/public-config

Check domain availability - GET /spaces/domain/{domain}/status

Set domain - PUT /spaces/{id}/domain

My invite - POST/GET/DELETE /spaces/{id}/my-invite

Join directly - POST /spaces/{id}/join

Submit application - POST /spaces/{id}/applications

Approve/reject - POST /applications/{applicationId}/approve|reject

Creating and Configuring Spaces

Create a Space

POST /spaces
{
"displayName": "Design Team",
"description": "Internal design collaboration"
}

Creates a new space with you as the first admin. Space starts in closed (invite-only) mode.

Update Space Profile

PUT /spaces/{id}
{
"id": "space_xyz",
"displayName": "Updated Name",
"description": "Updated description",
"avatarId": "media_abc",
"bannerId": "media_def",
"backgroundId": "media_ghi"
}

Update space name, description, and profile media.

Delete a Space

DELETE /spaces/{id}

Soft-deletes the space. Requires admin role.

Domains

Check Domain Availability

GET /spaces/domain/design-team/status

Response:

{
"status": "available" // or "taken" or "invalid"
}

Check before claiming. Domains are 3-63 chars, lowercase alphanumeric + hyphens.

Claim a Domain

PUT /spaces/space_xyz/domain
{
"id": "space_xyz",
"domain": "design-team"
}

Claim a domain for the space. Domains are optional but required for memorable public profile URLs.

Public Configuration

Set Public Profile and Join Mode

PUT /spaces/space_xyz/public-config
{
"id": "space_xyz",
"isPublic": true,
"joinMode": "application"
}

Join modes:

  • "closed" - Invite-only (default)
  • "open" - Anyone can join directly (requires public profile enabled)
  • "application" - Anyone can apply, admins approve/reject

Note: Setting isPublic: true with joinMode: "open" makes the space publicly discoverable.

Invites (Per-Admin Model)

Each admin gets one active invite link. Regenerating creates a new code and invalidates the old one.

Generate Your Invite

POST /spaces/space_xyz/my-invite
{
"id": "space_xyz",
"maxUses": 10,
"expiresInMinutes": 10080,
"joinModeOverride": "instant"
}

Parameters:

  • maxUses - How many times the code can be used (max: 1000)
  • expiresInMinutes - When the code expires (max: 30 days / 43200 min)
  • joinModeOverride:
    • "instant" - Skip application flow, join immediately (default)
    • "application" - Force application flow
    • "inherit" - Inherit space join mode

Response:

{
"inviteId": "space_invite_xyz",
"inviteCode": "abc123xyz",
"expiresAt": "2025-01-30T10:00:00.000Z",
"usesRemaining": 10,
"maxUses": 10,
"joinModeOverride": "instant",
"createdAt": "2025-01-23T10:00:00.000Z"
}

Share inviteCode with people you want to invite.

Get Your Current Invite

GET /spaces/space_xyz/my-invite

Returns your active invite details (if you have one).

Invalidate Your Invite

DELETE /spaces/space_xyz/my-invite

Revoke your current invite code.

Preview Invite (Before Joining)

GET /spaces/invites/abc123xyz

Anyone can preview invite info to see what space they're being invited to:

{
"spaceDID": "did:dfos:...",
"displayName": "Design Team",
"description": "Internal design collaboration",
"avatar": { "url": "https://...", "width": 400, "height": 400 },
"banner": null,
"memberCount": 12,
"isPublic": false,
"effectiveJoinMode": "instant",
"applicationQuestions": null,
"userStatus": {
"isMember": false
}
}

Join via Invite Code

POST /spaces/join/abc123xyz
{
"code": "abc123xyz"
}

Join the space using an invite code. Behavior depends on invite's joinModeOverride.

Joining Spaces

Join Directly (Open Spaces)

POST /spaces/space_xyz/join
{
"id": "space_xyz"
}

Join a space with open join mode. Requires space to have isPublic: true and joinMode: "open".

Submit Application

POST /spaces/space_xyz/applications
{
"id": "space_xyz",
"responses": [
{
"question": "Why do you want to join?",
"response": "I'm interested in collaborating on design projects"
}
]
}

Submit application to join. If space has application questions configured, include responses array.

Check Your Application Status

GET /spaces/space_xyz/applications/me

Check if you have a pending/approved/rejected application for this space.

Response:

{
"applicationId": "application_xyz",
"status": "pending",
"submittedAt": "2025-01-23T10:00:00.000Z"
}

Member Management

List Members

GET /spaces/space_xyz/members

Get all space members with their roles.

Update Member Role

PUT /spaces/space_xyz/members/did:dfos:member123
{
"id": "space_xyz",
"memberId": "did:dfos:member123",
"role": "admin"
}

Promote member to admin or demote admin to member.

Kick Member

DELETE /spaces/space_xyz/members/did:dfos:member123

Remove member from space. They can rejoin if not banned.

Ban Member

POST /spaces/space_xyz/members/did:dfos:member123/bans
{
"id": "space_xyz",
"memberId": "did:dfos:member123"
}

Ban member permanently. Kicked from space and cannot rejoin.

List Bans

GET /spaces/space_xyz/bans

Get all banned members (admins only).

Unban Member

DELETE /spaces/space_xyz/bans/did:dfos:member123

Remove ban. Member can now join again (if invited or space is open/application mode).

Leave Space

DELETE /spaces/space_xyz/membership

Leave a space you're a member of.

Applications (Admin Workflows)

Approve Application

POST /applications/application_xyz/approve
{
"applicationId": "application_xyz"
}

Approve application. Applicant becomes a member.

Reject Application

POST /applications/application_xyz/reject
{
"applicationId": "application_xyz"
}

Reject application. Applicant can reapply later.

Configure Application Questions

PUT /spaces/space_xyz/application-settings
{
"id": "space_xyz",
"questions": [
{
"question": "Why do you want to join?",
"isRequired": true
},
{
"question": "How did you hear about us?",
"isRequired": false
}
]
}

Set up to 5 custom questions for applications. Questions shown to applicants and in public profile (if enabled).

Get Application Questions

GET /spaces/space_xyz/application-settings

Get current application questions for a space.

Additional Features

Get Viewer Relationship

GET /spaces/space_xyz/viewer

Get your relationship to the space (member role, application status, etc.). Useful for determining what actions you can take.

Response (member):

{
"status": "member",
"role": "admin",
"canApply": false
}

Response (non-member with pending application):

{
"status": "pending",
"canApply": false
}

Set Your Status Message

PUT /spaces/space_xyz/status
{
"id": "space_xyz",
"status": "Working on the new feature"
}

Set a personal status message visible to other members in this space.

Get Space Notification Counts

GET /spaces/notifications

Get unread notification counts per space:

{
"items": [
{
"space": {
"id": "space_abc",
"did": "did:dfos:...",
"displayName": "Dark Forest Collective"
},
"unreadCount": 5,
"lastNotifiedAt": "2025-01-15T10:30:00.000Z"
}
],
"totalUnreadCount": 12
}

Useful for showing per-space notification badges.

Authorization

  • Creating spaces: Authenticated users
  • Viewing public spaces: Anyone (limited info)
  • Viewing full space details: Members only
  • Updating space: Admins only
  • Managing members: Admins only
  • Creating invites: Admins only (one per admin)
  • Joining: Depends on join mode, invites, and applications
  • Application questions: Admins can set, anyone can view (for public spaces)

See Also