x402 content artifacts textus.dev/docs

Developer guide · Content contract 1.1.0

Find content. Buy production material.

Inspect free metadata, buy one exact content JSON, and keep or steer its baseline direction. No Textus account, hidden client secret, or framework requirement.

Start with the content contract →

1. Evaluate the complete format without a wallet

Download the free synthetic content example. Its multi-scene dialogue demonstrates text, normalization, documented and unknown bibliographic roles, narrator and character casting, exact utterance and non-spoken spans, and editable pace and delivery choices. It is evaluation material, not a purchasable resource or a real pilot-work excerpt. Its embedded rights permit evaluation, integration testing and documentation only.

curl -fsS https://api.textus.dev/api/v1/samples/content-production-material.json

2. Discover a resource that fits the task

For machine-readable search discovery, start at the API index. Its search object gives the GET metadata-search URI template in RFC 6570 form. Omit unused variables rather than sending empty values, then follow returned pagination links. Catalogue GET responses, including errors, expose a Link header to browser clients: service-meta points to the index, service-desc to OpenAPI and service-doc to this guide. The catalogue JSON contract is unchanged.

Read the free resource catalogue. Compare type, language, metadata, rights, editorial status, and exact delivery identity with your task. A discovery record is not the paid content. If a required property is unknown or the offer does not fit the task or budget, do not buy.

Current records expose metadata.bibliography both before purchase and in the paid JSON. Inspect authors, collectors, editors and translators separately. Each role has status (documented or unknown) and persons with a name, source URL and credited or traditional attribution. A collector is not automatically the author, and unknown means no attribution is supplied—not a rights clearance. Current artifacts use schema version 1.1; the major-version-1 schemas continue to validate historical 1.0 deliveries.

curl -fsS https://api.textus.dev/api/v1/resources.json

The public catalogue contains released content only. Deferred review records are excluded from listings, search and counts. A listed resource can still be temporarily unpurchasable when payments are disabled. Without a query, discovery returns the full {contractVersion,data} public catalogue. Any valid nonempty query enables pagination: page defaults to 1 (1–1000000), limit to 25 (1–100). Combine language, resourceType, author, collector and purchaseAvailable=true|false with AND. Language and type match exactly; author and collector match case-insensitive Unicode substrings of names in their separate bibliography roles. Unknown roles do not match.

Add optional q to search free metadata on the same endpoint: title, themes, character labels, scene titles and bibliographic person names. Supply 1–200 UTF-8 bytes before normalization and at most ten whitespace-separated terms. Surrounding whitespace is trimmed and repeated whitespace is collapsed. Every term must match a literal, case-insensitive Unicode substring somewhere in those combined fields; terms and other filters combine with AND. Punctuation is literal, not query syntax. Control characters and searches without any letter or number are invalid. There is no stemming, translation, semantic matching, relevance ranking or search of paid full text.

curl -fsS --get 'https://api.textus.dev/api/v1/resources.json' --data-urlencode 'q=friendship' --data-urlencode 'language=en' --data-urlencode 'resourceType=fable'

Send short content keywords, not complete user prompts, personal data, credentials or wallet material. Textus can measure only criteria sent to its catalogue endpoint. The full catalogue remains available for private selection within your own client; search is optional. See the privacy notice for the bounded first-party demand statistics.

Responses containing q use Cache-Control: private, no-store because continuation links include the search text. Full-catalogue and filter-only responses remain publicly cacheable for up to 60 seconds. Private or cached searches outside Textus are not observable.

curl -fsS 'https://api.textus.dev/api/v1/resources.json?language=de&collector=Grimm&purchaseAvailable=true&limit=25&page=1'

This free query finds currently purchasable German resources collected by Grimm; it does not buy anything. Select a returned record only after checking its task fit, rights and budget. If no record fits, do not buy.

Queried results sort by ID ascending and add pagination with page, limit, total, snapshot, next and previous. Follow the canonical absolute links; they retain q, filters, page size and the snapshot of all filtered records. Missing links are null. If the catalogue changes, 409 catalogue_changed means discard the old traversal and restart from page 1 without snapshot. An out-of-range page has empty data, null next and a previous link to the last available page.

Unknown, duplicate, empty or malformed parameters return 400 invalid_query. Page and limit must be positive decimal integers without leading zeros; language syntax is ^[a-z]{2,3}(?:-[A-Z]{2})?$, resource type syntax is ^[a-z][a-z_]*$, and snapshot is 64 lowercase hexadecimal characters. The optional pagination envelope retains discovery contract 1.1.0; paid schemas and immutable deliveries are unchanged.

Proceed only when the selected record has offer.purchaseAvailable: true. Record its ID and the offer's exact offer.url, SKU, revision, digest, byte count, schema and terms. Use the returned URL for both the unsigned challenge and the authorized retry; do not invent an ID or construct a purchase URL from an example. The catalogue, not this page, establishes current availability.

3. Read the content contracts

One purchase delivers complete content, metadata and provenance, plus an editable basisDirection. Story material retains characters, speaker assignments, scenes, utterance spans, reading policy, and pacing. Source text is separate from the suggested performance. Buyer-controlled tools may change the direction, assign provider voices, and render. This is production material, not finished audio, a provider request payload, or a guarantee of historical truth.

4. Request a fresh challenge

The service description applies to the whole route. The selected artifact's exact revision, digest and terms version are in extensions.textusProduct. Compare them with the catalogue offer and echo all challenge extensions unchanged in your payment payload; missing or altered identity is rejected before payment verification.

Set purchase_url to the exact offer.url copied from your selected record, then request it without a payment header. This only requests a challenge; it does not authorize payment:

curl -i "${purchase_url:?Set purchase_url to the selected record's offer.url}"

When released and payments are enabled, the resource returns HTTP 402 with x402 v2 requirements in the body and PAYMENT-REQUIRED header. Validate the exact canonical resource URL, MIME type, SKU content-production-material-v1, revision, digest and terms identity against the selected offer. Validate scheme, network, asset, EIP-712 metadata, amount, recipient and timeout before signing. The pilot price is 0.49 USDC; the live offer and fresh challenge are authoritative. Retain the catalogue byte count for delivery verification.

5. Authorize with a buyer-controlled wallet

Use a compatible x402 v2 Exact-EVM client and retry the same selected resource. Never reuse a signature from another SKU or follow a cross-domain redirect for a signed request.

The following shows the request shape; {id} comes from the selected returned URL, not from a guessed resource:

GET /api/v1/resources/{id}/content.json HTTP/1.1
Host: api.textus.dev
PAYMENT-SIGNATURE: <base64-encoded-x402-v2-payload>

Keep wallet authority client-side. Never send private keys, seed phrases, or payment signatures to support.

6. Verify and use the production material

A successful response has HTTP 200, PAYMENT-RESPONSE, X-Textus-Receipt, X-Textus-Delivery: settled, X-Textus-Product-SKU and Content-Digest. The retained X-Story-Receipt and X-Story-Delivery headers are identical legacy aliases. Compare the exact body SHA-256 and byte count with the selected offer, check the SKU, and validate Content Artifact 1. Do not hash reserialized JSON instead of the received bytes.

Keep or adapt the baseline direction in your own production workflow. When present, basisDirection.nonSpokenSpans marks source stage directions and speaker labels with paragraph-relative Unicode-codepoint boundaries; exclude these spans from spoken output while preserving the original text. The purchase includes all material for this resource, not the whole Textus corpus, provider execution or rendered audio.

7. Recover an interrupted delivery

Replay the identical settled request with the identical signature to recover the exact purchased bytes without another settlement. The response reports X-Textus-Delivery: recovered and the identical legacy X-Story-Delivery alias. Verify against the original purchase identity, not a later catalogue revision. Retain non-secret receipt and transaction evidence. Reconcile ambiguous outcomes before creating a new authorization.

HTTP 404 means no released resource; 409 means the authorization is processing; 429 requires honoring Retry-After; 503 means payments are unavailable or settlement needs reconciliation. See OpenAPI for complete response contracts.

Read-only MCP discovery server

Textus exposes a stateless Streamable HTTP MCP endpoint at https://api.textus.dev/mcp. Configure a compatible client for JSON-RPC POST requests. For repository-local development, npm run mcp:start serves the same contract at http://127.0.0.1:3000/mcp.

search_textus_resources is the only MCP tool. It accepts the public catalogue search filters and returns only public metadata, provenance, rights, offer and pagination information. It cannot buy content, use a wallet, return paid full text or basisDirection, and it does not search Source Moments. The direct catalogue API remains the canonical product and purchase path.

Historical receipt recovery

Story Reading packages and ElevenLabs plans are retired from new sales. The former catalogue and purchase routes return 410 Gone for new purchases. Use the resource catalogue and Content Production Material workflow above.

If an earlier purchase settled, replay its exact original request with the identical payment signature. Recovery returns the receipt-bound bytes and original SKU without a second settlement. Archived schemas remain available to validate that historical delivery; validate against the original receipt, not a current offer. Never create a new authorization for a retired product or send a signature to support.

If recovery is unavailable or settlement remains ambiguous, contact support with non-secret receipt evidence.

Live values win. The current catalogue, fresh challenge, exact response bytes, and current terms are authoritative. Documentation examples explain the flow but never override them.