Official Go software development kit for the Offering Discovery Protocol, the open protocol for discovering Services and navigating their Offerings.
ODP separates Service discovery from catalog discovery. An Agent searches the canonical directory for candidate Services, inspects each Service's live ODP document, and then navigates or searches that Service's Collections and Offerings.
github.com/offering-protocol/odp-go
├── odp Protocol models, validation, identity, references, and pagination
├── agent Agent-oriented discovery and catalog navigation
├── directory Canonical production and sandbox directory client
└── service Service document, catalog operations, and integration helpers
The root import path uses package name odp.
import (
odp "github.com/offering-protocol/odp-go"
"github.com/offering-protocol/odp-go/agent"
"github.com/offering-protocol/odp-go/directory"
"github.com/offering-protocol/odp-go/service"
)Role packages depend toward the root odp package; agent composes directory. The root package
does not depend on role packages, and service does not depend on Agent or directory behavior.
The root package validates wire documents against the exact schemas published by odp-specs, then
decodes them into typed Go values. JSON members permitted by the protocol's additive evolution rules
are preserved in Additional and survive a marshal round trip.
document, err := odp.ParseServiceDocument(body)
if err != nil {
var validation *odp.ValidationError
if errors.As(err, &validation) {
log.Printf("invalid Service Document: %+v", validation.Issues)
}
return err
}
origin, err := odp.DeriveServiceOrigin(serviceDocumentURL)
if err != nil {
return err
}
offeringURL, err := odp.BuildOperationURL(
document.HTTP.EndpointBase,
odp.OperationGetOffering,
origin,
"gpu-a100",
)Pagination uses Go iterators, carries cancellation through context.Context, rejects continuation
loops, and enforces the protocol's 16-page traversal limit.
Service payment descriptors may advertise payment-option labels such as PaymentOptionInflow,
PaymentOptionSolana, or PaymentOptionBase. IsPaymentOption checks the closed ODP vocabulary.
These labels summarize compatibility; live MPP and x402 responses provide the authoritative payment
terms.
for offering, err := range odp.IterateItems(ctx, firstPage, loadPage) {
if err != nil {
return err
}
consume(offering)
}Collection search distinguishes an omitted hierarchy constraint, a root-Collection constraint, and a specific parent:
unconstrained := odp.CollectionSearchRequest{ODPVersion: odp.Version, Query: "desk"}
roots := odp.CollectionSearchRequest{ODPVersion: odp.Version, ParentID: odp.Null[string]()}
children := odp.CollectionSearchRequest{ODPVersion: odp.Version, ParentID: odp.Some("office")}Package directory searches candidate Services through the canonical production directory or its
fixed sandbox environment. It validates cached Service summaries, follows opaque same-origin
continuations, exposes structured facets, and provides keyword suggestions.
directoryClient, err := directory.New(directory.Options{})
if err != nil {
return err
}
for candidate, err := range directoryClient.SearchServices(ctx, directory.SearchRequest{
Filters: &directory.ServiceFilters{
Keywords: []string{"gpu"},
Payments: []directory.PaymentFilter{{
Name: odp.ProtocolMPP,
Options: []odp.PaymentOption{odp.PaymentOptionInflow, odp.PaymentOptionSolana},
}},
},
}, directory.IterationOptions{MaxItems: 20}) {
if err != nil {
return err
}
inspect(candidate.ServiceOrigin)
}See the directory package guide for page traversal, suggestions, and sandbox usage.
Package agent inspects live Service Documents and provides validated, lazy Collection and Offering
navigation. Its federated discovery client searches candidate Services through directory, queries
their catalogs with bounded concurrency, and emits results in directory order.
Run the small Service and Agent examples in separate terminals:
go run ./examples/odp-service-small
go run ./examples/odp-agent-discoveryThe Agent example uses a clearly labeled mock directory and performs live inspection, listing, and full Offering retrieval against every reachable configured Service. See the Agent package guide for caching, transport composition, and API usage.
Package service implements the ODP HTTP runtime for Go's standard net/http stack. Small Services
can use its validated static catalog; large Services provide storage-backed operation functions.
Optional functions directly control the operations advertised by the Service Document.
Run the complete small-Service example with:
go run ./examples/odp-service-smallSee the Service package guide and runnable example.
Go 1.25 or newer is required. Run the complete merge gate with:
make verifyWhen an odp-specs checkout is available, verify the bundled schemas and conformance vectors with
ODP_SPECS_DIR=/path/to/odp-specs make spec-sync. Continuous integration runs both gates.
Generate Agent and Service conformance reports with:
ODP_SPECS_DIR=/path/to/odp-specs make conformanceThe language-neutral harness executes the module's public behavior and writes release evidence to
.conformance/reports/.
Run the Go Agent against the Node.js reference Service with:
ODP_NODE_DIR=/path/to/odp-node make interoperabilityVersion tags publish a GitHub release after the complete verification, clean consumer-module, and shared conformance gates pass. Each release includes its Agent and Service conformance reports.
See DEVELOPMENT.md for the contributor workflow and
odp-specs for the normative draft, schemas,
examples, and test vectors.
See SECURITY.md for vulnerability reporting.
MIT.