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 marketplace and machine contract:
GET https://talkshi.com/#buy
GET https://talkshi.com/docs/buy-services.md
No authentication is required to search or read offers.
Search and rank services
curl -s 'https://talkshi.com/api/buy?q=turn%20a%20website%20into%20markdown&search=all&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 |
all (default), exact, terms, or semantic. all runs every strategy; hybrid is a compatibility alias for all. |
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, nullable sponsored, and services.
sponsored is eligible only on the first page when an approved marketplace ad
clears the deterministic relevance threshold for the query or capability. It
is a separately disclosed paid result and is never a member of services, so
it cannot change organic rank, totals, ratings, or reviews. Each organic 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:
exactrequires the normalized query as a phrase in a catalog field;termsmatches normalized keywords and simple word variants;semanticexpands outcome language into documented concepts and capabilities;allcombines all three scores and is the default for agents;hybridis retained as an equivalent alias for existing callers.
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.
Human clients may display sponsored as a visibly labeled paid placement. Its
short-lived impression.token may be POSTed to impression.url only after at
least 50% of the rendered card has remained visible for one continuous second;
fetching a search response is not an impression. Talkshi's browser client
deduplicates one counted view per pseudonymous visitor, campaign, and UTC day.
Machine clients that do not render the placement should ignore the impression
callback.
Match an outcome or conversation
Use the stateless outcome endpoint when the caller has a goal rather than a catalog query:
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",
"conditions": [
{"id":"budget","requirement":"Cost under $500","priority":"must"},
{"id":"startup-fit","requirement":"Experience with seed-stage software companies","priority":"prefer"}
],
"search": "all",
"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:
{
"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.
conditions accepts at most 12 entries. Each entry has an optional unique id,
a requirement of at most 240 characters, and priority: "must" | "prefer".
Plain strings are accepted as must-haves. Talkshi checks each returned provider
against current profile, purchasing-surface, price, and first-hand evidence and
returns satisfied, unknown, or failed with a short evidence explanation.
An absent catalog fact stays unknown; it is never converted into a pass.
The /api/buy/match body is capped at 32 KiB. Valid outcome matches and MCP
find_services calls share one source-IP budget of 30 per hour and 100 per
rolling 24 hours; 429 includes Retry-After. MCP initialization, ping, and
tool-list traffic do not consume this matcher budget. The MCP JSON envelope is
capped at 128 KiB.
Each entity has conditionFit:
eligible: every must-have has supporting current catalog evidence;needs_research: no must-have is known to fail, but one or more remain unknown;excluded: at least one must-have is known to fail; excluded entities are not returned in the shortlist and instead appear in the separate boundedexcludedaudit list with the failed checks.
Preferred conditions affect ordering after must-have fit. The response also
returns eligibleTotal, needsResearchTotal, and excludedTotal. A
catalog-supported condition is bounded by the linked evidence; vendor research
or confirmation may still be needed for contract scope, total price, availability,
and facts the catalog does not contain.
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.sponsored: a separate nullable paid placement matched to the stated outcome; it never affects the rankedentitiesarray.
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.
Attach procurement files to the human matcher
The homepage B2B request form accepts PDFs or images through the existing
picker, paste, or drop target. Ordinary procurement attachments are limited to
four files and 12,000,000 bytes total. One business-insurance policy can instead
be attached by itself up to 25,000,000 bytes. The browser processes files
sequentially and includes their privacy-minimized summaries with the exact typed
request when it calls /api/buy/match.
The underlying endpoint accepts exactly one raw file per request:
curl -s -X POST https://talkshi.com/api/buy/attachment \
-H 'Content-Type: image/webp' \
--data-binary @product.webp
Supported media types are application/pdf, image/jpeg, image/png, and
image/webp. The declared type must match the file bytes. A client limited to
application/octet-stream must also send X-File-Type with the actual type.
Each file may contain at most 3,000,000 bytes; multipart forms and JSON/base64
wrappers are not accepted. The browser caps one selection at four files and
12,000,000 bytes total. It sends a file over 3,000,000 bytes directly to the
commercial-insurance endpoint below. For a smaller file, the generic extractor
returns a fuller insuranceBrief in the same response when it classifies the
file with attachment.kind: "commercial_insurance"; the browser uses that
brief without uploading the file twice. Ordinary vendor quotes remain
commercial_quote and keep their generic procurement summary.
A successful response is shaped like:
{
"ok": true,
"summary": "Silver-tone oval buckle with a raised bull skull, dark recessed accents, and engraved border details.",
"attachment": {
"kind": "product_image",
"fileType": "webp"
}
}
summary is an objective, privacy-minimized description capped at 360
characters. A commercial_insurance response also includes a privacy-minimized
three-line insuranceBrief capped at 1,200 characters; it is null for every
other attachment kind. The extractor does not follow instructions, links, or QR
codes embedded in a file and does not infer unsupported prices, shipping terms,
brands, or models.
Talkshi does not persist the raw file; OpenAI processing uses store: false.
No account is required. Requests are limited to 15 per hour and 40 per rolling
24 hours per source, with project-wide extraction capacity of 60 per hour and
200 per rolling 24 hours; 429 includes Retry-After. An oversized file
returns 413, a missing, unsupported, or mismatched media type returns 415,
an empty, unreadable, unsupported, or non-procurement file returns 422, and
unavailable processing returns 503.
This extraction only supplies context to the stateless catalog matcher. It does not contact a seller, calculate a quote, arrange shipping, or persist a private procurement request.
Turn a commercial insurance file into a shopping brief
Send one commercial/business insurance renewal or existing-quote document as the raw request body:
curl -s -X POST https://write.talkshi.com/insurance-document \
-H 'Content-Type: application/pdf' \
--data-binary @renewal.pdf
Supported media types are application/pdf, image/jpeg, image/png, and
image/webp. The declared type must match the file bytes. A client limited to
application/octet-stream must also send X-File-Type with the actual
supported media type. Send exactly one file, at most 25,000,000 bytes; multipart
form data and JSON/base64 wrappers are not accepted.
A successful response is shaped like:
{
"ok": true,
"brief": "Need: Re-shop the company’s commercial insurance renewal.\nMust: Preserve the documented coverage limits and effective date.\nPrefer: Compare deductible and premium tradeoffs.",
"document": {
"kind": "commercial_insurance",
"fileType": "pdf"
}
}
brief is a privacy-minimized Need:/Must:/Prefer: shopping input capped at 1,200
characters. document.fileType is the short detected type, such as pdf,
jpeg, png, or webp. A client can review or edit the brief, then send it as
the outcome to /api/buy/match to shortlist commercial-insurance brokers.
The endpoint accepts commercial/business insurance only. Personal, health,
life, disability, non-insurance, and unreadable documents return 422. The
output supports broker shopping and does not provide an insurer quote, binding
indication, vendor outreach, or purchase.
No account is required. Requests are limited to 5 per hour and 15 per rolling
24 hours per source, with shared capacity of 20 per hour and 50 per rolling 24
hours across the canonical and compatibility paths; 429 includes
Retry-After. Talkshi does not persist the
raw file. Document processing uses the OpenAI API with store: false.
The Worker temporarily uploads the file to OpenAI for extraction, attempts
immediate deletion before returning the result, and sets a one-hour expiry as a
cleanup backstop.
POST https://talkshi.com/api/insurance-document remains a compatibility path
for files at most 3,000,000 bytes. Use the canonical write.talkshi.com endpoint
for the full 25,000,000-byte limit.
Operator-hosted re-shop draft runner
The repository also includes a separately operated insurance re-shop backend.
It runs pinned OpenCode 1.18.14 with the exact model
openai/gpt-5.6-sol and accepts one PDF, JPEG, PNG, or WebP file up to
25,000,000 bytes. This service is not deployed at talkshi.com or
write.talkshi.com; an operator starts it, protects it with a bearer token, and
calls POST /v1/drafts on that private origin. See
insurance-reshop/README.md
for the multipart fields and operating instructions.
The bearer is the operator-set INSURANCE_RESHOP_TOKEN, not a Talkshi account
token.
The runner produces a validated draft_only packet. It never contacts a
broker, submits a form, creates an account, accepts terms, appoints a broker of
record, binds or changes coverage, pays, or cancels. Missing underwriting facts
stay unknown and appear as required inputs; neither an authority flag nor a
ready_for_human_review status permits submission. Uploaded bytes use a
per-request temporary directory that the backend deletes after success or
failure. The pinned OpenCode configuration sends OpenAI Responses with
store: false; operators must separately configure any required OpenAI project
data controls. Keep the service private or add gateway request and spend limits;
its per-process one-job lock is not a distributed quota or persistent
idempotency layer. A human must review the exact application, certifications,
clickwrap, data transmission, BOR/AOR or exclusivity terms, and every protected
action.
Claude Code
All Claude Code surfaces use the same condition-aware matcher documented above. The plain HTTP contract remains canonical.
Remote MCP and tool
Add Talkshi's stateless remote server:
claude mcp add --transport http talkshi https://talkshi.com/api/mcp
Claude Code discovers one read-only tool named find_services. Its input accepts
the same outcome, conditions, constraints, search, and limit fields as
POST /api/buy/match; its structured result mirrors that endpoint's schema-v2
JSON. The MCP endpoint performs discovery only and requires no account token.
Skill and plugin
The Talkshi repository includes a Claude Code plugin that bundles the remote MCP
configuration and the find-b2b-services skill:
git clone https://github.com/rayxc-org/talkshi.git
cd talkshi
claude --plugin-dir ./integrations/claude-code/talkshi-procurement
Invoke /talkshi-procurement:find-b2b-services, or ask Claude to source or compare
a B2B service and let it select the skill. A project that wants only the skill
can copy integrations/claude-code/talkshi-procurement/skills/find-b2b-services
into its own .claude/skills/ directory. The skill preserves unknown must-haves
as research tasks and tells Claude to verify them from current primary sources
when suitable research tools are available.
The MCP server, its find_services tool, the skill, direct HTTP clients, and the
homepage textbox all use normalizeProcurementInput and
matchProcurementOutcome; they do not maintain separate rankings.
Save a company procurement request
A verified company account can save the exact condition-aware shortlist as a
private, immutable snapshot. Submit a business mailbox to POST /api/signup,
open its secure access link, explicitly confirm it, and copy the newly issued token from the confirmation
page, or use HTTPS domain verification. The unauthenticated signup response never
contains the token. Then send the account token as a bearer credential:
curl -s -X POST https://talkshi.com/api/procurement/requests \
-H "authorization: Bearer $TALKSHI_TOKEN" \
-H "content-type: application/json" \
-H "idempotency-key: soc2-search-2026-08" \
-d '{
"outcome":"Find a SOC 2 auditor for a seed-stage software company",
"conditions":[
{"id":"budget","requirement":"Cost under $5,000","priority":"must"},
{"id":"timeline","requirement":"Can begin this quarter","priority":"must"}
],
"limit":8
}'
The 201 response contains request.id, status, company identity, normalized
input, the frozen schema-v2 match result, timestamps, expiresAt, and statusUrl. Read it
with the same verified account:
curl -s https://talkshi.com/api/procurement/requests/prq_... \
-H "authorization: Bearer $TALKSHI_TOKEN"
The stored status is shortlist_ready, needs_research, or no_match. A saved
request records discovery and condition evidence; it does not authorize vendor
contact, accept terms, spend money, or make a commercial commitment.
The JSON body is capped at 32 KiB. Idempotency-Key is required, must contain
8–200 letters, numbers, ., _, :, or -, and is scoped to the verified
account. Repeating the same key and normalized body returns the original request
with 200 and idempotentReplay: true; changing the body under that key returns
409. Keep one key stable across network retries.
New snapshots are limited to 10 per verified account and 50 across a verified
company domain per UTC day; 429 includes Retry-After. Idempotent replays do
not consume a new slot, including concurrent retries. A snapshot is readable for
90 days and then returns 404; expired request data and its idempotency-key
reservation are deleted lazily when a later request is created. Export any audit
record that must live longer.
Fetch every offer from one service
Use the stable services[].id from search:
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 providerslug, name, website, and TalkshiprofileUrl;surface: the MPP or x402 integration identity, its separateprofileUrl, andreputationScope: "surface";protocol:mpporx402;capabilitiesandprimaryCapability: task-oriented Talkshi classification;startingPriceUsdandstartingPriceLabel;testStatus:output_received,no_output, oruntested;reviewUrl,rating,reviewCount, andtestedAtwhen available;calls30danduniquePayers30d: x402 directory measurements, otherwise null;catalogSourceandcatalogObservedAt;offers: every normalized paid endpoint.
Important offer fields:
method,path, andproviderUrl;priceUsd,priceLabel,dynamicPrice,unitType, andintent;quickstart: a copyable command with placeholders preserved;callUrl: the Talkshi route when transparent pass-through is validated;routedByTalkshi: whethercallUrlis currently usable;docsUrl.
Calling through Talkshi
x402 offers currently use the existing allowlisted observer as their callUrl:
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_receivedmeans Talkshi received the promised result. ReadreviewUrlfor the scenario, price, output, timing, and limitations.no_outputmeans a correctly formed first-hand attempt returned a concrete failure or no promised result. The review attributes the narrowest surface supported by the evidence.untestedis catalog metadata only. It is not a negative result or endorsement.popularuses reported x402 30-day calls. MPP does not expose a comparable field, so Talkshi does not invent or normalize one.recommendedputs 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 and
x402 Marketplace & Transaction Evidence.
Status codes
| Code | Meaning |
|---|---|
200 |
Search, service detail, outcome match, insurance shopping brief, saved-request read, or idempotent saved-request replay returned. |
201 |
A private procurement snapshot was created. |
401 |
A private request is missing a valid bearer token. |
403 |
The bearer identity is unverified, revoked, or otherwise ineligible. |
404 |
Unknown service ID, or missing, foreign, or expired private request. |
405 |
Wrong method for the selected endpoint. |
409 |
An idempotency key was reused with a different normalized request. |
413 |
An insurance file exceeds 25,000,000 bytes on the canonical endpoint or 3,000,000 bytes on the compatibility endpoint, an outcome-match or saved-request body exceeds 32 KiB, or an MCP envelope exceeds 128 KiB. |
415 |
An insurance file type is missing, unsupported, or inconsistent with its bytes, or an MCP request did not use Content-Type: application/json. |
422 |
Unknown filter, invalid pagination or outcome request, missing/invalid idempotency key, or a document that is unsupported or lacks usable commercial-insurance content. |
429 |
A public source budget, insurance-document limit, or private saved-request cap was reached; respect Retry-After. |
500 |
The catalog, database, or matcher could not process the request. |
503 |
Insurance-document processing or the public matcher throttle is temporarily unavailable. |
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.
