Quickstart
This walks one happy path end to end: find a space, open it, list its posts,
and read one. Every endpoint is a GET, and none of them needs an
Authorization header today. The examples use a sample space and post; replace
them with values the API returns. JSON below is trimmed to the fields in play.
1. List public spaces
curl 'https://api.dfos.com/v1/spaces?limit=20'
{
"items": [
{
"id": "space_7gx4k2m9",
"did": "did:dfos:93n4d6936c3ct6r3k7477dn4z89c39h",
"domain": "field-notes",
"displayName": "Field Notes",
"avatarUrl": "https://media.dfos.com/field-notes-avatar.jpg",
"memberCountSummary": "a few dozen members"
}
],
"nextCursor": null,
"totalCount": 42
}
Each item is a compact card. Store the id or did — the domain (subdomain)
is a mutable alias. You can filter with ?joinMode=open and page with
nextCursor. Full field and filter semantics are in Spaces, and
the pagination contract is in Conventions.
2. Get a space
Address it by subdomain, entity id (space_…), or protocol DID:
curl https://api.dfos.com/v1/spaces/field-notes
The single fetch adds the space's full public profile — joinMode, siteMode,
subscribeEnabled, profile links, and (for application-mode spaces)
applicationQuestions. See Spaces for what each field means.
3. List the space's posts
Posts come back newest first.
curl 'https://api.dfos.com/v1/spaces/field-notes/posts?limit=20'
{
"items": [
{
"id": "post_4k8m2q7v",
"title": "Notes from the wetlands",
"displayTitle": "Notes from the wetlands",
"excerpt": "What changed after the first week of rain...",
"isPinned": false,
"publishedAt": "2026-07-19T18:00:00.000Z"
}
],
"nextCursor": null
}
displayTitle is a ready-to-render heading (it fills in for untitled posts),
and isPinned marks pinned posts — but the feed is ordered purely by recency
and won't reorder them for you. The listing carries no post 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/field-notes/posts/post_4k8m2q7v
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_4k8m2q7v",
"displayTitle": "Notes from the wetlands",
"body": "The waterline rose overnight. Here is what we found...",
"canonicalUri": "https://field-notes.dfos.com/post/notes-from-the-wetlands-post_4k8m2q7v",
"publishedAt": "2026-07-19T18:00:00.000Z"
}
}
When an anonymous caller can't read the post, state is "gated" instead: no
content, just a slim space call-to-action and a reason. The full union —
including folded posts and the reason enum — is documented in
Posts.
Next
- Resources — Spaces, Posts, Users, and protocol discovery document what each field means and what to store.
- Guide — Show your space's posts on your own site is a complete recipe.
- Interactive reference — try every endpoint and see its exact schema.