# OpenMerch -- llms-full.txt Last verified against source: 2026-04-04 Status: Pre-launch. Curated onboarding and no-custody execution flows are implemented. SDK package metadata exists in source; npm publication is still pending. Provider activation is operator-gated. OpenMerch does not yet publish a stable public service catalog. --- ## 1. What OpenMerch Is OpenMerch is a discovery, routing, and execution coordination layer for machine-sellable services, built above MPP. MPP handles machine payment negotiation and receipts. OpenMerch handles service discovery, ranking, execution orchestration, usage metering, provider onboarding, and provider-side fee collection. Agents query available services, rank candidates, execute work, and handle MPP 402 payment challenges when needed. Providers register services, expose execution endpoints, validate readiness, and settle accrued platform fees. OpenMerch does not process payments or hold funds. When a provider requires payment, OpenMerch stores and relays the MPP 402 challenge to the agent. The agent pays the provider directly. OpenMerch forwards the paid retry to the provider and returns the result to the agent. The platform collects fees from providers (not agents) as a percentage of routed execution value. In the current Phase 0 configuration, fees are computed and logged but enforced at 0%. --- ## 2. What OpenMerch Is Not - Not the payment protocol itself. That is MPP. OpenMerch coordinates above it. - Not a broad open marketplace today. Provider onboarding is curated and operator-gated. Self-serve listing is not yet available. - Not a generic SDK package. The real packages are `@openmerch/agent` and `@openmerch/provider`. There is no `@openmerch/sdk` package. - Not custodial. The approved production direction is no-custody. OpenMerch should not be described as controlling customer funds, holding pooled balances, or intermediating provider payouts. The codebase contains wallet, reservation, and funding scaffolding for dev/test flows. Those pieces should not be treated as the long-term money model. - The marketing site provides a high-level overview. For exact endpoints, request/response shapes, and integration details, use the OpenAPI spec and SDK source. --- ## 3. Current State As of the current implementation: - Sync, async, and streaming execution paths are implemented - MPP 402 challenge proxying is implemented for execution - Payment-aware discovery is implemented in OMQL - Provider-side fee collection via MPP 402 negotiation is implemented - Curated provider onboarding with automated validation is implemented - TypeScript agent and provider SDKs exist in source at version 0.2.0 - SDK publishing to npm is still listed as remaining work - A public OpenAPI 3.1 spec is available Current-state caveats: - Package metadata exists for @openmerch/agent and @openmerch/provider, but npm publication is not yet confirmed - GET /v1/wallet and POST /v1/wallet/fund exist, but wallet funding is explicitly described in source as MVP or dev-mode scaffolding - A stable public service catalog is not yet published --- ## 4. Public API Surface Authentication: API keys with `om_live_` prefix, sent via `X-OpenMerch-Key` header. Operator/admin routes use `X-Operator-Key`. `Authorization` header is reserved for MPP `Payment` credentials on paid retries and fee settlement flows. Unauthenticated endpoints: - GET /v1/services -- list active services, supports ?category= filter - GET /v1/services/{serviceID} -- service detail - POST /v1/query -- OMQL service discovery - POST /v1/providers/register -- register a new provider org, returns API key Agent-authenticated endpoints: - POST /v1/execute -- execute a service (sync, async, or streaming mode). An unpaid execution attempt can return HTTP 402; the provider challenge is relayed through OpenMerch. A successful MPP-paid execution can include a Payment-Receipt header. - GET /v1/executions/{executionID} -- execution status and result - POST /v1/executions/{executionID}/cancel -- cancel an execution - GET /v1/wallet -- agent wallet balance and reserved amount - POST /v1/wallet/fund -- fund agent wallet (MVP/dev scaffolding only; not the production payment model) Provider-authenticated endpoints (pending or active status): - POST /v1/services/register -- register a service from manifest - GET /v1/providers/me -- provider self-view with services and readiness summary - GET /v1/providers/me/services -- list provider's own services with validation status - POST /v1/services/{serviceID}/validate -- run automated validation checks - POST /v1/providers/me/request-activation -- signal readiness for operator review Provider-authenticated endpoints (active status only): - POST /v1/executions/{executionID}/complete -- async execution completion callback with result and units_used - POST /v1/executions/{executionID}/fail -- async execution failure callback - GET /v1/fees/balance -- fee account summary (total accrued, settled, outstanding) - POST /v1/fees/settle -- settle outstanding fees via MPP 402 negotiation Operator/admin endpoints exist under /internal/* for operator use. Authenticated via X-Operator-Key when OPERATOR_KEY is set; open in dev mode when the env var is unset. Execution modes: - sync -- platform proxies to provider, waits for response, returns 200 - async -- platform returns 202, provider calls back to complete or fail - streaming -- platform relays SSE stream from provider with budget cap Health probes: GET /healthz (liveness), GET /readyz (readiness). Full specification: OpenAPI 3.1 spec (api/openapi.yaml). --- ## 5. Agent Integration Package: @openmerch/agent v0.2.0 Package metadata exists in source; npm publication is still pending. Primary class: OpenMerchAgent Real example from the SDK README: import { OpenMerchAgent } from "@openmerch/agent"; const agent = new OpenMerchAgent({ baseUrl: "http://localhost:8080", apiKey: process.env.OPENMERCH_API_KEY!, }); const { candidates } = await agent.discover({ query_version: "omql/v0.1", task: { type: "service", category: "llm" }, preferences: { optimize_for: "cheapest" }, }); const result = await agent.execute({ service_id: candidates[0].service_id, payload: { messages: [{ role: "user", content: "Hello" }] }, max_cost: 500000, idempotency_key: `task-${Date.now()}`, }); Constructor accepts AgentConfig: - baseUrl -- OpenMerch platform URL - apiKey -- agent API key (om_live_...) - retries -- retry count for 502/504 (default: 0) - timeoutMs -- request timeout in milliseconds - paymentHandlers -- array of MPP 402 payment handlers, each with a method string and a pay(challenge) function returning a credential - preferredMethods -- preferred payment method ordering for challenges - maxPaymentRetries -- max 402 negotiation attempts (default: 3) Methods: - discover(request) -- OMQL query via POST /v1/query. Auto-injects supported_methods and preferred_methods from configured payment handlers. - getService(serviceId) -- single service lookup - execute(options) -- sync or async execution with transparent MPP 402 negotiation when paymentHandlers are configured - executeStream(options) -- streaming execution returning an async iterator over SSE events. Handles MPP 402 before stream begins. - runTask(options) -- discover via OMQL, take the top-ranked candidate, execute against it. No failover to candidate[1]. - getExecution(executionId) -- check execution state - cancelExecution(executionId) -- cancel an executing or reserved execution - pollExecution(executionId, intervalMs?, timeoutMs?) -- poll an async execution until it reaches a terminal state - getWallet() -- get wallet balance (dev scaffolding) - fund(amount) -- deprecated MVP stub. In the MPP model, agents pay providers directly. Request and response fields use snake_case to match backend JSON. Retry is opt-in, limited to 502/504 gateway errors. 402 responses are MPP negotiation, handled separately. Do not assume a package named @openmerch/sdk or methods named bestRoute() or similar convenience APIs that do not exist in source. SDK source: sdk/agent-ts/ --- ## 6. Provider Integration Package: @openmerch/provider v0.2.0 Package metadata exists in source; npm publication is still pending. Exports: - OpenMerchProvider -- HTTP server with handler registration - OpenMerchClient -- API client for platform calls - BudgetTracker / BudgetExceededError -- cost tracking for streaming - buildWWWAuthenticateHeaders, parseAuthorizationPayment -- MPP server helpers - parseWWWAuthenticate, selectProviderPaymentHandler -- MPP client helpers (used during fee settlement) Real example from the SDK README: import { OpenMerchProvider, type ServiceManifest } from "@openmerch/provider"; const manifest: ServiceManifest = { name: "my-service", category: "utility", pricingType: "per_unit", pricingUnit: "request", pricePerUnit: 10000, executionModes: ["sync"], }; const provider = new OpenMerchProvider(manifest, { openMerchBaseUrl: "http://localhost:8080", apiKey: process.env.PROVIDER_API_KEY!, port: 3000, }); provider.onExecute(async (ctx) => { return { output: { result: "hello" }, unitsUsed: 1 }; }); await provider.start(); OpenMerchProvider constructor takes ServiceManifest, ProviderConfig, and optional PaymentGateConfig. Manifest declares payment methods but PaymentGateConfig must also be provided (and vice versa). Handlers: - onExecute(handler) -- sync and async execution. Receives ExecutionContext (executionId, mode, payload, maxCost, timeoutMs). Returns { output, unitsUsed }. - onStream(handler) -- streaming. Receives ExecutionContext and StreamWriter (writeChunk, done, error). start() exposes: - GET /openmerch/health - GET /openmerch/capabilities - POST / for execution OpenMerchClient methods: - registerService(manifest, executionEndpoint) - completeExecution(executionId, output, unitsUsed) - failExecution(executionId, error) - getFeeSummary() - settleBalance(options?) -- settles outstanding fees with automatic MPP 402 negotiation. Accepts paymentHandlers and preferredMethods. For MPP-capable services, the source-level pattern is: declare manifest.payment.methods, supply a PaymentGateConfig, issue HTTP 402 on unpaid requests, validate Authorization: Payment on paid retries, and optionally emit Payment-Receipt headers. The SDK exposes lower-level MPP helpers for header construction and parsing. Do not assume higher-level helpers unless they are present in the source you are integrating against. Key types: ServiceManifest, ProviderConfig, ExecutionContext, ExecutionResult, StreamWriter, FeeSummary, SettleBalanceOptions, SettleBalanceResult, PaymentGateConfig, PaymentMethodDeclaration. SDK source: sdk/provider-ts/ --- ## 7. Provider Onboarding Flow OpenMerch is curated-first. Registration alone does not make a provider or service publicly routable. Flow: 1. Provider registers via POST /v1/providers/register (unauthenticated). Creates a provider record with status "pending". Returns an API key (shown once). 2. Provider registers services via POST /v1/services/register (provider-authenticated). Each service starts with status "inactive". Required fields: name, category, execution_endpoint. Optional: payment_methods array (each with method and intent). When payment_methods is non-empty, the service's payment_mode is derived as "mpp" (otherwise defaults to "custody"). 3. Provider runs automated validation via POST /v1/services/{serviceID}/validate. Checks include: healthcheck reachability, sample sync execution, sample streaming execution when relevant, payment method checks for MPP services. Results persisted per service as pass or fail. 4. Provider checks readiness via GET /v1/providers/me. Returns a deterministic readiness summary with one of six states: missing_services, validation_required, validation_failed, ready_to_request, activation_requested, active. 5. Provider signals readiness via POST /v1/providers/me/request-activation. Requires all services validated and passing. 6. Operator reviews pending providers and activates via admin endpoints. Provider transitions from "pending" to "active". Services must also be individually activated before they become discoverable and routable. Suspension and reactivation are implemented for both providers and services. --- ## 8. Payments and MPP OpenMerch is built above MPP and implements a no-custody payment model. All monetary values use microcents as BIGINT: - 1 cent = 10,000 microcents - $1.00 = 10,000,000 microcents - No floating point in financial paths Execution payment flow: 1. Agent calls POST /v1/execute with service_id, payload, max_cost, and idempotency_key. 2. Platform proxies the request to the provider's execution_endpoint. 3. If the provider requires payment, it returns HTTP 402 with WWW-Authenticate challenge headers. 4. Platform stores the challenge and relays the 402 response to the agent. 5. Agent SDK auto-negotiates payment using configured paymentHandlers. 6. Agent retries with Authorization: Payment header. 7. Platform forwards the paid retry to the provider. 8. Provider returns the result. A successful paid response can include a Payment-Receipt header. This flow works across all three execution modes (sync, async, streaming). Fee model: Fees are provider-side, following a Stripe-style take rate. Providers pay OpenMerch; agents have no financial relationship with OpenMerch in V1. Agents pay only providers, via MPP. Fee resolution uses 4-level precedence: - Transaction-level override (highest) - Provider-level override - Service-level override - Global default (lowest) Phase 0 configuration: 0% fee rate, shadow mode. Fees are computed and logged but $0 is enforced. When enforcement is enabled, fees accrue as receivables per execution. Fee settlement: providers settle outstanding fees via POST /v1/fees/settle, which uses the same MPP 402 negotiation pattern. The production-grade settlement verifier in source is "onchain" (ERC-20 USDC transfer verification). A "platform" verifier exists for dev/test only. Wallet caveat: GET /v1/wallet and POST /v1/wallet/fund remain in the API. The agent SDK explicitly labels fund() as deprecated MVP scaffolding. Treat those as current API surface, not as the definitive long-term payment architecture. --- ## 9. OMQL OMQL is a JSON query envelope, not a string DSL. Canonical query version: omql/v0.1 Example: { "query_version": "omql/v0.1", "task": { "type": "service", "category": "llm" }, "constraints": { "max_price": 50000 }, "filters": { "latency_class": "fast" }, "preferences": { "optimize_for": "cheapest" }, "payment": { "supported_methods": ["tempo", "lightning"], "preferred_methods": ["tempo"] } } Filter fields: - category -- service category (e.g., "llm", "embedding") - tags -- array match - max_price -- maximum price per unit in microcents - latency_class -- "fast", "medium", "slow" - region -- deployment region - execution_mode -- "sync", "async", "streaming" Post-filters (applied after SQL): - excluded_providers - pricing_unit Payment filters: - supported_methods -- hard filter, only services supporting at least one - payment_mode_filter -- "mpp" or "custody" - preferred_methods -- ranking tie-breaking, capability-gated Ranking modes: cheapest, fastest, balanced (configurable weights). Ranking incorporates reputation scores and health status. Deterministic tie-breaking: score DESC, price ASC, service_id ASC. Responses can include payment_compatible and matched_payment_methods annotations per candidate. --- ## 10. Catalog Status OpenMerch does not currently publish a stable verified public catalog. Public provider and service availability remains curated until launch criteria are met. A stable verified catalog is not yet available. --- ## 11. Canonical References - Website: https://openmerch.dev/ - MPP reference: https://mpp.dev/llms.txt - MPP full reference: https://mpp.dev/llms-full.txt - OpenAPI spec: api/openapi.yaml - Agent SDK: sdk/agent-ts/ - Provider SDK: sdk/provider-ts/ SDK packages (@openmerch/agent, @openmerch/provider) have package metadata and READMEs in source. npm publication is pending scope access. For current implementation details, prefer the SDK source. Use the OpenAPI spec as the authoritative reference for technical integration details.