Skip to main content
The vendor API is the HTTP surface for agents and scripts working on a vendor team: read the catalog, your listings and their quality runs, the opportunities you can respond to, your sales and earnings, and estimations, and manage inventory. Publishing and moving money stay in the web app. Base URL https://api.datavendor.ai, every route under /v2, authenticated with a team API key. Keys, conventions, and errors are shared with the buyer API and described on Using the API. The OpenAPI document behind this page is served with an interactive reference. A first call, returning your team’s listings:

Objects

The same reads are available as MCP tools for coding agents.
Endpoint reference

Catalog

The same view of published listings a buyer has, including each listing’s vendor organization (team_name). A vendor-only team is behind the browse gate until it has enough live listings of its own: browse then serves only the first unfiltered page, and GET /v2/listings/browse/access reports your progress.

Browse

Browse is filtered and sorted server-side. The first page carries tab counts and filter facets; follow next_cursor for the rest. Vocabularies for the filters come from the taxonomy endpoints.
Request
Response 200
Request
Response 200
Request
Response 200
Request
Response 200
Request
Response 200
Request
Response 200
Request
Response 200

Taxonomy

The vocabularies vendors classify with and buyers filter by. Pass the returned values into browse filters; an unknown value matches nothing rather than erroring.
Request
Response 200
Request
Response 200
Request
Response 200
Request
Response 200

Selling

The key-holding team’s vendor side: its listings, their quality runs, sales, and the open listing requests it can respond to.

Listings

Listings are composed, submitted, and published in the web app. The API reads them and manages which codebase assets a listing carries.
Request
Response 200
Request
Response 200
Request
Response 200
Request
Response 200
Request
Response 201
Request
Returns 204 with an empty body.

Quality and sales

Request
Response 200
Request
Response 200
Request
Response 200

Opportunities

Open listing requests your team can view, and read-only project bid history. Project opportunities and bids cannot be created or changed. Listing submissions remain available in the web app.
Request
Response 200
Request
Response 200
Request
Response 200
Request
Response 200

Inventory

A vendor team’s supply before and after it is listed. Every offering is an asset, in an asset group. Codebases and raw data support metadata-only proposals; tasks are imported platform versions and never have a proposed stage. supports_proposals on the asset-type catalog identifies this capability. Use the SKU collections for typed details and writes. GET /v2/assets returns cross-SKU summaries. These collections return items, total, limit, and offset, default to 50 rows, and accept at most 200 rows per page. They share repeated id, group_id, listing_id, stage, filter, sort, and sort_direction parameters. Use GET /v2/assets/window for grouped inventory with leaf_budget, header_budget, and after_group_id; follow up inside one group with GET /v2/assets?group_id=...&limit=...&offset=.... Stages are derived: missing metadata makes an asset incomplete; complete metadata without an artifact makes a proposal-capable asset proposed; complete metadata with its artifact makes it complete. A task’s platform version counts as its artifact. Archive and analysis progress are separate from stage. PATCH changes only supplied fields; nullable fields can be cleared with null, while arrays and maps clear with [] and {}.

Assets

Request
Response 200
Request
Response 200
Request
Response 200
Request
Response 201
Request
Returns 204 with an empty body.
Request
Response 200
Request
Response 200

Tasks

Import the tasks you build on the platform as inventory, one asset per task version. A task asset exists or it does not: there is nothing to propose up front, so POST /v2/tasks/import is the one way a task asset comes to exist. Send one taskset id to import every live task in it, or up to 500 task ids to pick tasks by hand, plus the task_type every imported task gets (coding, finance, legal or general; QC runs per type, so the type is required and has no default); the server resolves each task to its latest version and imports it when that version’s build succeeded. You can import from the tasksets you can view; a task you cannot view reads as not found. Tasks left out are listed in skipped with a reason (no_version, no_build, build_not_succeeded, deleted, foreign). A version imports once: importing again returns its asset under existing, and a task you edit on the platform imports again as a new asset titled with its version. A task asset has no data object to link; its task block names the version it stands for, and typed details read through GET /v2/tasks/{asset_id}. Imported assets arrive without a domain or asking price (and without a description when the task has none), so they are incomplete until you fill those in with PATCH /v2/tasks/{asset_id}; once the description, domain and asking price are set the asset is complete. The same call changes a task’s task_type later; the type never affects the stage. Without group_id they land in a group named after the taskset, or in your default group when the picked tasks span several tasksets. One import creates at most 500 assets; a larger taskset is imported in batches of task_ids. The task block also carries the task’s QC metadata, read from the platform when the task is imported, counting your team’s own traces on it: qc.pass_at_k lists every model that has graded runs on the version, by model name, with its pass_at_k (the mean reward over the newest five runs), k, runs, avg_reward and last_run_at (graded runs whose trace names no catalog model sit apart in qc.unattributed_runs, same shape); qc.qa_agents lists the standard QA checks whose result is in effect on the version’s latest trace, by agent key (false_positive, false_negative, reward_hacking, prompt_alignment, failure_analysis), each with its status, verdict and the number of findings. The document holds aggregates only: trace ids and the checks’ write-ups stay on the platform, where project access applies; qc.environment says whether the version’s build is built. Three facts derive from that document for filtering: has_traces (any graded run), has_qa_results (any completed check) and has_environment. qc_refreshed_at is when the platform was last read; POST /v2/tasks/refresh-qc reads it again for every task asset of your team, in the background, one refresh per team at a time (a request while one runs answers with that one), and GET /v2/tasks/refresh-qc reports the refresh in flight or the last one with its total and refreshed counts. Filter the inventory on GET /v2/assets with has_traces, has_qa_results, has_environment (true or false), ran_on_model:is:<model name> and qa_agent:is:<agent key>; GET /v2/tasks/qc-facets lists the model names and agent keys your tasks carry, to pick from.
Request
Response 200
Request
Response 200
Request
Response 202
Request
Response 200
Request
Response 200
Request
Response 200
Request
Response 200

Codebases

Register repositories your team could supply, one at a time or in an atomic metadata-only batch with POST /v2/codebases/batch and body {"items": [...]} (at most 500 rows). Only title and exclusivity are required. Anything else you leave out, including the description, domain and asking price, is listed in missing and keeps the proposal incomplete until a PATCH fills it. A proposal stays editable, and can be deleted until a data object is attached. Once the linked data is read, a description you left blank is filled from the repository’s root README, or failing that from the repository’s About text or your manifest’s description. A description you wrote is never replaced. Metadata read from the linked data, and metadata you send with an API key, is locked: locked_fields maps each such field to its source (github, gitlab, bitbucket or zip for the linked data, api for an API-key request). A locked field can’t be edited in the inventory, only through the API or a new reading of the data.
Request
Response 200
Request
Response 201
Request
Response 201
Request
Response 200
Request
Response 200
Request
Response 200
Request
Returns 204 with an empty body.
Request
Response 202
Request
Response 200

Raw data

Register the raw data your team can supply, with an optional completed upload as data. Complete metadata without an upload is proposed. With an upload, a row sent with its description, domain and asking price is complete from the start; one without them lists them in missing and stays incomplete until a PATCH fills them. A blank description is filled from the archive’s root README once the upload is read. Its columns can be edited until it is deleted. Exclusivity is a codebase field: raw data rows do not carry it, and an exclusivity value sent here is refused.
Request
Response 200
Request
Response 201
Request
Response 200
Request
Response 200
Request
Returns 204 with an empty body.
Request
Response 201
Request
Returns 204 with an empty body.
Request
Response 200
Request
Response 202
Request
Response 200

Groups

Request
Response 200
Request
Response 201
Request
Response 200
Request
Response 200
Request
Returns 204 with an empty body.

Account

Estimations

Request
Response 200
Request
Response 200
Request
Response 200
Request
Response 200

Wallet and notifications

Converting, withdrawing, and payout setup stay in the web app.
Request
Response 200
Request
Response 200
Request
Response 200