The problem starts when an agent receives an invoice as a PDF and needs five fields before it can approve payment. It does not want a page full of service names. It needs a service that accepts the file, states its price, returns a predictable object, and tells the agent whether the result is safe to use.
That is the real test for an AI service marketplace. An AI service marketplace with crypto payments must make the payment step as inspectable as the service step. A marketplace is a catalog plus a machine-readable request path that carries a job from selection to payment, execution, result, and recovery.
This article follows the invoice request because the checks are easy to see. A Tangle Blueprint is a reusable service template that defines jobs and the artifacts that an operator, the provider running the service, can run. An operator is the provider that runs a Blueprint on its own machine. The operator runtime is the environment where that service code runs, including its hardware, network, credentials, and isolation boundary. A Service is a live instance of a Blueprint with its own operator, configuration, and lifecycle. A Job is one callable unit of work sent to that Service. Tangle is the protocol network that coordinates these service definitions, operators, Jobs, payments, and lifecycle records. An x402 request is an HTTP payment flow in which a server returns payment requirements and the client retries with a signed payment payload.
The example uses an illustrative invoice service. It does not claim that Tangle currently exposes that exact endpoint or catalog schema. The public Tangle Blueprint docs, Blueprint SDK, a Rust toolkit for building services, and x402 docs are the authorities for the live integration surfaces.
Discovery starts with a job contract
The agent’s request is:
Extract vendor, invoice date, currency, subtotal, tax, total, and the source location of each field from this PDF.
That sentence gives the marketplace more useful information than the category “document AI.” The listing should answer:
| Field | Example |
|---|---|
| Job name | extract_invoice |
| Input | PDF or image under a stated size |
| Output | versioned JSON with fields and source locations |
| Price | fixed USDC amount, using a dollar-pegged token, or an expiring quote |
| Time limit | maximum queue and execution time |
| Data policy | who can read the file and how long it is retained |
| Evidence | request ID, input hash, model version, and result hash |
| Failure | unsupported file, timeout, provider error, or invalid result |
A listing that says “invoice AI” gives an agent nothing it can validate. The job contract is the product surface.
A machine-readable listing prevents guesswork
A human page can explain the service. An agent needs a structured record that it can compare with its own requirements.
{
"service": "invoice-extractor",
"blueprint": "invoice-extraction-v2",
"operator": "operator-example",
"jobs": [
{
"name": "extract_invoice",
"input": "application/pdf",
"maxBytes": 10000000,
"output": "invoice-json-v1",
"price": {
"asset": "USDC",
"amount": "$0.03"
},
"timeoutSeconds": 45,
"evidence": [
"request_id",
"input_hash",
"model_version",
"output_hash"
]
}
]
}
This is an illustrative catalog record. The version is important because a cached agent must know when an input limit, output schema, price, or evidence field changed. The operator field also matters because two providers can run the same Blueprint with different availability, data boundaries, and prices.
The catalog is a discovery aid, not a quality certificate. The caller still has to read the service release, operator policy, and result check.
A marketplace has three separate contracts
The listing becomes easier to review when its promises are separated into discovery, execution, and result contracts.
| Contract | Question it answers | Failure when it is missing |
|---|---|---|
| Discovery | Can a program find and compare this job? | The agent chooses by name or price alone |
| Execution | What exactly leaves the caller, and what does the operator do? | The request is accepted with an unclear data or timeout boundary |
| Result | What makes the returned object acceptable? | A paid response is treated as a correct answer |
The discovery contract is the catalog record. It should be stable enough for a program to filter candidates without opening a human page for every request. It should also carry a version and an update time so a cached record cannot silently outlive the interface it describes.
The execution contract begins when the caller selects a Service. It should identify the accepted media type, maximum size, request identifier, quote expiry, timeout, retry behavior, and retention policy. The request identifier connects a payment event to one attempt and prevents a retry from being mistaken for a second charge.
The result contract finishes the job. It should state the output schema, the model or artifact version, the evidence fields, and the check that turns a response into an accepted result. For invoice extraction, arithmetic consistency is one check, source locations are another, and a human review threshold may be a third. The marketplace should expose those checks instead of calling the output “verified” without a definition.
For the invoice example, a safe caller can make a small preflight decision:
sample candidate accepts application/pdf
-> candidate accepts the file size and data policy
-> sample quote covers one extract_invoice Job and expires in 60 seconds
-> result includes invoice-json-v1 and source locations
-> failure policy says whether a timeout is retryable or refundable
-> caller authorizes payment and sends the file
This preflight does not guarantee a good extraction. It prevents the more basic error of paying a service whose contract cannot satisfy the request.
Cache the contract, not the promise
An agent may cache a catalog record to avoid rediscovering the same service for every invoice. The cache needs an expiry and a version check because price, input limits, model behavior, and data policy can change independently.
Store the fields that explain the selection:
| Cached field | Why retain it |
|---|---|
| Blueprint and Service version | Reconstructs which interface the agent selected |
| Operator identity | Shows which provider received the request |
| Quote or price expiry | Prevents authorization against an old amount |
| Input and output schema | Lets the caller reject an incompatible request |
| Data and retention policy | Keeps a sensitive file from going to an unapproved boundary |
| Result and failure rules | Preserves the recovery action the agent was built to take |
Do not cache a quality conclusion as if it were a service property. The agent can remember that a particular result passed an evaluation on a particular version and task, but that evidence should not become “this operator is always correct.” The same service can change its model, upstream provider, queue behavior, or retention policy at its next release.
When a record expires, the safe behavior is to revalidate the fields that affect the current request. That may be only a price and version check for a public, low-risk extraction. It may require a fresh privacy and attestation review for a sensitive document.
x402 turns payment into a retryable HTTP step
The current x402 flow is:
client requests the paid endpoint
-> server responds 402 with PAYMENT-REQUIRED
-> wallet creates a payment payload
-> client retries with PAYMENT-SIGNATURE
-> server or facilitator verifies and settles
-> server returns the resource and PAYMENT-RESPONSE
x402 is useful for machine-to-machine payment because the caller can pay for one request without first creating a conventional account or subscription. A facilitator is an optional service that verifies payment payloads and can submit the settlement transaction for the server.
The payment event should remain separate from the result decision. Payment can prove that the caller authorized a charge. It cannot prove that the invoice fields are correct.
A current x402 client shape
The official x402 buyer quickstart uses the fetch wrapper, an exact Ethereum Virtual Machine (EVM) payment scheme, and a wallet signer. The following is a plausible Node or TypeScript client with the service URL left illustrative.
import type { Hex } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import {
x402Client,
x402HTTPClient,
wrapFetchWithPayment
} from '@x402/fetch'
import { registerExactEvmScheme } from '@x402/evm/exact/client'
const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as Hex)
const client = new x402Client()
registerExactEvmScheme(client, { signer })
const fetchWithPayment = wrapFetchWithPayment(fetch, client)
const response = await fetchWithPayment(
'https://service.example.com/invoice',
{
method: 'POST',
headers: { 'content-type': 'application/pdf' },
body: invoiceFile
}
)
if (!response.ok) {
throw new Error('paid invoice job failed with status ' + response.status)
}
const receiptReader = new x402HTTPClient(client)
const paymentReceipt = receiptReader.getPaymentSettleResponse(
(name) => response.headers.get(name)
)
const result = await response.json()
The package names and header handling follow the current x402 buyer quickstart. The endpoint and invoiceFile value are placeholders for a real seller. A production client should also pin the accepted network and asset, enforce a request timeout, protect the signing key, and handle an expired payment requirement without blindly paying twice.
Blueprints make the service repeatable
The marketplace does not execute the invoice extraction itself. It describes a Blueprint and selects or exposes a Service instance. The operator runs the service artifact, accepts the Job, and returns a result and evidence.
The Blueprint SDK docs describe the current Rust toolkit, Blueprint Runner, command-line tool, and optional HTTP or x402 gateways. The x402 gateway guide explains that a verified payment can be converted into a JobCall for the runner.
For each listing, a caller should be able to inspect:
| Marketplace field | Buyer decision |
|---|---|
| Blueprint and service version | Is this the interface the agent integrated with? |
| Operator identity and status | Who receives the file and can the instance accept work? |
| Price or quote expiry | Can the agent authorize the right amount at the right time? |
| Runtime and data policy | What can the operator or model provider access? |
| Timeout and retry rule | Should the agent wait, retry, or choose another instance? |
| Result and evidence | Can the agent validate and support the output? |
| Refund rule | What happens after payment but before a usable result? |
A lower price is not automatically the best listing. An operator with complete receipts, a clear data policy, and reliable recovery can be easier to use than one with a smaller quote.
The result needs an application check
The invoice service might return:
{
"vendor": "Example Supply",
"subtotal": 100.00,
"tax": 8.25,
"total": 108.25,
"source": {
"total": "page 1, lower right"
},
"request_id": "job-123",
"model_version": "invoice-model-v2"
}
The caller can run a cheap deterministic check:
function acceptInvoice(value: {
subtotal: number
tax: number
total: number
}) {
const expected = Math.round((value.subtotal + value.tax) * 100)
const actual = Math.round(value.total * 100)
return expected === actual
}
This check catches arithmetic inconsistency. It does not catch a vendor name copied from the wrong page or a tax rate misread by the model. The service needs more evidence for those cases, such as source locations, a fixed labeled test set, or human review above a value threshold.
An evaluation is a check against a stated task requirement. A trace is a structured record of the request, payment, operator steps, timings, errors, and result references. The caller should receive or be able to query enough of the trace to decide whether to accept, retry, refund, or escalate the result.
Retries need an identity rule
Payment makes retries more consequential than ordinary HTTP retries. A network timeout can mean that the operator never saw the Job, that the operator finished but the response was lost, or that the payment settled while the result was still being written. The caller must not infer which case occurred from a missing response alone.
Use an application-level request identifier or idempotency key for the Job. The operator can use it to return the prior result when the same request is safely replayed, or to state that the previous attempt is still running. The marketplace should document how long that identity remains valid and whether a new quote is required after expiry.
An illustrative retry record might look like this:
{
"request_id": "job-123",
"attempt": 2,
"payment": "settled-on-attempt-1",
"execution": "result-available",
"action": "retrieve-existing-result"
}
The record is not a current Tangle schema. It shows why payment state, execution state, and delivery state deserve separate fields. If the caller instead creates a new payment for every timeout, a transient network problem becomes a duplicate charge. If the operator returns the first result without checking the request identity, a later caller could receive another customer’s artifact.
The useful marketplace promise is narrower than “pay and get an answer.” It is “pay for a named Job, receive a result tied to that Job, and follow a documented recovery path when delivery is interrupted.”
Paid failures need distinct outcomes
Before adding ten services to a marketplace, exercise one service through its unhappy paths.
| Failure | What the agent needs to know |
|---|---|
| Unsupported input | Reject before payment or state the charge clearly |
| Expired payment requirement | Request a fresh requirement without replaying a stale payload |
| Payment accepted, operator unavailable | Retry another eligible instance or request the documented refund |
| Operator timeout | Know whether the original payment can be reused |
| Old service version | Reject the result or mark it as produced by an older contract |
| Schema-valid but wrong output | Run the application evaluation and escalate if needed |
“Something went wrong” is not a retry policy. An agent needs a typed failure, a safe next action, and a record that support can inspect.
For variable-cost jobs, request-for-quote job quotes and Tangle operator accountability explains how an expiring quote binds a price to a particular job. For privacy boundaries around paid inference, read Anonymous LLM Usage With Shielded Payments.
Crypto is a payment choice, not a marketplace strategy
Pay-per-request crypto payment fits a service with many small machine calls, variable cost, or buyers who do not need a long-lived account. It is not automatically better than cards, invoices, or subscriptions.
Cards and subscriptions can be easier when a human team needs refunds, procurement, tax documents, spending controls, and predictable monthly reconciliation. x402 can be easier when a program needs to authorize a precise request without creating an account first.
Neither payment rail solves discovery, operator quality, support, prompt privacy, or result correctness. Those decisions belong in the marketplace and service contract.
Decision rule
Build an AI service marketplace with crypto payments when you can define one bounded job, publish its input and output, quote it before work starts, return evidence after it finishes, and state what happens when payment succeeds but the job does not.
Start with one paid request that an agent can discover, authorize, validate, and retry. Add more services only after the first request has a visible result and a visible failure path.
What is an AI service marketplace with crypto payments?
It is a catalog and request path where people or programs discover a defined AI job, pay through crypto-native rails, and receive a result with evidence and failure behavior.
Why use pay-per-request instead of a subscription?
Pay-per-request can fit one-off jobs, machine-to-machine calls, and services whose cost changes with input size. Subscriptions can be better for predictable human usage and procurement.
What services should launch first?
Choose a job with a bounded input, clear output, observable success check, and explicit failure path. Invoice extraction, browser testing, code audit, and data transformation are possible examples when their boundaries are documented.
What does Tangle add?
Tangle provides the Blueprint and operator model for reusable services that independent providers can run. The marketplace still has to publish prices, versions, data boundaries, evidence, support, and recovery behavior.
Does x402 prove the service result is correct?
No. x402 proves a payment flow was authorized and settled according to the selected scheme. Result quality requires a separate evaluation matched to the job.