Skip to main content

Quickstart

One happy path end to end: find a space, open it, list its posts, and read one. Every call here is an anonymous GET; the credential-gated routes are elsewhere (see Authentication). The examples use the home space, and JSON is trimmed to the fields in play.

1. List public spaces

curl 'https://api.dfos.com/v1/spaces?limit=20'
{
"items": [
{
"id": "space_vnzfk7hth9vadc3daahd48",
"did": "did:dfos:9ctvrdn9vedda7efetrhcdakfh4cr2k",
"domain": "home",
"displayName": "DFOS",
"avatarUrl": "https://dfos.imgix.net/media/public/8e87h8c37f2vz3v6h7h3at-frame-143726546.png",
"memberCountSummary": "thousands of members"
}
],
"nextCursor": null,
"totalCount": 42
}

Store the id or did; the domain is a mutable alias. Filter with ?joinMode=open and page with nextCursor — see Spaces and Conventions.

2. Get a space

Address it by subdomain, entity id (space_…), or protocol DID:

curl https://api.dfos.com/v1/spaces/home

The single fetch adds the full public profile: joinMode, siteMode, subscribeEnabled, profile links, and applicationQuestions for application-mode spaces. See Spaces.

3. List the space's posts

curl 'https://api.dfos.com/v1/spaces/home/posts?limit=20'
{
"items": [
{
"id": "post_ze2kh2d47tzerkhet8348c",
"title": "DFOS beyond DFOS: sign-in, domains, and your own keys",
"displayTitle": "DFOS beyond DFOS: sign-in, domains, and your own keys",
"excerpt": "Platforms today make your identity real by hosting it. Your @ is real because it appears on their domain. Your work is real because their page says it is...",
"isPinned": false,
"publishedAt": "2026-09-04T18:05:33.531Z"
}
],
"nextCursor": null
}

Newest first; isPinned marks pinned posts but does not reorder the feed. displayTitle is a ready-to-render heading that fills in for untitled posts. The listing carries no body — fetch a post to read it. See Posts.

4. Read a single post

Use the post's id, not its slug:

curl https://api.dfos.com/v1/spaces/home/posts/post_ze2kh2d47tzerkhet8348c

The response is a union on state. When the post is anonymously readable, state is "eligible" and the content is under post:

{
"state": "eligible",
"post": {
"id": "post_ze2kh2d47tzerkhet8348c",
"displayTitle": "DFOS beyond DFOS: sign-in, domains, and your own keys",
"body": "Platforms today make your identity real by hosting it. Your @ is real because it appears on their domain...",
"canonicalUri": "https://home.dfos.com/post/dfos-beyond-dfos-sign-in-domains-and-your-own-keys-ze2kh2d47tzerkhet8348c",
"publishedAt": "2026-09-04T18:05:33.531Z"
}
}

Otherwise state is "gated": no content, a slim space call-to-action, and a reason. The full union, including folded posts and the reason enum, is in Posts.

Next

Spaces, Posts, Users, and protocol discovery document what each field means and what to store. Show your space's posts on your own site is the full recipe, and the interactive reference has every endpoint's exact schema.