HTTP 402 + EIP-3009. Your Agent signs a transferWithAuthorization once and a facilitator settles it on whichever chain it already holds USDC. No gas needed.
A place for an Agent's own things.
Tack pins what your Agent wants the world to find, and stores what only the paying wallet should read. Two tracks, same wallet, same x402 and MPP rails, no signup and no API keys.
Pin services were built for humans. Agents need different defaults.
The two kinds of things an Agent produces.
- 01Generated artifactsImages, PDFs, code bundles, video.
- 02RAG corporaShared knowledge across an Agent fleet.
- 03Replayable outputsCache deterministic tool calls and skip the work if the CID resolves.
- 04Inter-agent handoffsCIDs as pointers, one Agent pins and another retrieves.
- 01Long-term memoryEmbeddings, summaries, working notes the Agent uses across runs.
- 02Task receiptsOn-chain payment paired with off-chain content the Agent owns.
- 03Drafts and per-user stateAnything the Agent will edit before publishing, or keep scoped to one tenant.
The flow is the same shape for both tracks.
- Step 01The Agent POSTs to
/pinswith a CID. Tack responds402and quotes the price for the duration the Agent picked. - Step 02The wallet signs one on-chain authorization. x402 on Taiko or Base, MPP on Tempo, whichever rail the wallet already holds funds on.
- Step 03Tack returns
202 Acceptedand pins the content. The wallet owns the pin and can list, replace, or delete any time.
- Step 01The Agent POSTs the bytes to
/private/objectswith the retention it wants. Tack responds402with the size-and-duration quote. - Step 02The wallet signs the same x402 or MPP authorization it would for a public pin. Tack settles and stores the object on its private volume.
- Step 03Tack returns the object id and a bearer token. The wallet reads its bytes back at
/private/objects/:objectId/content. - Step 04When the token expires the Agent signs back in with SIWE at
/auth/challengeand/auth/tokenfor a fresh token. No CID is ever emitted.
Two endpoints, one integration.
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme, toClientEvmSigner } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";
import { createPublicClient, http } from "viem";
import { taiko, base } from "viem/chains";
const account = privateKeyToAccount("0x..."); // holds USDC on Taiko or Base
const taikoSig = toClientEvmSigner(account, createPublicClient({ chain: taiko, transport: http() }));
const baseSig = toClientEvmSigner(account, createPublicClient({ chain: base, transport: http() }));
const pay = wrapFetchWithPaymentFromConfig(fetch, {
schemes: [
{ network: "eip155:167000", client: new ExactEvmScheme(taikoSig) },
{ network: "eip155:8453", client: new ExactEvmScheme(baseSig) },
],
});
// Pin a CID for 6 months. USDC on whichever chain your wallet holds.
const res = await pay("https://tack.inferenceroom.ai/pins", {
method: "POST",
headers: { "X-Pin-Duration-Months": "6" },
body: JSON.stringify({ cid: "Qm..." }),
});
import { Mppx, tempo } from "mppx/client";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount("0x..."); // holds USDC.e on Tempo
const mppx = Mppx.create({
methods: [tempo({ account })], // Tempo 4217
});
// Same endpoint. USDC.e on Tempo.
const res = await mppx.fetch("https://tack.inferenceroom.ai/pins", {
method: "POST",
headers: { "X-Pin-Duration-Months": "6" },
body: JSON.stringify({ cid: "Qm..." }),
});
# Ask for the quote. Tack returns a machine-readable 402.
curl -i -X POST https://tack.inferenceroom.ai/pins \
-H "X-Pin-Duration-Months: 6" \
-d '{"cid":"Qm..."}'
# → HTTP/1.1 402 Payment Required
# → payment-required: accepts=[
# → {network:"eip155:167000", asset:"USDC", amount:"0.10"},
# → {network:"eip155:8453", asset:"USDC", amount:"0.10"},
# → ]
# → WWW-Authenticate: Payment method="tempo", chainId=4217
# Pick any chain your wallet holds. Sign, retry. Tack pins, returns 202.
// Same wallet, same x402 (or MPP) credential as /pins.
// Tack stores the bytes on its private volume — no CID is emitted.
const bytes = new TextEncoder().encode("agent memory: ...");
const res = await pay("https://tack.inferenceroom.ai/private/objects", {
method: "POST",
headers: {
"Content-Type": "application/octet-stream",
"X-Content-Size-Bytes": String(bytes.byteLength),
"X-Storage-Duration-Months": "3",
"X-Object-Name": "agent-memory-2026-05-19",
},
body: bytes,
});
const { id } = await res.json();
const bearer = res.headers.get("x-wallet-auth-token");
// Read the bytes back any time. Only the paying wallet can.
const read = await fetch(`${o}/private/objects/${id}/content`, {
headers: { "Authorization": `Bearer ${bearer}` },
});
Two protocols, three chains, one set of endpoints.
Machine Payment Protocol + TIP-20. Tack re-reads the on-chain Transfer event to bind the pin to the EOA that signed, not the relay.
Pay for size and duration, on either track.
- Minimum$0.001 / pin
- Term1 – 24 months
- AssetUSDC / USDC.e
- RetrievalFree · paywalls opt-in
- Same rate$0.10 / GB · month
- Term1 – 24 months
- OwnerPaying wallet only
- RefundUnused term on delete
- Minimum12 months locked
- TermFixed 12 only
- ChainsBase only
- Protocolsx402 only
Same $0.10 / GB·month rate. Pinata’s demo locks every pin to 12 months; Tack lets you pick 1–24. At 3 mo it’s 4× cheaper, 6 mo 2×, 12 mo the same.
- Settled in
USDCon Taiko or Base, orUSDC.eon Tempo. - Retrieval is free. Paywalls are opt-in, per CID.
- Pins and private objects auto-expire. No recurring charges.
- Owner ops — list, replace, delete — don't re-charge.
price = clamp(sizeGB × $0.10 × months, $0.001, $50). Size is binary (1 GB = 1,073,741,824 bytes). Duration is 1–24 months, set withX-Pin-Duration-Monthsfor pins orX-Storage-Duration-Monthsfor private objects. Settlement rounds up to the next asset unit.
The full surface, pin endpoints and private object endpoints.
Tack is the first product in Inference Room.
Inference Room is an independent launchpad for AI Agents and the infrastructure they need to ship. Tack is the first resident, focused on storage. Bantō, the finance multisig Agent on Safe, is the second.
Every resident has its own product, its own brand, and its own roadmap. What they share is a thesis: AI Agents need primitives that were designed for Agents, not retrofitted from products built for humans. Pin-for-humans does not work for Agents, multisig-for-humans does not work for finance Agents, and the same shape of mismatch shows up in every layer underneath.
Inference Room is where those primitives get built and shipped.
Questions builders actually ask.
POST /private/objects, sign the EIP-3009 authorization over x402 or attach an MPP credential, and the object is stored on Tack's private volume scoped to the paying wallet. No CID is ever emitted, no IPFS gateway will serve it, and only the owning wallet can read it back through the API.transferWithAuthorization. The Agent posts to a paid endpoint, the server returns 402 with a price quote, the Agent's wallet signs the transferWithAuthorization once, and the server resubmits the request with the signed payment header. A facilitator settles the USDC transfer on whichever chain the wallet already holds funds on. No gas is required, no separate billing account is needed.GET /ipfs/<cid>. For private objects, send GET /private/objects/<obj_id>/content with the bearer token returned at payment, or sign back in with SIWE at /auth/challenge and /auth/token if the original token has expired./.well-known/agent.json. Any HTTP client an Agent uses works. No SDK is required, no platform-specific adapter, and no API key beyond the wallet signature.A place for your Agent to keep things. The public ones and the private ones.
Two endpoints away.