Arweave Storage
Every version pushed to Inkd stores its content on Arweave — a permanent, decentralized storage network. Once uploaded, content can never be modified, deleted, or taken down.
How it works
When you push a version, the flow is:
Upload to Arweave
Your file is uploaded via ArDrive Turbo — a Layer 2 for Arweave that provides instant upload confirmation and pay-as-you-go pricing.
POST /v1/upload
→ File stored on Arweave
→ Returns ar://QmAbc123...Register on-chain
The ar:// hash is recorded in the InkdRegistry contract on Base. This creates a permanent, immutable link between your project version and the content.
registry.pushVersion(
projectId,
"ar://QmAbc123...", // content hash
"v1.0.0", // version tag
"Initial release" // changelog
)Content is permanent
The content at ar://QmAbc123... is now accessible forever via:
https://arweave.net/QmAbc123- Any Arweave gateway
Addressing
Arweave uses content-addressed storage. The ar:// prefix followed by a base64-encoded transaction ID uniquely identifies content.
ar://QmAbc123xyz456...
└─ Arweave transaction ID (43 characters)The same content always produces the same ID. You can verify the content of any version by fetching it from any Arweave gateway.
Pricing
Arweave storage costs are based on file size. The protocol charges the exact cost plus a 20% markup.
| File size | Approx. cost (USDC) |
|---|---|
| 1 KB | ~$0.0022 |
| 10 KB | ~$0.022 |
| 100 KB | ~$0.22 |
| 1 MB | ~$2.21 |
Use the estimate endpoint to get the exact fee:
curl "https://api.inkdprotocol.com/v1/upload/price?bytes=102400"See Fee Model for a full breakdown.
Supported content types
The Inkd API accepts any content type. Common examples:
| Content type | Use case |
|---|---|
application/javascript | Agent code, CLI tools |
application/json | Manifests, schemas, metadata |
application/wasm | WebAssembly modules |
text/plain | Scripts, configs |
application/octet-stream | Binary artifacts |
Uploading content
Via CLI
inkd version push --id 10 --file ./dist/agent.js --tag v1.0.0The CLI uploads the file and records the hash in one command.
Via API
# 1. Upload the file
curl -X POST https://api.inkdprotocol.com/v1/upload \
-H "Content-Type: application/json" \
-d '{
"data": "<base64-encoded content>",
"contentType": "application/javascript",
"filename": "agent.js"
}'
# Returns:
# { "hash": "ar://QmAbc123...", "url": "https://arweave.net/QmAbc123...", ... }
# 2. Push the version with the hashVia SDK
import { ProjectsClient } from "@inkd/sdk"
import { readFileSync } from "fs"
const client = new ProjectsClient({ privateKey: process.env.INKD_PRIVATE_KEY })
// Upload returns ar:// hash
const { hash } = await client.uploadContent({
data: readFileSync("./dist/agent.js"),
contentType: "application/javascript",
})
// Record on-chain
await client.pushVersion({
projectId: 10,
arweaveHash: hash,
versionTag: "v1.0.0",
})Accessing stored content
Once uploaded, content is accessible via any Arweave gateway:
# Primary gateway
https://arweave.net/QmAbc123xyz456...
# Alternative gateways
https://ar-io.dev/QmAbc123xyz456...
https://arweave.net/QmAbc123xyz456...Important notes
- Uploads are permanent. There is no way to delete or modify content on Arweave.
- Content is public. By default, all uploaded content is publicly readable. Encrypt sensitive data before uploading.
- The Inkd API accepts uploads up to 50 MB. For larger files, upload directly to Arweave and pass the
ar://hash.
