Protocol discovery
GET /v1/protocol returns the DFOS protocol discovery document:
curl https://api.dfos.com/v1/protocol
{
"relayUrl": "https://relay.dfos.com",
"didMethod": "did:dfos",
"specUrl": "https://protocol.dfos.com/spec",
"endpoints": {
"wellKnown": "https://relay.dfos.com/.well-known/dfos-relay",
"identity": "https://relay.dfos.com/proof/v1/identities/{did}",
"identityLog": "https://relay.dfos.com/proof/v1/identities/{did}/log",
"content": "https://relay.dfos.com/proof/v1/content/{contentId}",
"contentLog": "https://relay.dfos.com/proof/v1/content/{contentId}/log",
"operation": "https://relay.dfos.com/proof/v1/operations/{cid}",
"blob": "https://relay.dfos.com/content/{contentId}/blob",
"indexContent": "https://relay.dfos.com/index/v0/content",
"indexIdentities": "https://relay.dfos.com/index/v0/identities"
}
}
relayUrl— the base URL of the DFOS protocol relay for this deployment.didMethod— the DID method used by everydidthe API emits.specUrl— the protocol specification.endpoints— URL templates for the relay's proof plane, content plane, and non-authoritative indexes. Substitute{did},{contentId}, or{cid}with values from API responses rather than constructing relay paths yourself.
| Field | Resolves |
|---|---|
wellKnown | Relay metadata and capabilities |
identity | An identity chain's terminal state |
identityLog | The identity chain's ordered, signed operation log |
content | A content chain's terminal state |
contentLog | The content chain's ordered, signed operation log |
operation | One signed operation by CID |
blob | A content chain's current document bytes |
indexContent | The relay's non-authoritative content-chain index |
indexIdentities | The relay's non-authoritative identity-chain index |
Fetch this document rather than hardcoding relay.dfos.com; the relay URL can
change. The identity and identityLog templates also resolve identity chains
published by third-party apps that use
Sign in with DFOS, which never
appear in an API response.
Protocol handles on entities
Public posts carry an optional protocol block with the contentId of the
post's content chain and the chain's current headOpCid. It is absent briefly
after creation, and on legacy or protocol-ineligible posts.
Public user and space detail responses carry an optional protocol block with
the identity chain's headOpCid, plus profile.contentId and
profile.headOpCid when the identity has a public profile chain. profile is
absent when the profile is empty. List items carry no protocol handles.
Combine a handle with the templates above to fetch a chain and verify it independently — Verify a post is the walkthrough.
Verified domains resolve through the same templates
The verifiedDomain on a user or a
space is an origin binding: two halves that have
to name each other.
- The claim lives on the identity chain, as a
DfosOriginservice entry. Substitute the entity'sdidinto theidentityoridentityLogtemplate. - The attestation lives on the domain, as either
https://{domain}/.well-known/dfos-didor aTXTrecord at_dfos.{domain}, carrying the DID. Fetch it directly; no DFOS server is involved.
Either half alone is a claim anyone could make; both, agreeing, prove one party controls both at the moment you check. Origin binding has the normative model and the four verdicts; Verified domains is the same proof from the app side.
The relay is a read-only public window onto identity chains, public profile
documents, and post content chains. A members-only post's chain may be anchored
there as an existence-only proof, with no read credential and no document
served; the API surfaces protocol handles for public posts only. See
Relays & verification for what it serves, and
The protocol for the identity-and-authorship model
underneath DFOS.