Skip to main content

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 every did the 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.
FieldResolves
wellKnownRelay metadata and capabilities
identityAn identity chain's terminal state
identityLogThe identity chain's ordered, signed operation log
contentA content chain's terminal state
contentLogThe content chain's ordered, signed operation log
operationOne signed operation by CID
blobA content chain's current document bytes
indexContentThe relay's non-authoritative content-chain index
indexIdentitiesThe 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 DfosOrigin service entry. Substitute the entity's did into the identity or identityLog template.
  • The attestation lives on the domain, as either https://{domain}/.well-known/dfos-did or a TXT record 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.