# Marketplace

URL: https://docs.hanzo.ai/docs/openapi/marketplace

> The one market between orgs: agents and personas to hire, apps, skills, MCP servers and tools to buy, each sold by the org that owns it, and the two-sided work one org buys from another.

Also for this capability: **API** · [CLI](https://docs.hanzo.ai/docs/cli/marketplace) · [MCP](https://docs.hanzo.ai/docs/mcp-tools/marketplace) · [SDKs](https://docs.hanzo.ai/docs/sdks)

The one market between orgs: agents and personas to hire, apps, skills, MCP servers and tools to buy, each sold by the org that owns it, and the two-sided work one org buys from another.

> [All API references →](https://docs.hanzo.ai/docs/openapi) · [Get started →](https://docs.hanzo.ai/docs/guides)

|                |                                        |
| -------------- | -------------------------------------- |
| **Base URL**   | `https://api.hanzo.ai`                 |
| **Operations** | 23                                     |
| **Auth**       | `Authorization: Bearer $HANZO_API_KEY` |

## Specification

> **HIP-1137 · Marketplace — Listings and Installs** — Draft · [read the specification →](https://github.com/hanzoai/hips/blob/7ed737180339cd05b5f2935eafe7f7b83d2449a2/HIPs/hip-1137-marketplace-listings.md)

`/v1/marketplace` is the shop for tools and agents: browse, install into your
project, publish your own free or priced. It is a thin layer over the unified
tool plane — discovery reads the tool registry, install and uninstall ARE the
registry's activation writes — plus a listing store that says what a tool costs
and which wallet is paid. Marketplace never dispatches a tool and never moves
money itself. It is implemented in `hanzoai/cloud` at `apps/marketplace`
(HIP-0106).

### Motivation

A marketplace that keeps its own installed-tools table drifts from the registry
that actually dispatches, and a price that lives only in one process's memory
is not enforced anywhere else. Both defects were real here: the price table,
the charger and the wallet resolver were process-globals, the fleet runs one
process per app, so in the settling process the table was nil — and reading a
nil table as "nothing is priced" made every listed tool free the moment the
fleet split (`apps/marketplace/marketplace.go:16-30`).

### Specification

The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted
as in RFC 2119.

#### §1 One store, and what is deliberately not in it

The listing store is one encrypted SQLite file, the deployment's own
`marketplace` (`apps/marketplace/store.go:51`), keyed by (publisher\_org, id) —
a publisher only ever mutates its own listings. Installs are NOT in it:
install and uninstall are the tool registry's activation writes for the
caller's (org, project), so there is one store and one truth for what is
active (`apps/marketplace/marketplace.go:8-15`).

#### §2 The address

Six operations under `/v1/marketplace`, all typed: discovery (catalog plus
listing overlay plus installed flag), the caller org's own listings, publish,
unpublish, install, uninstall. A published listing must name a tool that
already resolves in the publisher's own scope, so a listing can never
advertise a capability that does not exist; a priced listing must name the
payout wallet, so a monetized offer is never unpayable; the price is exact to
18 decimal places, so a per-call price below a cent is a real price and not a
rounded-away zero.

#### §3 Money: the table here, the rail elsewhere

Marketplace itself is free (`cloud.Free`, `plugin/marketplace/main.go`). A
monetized listing is enforced per call by the x402 rail, and the enforcement is
four internal-plane operations, each served by the process that owns the
answer: tools asks x402 to settle; x402 asks marketplace what it costs and who
is paid; x402 asks wallets to resolve the payee; x402 asks commerce to credit
it (`apps/marketplace/marketplace.go:32-39`). The in-process seam stays the
fast path where an owner is co-resident; both paths are the same policy and
both fail closed, asserted against each other by a one-process test and a
five-process test (`apps/marketplace/marketplace.go:41-44`).

On the plane, the price answer carries the row's recipient, never a request's:
a buyer that could state either would buy at its own price or redirect the
credit. `priced=false` means FREE and is an ANSWER — an unlisted tool lands
there — while a store failure is an ERROR, because "I could not look it up"
must never read as "it costs nothing" (`apps/marketplace/rpc.go:22-33,47-50`).
The price op reads no tenant and requires none: a price is the shop window,
the same figure for everyone.

#### §4 Tenancy

Every REST operation is org-gated on the validated principal (HIP-0026),
parked by the bridge the composer installs once at the root. The payee is
structurally the publisher's: PublisherOrg is the payee org, and the wallet id
resolves only within the org that is asked for, which makes a cross-org credit
unconstructible rather than merely unlikely
(`apps/marketplace/store.go:25-31`).

#### §5 Events, observability, stage, upstream

It publishes nothing on the bus and emits nothing beyond the request span
every route gets. The stage is `beta` (`manifest/apps.go:430`, `Stage: Beta`):
reached by flag until promoted (HIP-0139 §8). It derives from no upstream.

### Rationale

The alternative to "install is activation" is a marketplace-owned installs
table, which is a second copy of the registry's fact — the defect the plugin
contract names — and it would disagree first exactly where it matters, on
whether a priced tool is active. The alternative to asking the owning process
for the price was replicating the table into the rail's process, a cache that
turns every price change into a coherence problem on the money path.

### Security Considerations

The money path is the exposure, and its two failure shapes are opposite. Fail
open: a missing price table read as "free" dispensed paid tools for nothing —
closed by making absence an error and free an explicit answer. Redirection: a
caller-influenced recipient or price turns the rail into a payout to the
attacker — closed by binding both to the listing row, publisher-owned and
publisher-org-payable only. The listing store's own writes are bounded by the
(publisher\_org, id) key, so a tenant can unpublish only what it published.

## Four surfaces

| Surface  | Reaches this capability as                          | Coverage                                                                   |
| -------- | --------------------------------------------------- | -------------------------------------------------------------------------- |
| **REST** | `marketplace` at its own prefix                     | 23 operations                                                              |
| **CLI**  | `hanzo marketplace …`                               | 6 of 23 — the CLI pins the document on its own clock                       |
| **SDK**  | `MarketplaceApi` in every published client          | 23 methods                                                                 |
| **MCP**  | tool `marketplace` on `https://api.hanzo.ai/v1/mcp` | 23 operations, 3 under the document's own id — ask `describe` for the rest |

## Quickstart

```bash
export HANZO_API_KEY=sk-...   # console.hanzo.ai → API keys
```

Then the first call — a read that needs nothing but the key. `GET /v1/marketplace`, operation `get_marketplace`:

**CLI**

```bash
hanzo marketplace get
```

**SDK**

**.ts**

```ts
import { Configuration, MarketplaceApi } from 'hanzoai';

const api = new MarketplaceApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.getMarketplace();
```

**.py**

```python
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import MarketplaceApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = MarketplaceApi(client).get_marketplace()
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.MarketplaceAPI.GetMarketplace(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
use hanzo_client::apis::{configuration::Configuration, marketplace_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = marketplace_api::get_marketplace(&cfg, Default::default()).await?;
```

**.java**

```java
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.MarketplaceApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new MarketplaceApi(client).getMarketplace();
```

**HTTP**

```bash
curl https://api.hanzo.ai/v1/marketplace \
  -H "Authorization: Bearer $HANZO_API_KEY"
```

**MCP**

MCP reaches **marketplace** through the `marketplace` tool, which names its 23 operations with its own verbs — this one among them, under a name only MCP declares. `describe` explains any of them:

```bash
curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "list_marketplaces"
         }
       }
     }'
```

Answers `200` with `object` — ok.

## Endpoints

| Endpoint                                                                                                                            | What it does                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`POST /v1/marketplace/install`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-install)                           | Activates one tool for the caller's own org and project.                                                                                                                                                                                                                                                                                                                                                                                             |
| [`POST /v1/marketplace/jobs/{id}/accept`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-jobs-by-id-accept)        | Accepts a job the caller's org was hired for: the seller takes the work on and the clock toward its deadline is the seller's.                                                                                                                                                                                                                                                                                                                        |
| [`POST /v1/marketplace/jobs/{id}/cancel`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-jobs-by-id-cancel)        | Takes back a job the caller's org opened, before the seller accepts it.                                                                                                                                                                                                                                                                                                                                                                              |
| [`POST /v1/marketplace/jobs/{id}/decline`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-jobs-by-id-decline)      | Declines a job the caller's org was hired for, before any work.                                                                                                                                                                                                                                                                                                                                                                                      |
| [`POST /v1/marketplace/jobs/{id}/deliver`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-jobs-by-id-deliver)      | Records delivery of a job the caller's org accepted, before its deadline, and starts the review window: the buyer releases or disputes within it, or it releases itself when it closes.                                                                                                                                                                                                                                                              |
| [`POST /v1/marketplace/jobs/{id}/dispute`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-jobs-by-id-dispute)      | Stops a job for a ruling, as either party: before delivery (and before the deadline), or within the review window after it.                                                                                                                                                                                                                                                                                                                          |
| [`POST /v1/marketplace/jobs/{id}/feedback`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-jobs-by-id-feedback)    | Rates the other party of a settled job — the seller when the caller's org bought, the buyer when it sold — once per party per job, and never edited.                                                                                                                                                                                                                                                                                                 |
| [`POST /v1/marketplace/jobs/{id}/refund`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-jobs-by-id-refund)        | Refunds a job the caller's org accepted, as the seller, at any point before it is paid: nothing was moved, so the buyer's authorization is given up, never settled, and the amount it set aside returns to the buyer's wallet.                                                                                                                                                                                                                       |
| [`POST /v1/marketplace/jobs/{id}/release`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-jobs-by-id-release)      | Releases a job the caller's org is paying for, paying the seller the whole amount: the buyer's authorization is settled on the rail, once, and the rail states the payment.                                                                                                                                                                                                                                                                          |
| [`GET /v1/marketplace/jobs/{id}`](https://docs.hanzo.ai/docs/openapi/marketplace/get-marketplace-jobs-by-id)                        | Reads one job the caller's org is a party to.                                                                                                                                                                                                                                                                                                                                                                                                        |
| [`GET /v1/marketplace/jobs`](https://docs.hanzo.ai/docs/openapi/marketplace/get-marketplace-jobs)                                   | Lists the jobs the caller's org is a party to, newest first: as buyer, the work it hired — with the quotes it has not paid and the jobs being funded, each with the attempt that made it, so a hire whose answer was lost is found here — and as seller, the work it was hired for, which never includes another org's quote.                                                                                                                        |
| [`POST /v1/marketplace/jobs`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-jobs)                                 | Hires another org for a piece of work, through a public listing or by a direct offer, and answers 201 with the job — open, waiting for the seller.                                                                                                                                                                                                                                                                                                   |
| [`PATCH /v1/marketplace/listings/{id}`](https://docs.hanzo.ai/docs/openapi/marketplace/patch-marketplace-listings-by-id)            | Edits one of the caller org's listings — its copy, price, payout wallet, visibility and documentation — under the same rules publish applies, and answers the listing as it now stands.                                                                                                                                                                                                                                                              |
| [`DELETE /v1/marketplace/listings/{id}`](https://docs.hanzo.ai/docs/openapi/marketplace/delete-marketplace-listings-by-id)          | Withdraws one of the caller org's listings from the marketplace and answers 204.                                                                                                                                                                                                                                                                                                                                                                     |
| [`GET /v1/marketplace/listings`](https://docs.hanzo.ai/docs/openapi/marketplace/get-marketplace-listings)                           | Returns the listings the caller's own org has published — what this org is offering, not what it can buy.                                                                                                                                                                                                                                                                                                                                            |
| [`POST /v1/marketplace/listings`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-listings)                         | Offers one thing the caller's org owns on the marketplace — an agent, persona, app, skill or MCP server, or, for the platform, a tool sold per call — optionally monetized.                                                                                                                                                                                                                                                                          |
| [`POST /v1/marketplace/seller/payout/verify`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-seller-payout-verify) | Binds the caller org's payout wallet: the signature over its outstanding challenge is recovered, and must recover to the wallet's address, before the challenge expires.                                                                                                                                                                                                                                                                             |
| [`POST /v1/marketplace/seller/payout`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-seller-payout)               | Starts binding one of the caller org's wallets as the wallet it is paid into: answers a challenge naming the org, the wallet and its address, to be signed with that wallet within fifteen minutes and sent to POST /v1/marketplace/seller/payout/verify.                                                                                                                                                                                            |
| [`GET /v1/marketplace/seller`](https://docs.hanzo.ai/docs/openapi/marketplace/get-marketplace-seller)                               | Answers where the caller's org stands as a seller, in one read: its founders' identity verification (KYC) and legal entity (KYB), its tax form and whether it is certified and valid, its own sanctions screening — only what an org may see about itself — the payout wallet it proved, the TaxPrincipalCredentials signed for its agents, what it earned in the year from the economic events the rails stated, and the 1099s payers furnished it. |
| [`GET /v1/marketplace/shop/{id}`](https://docs.hanzo.ai/docs/openapi/marketplace/get-marketplace-shop-by-id)                        | Reads one public listing as the shop shows it — its seller's public face, its reputation and the ways to buy it.                                                                                                                                                                                                                                                                                                                                     |
| [`GET /v1/marketplace/shop`](https://docs.hanzo.ai/docs/openapi/marketplace/get-marketplace-shop)                                   | Searches every public listing of every kind — agents and personas to hire, apps, skills, MCP servers and tools — newest first, with facets by kind, category, price and rating, paged.                                                                                                                                                                                                                                                               |
| [`POST /v1/marketplace/uninstall`](https://docs.hanzo.ai/docs/openapi/marketplace/post-marketplace-uninstall)                       | Deactivates one tool for the caller's own org and project, so it stops being dispatchable there.                                                                                                                                                                                                                                                                                                                                                     |
| [`GET /v1/marketplace`](https://docs.hanzo.ai/docs/openapi/marketplace/get-marketplace)                                             | Lists every tool and agent the caller can reach in their own org and project, enriched with any public listing's title, category and price, and with installed=true on the ones already activated for that scope.                                                                                                                                                                                                                                    |

---

[All Hanzo APIs](https://docs.hanzo.ai/docs/openapi) · [Interactive reference](https://docs.hanzo.ai/docs/openapi/reference)
