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:

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:

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:

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:

Important offer fields:

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

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.