Skip to main content

Marketplace

Publish one of your project's tools or agents for other projects to install, and install what others publish.

Overview​

A listing is a tool or an agent a project offers to other projects. An install is another project using it: once installed, the project names the tool or agent by its id like one of its own. Every call runs on the publisher's configuration — its endpoint, secrets, instructions and provider — and the records and usage stay in the installing project. A publisher may price its listing; see Pricing.

See the OpenAPI specs for listings and installs, or browse them under API Reference → Listings and API Reference → Installs.

Data Model​

Listing​

FieldTypeDescription
idstringPublic listing ID (lst_ prefix).
project_idstringThe publishing project. Not shown in the marketplace.
resource_typetool | agentWhat the listing publishes.
resource_idstringThe published tool or agent.
titlestringUp to 120 characters.
descriptionstring, nullableUp to 2,000 characters.
statedraft | in_review | listed | suspendedSee Publishing.
pricingarrayWhat an installing project is charged per call. Empty is free. See Pricing.
pricing_nextobject, nullableA price increase waiting out its notice: effective_from and the new pricing.
created_atstring (date-time)
updated_atstring (date-time)

A public listing carries interface instead of project_id: what an installing project sees of the resource.

Install​

FieldTypeDescription
idstringPublic install ID (ins_ prefix).
project_idstringThe installing project.
listing_idstringThe installed listing.
resource_typetool | agent
resource_idstringThe id the project names the resource by.
stateactive | suspended | blockedSee Suspending and blocking.
installed_atstring (date-time)
updated_atstring (date-time)

The publisher's view of an install carries project_name, calls_cycle, errors_cycle and sampled_at instead: the installing project's calls through the listing this billing cycle, sampled every 15 minutes. It never carries what those calls contained.

Key Concepts​

Publishing​

Any project member can publish. A listing starts as draft; submitting it moves it to in_review, and naturali either lists it in the marketplace or sends it back to draft. A draft or in_review listing installs by its id, so you can try it from a second project before it is listed.

An agent on a naturali model must have a price: a listing on an unpriced model answers 503 model_not_priced, and so does changing a listed agent's provider or model to one. An agent on a provider of your own has no such check.

What an installing project sees​

TypeinterfaceWhere it can be used
Toolid, name, description, parametersAn agent's tool bindings, an ingestion rule, a direct call
Agentid, nameA direct generation, a conversation, a session, an ingestion rule as converter

Never instructions, provider, headers or secrets. interface is read live, so a change to the tool shows on the next read.

The installing project pays for its runs and for the model, like any generation of its own, plus the listing's price. An installed agent on a naturali model is refused like your own: 402 insufficient_credit while credit_balance_usd is negative, 503 model_not_priced on a model with no price. Its model usage is billed even if you uninstall it before the next reconciliation.

Pricing​

A price is a list of components, each { component, unit, quantity, unit_price }. quantity is JSON Logic giving how many units a call uses; leave it null to charge one per call. It can read:

TypeWhat quantity reads
Toolinput, action, response, outcome, duration_ms
Agentresponse.usage, response.cost_usd, response.steps, response.tool_calls, response.stop_reason, outcome

Anything else is refused with 400, naming the field. component cannot be a name the platform already meters, such as input_tokens or tool_call.

  • A failed call is never charged a component. It still counts as a run, and any model cost is still paid.
  • What pays a fee. Only purchased credit and marketplace earnings that model usage has not spent, never a plan's included credit or granted credit. Usage spends included credit first, then granted, then purchased. A call to a priced listing, a generation on an agent that has one among its tools, or an ingest through an ingestion rule naming one, answers 402 insufficient_credit with details.balance: "paid" while paid_balance_usd is zero or less. When fees take it below zero, the schedule triggers and orchestration runs that name a priced listing are paused, and can be restored once it is positive again.
  • What the publisher earns. 90% of each fee the consumer paid, credited to the publisher's earned_balance_usd every 15 minutes. A fee the consumer has not yet paid for is credited once they buy credit.
  • Changing a price. A lower price applies the next minute. A higher unit price or a new component applies 7 days later: until then the listing returns it in pricing_next, and every installing project's billing owner gets an email. A component you leave out is no longer charged. A listing nobody has installed changes price the next minute either way.

Suspending and blocking​

  • Suspending a listing stops it in every installing project at once: an agent runs without the tool, and a converter fails with CONVERTER_FAILED. Installs are kept, and listing it again resumes them with no reinstall. A listing naturali suspended cannot be resumed by its publisher.
  • Removing one install blocks that project: its install becomes blocked and installing again answers 403 install_blocked. Removing the blocked install lets it install again.
  • A listing whose tool or agent is deleted is suspended within the hour.

The installing project's billing owner gets an email when a listing is suspended, at most one a day per listing, and whenever its access is removed.

Uninstalling​

While agents, ingestion rules or other resources still name the installed resource, uninstalling answers 409 install_in_use with them in details.references. force=true uninstalls anyway, and those resources stop reaching it.

Limits​

  • An installed tool has no version: a change by its publisher applies to every installing project.
  • An installed agent runs its publisher's current release. Each generation records the version it ran.
  • An installed agent cannot be bound as a tool of another agent.

Managed conversion​

The converter behind managed conversion is naturali's own listing, installed in every project with conversion on. It cannot be installed by hand (403 managed_resource_read_only), and while conversion is on its install is removed by turning conversion off, not by uninstalling. Answer from images and audio lists the rules that name it.

Who may do what​

Every project route needs any project member. Browsing the marketplace needs only a signed-in caller.

Examples​

Publish a tool and submit it​

naturali create-listing \
--project-id proj_V1StGXR8Z5jdHi6B \
--resource-type tool \
--resource-id tool_V1StGXR8Z5jdHi6B \
--title "Invoice OCR"

naturali submit-listing \
--project-id proj_V1StGXR8Z5jdHi6B \
--listing-id lst_V1StGXR8Z5jdHi6B

Browse the marketplace and install​

GET /v1/listings, then POST /v1/projects/{project_id}/installs.

naturali list-public-listings

naturali create-install \
--project-id proj_6NgFz3xXy2kPq9Wd \
--listing-id lst_V1StGXR8Z5jdHi6B

The installed tool is then named by its resource_id in an agent's tool bindings, like any tool of the project's own.

See who installed your listing​

naturali list-listing-installs \
--project-id proj_V1StGXR8Z5jdHi6B \
--listing-id lst_V1StGXR8Z5jdHi6B

Price a listing​

naturali update-listing \
--project-id proj_V1StGXR8Z5jdHi6B \
--listing-id lst_V1StGXR8Z5jdHi6B \
--pricing '[{ "component": "page", "unit": "count", "quantity": { "var": "response.page_count" }, "unit_price": 0.002 }]'

Suspend and resume a listing​

naturali update-listing \
--project-id proj_V1StGXR8Z5jdHi6B \
--listing-id lst_V1StGXR8Z5jdHi6B \
--state suspended

naturali update-listing \
--project-id proj_V1StGXR8Z5jdHi6B \
--listing-id lst_V1StGXR8Z5jdHi6B \
--state listed

Block a project, then let it back​

DELETE /v1/projects/{project_id}/listings/{listing_id}/installs/{install_id} blocks the install; the same call on the blocked install removes it.

naturali delete-listing-install \
--project-id proj_V1StGXR8Z5jdHi6B \
--listing-id lst_V1StGXR8Z5jdHi6B \
--install-id ins_V1StGXR8Z5jdHi6B

Uninstall​

naturali delete-install \
--project-id proj_6NgFz3xXy2kPq9Wd \
--install-id ins_V1StGXR8Z5jdHi6B \
--force true