Appendix B - Protocol and API Reference

This appendix provides rules for reading and implementing the interfaces. Paths, fields, and statuses are cross-checked against each node’s service entry points, oan-protocol-common/schemas/agent-contract/openapi.yaml, the frontend and backend API wrappers on the official website, and actual deployment configuration; capabilities declared only in the common contract must not be written as if they were exposed by all nodes. Interface changes must be associated with the protocol version, error pattern, authentication method, idempotency rules, and the change record in Chapter 24.

B.1 Endpoint Catalog

The endpoint catalog lists health, DID, resource registration, Root platform publication, content distribution, discovery, governance status, and statistics interfaces by service role, and distinguishes public entry points, node-to-node entry points, internal-only entry points, and deployment prefixes. The official website currently forwards some registration and discovery requests through a same-origin backend; the nodes themselves also expose independent service endpoints, so website paths cannot automatically be inferred as protocol paths for all nodes. Example base URLs use placeholders and do not hard-code the website’s current domain or a particular server address as a protocol requirement; each row records at least the call direction, HTTP method, authentication, request/response pattern, failure behavior, and version. The table below lists only representative entry points that can be verified in the current code; management, statistics, and debugging interfaces not listed here remain subject to the routes of their corresponding nodes.

Service role Call direction, method, and path Authentication boundary Main returns
Registrar node Client -> Registrar node: POST /resources/register; Client -> Registrar node: GET /registrar/status, GET /registrar/did The registration endpoint receives a resource control proof; node-to-node forwarding to the Root platform uses node-to-node signatures Registration VC, acceptance status, Root platform response
Root platform Registrar node -> Root platform: POST /root/resources/verify-and-publish; Client or node -> Root platform: GET /root/resources/{did}, GET /root/status Publication writes are limited to authorized nodes or administrative calls; public reads depend on deployment Root proof, resource version, status, and cursor
content distribution platform Root platform or publisher -> content distribution platform: POST /cdn/resources, POST /cdn/resources/batch; Client or node -> content distribution platform: GET /cdn/resources/{did}, GET /cdn/resources/index Publication uses node-to-node authentication; resource reads and index reads depend on deployment ResourcePackage, index entries, synchronization status
Discovery node Client -> Discovery node: POST /discovery/resources/query; Node or operations personnel -> Discovery node: GET /discovery/index/resources/{did}, GET /discovery/status Queries may be public; management and synchronization interfaces are restricted Resource results, source, and proof references
Operations API Operations personnel -> node: GET /health and node status, metrics, and audit interfaces Operations authentication and network boundary Status summary, without secrets

The correspondence between core payload types and endpoints is as follows. When shared types come from oan-protocol or oan-package, field names follow the JSON mapping of serde; Value represents a dynamic response in the current implementation and cannot be used to infer a fixed schema that does not exist.

Endpoint Request JSON type Response type or main fields Notes
POST /resources/register ResourceRegistrationSubmission Dynamic JSON: registration status, resource DID, registration VC, Root platform response /resources/submit is bound to the same handler
POST /root/resources/verify-and-publish ResourceVerifyAndPublishRequest Dynamic JSON: resource-verified-and-queued, version, three categories of hashes, and CDN queue status Node-to-node call limited to authorized Registrar nodes
POST /cdn/resources ResourceCdnPublishRequest Dynamic JSON: published, version, and publication cursor ResourcePackage must pass Root platform source and hash validation
POST /discovery/resources/query ResourceDiscoveryQuery ResourceDiscoveryResponse limit defaults to 10, versionMode defaults to latest
POST /discovery/query/explain ResourceDiscoveryQuery Dynamic explanation JSON Not equivalent to a normal discovery response
GET /cdn/resources/{did} Path parameter did ResourcePackage Reads a ResourcePackage directly
POST /cdn/resources/batch-get Local ResourceBatchGetRequest requestedCount, foundCount, items The request body contains a resourceDids array

B.2 Request Header Fields and Signatures

Request headers and signature materials are defined by the interface profile. The current node-to-node SignedRequestEnvelope uses JSON fields such as requestId, protocolVersion, purpose, method, path, aud, requestTimestamp, requestNonce, bodyHash, and proof to carry signature semantics; the browser-facing public registration and discovery entry points on the official website must not arbitrarily add a set of required X-OAN-* headers that are not defined at the service entry point. If the interface uses a protocol envelope to carry this information, the JSON fields take precedence; if the deployment layer additionally uses HTTP headers, they may only be documented as deployment-profile details. The server must validate the normalized request covered by the signature, the target DID, the time window, and the nonce; it must reject missing, expired, replayed, or misdirected requests.

The roles of node-to-node protocol envelope fields can be checked against the table below. method and path bind the protected HTTP request, aud binds the recipient, and bodyHash binds the request body; together, these fields prevent a valid proof issued by one node from being moved to another request. When a browser submits a resource, the resource control proof is located in the request body’s subjectControlProof; it must not be mistakenly written as a node-to-node HTTP header.

Field Purpose Validation focus
requestId Identifies one node-to-node request Used for log correlation; cannot replace replay protection
protocolVersion, purpose Identifies the protocol version and call purpose Must match the profile allowed by the receiving interface
method, path, aud Binds the HTTP method, path, and recipient Must not differ from the actual request or target node
requestTimestamp, requestNonce Restricts the time range and prevents reuse Check the clock window and nonce replay cache
bodyHash, proof Binds the request body and provides an integrity proof Recalculate the request-body digest and validate the proof
POST /resources/register
Host: registrar.example
Content-Type: application/json

The upstreamAuth.proof of a node-to-node request should cover the method, normalized path, recipient, timestamp/nonce, content digest, and actual request body; the server should perform the write only after completing the time-window, replay-cache, signer-authorization, and resource-control checks. In a browser registration request, the resource control proof is located in the request body’s subjectControlProof; it is not the same type of credential as node-to-node upstreamAuth.

B.3 Response Header Fields and Cache Directives

A response may provide the source, protocol/mode version, data time, freshness, ETag, cache control, correlation identifier, and necessary security headers when applicable; these fields are not guaranteed to be uniform public response headers across all current node interfaces, and the X-* items below may only serve as deployment-layer or interface-profile extension conventions. An ETag or cache hit only indicates that the content version has not changed; it does not prove that the resource status or governance authorization remains valid. When returning an old snapshot, the response or body should include identifiable time and degradation indicators; caching must not be used to conceal an upstream failure.

Field or directive (when applicable) Purpose Usage notes
ETag Identifies the response content version Does not mean that the governance status is valid
Cache-Control Specifies caching and revalidation policy An old snapshot must also identify its freshness
X-Request-Id Correlates the client, nodes, and logs Must not contain private information
X-OAN-Data-Time Indicates the data generation or collection time Distinguish it from the server response time
X-OAN-Freshness Indicates statuses such as current and stale Must not conceal an upstream failure

B.4 Status Codes and Error Codes

HTTP status codes express transport-layer and generic processing results, while OpenAgenet (OAN) error codes express specific semantics such as field errors, invalid signatures, unauthorized access, not found, duplication, version conflicts, dependency failures, synchronization lag, and internal errors. The current public error-code vocabulary is defined by oan-protocol-common/docs/error-codes.md, including invalid_did_document_structure, invalid_registration_credential, invalid_request_signature, unauthorized_domains, invalid_root_proof, and package_decode_failed; that file defines error semantics but does not bind every error code to a unique HTTP status. Different nodes may map these errors through an HTTP status or response body. Clients should determine whether to retry from the actual error structure; they must not treat every 2xx response as publication success, nor conflate 404, empty results, and synchronization incomplete.

HTTP status OAN error code examples Client action
400 invalid_did_document_structure, invalid_authorized_domains, package_decode_failed Correct the input or ResourcePackage and retry; the specific status depends on the interface implementation
401/403 invalid_request_signature, unauthorized_domains Re-authenticate, use an authorized node, or stop the request
404 Resource-not-found error returned by the node Distinguish not found from an unsynchronized index
409 Duplicate or version-conflict error returned by the node Obtain the current version and process it according to the update rules
429 Deployment-layer rate-limit error Follow the retry indication and back off
5xx Dependency unavailable or internal error Back off and retry only when the interface marks the request as retryable

B.5 Pagination and Cursor Rules

List interfaces use explicit limit, cursor, and sorting rules. Cursors may only be generated and interpreted by the server; clients must not assume that they are readable or modifiable. The current public ResourceDiscoveryQuery type always provides limit, with a default value of 10, but the request model of POST /discovery/resources/query has no cursor field; the Discovery node truncates candidate results according to limit. The interface that actually provides afterCursor, nextCursor, and hasMore is the content distribution platform’s GET /cdn/resources/index; its cursor is not the same type as the discovery query’s limit. Page size should have a deployment limit, and the sort key must remain stable during pagination; expired, invalid, or filter-mismatched cursors should return an error. Publication cursors, synchronization cursors, event cursors, and pagination cursors must not be used interchangeably.

GET /cdn/resources/index?limit=20&afterCursor=1800
Accept: application/json

{
  "items": [],
  "count": 0,
  "afterCursor": 1800,
  "nextCursor": 1800,
  "hasMore": false
}

A pagination cursor only represents the reading position in the content distribution platform’s list; the limit in a discovery query only controls the number of candidate results for that request and does not produce a resumable discovery pagination cursor. Publication sequences, distribution synchronization cursors, and governance event cursors must use the fields and validation rules defined by their respective interfaces.

B.6 Version and Compatibility Header Fields

Protocol versions, resource schema versions, capability declarations, and compatibility policies are expressed through defined protocol envelope fields, request-body fields, or deployment profiles, and remain traceable in requests and responses. Current public protocol constants include oan-resource-2026, while the default value of ResourceDiscoveryQuery.versionMode is latest; such protocol fields must not be directly rewritten as uniform HTTP headers without code support. When the server encounters an unsupported version, it should return an explicit incompatibility result; compatible extensions must not change the semantics of DID, signatures, status, or publication sequences. See Chapter 24 for version selection rules.

{
  "query": "a tool that can search code repositories and summarize project structure",
  "capabilityTags": ["code-search", "project-structure-summary"],
  "versionMode": "latest",
  "limit": 10
}

The example above is a discovery query request for POST /discovery/resources/query; all fields correspond to the current ResourceDiscoveryQuery. protocolVersion belongs to the node-to-node SignedRequestEnvelope and must not be mixed into this query object. The current query model has no unified capabilities field; capability conditions should be expressed through capabilityTags or an extension explicitly supported by the target interface. When the server does not support the requested version, it should return an explicit version-incompatibility error and the range of acceptable versions; clients must not ignore the response-mode version merely because they received an HTTP 2xx response.

B.7 Health, Readiness, and Liveness Response Formats

The common minimum structure of the public /health response across current nodes is HealthResponse: status, nodeType, and an optional node DID. A node status interface may additionally provide database, upstream, synchronization cursor, or error summaries. Operations systems can use this information to distinguish process liveness, dependency readiness, business availability, and data synchronization status, but must not treat every field as a uniform schema present on every node. Passing liveness does not imply readiness, and passing readiness does not imply that registration or discovery smoke tests have passed; sensitive configuration and tokens must not appear in the response.

{
  "status": "ok",
  "nodeType": "discovery",
  "did": "did:oan:INDS:7YpQm9Kx2VnRb6Ts3WfHa4Cd5Ej8LgNz"
}

If the deployment provides an extended status interface, it may add check time, dependency status, and synchronization cursors beyond the minimum response above; extension fields should identify their source and version, and the extended response must not be treated in reverse as the mandatory response structure of /health on every node.

Check type What it proves What it does not represent
liveness The process can still respond Dependency and business availability
readiness The service is ready to receive requests Successful registration or discovery smoke tests
dependency Database, upstream, or off-chain trust indexer status All business paths are functioning normally
smoke test A critical business flow can be completed Long-term performance and full correctness

B.8 Public, Authenticated, and Operations-Only API Matrix

The interface matrix must at least distinguish public read-only interfaces, authenticated publication/registration interfaces, node-to-node interfaces, and operations-only interfaces. Public discovery, DID, status, and necessary statistics may be accessible from the Internet; write, management, database, full-log, detailed access-statistics, and key-related interfaces must be protected by authentication, network boundaries, and auditing. The relay interface of the official website’s backend must not expand downstream service permissions, and ordinary users must not obtain backend statistics or secrets through public interfaces.

Access level Examples Permitted data Protection requirements
Public read-only DID, discovery, necessary status Published ResourcePackages and public proofs Rate limiting, input validation, auditing
Authenticated write Registration, updates, node-to-node synchronization Objects within the authorized scope Signatures, nonce, idempotency, and authorization checks
Operations only Metrics, full logs, administrative operations Internal operational data Strong authentication, network isolation, and least privilege
Prohibited from public access Database, private keys, detailed access statistics Not open to Internet users Must not be leaked through the official website’s relay

Reference Sources

Source Type Link
oan-protocol-common Code repository: protocol types, OpenAPI contract, and error codes https://github.com/wolfbrother/oan-protocol-common
oan-root-services Code repository: Root platform API https://github.com/OpenAgenet/oan-root-services
oan-registrar-node Code repository: registration API https://github.com/OpenAgenet/oan-registrar-node
oan-discovery-node Code repository: discovery API https://github.com/OpenAgenet/oan-discovery-node
oan-sdk-ts Code repository: client API wrappers https://github.com/OpenAgenet/oan-sdk-ts
OAN Resource Identity and Discovery IETF Internet-Draft: resource identity and discovery API https://datatracker.ietf.org/doc/draft-xu-oan-resource-identity-discovery/
Efficient Agent Discovery Profile IETF Internet-Draft: discovery API profile https://datatracker.ietf.org/doc/draft-xu-efficient-agent-discovery-profile/
On this page