Teppi API
Read the record from code. Reads are free and need no key; paid endpoints answer 402 with their terms.
Quickstartthree ways in, no account
1Check before you pay
Grade, price and listing defects for any x402 url.
curl -s "https://api.teppi.xyz/v1/check?url=https://api.teppi.xyz/v1/docs/extract&method=POST"2Verify what it said
Every answer is signed against published keys.
import { check, publishedKeys, verify } from 'teppi-client';
const answer = await check(url);
await verify(answer, await publishedKeys());3Or hand it to an agent
The same record as MCP tools, no key.
{ "mcpServers": { "teppi": { "url": "https://api.teppi.xyz/mcp" } } }Free readsNo key, no payment. The record as JSON.
GET/v1/checkFree
Returns what the record holds about any x402 endpoint url before you pay it: the grade if one exists, the price and rails its last 402 offered, and what is wrong with the listing. A url never seen is put in line for a free handshake, so ask again in an hour.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
| url | query | string | required | uri · 8 to 2048 characters |
| method | query | string | optional | one of GET, POST |
| pay_to | query | string | optional | the payTo address from the 402, to learn what the record knows about who gets paid · matches ^0x[0-9a-fA-F]{40}$|^[1-9A-HJ-NP-Za-km-z]{32,44}$ |
Responses
200 · 98 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| band | string | required | a letter, or UNRATED when not enough is known · one of A, B, C, D, F, UNRATED |
| tier | string or null | required | what measured it · one of LIVENESS_VERIFIED, DELIVERY_VERIFIED, OUTCOME_VERIFIED, null |
| composite | number or null | required | the number the letter summarises |
| why | string | required | why the grade is what it is, in words |
| asked | string | required | the url or id as it was asked |
| matched | string | required | how the url met the record: exactly, by path alone, or not at all · one of exact, path, none |
| defects | array of object | required | what is wrong with the listing |
| defects[].defect | string | required | what the listing gets wrong |
| defects[].says | string | required | the same in words |
| defects[].seenAt | string or null | optional | when it was last seen |
| capabilityId | string | optional | the endpoint in the record, when it is there |
| url | string | optional | the url the record holds for it |
| components | object or null | optional | every part of the grade, each with its bound and sample count |
| components.liveness | object | optional | one measured part of the grade |
| components.liveness.point | number or null | required | what the samples showed |
| components.liveness.lower | number or null | required | the published lower bound |
| components.liveness.upper | number or null | optional | the upper bound, where one is computed |
| components.liveness.n_eff | number | required | effective samples behind it · at least 0 |
| components.liveness.method | string | required | how the bound was computed |
| components.correctness | object | optional | one measured part of the grade |
| components.correctness.point | number or null | required | what the samples showed |
| components.correctness.lower | number or null | required | the published lower bound |
| components.correctness.upper | number or null | optional | the upper bound, where one is computed |
| components.correctness.n_eff | number | required | effective samples behind it · at least 0 |
| components.correctness.method | string | required | how the bound was computed |
| components.honesty | object | optional | one measured part of the grade |
| components.honesty.point | number or null | required | what the samples showed |
| components.honesty.lower | number or null | required | the published lower bound |
| components.honesty.upper | number or null | optional | the upper bound, where one is computed |
| components.honesty.n_eff | number | required | effective samples behind it · at least 0 |
| components.honesty.method | string | required | how the bound was computed |
| components.schema_conformance | object | optional | one measured part of the grade |
| components.schema_conformance.point | number or null | required | what the samples showed |
| components.schema_conformance.lower | number or null | required | the published lower bound |
| components.schema_conformance.upper | number or null | optional | the upper bound, where one is computed |
| components.schema_conformance.n_eff | number | required | effective samples behind it · at least 0 |
| components.schema_conformance.method | string | required | how the bound was computed |
| components.latency_p95 | object | optional | one measured part of the grade |
| components.latency_p95.point | number or null | required | what the samples showed |
| components.latency_p95.lower | number or null | required | the published lower bound |
| components.latency_p95.upper | number or null | optional | the upper bound, where one is computed |
| components.latency_p95.n_eff | number | required | effective samples behind it · at least 0 |
| components.latency_p95.method | string | required | how the bound was computed |
| components.price_stability | object | optional | one measured part of the grade |
| components.price_stability.point | number or null | required | what the samples showed |
| components.price_stability.lower | number or null | required | the published lower bound |
| components.price_stability.upper | number or null | optional | the upper bound, where one is computed |
| components.price_stability.n_eff | number | required | effective samples behind it · at least 0 |
| components.price_stability.method | string | required | how the bound was computed |
| sampleCount | integer | optional | samples behind the grade · at least 0 |
| computedAt | string or null | optional | when the grade was computed |
| observationsSince | integer | optional | observations newer than the grade · at least 0 |
| withdrawnSince | integer | optional | records the grade stood on that a correction withdrew after it was signed; when it equals sampleCount the grade stands on nothing · at least 0 |
| flags | array of string | optional | conditions on the grade |
| observed | object | optional | what the free handshakes saw |
| observed.probes | integer | optional | handshakes · at least 0 |
| observed.answered | integer | optional | handshakes it answered · at least 0 |
| observed.askedForPayment | integer | optional | handshakes answered with a 402 · at least 0 |
| observed.firstSeen | string or null | optional | the first handshake |
| observed.lastSeen | string or null | optional | the newest handshake |
| observed.spanDays | number | optional | days from the first handshake to now |
| observed.advertised | object or null | optional | what its newest 402 asked |
| observed.advertised.amount | string | optional | the price · matches ^\d+\.\d{1,6}$ |
| observed.advertised.asset | string | optional | the token |
| observed.advertised.networks | array of string | optional | CAIP-2 ids |
| observed.distinctPrices | integer | optional | prices seen · at least 0 |
| observed.protocols | array of string | optional | x402, mpp |
| reproduce | string or null | optional | the command that runs the same handshake without us |
| scorecard | string or null | optional | the signed card behind the grade |
| corrections | array of object | optional | what we got wrong about it |
| corrections[].id | string | required | the correction id |
| corrections[].fault | string | required | which of our own faults it names |
| corrections[].says | string | required | what we got wrong |
| corrections[].issuedAt | string | required | when it was issued |
| corrections[].recordId | string or null | optional | the one record it names, or null for all of them |
| corrections[].gradeAt | string or null | optional | the one grade it names, or null |
| queued | boolean | optional | a url never seen, now in line for a handshake |
| next | string | optional | what to do next about a url the record has not seen |
| payee | object or null | optional | what the record knows about whoever pay_to names |
| payee.address | string | optional | the payout address |
| payee.origins | array of string | optional | origins that pay it |
| payee.listed | integer | optional | active endpoints behind it · at least 0 |
| payee.graded | integer | optional | of those, holding a letter · at least 0 |
| payee.bestBand | string or null | optional | the best letter behind it |
| payee.withDefects | integer | optional | of those, with a listing defect · at least 0 |
| buy | object | optional | how to buy it through Teppi and be charged only if the answer passes |
| buy.url | string | optional | where to send the call |
| buy.method | string | optional | GET or POST |
| buy.seller_price | string | optional | the seller's price as its own 402 last asked it · matches ^\d+\.\d{1,6}$ |
| buy.fee | string | optional | Teppi's fee on that price · matches ^\d+\.\d{1,6}$ |
| buy.total | string | optional | an estimate; the via url quotes again off the seller now · matches ^\d+\.\d{1,6}$ |
| buy.asset | string | optional | USDC |
| buy.guarantee | string | optional | when the buyer is charged |
| buy.publish | string | optional | the header that puts the call in the record |
| answered_at | string | required | when this answer was given |
| signing_key_id | string or null | required | the published key that signed this answer |
| canonicalization | string | optional | how the signed bytes were made: RFC8785 |
| signature | string or null | required | ed25519 over the canonical bytes of everything else here |
Example
curl -s "https://api.teppi.xyz/v1/check?url=https%3A%2F%2Fapi.teppi.xyz%2Fv1%2Fdocs%2Fextract&method=POST"
GET/v1/trust/{id}Free
Returns the quality grade for a paid endpoint, with the components behind it and a sample of the evidence. Use before paying an endpoint you have not used.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
| id | path | string | required | matches ^cap_[0-9A-HJKMNP-TV-Z]{26}$ |
Responses
200 · 30 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| schema | string | required | teppi.trust.v1 |
| capability_id | string | required | the endpoint |
| scorecards | array of object | required | the cards, deepest tier first |
| scorecards[].schema | string | required | teppi.scorecard.v1 or v2 |
| scorecards[].capability_id | string | required | the endpoint graded |
| scorecards[].tier | string | required | what measured it · one of LIVENESS_VERIFIED, DELIVERY_VERIFIED, OUTCOME_VERIFIED |
| scorecards[].band | string | required | the letter, or UNRATED · one of A, B, C, D, F, UNRATED |
| scorecards[].composite | number | required | the weighted sum of the lower bounds |
| scorecards[].components | object or null | required | every part of the grade, each with its bound and sample count |
| scorecards[].components.liveness | object | optional | one measured part of the grade |
| scorecards[].components.correctness | object | optional | one measured part of the grade |
| scorecards[].components.honesty | object | optional | one measured part of the grade |
| scorecards[].components.schema_conformance | object | optional | one measured part of the grade |
| scorecards[].components.latency_p95 | object | optional | one measured part of the grade |
| scorecards[].components.price_stability | object | optional | one measured part of the grade |
| scorecards[].weights_applied | object | optional | the weight each scored part carried |
| scorecards[].weights_version | string | optional | which weights |
| scorecards[].sample_count | integer | optional | samples behind it · at least 0 |
| scorecards[].window_days | integer | optional | the window it read · at least 0 |
| scorecards[].window_start | string | optional | where the window starts |
| scorecards[].computed_at | string | optional | when it was computed |
| scorecards[].flags | array of string | optional | conditions on the grade |
| scorecards[].evidence_sample | array of string | optional | the evidence hashes it stood on |
| scorecards[].method | string | optional | the method page it was computed under |
| scorecards[].verifier_version | string | optional | which verifier scored the samples |
| scorecards[].signing_key_id | string | optional | the published key that signed it |
| scorecards[].canonicalization | string | optional | RFC8785 |
| scorecards[].signature | string | required | ed25519 over the canonical bytes of the card |
| disputes | array of object | required | the seller's own receipts |
| corrections | array of object | required | what we got wrong |
Example
curl -s https://api.teppi.xyz/v1/trust/cap_01M2WA8B847Y9F6Y9EBWV2R7G5
GET/v1/trust/indexFree
One line per listed x402 endpoint: its band, the tier it stands on, its sample count, its defects and its signed card. Use to show the record beside every listing in a catalog.
Takes no parameters.
Responses
200 no response schema is published yet; run the example to see one
Example
curl -s https://api.teppi.xyz/v1/trust/index
GET/v1/trust/feedFree
Streams every grade as it is published, newline delimited, resumable from a cursor. Use to mirror the whole record.
Takes no parameters.
Responses
200 no response schema is published yet; run the example to see one
Example
curl -sN https://api.teppi.xyz/v1/trust/feed
GET/v1/archiveFree
Lists every file old handshakes, server looks and free cards were moved to, with the hash each unpacks to. Use to fetch what the database no longer holds.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
| subject | query | string | optional | one of liveness_probes, mcp_probes, grades, mcp_grades |
| page | query | integer | optional | at least 1 |
Responses
200 · 20 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| schema | string | required | teppi.archive.list.v1 |
| kept_in_the_database_for | object | required | how long each table keeps a row before it may move, iso 8601 |
| never_moved | array of string | required | what always stays |
| manifests | array of object | required | this page of files |
| manifests[].schema | string | required | teppi.archive.v1 |
| manifests[].id | string | required | the manifest |
| manifests[].subject | string | required | the table the rows came from · one of liveness_probes, mcp_probes, grades, mcp_grades |
| manifests[].from | string | required | the start of the day the rows fall in, iso 8601 utc |
| manifests[].to | string | required | the end of that day, exclusive |
| manifests[].rows | integer | required | how many rows the file holds · at least 0 |
| manifests[].content_hash | string | required | sha256 of the file once unpacked |
| manifests[].bytes | integer | required | the size of the file as served, packed · at least 0 |
| manifests[].verified_at | string | optional | when the file was read back from the store and hashed again |
| manifests[].format | string | optional | what a line of the file is |
| manifests[].file | string | required | where the file is served |
| manifests[].reproduce | string | optional | the command that fetches it and prints its hash |
| manifests[].signing_key_id | string | required | the published key that signed it, the one that signs scorecards |
| manifests[].canonicalization | string | optional | RFC8785 |
| manifests[].signature | string | required | ed25519 over the canonical bytes of the manifest |
| next | string or null | required | the next page, or null on the last |
Example
curl -s https://api.teppi.xyz/v1/archive
GET/v1/archive/{id}Free
Returns one archive manifest: the day, the row count, the hash of the unpacked file, and the command that fetches and checks it.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
| id | path | string | required | matches ^arc_[0-9A-HJKMNP-TV-Z]{26}$ |
Responses
200 · 15 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| schema | string | required | teppi.archive.v1 |
| id | string | required | the manifest |
| subject | string | required | the table the rows came from · one of liveness_probes, mcp_probes, grades, mcp_grades |
| from | string | required | the start of the day the rows fall in, iso 8601 utc |
| to | string | required | the end of that day, exclusive |
| rows | integer | required | how many rows the file holds · at least 0 |
| content_hash | string | required | sha256 of the file once unpacked |
| bytes | integer | required | the size of the file as served, packed · at least 0 |
| verified_at | string | optional | when the file was read back from the store and hashed again |
| format | string | optional | what a line of the file is |
| file | string | required | where the file is served |
| reproduce | string | optional | the command that fetches it and prints its hash |
| signing_key_id | string | required | the published key that signed it, the one that signs scorecards |
| canonicalization | string | optional | RFC8785 |
| signature | string | required | ed25519 over the canonical bytes of the manifest |
Example
curl -s https://api.teppi.xyz/v1/archive/cap_01M2WA8B847Y9F6Y9EBWV2R7G5
POST/v1/route/planFree
Turns a goal and a budget into a costed chain of endpoints, before any money is spent. Returns the plan and the estimate.
Request body application/json
| Name | Type | Required | Notes |
|---|---|---|---|
| goal | string | required | |
| budget_usd | string | required |
Responses
200 · 19 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| plan_id | string | required | the plan · matches ^pln_[0-9A-HJKMNP-TV-Z]{26}$ |
| estimated_usd | string | required | what the plan is expected to cost · matches ^\d+\.\d{1,6}$ |
| budget_usd | string | optional | the budget asked for |
| expires_at | string | required | when the quote stops being buyable |
| ttl_seconds | integer | optional | seconds the quote holds · at least 0 |
| steps | array of object | required | the calls, in order |
| steps[].index | integer | required | its place in the plan · at least 0 |
| steps[].class | string | required | what kind of call |
| steps[].capability_id | string | required | the endpoint picked |
| steps[].grade | object | optional | its grade and what measured it |
| steps[].grade.band | string | optional | one of A, B, C, D, F, UNRATED |
| steps[].grade.tier | string or null | optional | one of LIVENESS_VERIFIED, DELIVERY_VERIFIED, OUTCOME_VERIFIED, null |
| steps[].est_usd | string | required | its expected price · matches ^\d+\.\d{1,6}$ |
| steps[].purpose | string | optional | what the step is for |
| steps[].fallbacks | array of string | optional | endpoints tried instead, no dearer |
| missing | array of object | required | what the goal needed that nothing listed could do |
| missing[].class | string or null | optional | the kind of call |
| missing[].reason | string | optional | why it is missing |
| guarantee | string | required | when a buyer of the plan is charged |
Example
curl -si -X POST https://api.teppi.xyz/v1/route/plan -H 'content-type: application/json' -d '{}'
POST/v1/evaluateFree
Checks an answer you already got from a listed endpoint against the schema its seller published, and signs what the checks found. Free, and nothing is written to the record.
Request body application/json
| Name | Type | Required | Notes |
|---|---|---|---|
| capability_id | string | required | matches ^cap_[0-9A-HJKMNP-TV-Z]{26}$ |
| status | integer | required | at least 100 · at most 599 |
| body | string | required | 0 to 1000000 characters |
Responses
200 · 21 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| capability | object | required | |
| capability.id | string | optional | the endpoint |
| capability.url | string | optional | its url |
| capability.method | string | optional | GET or POST |
| evaluated | object | required | the answer judged, by its hash |
| evaluated.status | integer | optional | its status · at least 0 |
| evaluated.body | string | optional | sha256 of its body |
| passed | boolean | required | whole and matching the schema |
| checks | array of object | required | each check and its result |
| schema_declared | boolean | optional | the seller published a schema |
| schema_conformance | number or null | optional | share of the schema met |
| injection_observed | boolean | optional | the body tried to give instructions |
| honesty | null | optional | not measured: nothing was paid |
| correctness | null | optional | not measured: nobody holds the right answer |
| not_measured | string | optional | why |
| recorded | boolean | optional | nothing is written |
| verifier_version | string | optional | which verifier judged it |
| answered_at | string | required | when this answer was given |
| signing_key_id | string or null | optional | the published key that signed this answer |
| canonicalization | string | optional | how the signed bytes were made: RFC8785 |
| signature | string or null | required | ed25519 over the canonical bytes of everything else here |
Example
curl -si -X POST https://api.teppi.xyz/v1/evaluate -H 'content-type: application/json' -d '{}'
POST/v1/exposureFree
Looks up every paid endpoint your agents call at once and adds them up by the address each one pays: which are unknown, which took money and returned nothing, which list what they do not serve, and what that spend is. Free, signed, and a url never seen is put in line for a free handshake.
Request body application/json
| Name | Type | Required | Notes |
|---|---|---|---|
| dependencies | array of any | required | the paid endpoints your agents call, each a url or an object naming one |
Responses
200 · 52 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| schema | string | required | this document |
| dependencies | array of object | required | one line per dependency, in the order asked |
| dependencies[].asked | string | required | the url or id as sent |
| dependencies[].capability_id | string or null | required | the endpoint the record matched, or null |
| dependencies[].matched | string | required | how · one of exact, path, none |
| dependencies[].standing | string | required | what to look at first; not_in_record and handshake_only mean unknown · one of not_in_record, took_the_money, listing_mismatch, lettered, paid_no_letter, handshake_only |
| dependencies[].band | string | required | the deepest card, UNRATED if none · one of A, B, C, D, F, UNRATED |
| dependencies[].tier | string or null | required | what it stands on · one of LIVENESS_VERIFIED, DELIVERY_VERIFIED, OUTCOME_VERIFIED, null |
| dependencies[].sample_count | integer | optional | samples behind the card · at least 0 |
| dependencies[].computed_at | string or null | optional | when the card was worked out |
| dependencies[].paid_calls | integer | optional | paid calls the record holds, less any we withdrew · at least 0 |
| dependencies[].took_the_money | integer | optional | of those, settled with nothing back · at least 0 |
| dependencies[].defects | array of object | required | what the listing gets wrong before payment |
| dependencies[].defects[].defect | string | required | what the listing gets wrong |
| dependencies[].defects[].says | string | required | the same in words |
| dependencies[].defects[].seenAt | string or null | optional | when it was last seen |
| dependencies[].price | string or null | optional | the listed price · matches ^\d+\.\d{1,6}$ |
| dependencies[].payout | string or null | optional | the address it pays, when the 402 or the record names one |
| dependencies[].pay_to_seen_before | boolean or null | optional | the pay_to sent is one this seller was seen paying; null when unknowable |
| dependencies[].calls_per_month | integer or null | optional | as sent · at least 0 |
| dependencies[].monthly_spend | string or null | optional | price times calls_per_month · matches ^\d+\.\d{1,6}$ |
| dependencies[].card | string or null | optional | the signed card |
| dependencies[].reproduce | string or null | optional | the command that reruns the free handshake |
| by_payout | array of object | required | each address the fleet pays, and everything the record holds behind it |
| by_payout[].payout | string | required | the address |
| by_payout[].your_dependencies | integer | required | of the dependencies sent, how many pay it · at least 0 |
| by_payout[].origins | integer | optional | origins behind it · at least 0 |
| by_payout[].listed | integer | required | active endpoints behind it · at least 0 |
| by_payout[].lettered | integer | optional | of those, holding a letter · at least 0 |
| by_payout[].best_band | string or null | optional | the best letter behind it |
| by_payout[].with_defects | integer | optional | of those, with a listing defect · at least 0 |
| by_payout[].took_the_money | integer | required | of those, with a paid call settled and nothing back · at least 0 |
| totals | object | required | the lines added up; spend counts only lines that sent calls_per_month |
| totals.dependencies | integer | optional | lines · at least 0 |
| totals.not_in_record | integer | optional | unknown to the record · at least 0 |
| totals.took_the_money | integer | optional | settled with nothing back · at least 0 |
| totals.listing_mismatch | integer | optional | a defect before payment · at least 0 |
| totals.lettered | integer | optional | holding a letter · at least 0 |
| totals.paid_no_letter | integer | optional | paid for, too few samples for a letter · at least 0 |
| totals.handshake_only | integer | optional | answers a handshake, never paid for · at least 0 |
| totals.payouts | integer | optional | distinct addresses paid · at least 0 |
| totals.priced | integer | optional | lines with a spend · at least 0 |
| totals.monthly_spend | string | optional | all of it · matches ^\d+\.\d{1,6}$ |
| totals.monthly_spend_where_the_record_shows_a_failure | string | optional | took the money, a defect, D or F · matches ^\d+\.\d{1,6}$ |
| totals.monthly_spend_not_yet_measured | string | optional | no letter and no failure shown: unknown · matches ^\d+\.\d{1,6}$ |
| watch | object | optional | where to be told when a card falls |
| watch.url | string | optional | the endpoint |
| watch.says | string | optional | what to post |
| answered_at | string | required | when this answer was given |
| signing_key_id | string or null | optional | the published key that signed this answer |
| canonicalization | string | optional | how the signed bytes were made: RFC8785 |
| signature | string or null | required | ed25519 over the canonical bytes of everything else here |
Example
curl -si -X POST https://api.teppi.xyz/v1/exposure -H 'content-type: application/json' -d '{}'
POST/v1/watchersFree
Registers an https receiver to be posted a signed notice whenever the card of an endpoint it names falls. The receiver is sent a challenge first and must echo it; the token in the answer is shown once and reads or stops the watcher.
Request body application/json
| Name | Type | Required | Notes |
|---|---|---|---|
| url | string | required | matches ^https:[/]{2} · 0 to 2048 characters |
| watch | array of string | required | capability ids or urls to be told about |
Responses
200 · 10 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| watcher_id | string | required | the watcher |
| token | string | required | the one way to read or stop it; shown once and never again |
| url | string | required | where notices are posted |
| watching | array of string | required | the capability ids it is told about |
| not_in_record | array of string | required | what was named and is not in the record, so nothing will be said about it |
| since | string | required | nothing computed before this is news to it |
| manage | string | optional | where to read it back, with the token as a bearer |
| stop | string | optional | where to stop it, with the token as a bearer |
| notices | string | optional | the schema of what is posted: teppi.notice.v1 |
| says | string | optional | what to do with the token |
Example
curl -si -X POST https://api.teppi.xyz/v1/watchers -H 'content-type: application/json' -d '{}'
GET/v1/watchers/{watcher_id}Free
Reads a watcher back, with the token from registering as a bearer: what it follows, whether it is active, and the last fifty notices with whether each arrived.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
| watcher_id | path | string | required | matches ^wch_[0-9A-HJKMNP-TV-Z]{26}$ |
Responses
200 · 16 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| watcher_id | string | required | the watcher |
| url | string | required | where notices are posted |
| active | boolean | required | false once stopped; a stopped watcher stays stopped |
| created_at | string | optional | when it was registered |
| watching | array of string | required | the capability ids it is told about |
| notices | array of object | required | |
| notices[].notice_id | string | required | the notice |
| notices[].capability_id | string | required | what it is about |
| notices[].tier | string | optional | the tier that moved |
| notices[].change | string | required | band_fell, evidence_lapsed, depth_lost, flag_raised or composite_fell |
| notices[].from | string | optional | before |
| notices[].to | string | optional | after |
| notices[].observed_at | string | optional | when the card that moved was worked out |
| notices[].delivered_at | string or null | required | when the receiver took it, or null |
| notices[].attempts | integer | required | tries so far · at least 0 |
| notices[].last_error | string or null | optional | what the last failed try met |
Example
curl -s https://api.teppi.xyz/v1/watchers/cap_01M2WA8B847Y9F6Y9EBWV2R7G5
POST/v1/watchers/stopFree
Stops a watcher for good, with the token from registering as a bearer. A stopped watcher is sent nothing more and cannot be started again; register a new one instead.
Request body application/json
| Name | Type | Required | Notes |
|---|---|---|---|
| watcher_id | string | required | matches ^wch_[0-9A-HJKMNP-TV-Z]{26}$ |
Responses
200 · 2 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| watcher_id | string | required | the watcher |
| active | boolean | required | stopped |
Example
curl -si -X POST https://api.teppi.xyz/v1/watchers/stop -H 'content-type: application/json' -d '{}'
GET/v1/orders/{order_id}Free
Returns the signed receipt for one purchase made on delivery: the quote, both payments with their transactions, the checks the answer met, and commitments to the bytes.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
| order_id | path | string | required | matches ^ord_[0-9A-HJKMNP-TV-Z]{26}$ |
Responses
200 · 44 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| schema | string | required | teppi.order.v1 |
| order_id | string | required | the order |
| kind | string | required | a call, a plan or a step · one of via, plan, step |
| status | string | required | open, passed, failed or refused |
| reason | string or null | optional | why it did not pass |
| capability | object or null | optional | the endpoint bought, null on a plan |
| capability.id | string | optional | the endpoint |
| capability.url | string | optional | its url |
| capability.method | string | optional | GET or POST |
| plan | object or null | optional | every try at every step, on a plan |
| part_of | object or null | optional | the plan a step belongs to |
| quote | object | required | what the buyer was quoted |
| quote.seller_price | string | optional | the seller's price · matches ^\d+\.\d{1,6}$ |
| quote.fee | string | optional | Teppi's fee · matches ^\d+\.\d{1,6}$ |
| quote.total | string | optional | what the buyer signed for · matches ^\d+\.\d{1,6}$ |
| quote.asset | string | optional | USDC |
| buyer | string | required | the address that bought it |
| paid | object or null | optional | what the buyer paid |
| paid.receipt_id | string | optional | the receipt |
| paid.network | string | optional | the chain it settled on, CAIP-2 |
| paid.settled | string or null | optional | what moved, null until the chain has said · matches ^\d+\.\d{1,6}$ |
| paid.transaction | string or null | optional | the transaction |
| paid.final | boolean | optional | the receipt is closed |
| bought | object or null | optional | what Teppi paid the seller |
| bought.receipt_id | string | optional | the receipt |
| bought.network | string | optional | the chain it settled on, CAIP-2 |
| bought.settled | string or null | optional | what moved, null until the chain has said · matches ^\d+\.\d{1,6}$ |
| bought.transaction | string or null | optional | the transaction |
| bought.final | boolean | optional | the receipt is closed |
| request_commitment | string | optional | salted hash of the request |
| response_commitment | string or null | optional | salted hash of the answer |
| commitment_scheme | string | optional | how to check a commitment with the salt |
| checks | array or null | optional | what the answer was checked against |
| delivery | object | optional | liveness, schema conformance, honesty |
| correctness | string | optional | why correctness is not measured on a buyer's own request |
| published | boolean | optional | the buyer put the call in the record |
| evidence | string or null | optional | the record entry, when published |
| verifier_version | string or null | optional | which verifier checked it |
| opened_at | string | optional | when it was opened |
| closed_at | string or null | optional | when it closed |
| issued_at | string | required | when this receipt was issued |
| signing_key_id | string or null | optional | the published key that signed this answer |
| canonicalization | string | optional | how the signed bytes were made: RFC8785 |
| signature | string or null | required | ed25519 over the canonical bytes of everything else here |
Example
curl -s https://api.teppi.xyz/v1/orders/cap_01M2WA8B847Y9F6Y9EBWV2R7G5
GET/v1/buyers/{address}/ordersFree
Lists every purchase an address made on delivery, with what it was charged and what was not charged, when the request is signed by that address.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
| address | path | string | required | matches ^0x[0-9a-fA-F]{40}$ |
| page | query | integer | optional | at least 1 |
Responses
200 · 18 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| buyer | string | required | the address |
| totals | object | required | |
| totals.orders | integer | optional | orders · at least 0 |
| totals.passed | integer | optional | passed and charged · at least 0 |
| totals.not_charged | integer | optional | failed and not charged · at least 0 |
| totals.charged | string | optional | what the buyer was charged · matches ^\d+\.\d{1,6}$ |
| totals.covered_for_you | string | optional | what Teppi paid sellers for answers that failed · matches ^\d+\.\d{1,6}$ |
| page | integer | required | the page · at least 0 |
| orders | array of object | required | |
| orders[].order_id | string | optional | the order |
| orders[].kind | string | optional | via or plan |
| orders[].status | string | optional | its status |
| orders[].reason | string or null | optional | why it did not pass |
| orders[].capability | object or null | optional | the endpoint |
| orders[].plan_id | string or null | optional | the plan |
| orders[].total | string | optional | what it was quoted · matches ^\d+\.\d{1,6}$ |
| orders[].charged | string or null | optional | what was charged · matches ^\d+\.\d{1,6}$ |
| orders[].opened_at | string | optional | when it was opened |
Example
curl -s https://api.teppi.xyz/v1/buyers/cap_01M2WA8B847Y9F6Y9EBWV2R7G5/orders
Paid over x402Answer 402 with their terms; any x402 client pays and retries.
POST/v1/docs/extract$0.02 USDC a call · x402
Returns structured json extracted from a public pdf or html document url. Use when you have a document link and need typed fields.
Request body application/json
| Name | Type | Required | Notes |
|---|---|---|---|
| url | string | required | uri |
Responses
200 · 15 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| url | string | required | |
| content_type | string | required | |
| sha256 | string | required | matches ^sha256:[0-9a-f]{64}$ |
| bytes | integer | required | at least 0 |
| pages | integer or null | required | at least 1 |
| title | string or null | required | |
| headings | array of object | required | |
| headings[].level | integer | required | at least 1 |
| headings[].text | string | required | |
| links | array of object | required | |
| links[].href | string | required | |
| links[].text | string | required | |
| text | string | required | |
| text_chars | integer | required | at least 0 |
| truncated | boolean | required |
402 sent without payment: the terms are in the body and the payment-required header, settled in USDC on Base. Any x402 client pays and retries.
Example
curl -si -X POST https://api.teppi.xyz/v1/docs/extract -H 'content-type: application/json' -d '{"url":"https://example.com"}'
POST/v1/companies/lookup$0.02 USDC a call · x402
Returns legal entities matching a company name or lei, with jurisdiction, status and registered city, as the global lei registry publishes them.
Request body application/json
| Name | Type | Required | Notes |
|---|---|---|---|
| query | string | required | 2 to 200 characters |
Responses
200 · 11 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| query | string | required | |
| source | string | required | one of gleif |
| matches | array of object | required | |
| matches[].lei | string | required | matches ^[A-Z0-9]{20}$ |
| matches[].legal_name | string | required | |
| matches[].jurisdiction | string or null | required | |
| matches[].status | string or null | required | |
| matches[].registration_status | string or null | required | |
| matches[].city | string or null | required | |
| matches[].country | string or null | required | |
| matches[].last_update | string or null | required |
402 sent without payment: the terms are in the body and the payment-required header, settled in USDC on Base. Any x402 client pays and retries.
Example
curl -si -X POST https://api.teppi.xyz/v1/companies/lookup -H 'content-type: application/json' -d '{"query":"Coinbase"}'
POST/v1/web/evidence$0.02 USDC a call · x402
Returns source urls and verbatim quotations for a factual query, where every quote can be found at the url it cites.
Request body application/json
| Name | Type | Required | Notes |
|---|---|---|---|
| query | string | required | 3 to 300 characters |
Responses
200 · 8 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| query | string | required | |
| source | string | required | one of brave |
| searched | integer | required | at least 0 |
| fetched | integer | required | at least 0 |
| citations | array of object | required | |
| citations[].url | string | required | matches ^https:\/\/ |
| citations[].title | string or null | required | |
| citations[].quote | string | required | 24 to 2000 characters |
402 sent without payment: the terms are in the body and the payment-required header, settled in USDC on Base. Any x402 client pays and retries.
Example
curl -si -X POST https://api.teppi.xyz/v1/web/evidence -H 'content-type: application/json' -d '{"query":"x402 payment protocol"}'
POST/v1/research/brief$0.02 USDC a call · x402
Returns a brief on a factual query made only of verbatim quotes from public pages, each numbered to the url it was taken from.
Request body application/json
| Name | Type | Required | Notes |
|---|---|---|---|
| query | string | required | 3 to 300 characters |
Responses
200 · 6 fields
| Name | Type | Required | Notes |
|---|---|---|---|
| query | string | required | |
| brief | string | required | |
| citations | array of object | required | |
| citations[].url | string | required | matches ^https:\/\/ |
| citations[].title | string or null | required | |
| citations[].quote | string | required | 24 to 2000 characters |
402 sent without payment: the terms are in the body and the payment-required header, settled in USDC on Base. Any x402 client pays and retries.
Example
curl -si -X POST https://api.teppi.xyz/v1/research/brief -H 'content-type: application/json' -d '{"query":"x402 payment protocol"}'
Bought on deliveryTeppi buys from the seller for you, and charges only for an answer that passes.
POST/v1/route/executeThe seller's price + 10%, at least $0.002 USDC · x402
Buys every step of a plan from /v1/route/plan with one payment, and settles it only if every answer came back whole and matching the schema its seller published.
Request body application/json
| Name | Type | Required | Notes |
|---|---|---|---|
| plan_id | string | required | matches ^pln_[0-9A-HJKMNP-TV-Z]{26}$ |
| inputs | object | optional | Each step's input by its index. {"$from": {"step": 0, "pointer": "/id"}} copies a value out of an earlier step's answer. |
Responses
200 no response schema is published yet; run the example to see one
402 sent without payment: the seller's price plus the fee, in the body and the payment-required header, settled in USDC on Base only once the answer passes.
424 the answer failed its checks, and nothing was charged.
Example
curl -si -X POST https://api.teppi.xyz/v1/route/execute -H 'content-type: application/json' -d '{}'
GET/v1/via/{capability_id}The seller's price + 10%, at least $0.002 USDC · x402
Buys one call to a listed GET endpoint for you, with the query you send, and settles your payment only if the answer came back whole and matching its published schema.
Parameters
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
| capability_id | path | string | required | The endpoint to buy, by the id the record lists it under. · matches ^cap_[0-9A-HJKMNP-TV-Z]{26}$ |
Responses
200 no response schema is published yet; run the example to see one
402 sent without payment: the seller's price plus the fee, in the body and the payment-required header, settled in USDC on Base only once the answer passes.
424 the answer failed its checks, and nothing was charged.
Example
curl -s https://api.teppi.xyz/v1/via/cap_01M2WA8B847Y9F6Y9EBWV2R7G5
POST/v1/via/{capability_id}The seller's price + 10%, at least $0.002 USDC · x402
Buys one call to a listed POST endpoint for you, with the json body you send, and settles your payment only if the answer came back whole and matching its published schema.
Request body application/json
| Name | Type | Required | Notes |
|---|
Responses
200 no response schema is published yet; run the example to see one
402 sent without payment: the seller's price plus the fee, in the body and the payment-required header, settled in USDC on Base only once the answer passes.
424 the answer failed its checks, and nothing was charged.
Example
curl -si -X POST https://api.teppi.xyz/v1/via/{capability_id} -H 'content-type: application/json' -d '{}'
MoreAgents, files for programs, and libraries.
MCPhttps://api.teppi.xyz/mcpFree
The same record as tools, for any agent that speaks the Model Context Protocol. Streamable HTTP, protocol version 2025-06-18, no key.
| Tool | What it does | |
|---|---|---|
| search_capabilities | Search paid capabilities Search paid agent capabilities by task description. Returns the price, the input and output schemas, the networks each one settles on, and what has been verified about it. Sort by verified to put the ones with the most evidence behind them first. Use before paying an x402 endpoint you have not used. |
read only |
| get_capability | One capability in full Full detail for one capability: schemas, pricing, networks, the seller behind it, and every observation recorded against it. |
read only |
| plan_route | Plan a route Turn a goal and a budget into an ordered list of paid endpoints that could reach it, with a cost estimate and what has been verified about each step. Moves no money and buys nothing: it returns the plan for you to run yourself. |
read only |
| check_grade | What has been verified Return what has been verified about an x402 endpoint or its url: whether it answers, what it charges, and whether that price has moved. Answers unrated rather than guessing when the evidence is thin. Works for endpoints Teppi does not operate, and a url never seen is put in line for a free handshake, so ask again in an hour. |
read only |
| check_exposure | What your paid dependencies deliver Look up every paid endpoint your agents call in one go, added up by the address each one pays: which are unknown to the record, which took money and returned nothing, which list what they do not serve, and how much monthly spend sits on each. Unknown is reported as unknown, never as bad. |
read only |
Machine filesserved by api.teppi.xyz
| OpenAPI 3.1 | /openapi.json ↗ | This page, as a spec a tool generator reads |
| x402 manifest | /.well-known/x402 ↗ | Every paid endpoint with its price and networks |
| A2A agent card | /.well-known/agent-card.json ↗ | Who serves this, and its skills |
| ERC-8004 registration | /.well-known/agent-registration.json ↗ | The identity the service holds on chain |
| Signing keys | /.well-known/teppi-keys.json ↗ | The keys a grade and a check answer are signed with |
| llms.txt | /llms.txt ↗ | All of it in one text file an agent reads first |
| Check before you pay | /docs/check-before-you-pay ↗ | A worked example: ask the record, then pay |
| In your client | /docs/integrations ↗ | Where that check goes in the x402 client, a fetch or MCP |
| Skill file | /docs/skill ↗ | Makes an agent ask the record before it pays |
| Cursor rule | /docs/cursor-rule ↗ | The same instruction for Cursor |
| For catalogs | /docs/listings ↗ | The whole market in one file, and how to show it |
| The method | /docs/verification-method ↗ | How a grade is produced, versioned |
| Reports | /docs/reports ↗ | What the record says about the whole market, monthly |