{
  "openapi": "3.1.0",
  "info": {
    "title": "DFOS Web Relay",
    "version": "0.54.0",
    "description": "HTTP relay for the DFOS protocol. Receives, verifies, stores, and serves\nidentity chains, content chains, countersignatures, and content blobs.\n\nTwo data planes:\n- **Proof plane** (public): signed chain operations, countersignatures\n- **Content plane** (authenticated): raw content blobs gated by identity proofs and DFOS credentials\n"
  },
  "paths": {
    "/.well-known/dfos-relay": {
      "get": {
        "operationId": "getRelayMetadata",
        "summary": "Relay metadata",
        "description": "Returns the relay's DID, protocol identifier, version, capabilities,\nprofile artifact, configured peers, and operational stats.\n",
        "tags": [
          "Meta"
        ],
        "responses": {
          "200": {
            "description": "Relay metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "did",
                    "protocol",
                    "version",
                    "capabilities",
                    "profile",
                    "peers",
                    "stats"
                  ],
                  "properties": {
                    "did": {
                      "type": "string",
                      "description": "The relay's DID",
                      "example": "did:dfos:cnnnft9f8a2rn938d6nkz38r847v2kr"
                    },
                    "protocol": {
                      "type": "string",
                      "enum": [
                        "dfos-web-relay"
                      ]
                    },
                    "version": {
                      "type": "string",
                      "example": "0.16.0"
                    },
                    "capabilities": {
                      "type": "object",
                      "required": [
                        "proof",
                        "write",
                        "content",
                        "log",
                        "revocations",
                        "index",
                        "signing"
                      ],
                      "properties": {
                        "proof": {
                          "type": "boolean",
                          "description": "Always true — a relay without proof plane is not a relay"
                        },
                        "write": {
                          "type": "boolean",
                          "description": "Whether the relay accepts writes via POST /proof/v1/operations (false = lite pull-only node)"
                        },
                        "content": {
                          "type": "boolean",
                          "description": "Whether the relay supports the content plane (blob upload/download; enumerate a chain's documents via GET /proof/v1/content/{contentId}/log)"
                        },
                        "log": {
                          "type": "boolean",
                          "description": "Whether the global operation log is available (GET /proof/v1/log)"
                        },
                        "revocations": {
                          "type": "boolean",
                          "description": "Whether the revocation status index is served (GET /revocations/v1/*)"
                        },
                        "index": {
                          "type": "boolean",
                          "description": "Whether the index query family is served (GET /index/v0/*)"
                        },
                        "signing": {
                          "type": "boolean",
                          "description": "Whether the optional SIGNING 0.1 mailbox courier is enabled"
                        }
                      }
                    },
                    "ingestion": {
                      "type": "string",
                      "enum": [
                        "open",
                        "proof-required",
                        "closed"
                      ],
                      "description": "Admission-mode hint for POST /proof/v1/operations. `open` — anonymous\nsubmissions admitted, subject to policy; `proof-required` — anonymous\nrefused at the policy step (403); `closed` — no external ingestion (501).\nAbsent derives from capabilities.write. Advertisement is a hint; the\nrelay-local admission policy is the authority.\n"
                    },
                    "openapi": {
                      "type": "string",
                      "example": "/openapi.json",
                      "description": "OPTIONAL. URL of an OpenAPI document describing this relay's full HTTP surface — absolute, or root-relative resolved against the relay's base URL. Serving the document is SHOULD, never MUST; a relay that serves one advertises it here, and absence of the field means none is served. The document is discovery, never authority: the routes, capability gates, and auth rules the spec fixes govern regardless of what an advertised document says."
                    },
                    "profile": {
                      "type": "string",
                      "description": "The relay's profile artifact as a compact JWS token"
                    },
                    "peers": {
                      "type": "array",
                      "description": "Peers this relay is configured to sync from, for mesh discovery",
                      "items": {
                        "type": "object",
                        "required": [
                          "endpoint"
                        ],
                        "properties": {
                          "endpoint": {
                            "type": "string",
                            "description": "The peer relay's base URL"
                          }
                        }
                      }
                    },
                    "stats": {
                      "type": "object",
                      "description": "Operational statistics. pendingOps is always present; the remaining fields appear when the store computes them (getStats is an optional store surface).",
                      "required": [
                        "pendingOps"
                      ],
                      "properties": {
                        "pendingOps": {
                          "type": "integer",
                          "description": "Count of operations pending processing (-1 if unavailable)"
                        },
                        "opCount": {
                          "type": "integer",
                          "description": "Operations this relay HOLDS in its global log. On a relay that prunes or culls, this is below the log's tip position and is not a proxy for it; counts are relay-local and not comparable across relays"
                        },
                        "countsByKind": {
                          "type": "object",
                          "description": "Operation counts bucketed by primitive kind (all six keys present)",
                          "required": [
                            "identity",
                            "content",
                            "artifact",
                            "credential",
                            "countersign",
                            "revocation"
                          ],
                          "properties": {
                            "identity": {
                              "type": "integer"
                            },
                            "content": {
                              "type": "integer"
                            },
                            "artifact": {
                              "type": "integer"
                            },
                            "credential": {
                              "type": "integer"
                            },
                            "countersign": {
                              "type": "integer"
                            },
                            "revocation": {
                              "type": "integer"
                            }
                          }
                        },
                        "oldestOpAt": {
                          "type": "string",
                          "nullable": true,
                          "description": "createdAt of the oldest operation in the log, or null when empty"
                        },
                        "headCid": {
                          "type": "string",
                          "nullable": true,
                          "description": "CID of the newest operation in the log (the tip), or null when empty"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiDocument",
        "summary": "This OpenAPI document",
        "description": "Returns the OpenAPI document describing the relay's HTTP surface. Relay\nmeta, ungated exactly as the well-known is — no capability flag stands\nbetween a client and the description of the surface it is about to call.\nRegistered when the deployment is configured with a document\n(`createRelay({ openapi: { document } })`), and its path is the value\nadvertised in the well-known `openapi` field. Discovery, never\nauthority: the routes, capability gates, and auth rules the spec fixes\ngovern regardless of what this document says.\n",
        "tags": [
          "Meta"
        ],
        "responses": {
          "200": {
            "description": "An OpenAPI document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/signing/v0/requests": {
      "post": {
        "operationId": "depositSignRequest",
        "summary": "Deposit a credential-authorized sign request",
        "description": "Verifies the request envelope and a deposit credential rooted at the mailbox subject, then stores ephemeral courier state by request CID.",
        "tags": [
          "Signing Mailbox"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "request",
                  "credential"
                ],
                "properties": {
                  "request": {
                    "type": "string"
                  },
                  "credential": {
                    "type": "string"
                  },
                  "chain": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Identical request already deposited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningDepositResponse"
                }
              }
            }
          },
          "201": {
            "description": "Request deposited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningDepositResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "CID already holds a different request token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Deposit body exceeds 512 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Subject mailbox is at the pending-request cap",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      },
      "get": {
        "operationId": "pollSigningMailbox",
        "summary": "Poll the authenticated subject's pending sign requests",
        "description": "Returns only the authenticated subject's unexpired, unanswered requests in oldest-first order.",
        "tags": [
          "Signing Mailbox"
        ],
        "security": [
          {
            "IdentityProof": []
          }
        ],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Opaque composite-key cursor from a prior page's `next`"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum requests to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Pending requests, oldest first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningMailboxResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/signing/v0/requests/{cid}/response": {
      "post": {
        "operationId": "submitSignResponse",
        "summary": "Submit the subject-signed response artifact",
        "description": "Verifies a canonical compact JWS over the request's exact target bytes and stores it first-write-wins.",
        "tags": [
          "Signing Mailbox"
        ],
        "parameters": [
          {
            "name": "cid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "response"
                ],
                "properties": {
                  "response": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Identical response already stored",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningStoredResponse"
                }
              }
            }
          },
          "201": {
            "description": "Response stored",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningStoredResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "A different response already won the slot",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Response body exceeds the aggregate route limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      },
      "get": {
        "operationId": "getSignResponse",
        "summary": "Fetch request status or the response artifact",
        "description": "Returns the unexpired request's pending, declined, or responded state without authentication.",
        "tags": [
          "Signing Mailbox"
        ],
        "parameters": [
          {
            "name": "cid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pending, declined, or responded status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningResponseStatus"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/signing/v0/requests/{cid}/decline": {
      "post": {
        "operationId": "declineSignRequest",
        "summary": "Set the advisory decline flag",
        "description": "Idempotently marks an unexpired unanswered request declined; the request may still be answered later.",
        "tags": [
          "Signing Mailbox"
        ],
        "parameters": [
          {
            "name": "cid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Declined (idempotent)"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "A response already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Decline body exceeds the aggregate route limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/proof/v1/operations": {
      "post": {
        "operationId": "ingestOperations",
        "summary": "Submit operations for ingestion",
        "description": "Accept a batch of JWS tokens — identity operations, content operations,\nand countersignatures. The relay classifies, dependency-sorts,\nverifies, and stores each token.\n\nAdmission is a ladder, cheapest first: structural caps (400/413), then\nproof verification when an identity proof is presented (401 invalid /\n503 unverifiable), then the relay-local admission policy over\n(principal | anonymous) — a refusal is a request-level 403 with no\nper-item results — then full per-item verification. An identity proof is\nOPTIONAL here and, when presented, MUST carry `jti` (write-shaped).\n",
        "tags": [
          "Proof Plane"
        ],
        "security": [
          {},
          {
            "IdentityProof": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "operations"
                ],
                "properties": {
                  "operations": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 100,
                    "items": {
                      "type": "string",
                      "description": "JWS compact serialization token"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ingestion results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "results"
                  ],
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/IngestionResult"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "description": "An identity proof was presented and is invalid (bad signature, stale, wrong binding, missing or oversized jti)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Refused by the relay-local admission policy — request-level, no per-item results",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Replayed request — the proof's jti was already seen inside its freshness window",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Aggregate request body exceeds 16 MiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          },
          "503": {
            "description": "The presenter could not be resolved, the relay has no configured authority, or the admission policy could not be evaluated (fail closed)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/proof/v1/operations/{cid}": {
      "get": {
        "operationId": "getOperation",
        "summary": "Get an operation by CID",
        "tags": [
          "Proof Plane"
        ],
        "parameters": [
          {
            "name": "cid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "CIDv1 of the operation"
          }
        ],
        "responses": {
          "200": {
            "description": "Operation details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoredOperation"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/proof/v1/identities/{did}": {
      "get": {
        "operationId": "getIdentityChain",
        "summary": "Get an identity chain by DID",
        "tags": [
          "Proof Plane"
        ],
        "parameters": [
          {
            "name": "did",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "DID of the identity (e.g., did:dfos:cnnnft9f8a2rn938d6nkz38r847v2kr)"
          }
        ],
        "responses": {
          "200": {
            "description": "Identity chain terminal state (the operation log is served by /proof/v1/identities/{did}/log)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IdentityChainResponse"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/1.0/identifiers/{did}": {
      "get": {
        "operationId": "resolveDID",
        "summary": "Resolve a did:dfos to a W3C DID Document",
        "description": "Resolve a `did:dfos` identifier into a W3C DID Document, following the\nDIF Universal Resolver HTTP binding. Read-only and self-certifying: the\nrelay serves the DID-core projection of the identity chain's verified\nterminal state. A deactivated identity resolves to 200 with an empty\nverification-method set and `deactivated: true`. Additive — rides the\nfrozen v1 surface, does not touch the wire or the proof plane.\n",
        "tags": [
          "DID Resolution"
        ],
        "parameters": [
          {
            "name": "did",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "DID to resolve (e.g., did:dfos:cnnnft9f8a2rn938d6nkz38r847v2kr)"
          }
        ],
        "responses": {
          "200": {
            "description": "DIF resolution result",
            "content": {
              "application/did+ld+json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "@context",
                    "didDocument",
                    "didResolutionMetadata",
                    "didDocumentMetadata"
                  ],
                  "properties": {
                    "@context": {
                      "type": "string",
                      "example": "https://w3id.org/did-resolution/v1"
                    },
                    "didDocument": {
                      "type": "object",
                      "required": [
                        "@context",
                        "id",
                        "controller",
                        "verificationMethod"
                      ],
                      "properties": {
                        "@context": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "id": {
                          "type": "string"
                        },
                        "controller": {
                          "type": "string"
                        },
                        "verificationMethod": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string",
                                "example": "Multikey"
                              },
                              "controller": {
                                "type": "string"
                              },
                              "publicKeyMultibase": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "authentication": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "assertionMethod": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "capabilityInvocation": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "service": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "type"
                            ],
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              },
                              "serviceEndpoint": {},
                              "label": {
                                "type": "string",
                                "description": "Human-readable label, emitted for ContentAnchor service entries. Unrecognized service types are preserved verbatim, so additional properties may appear."
                              }
                            }
                          }
                        }
                      }
                    },
                    "didResolutionMetadata": {
                      "type": "object",
                      "properties": {
                        "contentType": {
                          "type": "string",
                          "example": "application/did+ld+json"
                        }
                      }
                    },
                    "didDocumentMetadata": {
                      "type": "object",
                      "properties": {
                        "created": {
                          "type": "string"
                        },
                        "updated": {
                          "type": "string"
                        },
                        "deactivated": {
                          "type": "boolean"
                        },
                        "operationCount": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed did:dfos identifier",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "didDocument": {
                      "nullable": true
                    },
                    "didResolutionMetadata": {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "example": "invalidDid"
                        }
                      }
                    },
                    "didDocumentMetadata": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No identity chain found for the DID",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "didDocument": {
                      "nullable": true
                    },
                    "didResolutionMetadata": {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "example": "notFound"
                        }
                      }
                    },
                    "didDocumentMetadata": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/revocations/v1/credential/{credentialCID}": {
      "get": {
        "operationId": "getCredentialRevocationStatus",
        "summary": "Revocation status for a credential",
        "description": "Read-only projection of the relay's revocation set — the same\n(issuerDID, credentialCID) index credential enforcement consults. A\nfrozen v1 contract at the relay root on its own version clock;\nrevocations still enter through POST /proof/v1/operations. Every positive answer carries the full\nrevocation JWS so a zero-trust caller re-verifies the proof instead of\ntrusting the boolean. `revoked: false` is an honest known-nothing answer\n— absence is NOT proof of non-revocation. Relays without the index\n(capabilities.revocations: false) return 501.\n",
        "tags": [
          "Revocation Status"
        ],
        "parameters": [
          {
            "name": "credentialCID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Credential CID (CIDv1 dag-cbor + sha256, bafyrei…)"
          }
        ],
        "responses": {
          "200": {
            "description": "Revocation status (revoked or honest known-nothing)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "credentialCID",
                    "revoked"
                  ],
                  "properties": {
                    "credentialCID": {
                      "type": "string"
                    },
                    "revoked": {
                      "type": "boolean"
                    },
                    "revocation": {
                      "type": "string",
                      "description": "The full revocation JWS token — present iff revoked. Self-proving."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed credential CID",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid credential CID"
                    }
                  }
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/revocations/v1/issuer/{did}": {
      "get": {
        "operationId": "getIssuerRevocations",
        "summary": "Paginated feed of all revocations ingested for an issuer",
        "description": "Every revocation this relay has ingested for the issuer, ordered by\ncredentialCID ascending and cursor-paginated. Each entry carries the full revocation JWS\n(self-proving). An issuer with none returns an empty array — same honest\nabsence semantics as the credential route.\n",
        "tags": [
          "Revocation Status"
        ],
        "parameters": [
          {
            "name": "did",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Issuer DID (canonical 31-char did:dfos)"
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Strictly-greater credentialCID keyset cursor. It need not name a present row; an unknown value resumes at the next greater key."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Issuer revocation list page (possibly empty)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "did",
                    "revocations",
                    "next"
                  ],
                  "properties": {
                    "did": {
                      "type": "string"
                    },
                    "revocations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "credentialCID",
                          "revocation"
                        ],
                        "properties": {
                          "credentialCID": {
                            "type": "string"
                          },
                          "revocation": {
                            "type": "string",
                            "description": "The full revocation JWS token — self-proving"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "Last row's credentialCID, or null when the page was not full"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed did:dfos identifier",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "invalid DID"
                    }
                  }
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/index/v0/identities": {
      "get": {
        "operationId": "indexIdentities",
        "summary": "Enumerate identity chains (non-authoritative index)",
        "description": "Cursor-paginated enumeration of identity chains, DID ascending. A\ndiscovery hint, never authority — every row carries the identifiers a\nclient needs to re-derive its claims from the frozen proof plane. The\nindex cannot lie by assertion (a fabricated row fails the client's\nfold) but CAN lie by omission — absence of a row is not proof of\nabsence. The `profile` object is the single well-known projection\n(profile/v1 → name): null only when the identity declares no\nprofile-labeled content-chain anchor; on circuit breakers the object is\nkept with docSchema/name null and anchor preserved as the verification\npointer. docSchema null is an honest unknown — bytes not held, bytes\nundecodable, or a document declaring no string $schema — never a claim\nabout what the document says.\n\nDELETED IDENTITIES: a relay MAY omit isDeleted rows from the DISCOVERY\nshapes of this route (the bare listing, the keyset and ordered walks,\nnameContains, hasPublicProfile) and MUST return them, carrying\nisDeleted true, from either RESOLUTION shape — did= and key=. The\npresence of did= or key= makes the request a resolution whatever other\nfilters it carries. Relays without the capability (capabilities.index\nfalse or absent) return 501.\n",
        "tags": [
          "Index"
        ],
        "parameters": [
          {
            "name": "did",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact DID match (zero or one row). A RESOLUTION shape: a deleted identity MUST still be returned, carrying isDeleted true."
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Reverse lookup \"which identities has this key ever been PROVED into\". Matched byte-for-byte against the multibase public-key strings of every key-role membership a possession proof admitted across the chain's whole history — auth, assert and controller alike, not just the current head, so a key a later update rotated out still matches. A key a chain merely DECLARED, with no possession proof admitting it, never matches: that membership is void, it publishes no link between chains, and indexing it would let a stranger burn a key they do not hold by writing it into a chain. One key may match many identities. A RESOLUTION shape: a deleted identity MUST still match — key-loss recovery starts from a restored seed holding no DID, and mint-time burn checking refuses a key that already proves somewhere, so a hidden sealed row is a wrong answer rather than a thinner one. The value is opaque: a string no chain ever proved matches nothing, with no format validation and no 400."
          },
          {
            "name": "hasPublicProfile",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Boolean filter on the predicate \"profile is non-null AND profile.publicRead is true\" — true keeps rows where it holds, false keeps rows where it does not, absent applies no filter"
          },
          {
            "name": "nameContains",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive substring filter over the projected profile name. Non-authoritative (index hint)."
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "genesisAt.desc",
                "headAt.desc"
              ]
            },
            "description": "Optional author-time ordering; ordered cursors are opaque"
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Keyset cursor — returns rows with `did` strictly greater than this value (from a prior page's next). Need not be a present key; a value between keys resumes at the next greater DID."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Identity index page",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "identities",
                    "next"
                  ],
                  "properties": {
                    "identities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "did",
                          "headCID",
                          "opCount",
                          "genesisAt",
                          "headAt",
                          "isDeleted",
                          "profile"
                        ],
                        "properties": {
                          "did": {
                            "type": "string"
                          },
                          "headCID": {
                            "type": "string"
                          },
                          "opCount": {
                            "type": "integer",
                            "description": "Operations stored for this chain, branch-inclusive"
                          },
                          "genesisAt": {
                            "type": "string",
                            "description": "Author-claimed createdAt of the genesis operation"
                          },
                          "headAt": {
                            "type": "string",
                            "description": "Author-claimed createdAt of the current head operation"
                          },
                          "isDeleted": {
                            "type": "boolean"
                          },
                          "profile": {
                            "type": "object",
                            "nullable": true,
                            "description": "The profile/v1 → name well-known projection, or null when the identity declares no profile-labeled content-chain ContentAnchor",
                            "required": [
                              "anchor",
                              "publicRead",
                              "docSchema",
                              "name"
                            ],
                            "properties": {
                              "anchor": {
                                "type": "string",
                                "description": "The anchored contentId — the client's verification pointer"
                              },
                              "publicRead": {
                                "type": "boolean",
                                "description": "Whether a standing public-read grant currently authorizes anonymous read of the anchored chain, per this relay's fold — a hint, never an access decision"
                              },
                              "docSchema": {
                                "type": "string",
                                "nullable": true,
                                "description": "$schema declared by the held head document; null when bytes are not held or not decodable"
                              },
                              "name": {
                                "type": "string",
                                "nullable": true,
                                "description": "Extracted iff the held head doc declares profile/v1 and name is a non-empty string; null on any circuit breaker"
                              }
                            }
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "Cursor for the next page (pass as `after`), or null when the page was not full"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid order or cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/index/v0/content": {
      "get": {
        "operationId": "indexContent",
        "summary": "Enumerate and filter content chains (non-authoritative index)",
        "description": "Cursor-paginated enumeration of content chains, contentId ascending.\nFilters are ANDed exact matches. docSchema matches only chains whose\ncurrent head document bytes the relay holds and can decode — a lower\nbound, not exhaustive coverage. Same hints-not-authority posture as the\nidentity index: verify by fetching the chain from the proof plane and\nfolding. Relays without the capability return 501.\n",
        "tags": [
          "Index"
        ],
        "parameters": [
          {
            "name": "contentId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact contentId match (zero or one row)"
          },
          {
            "name": "creator",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on the chain creator (genesis signer) DID"
          },
          {
            "name": "signer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact DID match against accepted operation signers in the chain"
          },
          {
            "name": "docSchema",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact opaque string match on the $schema declared by the held head document"
          },
          {
            "name": "publicRead",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Filter on the standing public-read grant fold"
          },
          {
            "name": "documentCID",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match against currentDocumentCID"
          },
          {
            "name": "isDeleted",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Exact match against terminal deletion state"
          },
          {
            "name": "titleContains",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive substring match over projected title. Implicitly restricts to publicRead=true; combining with publicRead=false is 400."
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "genesisAt.desc",
                "headAt.desc"
              ]
            },
            "description": "Optional author-time ordering; ordered cursors are opaque"
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Keyset cursor — returns rows with `contentId` strictly greater than this value (from a prior page's next). Need not be a present key; a value between keys resumes at the next greater contentId."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Content index page",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "content",
                    "next"
                  ],
                  "properties": {
                    "content": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "contentId",
                          "genesisCID",
                          "headCID",
                          "creatorDID",
                          "isDeleted",
                          "opCount",
                          "genesisAt",
                          "headAt",
                          "currentDocumentCID",
                          "publicRead",
                          "docSchema",
                          "title"
                        ],
                        "properties": {
                          "contentId": {
                            "type": "string"
                          },
                          "genesisCID": {
                            "type": "string"
                          },
                          "headCID": {
                            "type": "string"
                          },
                          "creatorDID": {
                            "type": "string"
                          },
                          "isDeleted": {
                            "type": "boolean"
                          },
                          "opCount": {
                            "type": "integer",
                            "description": "Operations stored for this chain, branch-inclusive"
                          },
                          "genesisAt": {
                            "type": "string"
                          },
                          "headAt": {
                            "type": "string"
                          },
                          "currentDocumentCID": {
                            "type": "string",
                            "nullable": true
                          },
                          "publicRead": {
                            "type": "boolean",
                            "description": "Standing public-read grant fold — a hint, never an access decision"
                          },
                          "docSchema": {
                            "type": "string",
                            "nullable": true,
                            "description": "$schema declared by the held head document; null when bytes are not held or not decodable"
                          },
                          "title": {
                            "type": "string",
                            "nullable": true,
                            "description": "The public post/v1 display-name projection, null on any circuit breaker"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "Cursor for the next page (pass as `after`), or null when the page was not full"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed creator DID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/index/v0/credits": {
      "get": {
        "operationId": "indexCredits",
        "summary": "Credits asserted by public head documents (non-authoritative index)",
        "description": "Enumerates who publicly readable post/v1 head documents say made them.\nRows are assertion-tier discovery hints derived only from held current-head\nbytes; non-public, deleted, malformed, unheld, and non-post documents have\nzero rows. Claim tokens and names are never projected, and hasClaim records\nonly string byte-presence. Rows are ordered by contentId then position.\n",
        "tags": [
          "Index"
        ],
        "parameters": [
          {
            "name": "did",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact credited DID match; malformed DIDs return 400"
          },
          {
            "name": "contentId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact content-chain identifier match"
          },
          {
            "name": "role",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact opaque role match; null-role rows match no role filter"
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Opaque composite cursor from a prior page's next"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Public-head credit page (possibly empty)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "credits",
                    "next"
                  ],
                  "properties": {
                    "credits": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "contentId",
                          "did",
                          "role",
                          "position",
                          "hasClaim"
                        ],
                        "properties": {
                          "contentId": {
                            "type": "string"
                          },
                          "did": {
                            "type": "string"
                          },
                          "role": {
                            "type": "string",
                            "nullable": true
                          },
                          "position": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "hasClaim": {
                            "type": "boolean"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "Opaque cursor for the next page, or null when the page was not full"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed DID or cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/index/v0/countersignatures": {
      "get": {
        "operationId": "indexCountersignaturesByWitness",
        "summary": "Countersignatures signed by a witness (non-authoritative index)",
        "description": "The reverse of GET /proof/v1/countersignatures/{cid}: every\ncountersignature this relay has ingested that was SIGNED BY the given\nwitness DID, ordered by countersignature CID ascending and\ncursor-paginated. Each entry carries the full JWS — self-proving, same\nposture as the issuer revocations feed. Relays without the capability\nreturn 501.\n",
        "tags": [
          "Index"
        ],
        "parameters": [
          {
            "name": "witness",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Witness DID (canonical 31-char did:dfos)"
          },
          {
            "name": "relation",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact opaque relation match"
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "createdAt.desc",
                "ingestedAt.desc"
              ]
            },
            "description": "Optional recency ordering; ordered cursors are opaque"
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Keyset cursor — returns rows with countersignature `cid` strictly greater than this value (from a prior page's next). Need not be a present key; a value between keys resumes at the next greater cid."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Countersignatures-by-witness page (possibly empty)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "witness",
                    "countersignatures",
                    "next"
                  ],
                  "properties": {
                    "witness": {
                      "type": "string"
                    },
                    "countersignatures": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "cid",
                          "targetCID",
                          "relation",
                          "jwsToken"
                        ],
                        "properties": {
                          "cid": {
                            "type": "string"
                          },
                          "targetCID": {
                            "type": "string"
                          },
                          "relation": {
                            "type": "string",
                            "nullable": true,
                            "description": "Open-namespace relation tag, null when omitted by the signer"
                          },
                          "jwsToken": {
                            "type": "string",
                            "description": "The full countersignature JWS — self-proving"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "Cursor for the next page (pass as `after`), or null when the page was not full"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or malformed witness DID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/index/v0/credentials": {
      "get": {
        "operationId": "indexCredentials",
        "summary": "Public credentials held by the relay (non-authoritative index)",
        "description": "Enumerates the relay's held PUBLIC credentials (aud \"*\"), filterable by\nissuer and/or resource, ordered by credential CID ascending and\ncursor-paginated. When the requested `resource` is a chain resource, the\n`chain:*` wildcard bucket is always unioned in (a chain:* grant may\nauthorize the named chain). Amber and relay-asserted: the result is a\nsuperset of candidates carrying the full self-proving JWS; the caller\nfolds each token against the proof plane (delegation roots at the chain\ncreator, revocation, expiry) before treating it as authorization — the\nrelay makes no authorization claim. Only public credentials are ever\nstored, so targeted bearer credentials are neither enumerable nor\nleakable. Relays without the capability return 501.\n",
        "tags": [
          "Index"
        ],
        "parameters": [
          {
            "name": "issuer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Issuer DID (canonical 31-char did:dfos); 400 when malformed"
          },
          {
            "name": "resource",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match against an att[].resource. For a chain resource the chain:* wildcard bucket is unioned in."
          },
          {
            "name": "action",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match against an att[].action"
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "createdAt.desc",
                "ingestedAt.desc"
              ]
            },
            "description": "Optional recency ordering; ordered cursors are opaque"
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "CID keyset cursor in lexical mode or opaque cursor in ordered mode"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Public-credentials page (possibly empty)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "credentials",
                    "next"
                  ],
                  "properties": {
                    "credentials": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "cid",
                          "issuerDID",
                          "aud",
                          "att",
                          "exp",
                          "jwsToken"
                        ],
                        "properties": {
                          "cid": {
                            "type": "string"
                          },
                          "issuerDID": {
                            "type": "string"
                          },
                          "aud": {
                            "type": "string",
                            "enum": [
                              "*"
                            ]
                          },
                          "att": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "required": [
                                "resource",
                                "action"
                              ],
                              "properties": {
                                "resource": {
                                  "type": "string"
                                },
                                "action": {
                                  "type": "string"
                                }
                              }
                            }
                          },
                          "exp": {
                            "type": "integer",
                            "description": "Expiry (unix seconds)"
                          },
                          "jwsToken": {
                            "type": "string",
                            "description": "The full credential JWS — self-proving, full-fidelity att"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "Cursor for the next page (pass as `after`), or null when the page was not full"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed issuer DID, order, or cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/index/v0/operations": {
      "get": {
        "operationId": "indexOperations",
        "summary": "Relay-held operation recency feed (non-authoritative index)",
        "description": "Metadata-only browse ordering over accepted operations. createdAt is\nauthor-claimed (credential iat normalized to ISO 8601); ingestedAt is\nrelay-observed. Rows never include JWS tokens or payloads. signerKey\nfilters by the public key the row's signature verified against at\ningest; a DID-addressed signer filter is not defined here.\n",
        "tags": [
          "Index"
        ],
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "identity-op",
                "content-op",
                "artifact",
                "countersign",
                "revocation",
                "credential"
              ]
            },
            "description": "Exact operation-kind match"
          },
          {
            "name": "chainId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact operation-log routing identifier match"
          },
          {
            "name": "signerKey",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact multibase public-key match against the key this operation's signature verified against at ingest. Matched byte-for-byte, with no format validation: a string no accepted operation was signed with is a 200 with an empty page, never a 400. Key-addressed, not DID-addressed."
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "createdAt.desc",
                "ingestedAt.desc"
              ],
              "default": "ingestedAt.desc"
            },
            "description": "Recency ordering"
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Opaque ordered cursor from a prior page's next"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Operation index page",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "operations",
                    "next"
                  ],
                  "properties": {
                    "operations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "cid",
                          "kind",
                          "chainId",
                          "createdAt",
                          "ingestedAt"
                        ],
                        "properties": {
                          "cid": {
                            "type": "string"
                          },
                          "kind": {
                            "type": "string"
                          },
                          "chainId": {
                            "type": "string"
                          },
                          "createdAt": {
                            "type": "string"
                          },
                          "ingestedAt": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "Opaque cursor for the next page, or null when caught up"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid kind, order, or cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/index/v0/artifacts": {
      "get": {
        "operationId": "indexArtifacts",
        "summary": "Enumerate standalone signed artifacts (non-authoritative index)",
        "description": "Metadata-only enumeration of verified standalone artifacts. The inline\ndocument bytes are held in the stored JWS, so docSchema coverage does\nnot depend on a separate blob. Rows never include the artifact payload.\n",
        "tags": [
          "Index"
        ],
        "parameters": [
          {
            "name": "cid",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact artifact CID match (zero or one row)"
          },
          {
            "name": "signer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact signing DID from the artifact JWS kid"
          },
          {
            "name": "docSchema",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact opaque match on the inline document $schema"
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "createdAt.desc",
                "ingestedAt.desc"
              ]
            },
            "description": "Optional recency ordering; absent means lexical CID order"
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "CID keyset cursor in lexical mode or opaque cursor in ordered mode"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Artifact index page",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "artifacts",
                    "next"
                  ],
                  "properties": {
                    "artifacts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "cid",
                          "signerDID",
                          "createdAt",
                          "ingestedAt",
                          "docSchema"
                        ],
                        "properties": {
                          "cid": {
                            "type": "string"
                          },
                          "signerDID": {
                            "type": "string"
                          },
                          "createdAt": {
                            "type": "string"
                          },
                          "ingestedAt": {
                            "type": "string"
                          },
                          "docSchema": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "Cursor for the next page, or null when caught up"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid signer DID, order, or cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/proof/v1/content/{contentId}": {
      "get": {
        "operationId": "getContentChain",
        "summary": "Get a content chain by content ID",
        "tags": [
          "Proof Plane"
        ],
        "parameters": [
          {
            "name": "contentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Content identifier (31-char hash)"
          }
        ],
        "responses": {
          "200": {
            "description": "Content chain terminal state (the operation log is served by /proof/v1/content/{contentId}/log)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentChainResponse"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/content/{contentId}/blob/{ref}": {
      "put": {
        "operationId": "uploadBlob",
        "summary": "Upload a content blob",
        "description": "Upload raw bytes for a document referenced by a content chain operation.\nRequires an identity proof carrying `jti` (this is a write-shaped route).\nThe proven DID must be the chain creator or the signer of the referenced\noperation. For PUT, `ref` MUST be the operation CID whose `documentCID`\nthis blob satisfies.\n",
        "tags": [
          "Content Plane"
        ],
        "security": [
          {
            "IdentityProof": []
          }
        ],
        "parameters": [
          {
            "name": "contentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "MUST be the CID of the content operation whose documentCID this blob satisfies"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Blob stored",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status",
                    "contentId",
                    "documentCID",
                    "operationCID"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "stored"
                      ]
                    },
                    "contentId": {
                      "type": "string"
                    },
                    "documentCID": {
                      "type": "string"
                    },
                    "operationCID": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Replayed request — the proof's jti was already seen inside its freshness window",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Blob body exceeds the configured maximum",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      },
      "get": {
        "operationId": "downloadBlobAtRef",
        "summary": "Download a content blob at a specific operation",
        "description": "Download the raw bytes of the document committed by a specific operation.\nThe ref parameter is an operation CID within the chain. Anonymous access\nis legal when a standing public-read grant authorizes it AND the ref\nresolves to the chain's current head document; a public (`aud: \"*\"`)\ngrant never covers a superseded document, stored or presented in\n`X-Credential`. Otherwise the creator presents an identity proof alone\nand a non-creator presents an identity proof plus a DFOS read credential\nin `X-Credential` whose audience names the requester.\n",
        "tags": [
          "Content Plane"
        ],
        "security": [
          {},
          {
            "IdentityProof": []
          },
          {
            "IdentityProof": [],
            "Credential": []
          }
        ],
        "parameters": [
          {
            "name": "contentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Operation CID within the chain"
          }
        ],
        "responses": {
          "200": {
            "description": "Blob data",
            "headers": {
              "X-Document-CID": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/content/{contentId}/blob": {
      "get": {
        "operationId": "downloadBlob",
        "summary": "Download a content blob at head",
        "description": "Download the raw bytes of the current document at chain head.\nAnonymous access is legal when a standing public-read grant authorizes\nit. Otherwise an identity proof is required (the AuthN half), and\nnon-creators must also present a DFOS read credential in `X-Credential`\n(the AuthZ half). A read-shaped proof carries no `jti`.\n",
        "tags": [
          "Content Plane"
        ],
        "security": [
          {},
          {
            "IdentityProof": []
          },
          {
            "IdentityProof": [],
            "Credential": []
          }
        ],
        "parameters": [
          {
            "name": "contentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Blob data",
            "headers": {
              "X-Document-CID": {
                "schema": {
                  "type": "string"
                },
                "description": "The documentCID of the returned blob"
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/proof/v1/log": {
      "get": {
        "operationId": "getLog",
        "summary": "Paginated global log of all accepted operations",
        "description": "Returns every operation the relay has accepted — across all identity and\ncontent chains, plus countersignatures — in acceptance order.\nCursor-based pagination. Used by peer relays to background-sync. Available\nonly when the relay advertises the `log` capability; otherwise returns 501.\n",
        "tags": [
          "Proof Plane"
        ],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "CID cursor — start after this operation CID"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Global log entries",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "entries",
                    "next",
                    "cursor"
                  ],
                  "properties": {
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "cid",
                          "jwsToken",
                          "kind",
                          "chainId"
                        ],
                        "properties": {
                          "cid": {
                            "type": "string"
                          },
                          "jwsToken": {
                            "type": "string"
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "identity-op",
                              "content-op",
                              "artifact",
                              "countersign",
                              "revocation",
                              "credential"
                            ]
                          },
                          "chainId": {
                            "type": "string",
                            "description": "Chain identifier (DID or contentId)"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "CID to pass as `after`, or null when the page was not full"
                    },
                    "cursor": {
                      "type": "string",
                      "nullable": true,
                      "deprecated": true,
                      "description": "Deprecated alias of `next`; removed in the next minor release"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid relay-local cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/NotImplemented"
          }
        }
      }
    },
    "/proof/v1/identities/{did}/log": {
      "get": {
        "operationId": "getIdentityLog",
        "summary": "Paginated log of identity chain operations",
        "description": "Returns operations belonging to this identity chain in chain order.\nCursor-based pagination.\n",
        "tags": [
          "Proof Plane"
        ],
        "parameters": [
          {
            "name": "did",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "DID of the identity"
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "CID cursor — start after this operation CID"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Identity chain log entries",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "entries",
                    "next",
                    "cursor"
                  ],
                  "properties": {
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "cid",
                          "jwsToken"
                        ],
                        "properties": {
                          "cid": {
                            "type": "string"
                          },
                          "jwsToken": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "CID to pass as `after`, or null when the page was not full"
                    },
                    "cursor": {
                      "type": "string",
                      "nullable": true,
                      "deprecated": true,
                      "description": "Deprecated alias of `next`; removed in the next minor release"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid relay-local cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/proof/v1/content/{contentId}/log": {
      "get": {
        "operationId": "getContentLog",
        "summary": "Paginated log of content chain operations",
        "description": "Returns operations belonging to this content chain in chain order.\nCursor-based pagination.\n",
        "tags": [
          "Proof Plane"
        ],
        "parameters": [
          {
            "name": "contentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Content identifier (31-char hash)"
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "CID cursor — start after this operation CID"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Content chain log entries",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "entries",
                    "next",
                    "cursor"
                  ],
                  "properties": {
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "cid",
                          "jwsToken"
                        ],
                        "properties": {
                          "cid": {
                            "type": "string"
                          },
                          "jwsToken": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "CID to pass as `after`, or null when the page was not full"
                    },
                    "cursor": {
                      "type": "string",
                      "nullable": true,
                      "deprecated": true,
                      "description": "Deprecated alias of `next`; removed in the next minor release"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid relay-local cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/proof/v1/countersignatures/{cid}": {
      "get": {
        "operationId": "getCountersignaturesByCID",
        "summary": "Get countersignatures targeting any CID",
        "description": "Countersignatures targeting any countersignable CID — operations AND\nartifacts. Cursor-paginated. Returns 404 only when the CID is not a\nknown operation and no countersignatures target it.\n",
        "tags": [
          "Proof Plane"
        ],
        "parameters": [
          {
            "name": "cid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "CIDv1 of the countersigned target (operation or artifact)"
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Cursor — start after this countersignature CID (from a prior page's next)"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum rows to return; values above 1000 are clamped"
          }
        ],
        "responses": {
          "200": {
            "description": "Countersignatures page",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "countersignatures",
                    "next"
                  ],
                  "properties": {
                    "countersignatures": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "cid",
                          "jwsToken"
                        ],
                        "properties": {
                          "cid": {
                            "type": "string",
                            "description": "CID of the countersignature itself"
                          },
                          "jwsToken": {
                            "type": "string",
                            "description": "JWS compact serialization (witness signature)"
                          }
                        }
                      }
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "Cursor for the next page (pass as `after`), or null on the last page"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "IdentityProof": {
        "type": "http",
        "scheme": "DFOS",
        "x-dfos-typ": "did:dfos:identity-proof",
        "description": "An identity proof — `Authorization: DFOS <did:dfos:identity-proof JWS>`.\nThe scheme token is `DFOS`, matched case-insensitively; it is deliberately\nNOT `Bearer`, because nothing carried here is a bearer token. The proof\nbinds one exact request (method, the relay's own configured authority,\norigin-form path, body hash) inside a freshness window the relay owns, and\nresolves the signer's key against CURRENT identity state. On a write-shaped\nroute (blob upload, operation ingestion) the proof MUST also carry a `jti`\nmember, recorded in the relay's replay cache.\n"
      },
      "Credential": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Credential",
        "description": "A DFOS credential JWS presented in the `X-Credential` header — the AuthZ\nhalf of the relay's split. `apiKey` is OpenAPI's honest generic type for\n\"a token in a named header\"; nothing carried here is a bearer artifact —\nthe possession claim lives entirely in the identity proof this scheme is\nANDed with, and a credential without its proof authorizes nothing. The\nrelay serves no request-proof (`did:dfos:request-proof`) route, so this\nscheme appears only in the identity-proof + credential combination.\n"
      }
    },
    "schemas": {
      "SigningDepositResponse": {
        "type": "object",
        "required": [
          "cid",
          "expiresAt"
        ],
        "properties": {
          "cid": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SigningMailboxResponse": {
        "type": "object",
        "required": [
          "requests",
          "next"
        ],
        "properties": {
          "requests": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "cid",
                "request",
                "depositedAt",
                "declined"
              ],
              "properties": {
                "cid": {
                  "type": "string"
                },
                "request": {
                  "type": "string"
                },
                "depositedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "declined": {
                  "type": "boolean"
                }
              }
            }
          },
          "next": {
            "type": "string",
            "nullable": true,
            "description": "Opaque cursor to pass as `after`, or null when the page was not full"
          }
        }
      },
      "SigningStoredResponse": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "stored"
            ]
          }
        }
      },
      "SigningResponseStatus": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "status"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "pending"
                ]
              }
            }
          },
          {
            "type": "object",
            "required": [
              "status"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "declined"
                ]
              }
            }
          },
          {
            "type": "object",
            "required": [
              "status",
              "response"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "responded"
                ]
              },
              "response": {
                "type": "string"
              }
            }
          }
        ]
      },
      "IngestionResult": {
        "type": "object",
        "required": [
          "cid",
          "status"
        ],
        "properties": {
          "cid": {
            "type": "string",
            "description": "CID of the operation"
          },
          "status": {
            "type": "string",
            "enum": [
              "new",
              "duplicate",
              "rejected"
            ]
          },
          "error": {
            "type": "string",
            "description": "Error message if rejected"
          },
          "kind": {
            "type": "string",
            "enum": [
              "identity-op",
              "content-op",
              "artifact",
              "countersign",
              "revocation",
              "credential"
            ]
          },
          "chainId": {
            "type": "string",
            "description": "Chain identifier (DID or contentId)"
          },
          "revokedGrant": {
            "type": "object",
            "required": [
              "wildcard",
              "contentIds"
            ],
            "description": "Revoked public grant scope; omitted when the credential was not held",
            "properties": {
              "wildcard": {
                "type": "boolean"
              },
              "contentIds": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "dependencyMissing": {
            "type": "boolean",
            "description": "True when rejection is retryable because a dependency is missing"
          }
        }
      },
      "StoredOperation": {
        "type": "object",
        "required": [
          "cid",
          "jwsToken",
          "chainType",
          "chainId"
        ],
        "properties": {
          "cid": {
            "type": "string"
          },
          "jwsToken": {
            "type": "string"
          },
          "chainType": {
            "type": "string",
            "enum": [
              "identity",
              "content",
              "artifact",
              "countersign",
              "revocation",
              "credential"
            ]
          },
          "chainId": {
            "type": "string"
          }
        }
      },
      "IdentityChainResponse": {
        "type": "object",
        "required": [
          "did",
          "headCID",
          "state"
        ],
        "properties": {
          "did": {
            "type": "string"
          },
          "headCID": {
            "type": "string",
            "description": "CID of the current head operation"
          },
          "state": {
            "type": "object",
            "description": "Verified terminal state. The three key arrays are EFFECTIVE state — the key-role memberships a possession proof admitted — so a key the chain declared but nothing ever proved does not appear in them and does not resolve. The optional declared / voidKeys / provedKeys / seenKeys members carry the rest of the picture; a relay MAY omit them.",
            "required": [
              "did",
              "isDeleted",
              "authKeys",
              "assertKeys",
              "controllerKeys",
              "services"
            ],
            "properties": {
              "did": {
                "type": "string"
              },
              "isDeleted": {
                "type": "boolean"
              },
              "authKeys": {
                "type": "array",
                "description": "Effective authentication keys.",
                "items": {
                  "$ref": "#/components/schemas/MultikeyPublicKey"
                }
              },
              "assertKeys": {
                "type": "array",
                "description": "Effective assertion keys.",
                "items": {
                  "$ref": "#/components/schemas/MultikeyPublicKey"
                }
              },
              "controllerKeys": {
                "type": "array",
                "description": "Effective controller keys.",
                "items": {
                  "$ref": "#/components/schemas/MultikeyPublicKey"
                }
              },
              "declared": {
                "type": "object",
                "description": "What the chain's head operation SAYS, void memberships included. Structural state — never a resolution basis.",
                "required": [
                  "authKeys",
                  "assertKeys",
                  "controllerKeys"
                ],
                "properties": {
                  "authKeys": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/MultikeyPublicKey"
                    }
                  },
                  "assertKeys": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/MultikeyPublicKey"
                    }
                  },
                  "controllerKeys": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/MultikeyPublicKey"
                    }
                  }
                }
              },
              "voidKeys": {
                "type": "array",
                "description": "Declared key-role memberships no possession proof admitted, and therefore absent from effective state. Empty on a fully-proved chain. Served so a controller can DISCOVER that a key they added does not resolve — a chain that verifies and a key that is not there is otherwise invisible to them. A void membership never invalidates the operation that declared it or the chain.",
                "items": {
                  "type": "object",
                  "required": [
                    "key",
                    "role",
                    "operationCID"
                  ],
                  "properties": {
                    "key": {
                      "$ref": "#/components/schemas/MultikeyPublicKey"
                    },
                    "role": {
                      "type": "string",
                      "enum": [
                        "auth",
                        "assert",
                        "controller"
                      ]
                    },
                    "operationCID": {
                      "type": "string",
                      "description": "CID of the operation whose declaration is unproved."
                    }
                  }
                }
              },
              "provedKeys": {
                "type": "object",
                "description": "HAS-EVER-PROVED — the union of every effective key state this chain has held. Monotonic: a key proved into a role and later rotated out stays, because the fact it names is that possession was once demonstrated. This is the basis for verifying long-lived artifacts across a rotation, and the basis of the key= reverse index on /index/v0/identities.",
                "required": [
                  "authKeys",
                  "assertKeys",
                  "controllerKeys"
                ],
                "properties": {
                  "authKeys": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/MultikeyPublicKey"
                    }
                  },
                  "assertKeys": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/MultikeyPublicKey"
                    }
                  },
                  "controllerKeys": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/MultikeyPublicKey"
                    }
                  }
                }
              },
              "seenKeys": {
                "type": "array",
                "description": "HAS-EVER-BEEN-DECLARED, as a key-id-to-material binding: one entry per key id this chain has ever written, carrying the Multikey that id went in with, in first-seen order. A key id is bound to one key for the life of a chain — an operation that re-points an existing id at new material is rejected — and this is the binding a verifier extending the chain one operation at a time enforces without re-walking the log.",
                "items": {
                  "$ref": "#/components/schemas/MultikeyPublicKey"
                }
              },
              "services": {
                "type": "array",
                "description": "Resolved discovery vocabulary (controller-signed). Each entry has a common envelope {id, type}; recognized types DfosRelay and ContentAnchor carry type-specific fields. The namespace is open — unrecognized types are preserved verbatim.",
                "items": {
                  "type": "object",
                  "required": [
                    "id",
                    "type"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          }
        }
      },
      "ContentChainResponse": {
        "type": "object",
        "required": [
          "contentId",
          "genesisCID",
          "headCID",
          "state"
        ],
        "properties": {
          "contentId": {
            "type": "string"
          },
          "genesisCID": {
            "type": "string"
          },
          "headCID": {
            "type": "string"
          },
          "state": {
            "type": "object",
            "required": [
              "contentId",
              "genesisCID",
              "headCID",
              "isDeleted",
              "currentDocumentCID",
              "length",
              "creatorDID"
            ],
            "properties": {
              "contentId": {
                "type": "string"
              },
              "genesisCID": {
                "type": "string"
              },
              "headCID": {
                "type": "string"
              },
              "isDeleted": {
                "type": "boolean"
              },
              "currentDocumentCID": {
                "type": "string",
                "nullable": true
              },
              "length": {
                "type": "integer"
              },
              "creatorDID": {
                "type": "string"
              }
            }
          }
        }
      },
      "MultikeyPublicKey": {
        "type": "object",
        "required": [
          "id",
          "type",
          "publicKeyMultibase"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "Multikey"
            ]
          },
          "publicKeyMultibase": {
            "type": "string"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Authentication required",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Insufficient permissions",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotImplemented": {
        "description": "Capability not supported by this relay",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Meta",
      "description": "Relay metadata and discovery"
    },
    {
      "name": "Proof Plane",
      "description": "Public routes for signed chain operations and countersignatures"
    },
    {
      "name": "Content Plane",
      "description": "Authenticated routes for content blob storage and retrieval"
    },
    {
      "name": "DID Resolution",
      "description": "DIF Universal Resolver binding — resolve a did:dfos to a W3C DID Document"
    },
    {
      "name": "Revocation Status",
      "description": "Read-only credential revocation status and issuer feeds"
    },
    {
      "name": "Index",
      "description": "Non-authoritative query surface over the relay's current-state projections — discovery hints, verified by the client against the proof plane"
    },
    {
      "name": "Signing Mailbox",
      "description": "Optional ephemeral SIGNING 0.1 request/response courier"
    }
  ]
}
