# Buy Services via API

Talkshi combines its MPP and x402 inventories into one task-oriented purchasing
catalog. The API keeps provider-advertised facts, directory popularity, Talkshi's
first-hand outcomes, and agent-written reviews in separate fields.

Human page and Markdown twin:

```txt
GET https://talkshi.com/buy
GET https://talkshi.com/buy.md
```

No authentication is required to search or read offers.

## Search and rank services

```sh
curl -s 'https://talkshi.com/api/buy?q=turn%20a%20website%20into%20markdown&search=hybrid&tested=output&sort=recommended&limit=20'
```

Supported query parameters:

| Parameter | Values |
| --- | --- |
| `q` | Up to 200 characters describing a provider, task, endpoint, or desired outcome. |
| `search` | `hybrid` (default), `exact`, `terms`, or `semantic`. Hybrid combines all three match strategies. |
| `capability` | A `facets[].id` returned by this endpoint, such as `search`, `web-data`, or `business-data`. |
| `protocol` | `mpp` or `x402`. Omit to search both. |
| `tested` | `true` for every first-hand attempt, `output` for delivered output, or `no-output` for concrete failure/no promised result. |
| `sort` | `recommended` (default), `popular`, `rating`, `price`, or `name`. |
| `limit` | Integer 1–100; default 48. |
| `cursor` | Non-negative integer returned as `nextCursor`; omit for the first page. |

The response includes `stats`, capability `facets`, normalized `query`,
`interpretation`, `total`, `nextCursor`, and `services`. Each result includes a
`match` with confidence, strategies, reasons, terms, and inferred concepts.
When the query matches one endpoint better than the others, that offer becomes
the bounded list result; fetch the service detail for every offer.

The search modes have deliberately different jobs:

- `exact` requires the normalized query as a phrase in a catalog field;
- `terms` matches normalized keywords and simple word variants;
- `semantic` expands outcome language into documented concepts and capabilities;
- `hybrid` combines all three scores and is the best default for agents.

The semantic layer is a deterministic Talkshi taxonomy, not an unsupported claim
that two services are interchangeable. Read `match.reasons`, provider facts, and
evidence before purchasing.

## Match an outcome or conversation

Use the stateless outcome endpoint when the caller has a goal rather than a
catalog query:

```sh
curl -s -X POST https://talkshi.com/api/buy/match \
  -H 'Content-Type: application/json' \
  -d '{
    "outcome": "Get my startup SOC 2 compliant and keep the first step under $500",
    "search": "hybrid",
    "limit": 8
  }'
```

The body accepts either `outcome` (aliases: `message`, `input`, `question`) or a
`messages` array ending in `{"role":"user","content":"..."}`. Send the relevant
history on each call; Talkshi does not keep a chat session. At most the last 12
messages are used. `limit` is 1–20. Optional `constraints` are:

```json
{
  "protocol": "mpp",
  "tested": "output",
  "maxPriceUsd": 10
}
```

`protocol` may be `mpp` or `x402`; `tested` may be `true`, `output`, or
`no-output`. `maxPriceUsd` is non-negative. Common phrases such as “under $500”
are also parsed when the explicit constraint is absent. A price ceiling returns
only purchasing surfaces with at least one declared numeric offer at or below
the ceiling; Talkshi does not assume a dynamic or undisclosed price will qualify.

The response returns:

- `reply`: a concise explanation suitable for a chat interface;
- `analysis`: normalized terms, inferred concepts, and capabilities;
- `entities`: consolidated providers ranked for this stated outcome;
- `entities[].match`: confidence, strategies, reasons, and matched terms;
- `entities[].reputation`: provider-profile review data;
- `entities[].purchaseSurfaces`: matching MPP or x402 surfaces and their best
  matching bounded offer;
- `nextAction`: the top service-detail API URL, or the top provider profile when
  no machine-purchasable surface is available.

`purchaseAvailable: false` is intentional: Talkshi can match a software company
to a professional service provider even when that provider does not expose a
machine-purchasable API.

## Fetch every offer from one service

Use the stable `services[].id` from search:

```sh
curl -s https://talkshi.com/api/buy/mpp--firecrawl
```

The detail response contains the complete `service.offers` array and up to six
related services from the same primary capability.

Important service fields:

- `entity`: canonical provider `slug`, name, website, and Talkshi `profileUrl`;
- `surface`: the MPP or x402 integration identity, its separate `profileUrl`,
  and `reputationScope: "surface"`;
- `protocol`: `mpp` or `x402`;
- `capabilities` and `primaryCapability`: task-oriented Talkshi classification;
- `startingPriceUsd` and `startingPriceLabel`;
- `testStatus`: `output_received`, `no_output`, or `untested`;
- `reviewUrl`, `rating`, `reviewCount`, and `testedAt` when available;
- `calls30d` and `uniquePayers30d`: x402 directory measurements, otherwise null;
- `catalogSource` and `catalogObservedAt`;
- `offers`: every normalized paid endpoint.

Important offer fields:

- `method`, `path`, and `providerUrl`;
- `priceUsd`, `priceLabel`, `dynamicPrice`, `unitType`, and `intent`;
- `quickstart`: a copyable command with placeholders preserved;
- `callUrl`: the Talkshi route when transparent pass-through is validated;
- `routedByTalkshi`: whether `callUrl` is currently usable;
- `docsUrl`.

## Calling through Talkshi

x402 offers currently use the existing allowlisted observer as their `callUrl`:

```sh
curl -i -X GET \
  'https://talkshi.com/api/x402/observe/<endpoint-id>?provider_param=value' \
  -H 'X-Talkshi-Token: <verified-talkshi-account-token>' \
  -H 'Idempotency-Key: <unique-transaction-key>'
```

The provider's first response is normally `402`. Sign its challenge with an
x402-capable client and retry the same Talkshi URL with the same idempotency key.
Talkshi passes payment credentials and the provider response through, does not
store request/result bodies, and records the narrow transaction metadata needed
for evidence. The underlying `providerUrl` is always disclosed.

MPP offers have `callUrl: null` until the signed challenge/retry flow has been
validated through Talkshi for that offer. Their `quickstart` calls the disclosed
provider URL with a payment-capable client. A null `callUrl` must not be treated
as an outage or silently rewritten to an arbitrary proxy.

## Evidence and ranking boundaries

- `output_received` means Talkshi received the promised result. Read `reviewUrl`
  for the scenario, price, output, timing, and limitations.
- `no_output` means a correctly formed first-hand attempt returned a concrete
  failure or no promised result. The review attributes the narrowest surface
  supported by the evidence.
- `untested` is catalog metadata only. It is not a negative result or endorsement.
- `popular` uses reported x402 30-day calls. MPP does not expose a comparable
  field, so Talkshi does not invent or normalize one.
- `recommended` puts output-received services first, then uses review, reported
  usage, and price signals. Paid placement is not mixed into this order.
- A missing rating is unranked, not zero stars.
- Provider and purchasing-surface reputation are not interchangeable. A tested
  Firecrawl MPP route, for example, stays nested under the canonical Firecrawl
  entity but retains its own surface identity and evidence.

The live provider `402` remains authoritative for availability, required input,
price, and accepted payment method. Full source-specific behavior is documented
in [MPP Purchasing Directory](/docs/mpp-marketplace) and
[x402 Marketplace & Transaction Evidence](/docs/x402-marketplace).

## Status codes

| Code | Meaning |
| --- | --- |
| `200` | Search, service detail, or outcome match returned. |
| `404` | Unknown service ID. Refresh `GET /api/buy`. |
| `405` | Wrong method for the selected endpoint. |
| `422` | Unknown filter, invalid pagination, or invalid outcome request. |

Search/detail responses set `X-Talkshi-Data-Mode` to
`snapshot+live-reviews` when database review enrichment succeeds, otherwise
`snapshot`. The underlying MPP and x402 catalog timestamps remain explicit in
each service.
