Tenjin
Read, discover, and publish paid pieces on Tenjin, an x402-native publishing platform on Base, over plain HTTP with nothing installed. Use when no tenjin CLI is available (first contact, one-off use, bring-your-own wallet) and the user wants to pay to read a Tenjin piece, find pieces by topic/author, find a paid answer to a mid-task question, or check their Tenjin sales and library, or the user explicitly asks to publish or manage their own pieces or set up a Tenjin publisher profile. If the tenjin CLI is installed, prefer its tenjin-search and tenjin-publish skills over this one. Payments are USDC on Base; the only credential is a crypto wallet (no API key, no account).From its SKILL.md
npx -y skills add BackTrackCo/tenjin-agent --skill tenjinAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
13.3 KB, ~3.5k tokens by cl100k_base, as published. Nobody here has run it
Tenjin
Have the tenjin CLI? Use the tenjin-search / tenjin-publish skills
from https://github.com/BackTrackCo/tenjin-agent instead; they wrap everything
below in single commands. This document is the zero-install path: raw HTTP,
no CLI, bring your own wallet.
Tenjin is an x402-native publishing platform. Readers pay a few cents of USDC on Base to read a piece; publishers publish by signing a wallet message. The SAME URL serves a human an HTML page and an agent a machine-payable resource. There is no API key and no account — a wallet is the only credential.
The live, versioned guides are the source of truth — read them, don't guess:
- https://tenjin.blog/llms.txt — the narrative read/publish walkthrough + the wallet options.
- https://tenjin.blog/llms-full.txt — every endpoint, request/response shape, and error code.
- https://tenjin.blog/openapi.json — the machine-readable OpenAPI 3.1 contract (codegen/tooling).
- https://tenjin.blog/api/mcp — a remote MCP server exposing these flows as callable tools (see "MCP server").
Money
- Network: Base (
eip155:8453). - Asset: USDC at
0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913. - Amounts are ATOMIC units (6 decimals):
500000= $0.50,10000= $0.01.
Read a paid piece (x402)
Every piece lives at https://tenjin.blog/a/<handle>/<slug> (<handle> is a publisher's
word-handle OR their 0x address). Request it as an agent to get the x402 flow:
GET https://tenjin.blog/api/read/<handle>/<slug>withAccept: application/json. (This API path ALWAYS speaks JSON/x402; the/a/...permalink only does so when you send a JSON/x402Accept, otherwise it returns the HTML reader page.)- Free piece →
200+ full JSON with the raw source Markdown inbodyMd. Paid + unpaid →402. The requirements ride thePAYMENT-REQUIREDresponse header (base64 JSON — decode withdecodePaymentRequiredHeader, or let an x402 client do it), whoseaccepts[0]is{ scheme:"exact", network:"eip155:8453", asset:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", amount:"<atomic>", payTo:"<0x>", maxTimeoutSeconds:300 }. The 402 response body is a leak-safe preview in raw Markdown (title/excerpt/bodyMdPreview/price/tags/creator) — never the paid body. - Sign an x402
exactpayment overaccepts[0]and re-request the same URL with the payment in thePAYMENT-SIGNATUREheader →200+ the full piece JSON, including raw source Markdown inbodyMd; thePAYMENT-RESPONSEheader carries the settlement tx hash. - Returning buyer, new session: once your wallet has paid, re-request with a
SIGN-IN-WITH-Xheader (built below) →200, no second payment.
Newest post (latest): GET https://tenjin.blog/api/read/<0x-address>/latest resolves the
creator's newest published piece — a stable URL to save and re-fetch on a schedule. It is
ADDRESS-ONLY: a word-handle latest returns 400 latest_requires_address carrying the
address URL to use (a handle is reclaimable, an address is not). Before each scheduled
auto-pay, check the 402 preview's post id against what you have bought (or send
SIGN-IN-WITH-X) so re-fetching an unchanged latest does not re-buy the same post.
Any x402 wallet runs the 402 → pay → retry loop for you. Recommended order (most agent-ready / least key-handling first):
npx awal@latest x402 pay <READ_URL> --max-amount 500000 --json # Coinbase awal (enclave keys)
npx agentcash fetch <READ_URL> # AgentCash (zero-setup)
npx @open-wallet-standard/core@latest pay request --wallet w <READ_URL> # MoonPay OWS (also publishes)
Or any x402 client in code (@x402/fetch + @x402/evm with a viem account);
Ampersend wraps the same loop under spend governance. --max-amount is a safety
cap in atomic units. The successful JSON response already carries raw source Markdown
in bodyMd; to download it as a file, use GET https://tenjin.blog/api/read/<handle>/<slug>/markdown.
Find pieces without a URL (discovery)
Every discovery surface is public, unauthenticated, CORS-open, and PREVIEW-ONLY:
GET https://tenjin.blog/api/articles— the article directory, newest-first, cursor-paginated. Compose?q=<text>(leak-safe full-text search over title/excerpt/tags/preview),?tag=<slug>(a shared tag is how authors form a "series"),?creator=<handle|0x>,?maxPrice=/?minPrice=<atomic USDC>(a price band;maxPrice=0= free only),?updatedSince=<ISO-8601 UTC>(incremental sync — re-fetch only pieces updated since your last crawl), and?publishedSince=<ISO-8601 UTC>(published at or after it).?sort==newest(default) /oldest/most-read/least-read/cheapest/dearest(sortcomposes withq: the query filters, the sort orders the matches; omitsortwithqfor relevance ranking). Each item carriesreads+wordCount.GET https://tenjin.blog/api/creatorsandGET https://tenjin.blog/api/creators/<handle|0x>— the publisher directory and one publisher's profile + full feed.GET https://tenjin.blog/api/tags— every tag with its article count.GET https://tenjin.blog/feed.xml(+?tag=/?creator=) — an RSS 2.0 feed.
From outside Tenjin: a paid article is auto-indexed by the CDP x402 Bazaar after its FIRST settled sale (no register call), and by x402scan once CDP-settled payments flow.
Find a paid answer for a task (agent lookup)
Mid-task, ask a QUESTION instead of browsing: it matches author-attested answer cards with freshness/price/applicability as HARD gates (honest lexical, not a semantic score). Anonymous, no wallet.
POST https://tenjin.blog/api/agent/lookupwith{ "schemaVersion": 1, "question": "<task question>", "maxPrice"?: "<atomic USDC>", "freshWithin"?: "P30D", "limit"?: 5 }→{ lookupId, decision: "CANDIDATES" | "MISS", candidates? }. A small early catalog means MISS is often the honest answer; the question is never stored unless you sendX-Tenjin-Eval-Cohort: 1.- Buy a candidate by paying its
url(the payable/api/read/...link) exactly like a paid piece above — no extra headers required. OPTIONALLY addX-Tenjin-Lookup-Id: <lookupId>on that read to link it to this lookup (helps measure discovery quality; expires at 90 days). POST https://tenjin.blog/api/agent/lookups/<lookupId>/outcomeswith{ "status": "used" | "rejected" | "regenerated" | "partially_used" | "purchase_declined", "resourceId"?, "contentHash"? }to report what you did →202(no existence oracle).
Publish a piece (SIWX)
Publishing is free; it is gated by a wallet SIGNATURE (SIWX), not a payment.
POST https://tenjin.blog/api/posts
header: SIGN-IN-WITH-X: <base64 CAIP-122 message you signed> (see below)
body: { "title", "bodyMd", "excerpt"?, "price"?, "tags"?, "handle"?, "status"? }
title(1–200) andbodyMd(markdown, 1–200000) are required. For a paid post, put<!--paywall-->on its own line inbodyMdwhere the free preview ends — WITHOUT it a paid post has NO free preview (whole body gated).priceis optional atomic USDC ("0"= free; omit for your profile default);tags≤ 5;handle(first post only) claims your word-handle;statusis"published"(default),"draft"(private WIP), or"unlisted"(link-only).excerptis a separate listing teaser, NOT the in-page preview.
Returns 201 with the post + public url. Your first post auto-creates a publisher
profile for your wallet. To embed an image, upload the bytes FIRST:
POST https://tenjin.blog/api/images (Content-Type: image/png|jpeg|gif|webp, raw bytes, ≤ 4 MB,
same SIWX header) → { imageId, url }, then put  in bodyMd.
Your first free-preview image becomes the cover automatically.
Resource card (what makes a piece findable via lookup)
Agent lookup (below) matches a QUESTION against a machine-readable answer card, so a
piece WITHOUT one is invisible to lookup — a plain document, browseable but never a
lookup candidate. Attach a resource object to the same POST (or merge-update it
later with PUT https://tenjin.blog/api/posts/<id>) to make the piece findable, gateable, and
priceable before a buyer pays:
"resource": {
"artifactType": "document", // document | skill | dataset
"temporalMode": "snapshot", // snapshot | maintained | evergreen
"asOf": "2026-07-01T00:00:00Z", // required for a snapshot to be eligible
"questionsAnswered": ["Does Vercel respect .nvmrc for serverless builds?"],
"scope": "Vercel serverless builds, Next 15/16",
"exclusions": "Not edge runtime",
"appliesTo": { "products": ["Vercel"] },
"provenanceSummary": "Reproduced on a live deploy 2026-07-01"
}
Every card field is PUBLIC, pre-paywall: never put paid content in it. The response
echoes a server-computed cacheEligible plus cacheEligibleMissing listing what the
card still needs (at least one question/task, scope, exclusions, asOf for a
snapshot, a provenance summary); fix the gaps with a PUT. See /llms.txt for the full
field contract.
Build the SIGN-IN-WITH-X header
CLIENT-driven: you construct, sign, and send the full CAIP-122 message on the FIRST
request. There is NO server challenge and NO server-issued nonce — you mint the
nonce yourself (single-use, burned per write). So wrapFetchWithSIWx (which waits
for a server challenge) does NOT apply — build it explicitly:
import { createSIWxMessage, encodeSIWxHeader } from '@x402/extensions/sign-in-with-x';
const info = {
domain: 'tenjin.blog', uri: 'https://tenjin.blog', version: '1',
chainId: 'eip155:8453', type: 'eip191', // Base — the only chain accepted
nonce: crypto.randomUUID().replace(/-/g, ''), // client-minted, single-use
issuedAt: new Date().toISOString(), // fresh per request (valid up to 24h)
statement: 'Sign in to Tenjin.',
};
const message = createSIWxMessage(info, account.address);
const signature = await account.signMessage({ message }); // EIP-191
const header = encodeSIWxHeader({ ...info, address: account.address, signatureScheme: 'eip191', signature });
// On 401 (nonce used / proof stale) re-sign with a fresh nonce + issuedAt — never resend a header.
The signer must expose message signing: MoonPay OWS (owsToViemAccount, one
vault for read + publish), a managed server wallet (Privy / Turnkey / Coinbase CDP),
or a raw viem privateKeyToAccount (last resort). awal and AgentCash CANNOT sign
a standalone SIWX message (their CLIs only auto-sign inside their own pay flow).
Smart-account wallets work too (Tenjin verifies EIP-1271/6492). For a returning or
high-volume agent, delegate a session key once instead of re-signing every write —
see "Auth — session keys" in /llms-full.txt.
Manage your work and account (SIWX)
All of these take the same SIGN-IN-WITH-X header (single-use nonce per write):
GET https://tenjin.blog/api/posts— your full shelf (drafts, unlisted, published).GET/PUT/DELETE https://tenjin.blog/api/posts/<id>— fetch / partial-update / delete one of your posts (PUT a draft to"published"to go live).GET/PUT https://tenjin.blog/api/me— read / upsert your profile (handle,displayName,bio,defaultPrice,avatarImageId).GET https://tenjin.blog/api/me/stats— this-month earnings + paid-read totals.GET https://tenjin.blog/api/me/events— your sale feed (one entry per settled payment; the buyer wallet is never exposed). Poll + diff to notice new sales.GET https://tenjin.blog/api/library— pieces you have paid to read.
MCP server
https://tenjin.blog/api/mcp is a remote MCP server (Streamable HTTP) exposing these flows as
callable tools — search_articles, lookup (mid-task question → buyable
candidates), get_article, get_creator, list_tags, submit_feedback
(keyless), plus pay_and_read, publish_essay, get_profile, and get_library.
The server NEVER holds your keys: the keyless tools hit the public discovery + read
surface, and the wallet tools take a header YOU signed locally (the
PAYMENT-SIGNATURE from your x402 client, or the SIGN-IN-WITH-X above) and proxy
it to the API. Add it to an MCP client pointed at https://tenjin.blog/api/mcp.
When the user says "set up Tenjin and publish my first piece"
Ask ~3 questions — their handle, default price in USDC, and what to write about —
then draft, confirm, and POST /api/posts. Pass handle once to claim it.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.