pinthis.cloud

Documentation

Put your media to work.

Start with uploads and embeds. Connect your publishing tools when you are ready. Account, storage, delivery, and advanced integration details are below.

Upload files from your browser

Sign in to an existing account with public publishing enabled, then open Publish your files on the account page. A standard web browser can upload files; Wildroot and a naming setup are not required for this workflow. Published media is public, so keep confidential material in the separate private-backup workflow.

  • Drop or choose files. Use choose a folder where your browser supports directory selection. PinThis stores the supplied bytes and builds an IPFS UnixFS archive; it does not transcode them. Folder paths are preserved beneath the chosen folder's root. A folder containing index.html can also serve a website.
  • Paste a CID for content already available on IPFS. The service retrieves and pins it through the Pinning Service API workflow. Keep the source available until pinning completes.

Keep the tab open while uploading. Once the files finish, the service prepares and queues the archive. The page shows its processing state; wait for pinned and check playback before publishing the link to your audience. An upload acknowledgement alone does not mean the public content is ready.

Interrupted uploads and large libraries

Resume saved uploads. Modern browsers send files in verified 8 MiB chunks. If a connection fails, Retry continues from acknowledged progress. After a reload or browser restart, open Saved uploads and select the same original files or folder. PinThis checks their contents and paths before sending only missing chunks. File contents are not kept in browser storage. If the service already has every file, Complete publishing can finish without selecting them again.

Preparing an upload reads the original files once to check their identity, using bounded memory. Keep the originals until publishing succeeds. Older clients using the whole-file API can retry unfinished files from their beginning. A lost finish response can recover the same publication receipt, even after the staging session has been cleared.

  • Session limits: at most 10,000 files per upload and eight unfinished sessions per account. A new session has a six-hour expiry window, refreshed after a verified chunk is committed. Expired incomplete uploads must be started again.
  • Temporary space: browser uploads share a staging pool before they reach long-term storage. Its service default is 16 GiB across uploads, with 1 GiB of disk headroom reserved; deployment settings can change these values. A storage plan's total allowance is not an equally large browser-upload allowance.
  • Finalization needs extra room: source files and the packed archive coexist while a session finishes. Leave room for both and for other active uploads. A 507 response means staging is full; it can happen even when your storage plan has room. Retry after space becomes available; Saved uploads can recover committed chunks after a reload. If the batch itself is too large for the staging pool, cancel it and choose smaller batches.

Test one representative large recording before uploading an entire library. The API exposes the same staging and account limits; it does not remove them.

The same thing from a shell, with the account page's API token — one file per call, the body is the file:

with curl
curl -T photo.jpg -H "Authorization: Bearer <token>" \
  "https://pinthis.cloud/api/upload?name=holiday&filename=photo.jpg"

For a folder, POST /api/uploads {"folder":true} opens a session, one PUT /api/uploads/<id>/files/<path> sends each file, and POST /api/uploads/<id>/finish hashes and queues the archive. URL-encode each path segment separately. GET /api/uploads/<id> reports the session; DELETE /api/uploads/<id> cancels an unfinished upload. File bytes count against the account while they arrive, and archive overhead is checked at finalization.

Private files

The same token can keep files that are not published: no address anyone can open, no gateway, no IPFS. A private file is stored under your account and comes back only through the API with your credential. Every plan has this, including Free and Keep; it counts against the plan's storage, and reading it back never counts against public delivery.

Think in files and folders. Slashes in the path make folders; prefix= lists one.

curl -T beach.jpg -H "Authorization: Bearer <token>" -H "Content-Type: image/jpeg" \
  https://pinthis.cloud/api/files/holiday/2026/beach.jpg          # store (201)
curl -H "Authorization: Bearer <token>" "https://pinthis.cloud/api/files?prefix=holiday/2026/"   # list
curl -H "Authorization: Bearer <token>" -o beach.jpg https://pinthis.cloud/api/files/holiday/2026/beach.jpg   # fetch
curl -X DELETE -H "Authorization: Bearer <token>" https://pinthis.cloud/api/files/holiday/2026/beach.jpg
  • PUT /api/files/<path> — the body is the file, Content-Length is required, and the answer is {path, bytes, sha256, type, modified} once the file is stored. Sending the same path again replaces it. Percent-encode each path segment.
  • GET /api/files — {files: [{path, bytes, sha256, type, modified}], count, bytes}; ?prefix= for a folder, ?limit= and ?after=<path> to page (more/next say when).
  • GET /api/files/<path> — the bytes, with Range support; HEAD for the headers alone. DELETE removes it.
  • Past the plan's storage the store answers 402; a body shorter or longer than its Content-Length is a 400 and nothing is kept.

What private means: the hosts that store the pieces cannot read them, and nobody without your credential can fetch them. The service itself holds the storage keys, so it can. If that matters, encrypt files before sending them; the API stores exactly the bytes it is given.

Video that streams

The gateway supports HTTP byte ranges so compatible players can fetch selected parts of a recording. Actual playback and seeking depend on the file's codecs, index, keyframes, the browser, and available bandwidth. MP4 with H.264 video and AAC audio is a useful starting point for broad browser compatibility; test on your audience's devices.

  • Put the MP4 index at the front. A tail index can require an extra range request and delay startup. For a compatible MP4, a lossless remux can move it: ffmpeg -i in.mp4 -c copy -movflags +faststart out.mp4. This does not change unsupported codecs into supported ones.
  • Keep keyframes reasonably close. Seeking may need to decode from the previous keyframe. Widely separated keyframes make jumps slower; changing their spacing requires re-encoding. Test a few seeks late in a long recording before sharing it.

During upload finalization, PinThis inspects supported media containers for common playback problems and can show preparation advice. These bounded checks are not a full playback test for every codec or file. They do not automatically remux or transcode your media. Available findings are returned as media and notes on finish. Storage, staging, and validation limits can still refuse an upload.

Share it, or put it in a page

Supported video and audio files in a confirmed public pin can use a watch page or an embeddable player:

  • A share link — https://pinthis.cloud/watch/<cid>/<path>: a page with the player, a download link and embed code. Open Graph and oEmbed metadata help compatible publishing tools preview it; your CMS may require you to allow the provider or paste the iframe explicitly.
  • An embed — <iframe src="https://pinthis.cloud/embed/<cid>/<path>" width="640" height="360" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen loading="lazy"></iframe> (height 80 for audio). Compatible players use range requests for playback and seeking. ?autoplay=1 requests muted autoplay, subject to browser policy; ?t=90 requests a start at 90 seconds.

The account page's share / embed button lists detected media with links to copy. A pin containing one file has no path: https://pinthis.cloud/watch/<cid>. Recognized extensions include video .mp4 .m4v .webm .mov and audio .mp3 .m4a .ogg .oga .wav .flac .aac .opus; recognizing an extension does not guarantee that every browser can decode it. The media bytes fetched through the player count against public delivery, including cache hits. Watch-page and embed-page HTML are not part of that media-byte counter.

Plans and limits

Publish costs $10/month and includes 1.5 TB of storage and 3 TB of public delivery per UTC calendar month, with $2 per additional TB. Additional delivery requires opt-in and a monthly spending limit. The previous month’s actual additional delivery is added to your next monthly bill; outstanding usage is settled when your subscription ends. TB is decimal (1,000,000,000,000 bytes). Keep remains $5/month for 1 TiB of private backup. Plan for both your stored library and the bytes people receive; temporary upload capacity is separate.

  • Storage — how much your account may keep. Existing pins and unfinished uploads count toward available room. Exceeding the quota refuses new uploads; it does not itself delete existing pins.
  • Devices — how many Wildroot installs (or other clients) may connect to the account.
  • Storage transfer allowance — the account's budget for transfers with storage hosts. If that funding allowance is exhausted, transfers can pause until the account's funding period renews. This is separate from the public gateway's delivery counter.
  • Public serving — how much the gateway will serve of your public pins in a month, on plans with public publishing enabled. Accounts that have never enabled additional delivery use the default policy: each request is delayed by 1.5 seconds at 100% of the allowance, and refused with 429 at 150%. Enrolled Publish accounts follow their additional-delivery settings instead; turning paid delivery off leaves only the remaining included delivery available. Your account shows the current stop threshold. The counter resets with the UTC calendar month. Cached deliveries count too. Exceeding a delivery limit does not itself delete stored files.

The plans list refreshes from the service. Card checkout is currently closed; existing accounts can sign in. The base free plan is private backup for a Wildroot identity. A verified naming identity may qualify for the separate name plan, with its own public-serving limits; that is not the general free browser-upload plan.

Delivery forecasts and alerts

Your account shows included delivery remaining, a month-end estimate, and the files or folders responsible for the most delivery. Estimates use the current UTC month and need at least one full day of account activity. They follow your average pace so far; future traffic can change.

In-app notices appear before the included allowance is used. Your account shows the slowdown and stop thresholds that apply to its current delivery settings. Additional-delivery charges and the monthly spending limit are shown separately from the included allowance. Cached delivery counts in both the estimate and enforcement. These alerts appear in your account; they do not send email.

Pinning Service API

The Publish plan includes the IPFS Pinning Service API at https://pinthis.cloud/pins, so tools you already use can pin to us. Create a token on your account page (it is shown once).

with kubo
ipfs pin remote service add pinthis https://pinthis.cloud <token>
ipfs pin remote add --service=pinthis --name="my site" <cid>
ipfs pin remote ls --service=pinthis --status=queued,pinning,pinned
with curl
curl -X POST https://pinthis.cloud/pins \
  -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
  -d '{"cid":"<cid>","name":"my site"}'

A request goes queued → pinning → pinned, or failed with the reason in info. Our own IPFS node fetches the content from whoever is providing it — over the DHT and bitswap, or from a provider that announces to IPNI — so it must be online somewhere when you ask. Once pinned it is served by us as above. Deleting the request drops our copy unless someone else keeps the same content online.

The gateway

Public pins are served at https://pinthis.cloud/ipfs/<cid>[/path]. It is a standard IPFS gateway for the content it holds:

  • Paths inside a directory resolve; a directory serves its index.html.
  • Range requests support seeking in compatible players and resumable downloads in clients that use byte ranges.
  • Trustless forms: ?format=raw (one block) and ?format=car with dag-scope=all|entity|block and entity-bytes=from:to (the verifiable form of a Range request: the path's blocks plus only the leaves that overlap the window), also by Accept header. Responses carry X-Ipfs-Roots, CORS for browser clients (including the OPTIONS preflight), Accept-Ranges, and are cached as immutable. Cache-Control: only-if-cached answers 412 rather than reading a host.
  • Content we do not hold is a 404; we do not fetch from the wider network on request.

Bytes served are counted to the pin's owner, against the plan's public serving allowance and any optional additional-delivery settings.

Finding it by CID

PinThis exposes public content through its HTTP gateway and IPFS provider integration. Retrieval by another IPFS client depends on provider discovery, connectivity, and the client's supported transport. Use https://pinthis.cloud/ipfs/<cid> when you need the service's direct HTTP URL, and test native IPFS retrieval separately for your integration.

There is also the standard delegated routing API: GET https://pinthis.cloud/routing/v1/providers/<cid> returns this HTTP gateway as a provider for public content it holds, and 404 otherwise. A compatible client configured to use this delegated router can retrieve verifiable blocks over HTTP. Check your client's delegated-routing and HTTP-retrieval settings before relying on this path.

Billing

Publish’s $2 per additional TB rate is separate from its $10 monthly subscription and 3 TB of included delivery. Additional delivery is off by default; it requires an active paid Publish subscription, a valid payment method, and your explicit approval. Publishing this rate does not create a charge on existing accounts. The plan review checks current payment availability with the service before opening checkout.

Paid plans use monthly Stripe subscriptions. Existing billing customers can use their account's billing portal to manage payment details, invoices, or cancellation. Cancellation takes effect at the end of the paid subscription period, after which the account uses its lower plan's limits. A downgrade does not itself delete pins, but public serving and new uploads depend on the resulting plan and available quota. Keep your own originals rather than treating a subscription as permanent preservation.

Optional additional delivery

On Publish, additional delivery is off by default. When available, enable it from Billing in your signed-in account, choose a monthly additional spending limit from $0.01 to $1,000, and explicitly accept the usage charges. The suggested $10 limit is not saved automatically. Other plans and dedicated integration allowances are unchanged.

Usage is counted by UTC calendar month at $2 per additional decimal TB above the included 3 TB. The previous month’s actual additional delivery is added to your next monthly subscription bill. Only eligible delivery after opt-in is billable: earlier usage is never charged retroactively. Partial TB are prorated by bytes, without rounding up to a whole TB. All delivery counts, including cached responses. Whole cents are added to the bill; fractions of a cent carry forward. The spending limit applies to each UTC month’s new additional delivery; your base subscription and any unpaid amount from earlier months are separate.

You can turn additional delivery off at any time, even while card payments are unavailable. Turning it off stops new paid-delivery requests; accrued charges remain payable. Outstanding usage is settled when your subscription ends, including usage since the last monthly bill. A final separate charge below $0.50 is waived, as are any remaining fractions of a cent; we never round a balance up to a minimum charge. Delivery may pause when the account's spending or payment limits are reached. Stored files are not deleted by these delivery limits, and storage-host funding limits remain separate.

Web sign-in uses a one-time email link. Wildroot and application integrations can use their separate identity authentication. The public-delivery counter resets by UTC calendar month; it is not the same as the subscription renewal date or the storage-host funding period.

Using it from Wildroot

Connect

Open Settings → Storage and choose pinthis.cloud. The browser signs one request with your identity key and the account is connected — there is no code to paste and no password. If you bought a plan on this site, import the name key that came with it first (below); the plan follows the key.

Back up

Choose a folder to keep. Wildroot seals every file on your device with a storage key that lives in its vault, then spreads the pieces across hosts. Neither we nor the hosts can open them. Restore from any device you have connected; if you lose every device, only a vault export can open the backup, so make one.

Keep online

A supported Wildroot publishing flow can ask PinThis to keep a public archive online. Once the pin is confirmed, its content is available through https://pinthis.cloud/ipfs/<cid>/ while the source computer is offline, subject to the account's service and delivery limits. Removing the last pin lets the service release its stored copy; keep a separate original if you need to recover it later.

The included name

Every payment on a paid plan — the first one and each monthly renewal — comes with one <label>.pinthis name. Choose the label at checkout or later from your account page.

The name is delivered as a key file, <label>.pinthis.hns-identity.json. Download it once and keep a safe copy. We erase our copy after download, or 14 days after issue if it remains undownloaded. PinThis cannot redeliver an erased key. Add it in Wildroot under Your names → Add a key file… — or connect Wildroot storage from the browser’s Settings › Storage and claim the name there, in which case it is held in the browser the moment it is issued, no file to download. From then on the name is your sign-in here, and the plan you bought is attached to it.

Labels are 1–63 characters: letters, digits and hyphens, not starting or ending with a hyphen. A label already held as <label>.w3 on hns.one is reserved for its holder.

(?) What is the name, technically pinthis is a Handshake top-level name we hold; the labels under it are records in a zone we sign and serve, resolved in Wildroot like any other name. Nothing goes on a chain when a name is issued and there is no token behind it — the key file is the proof of control, and hns.one's registry keeps the binding between the key and the label. This is the same "no wallet, no tokens" path as hns.one's free names, and the same key file format.

A site at your name

On a Publish plan a name can point at one of your public pins — a folder with an index.html, or a single file. Open Advanced → Names on the account page and choose a public pin. Once the relevant routing is ready, these addresses can lead to the same content:

  • https://<label>.pinthis.cloud/ — a standard HTTPS address, once the name's routing and certificate are ready. Media playback still depends on browser and codec support.
  • <label>.pinthis — in Wildroot, and any browser that resolves Handshake names. Wildroot reads the content natively over IPFS; other resolvers reach our gateway.
  • ipfs://<cid>/ and https://pinthis.cloud/ipfs/<cid>/ — the content itself, which never changes.

Repointing changes which public pin the name serves; cached responses and DNS may take time to catch up. The old pin remains until you remove it. Removing a pin that a name uses also requests removal of the pointer. A managed name is not a promise of permanent hosting.

(?) What pointing writes Three records at <label>.pinthis in the zone hns.one signs: a TXT ipfs=<cid> that Wildroot resolves natively, a _dnslink TXT that gateways and kubo understand, and an A record for resolvers that only speak HTTP. The pinthis.cloud subdomain is the same content served by the gateway under that host.

The signed API (for apps)

Wildroot talks to the service with signed requests rather than cookies: an Authorization: Nostr <base64 event> header in the NIP-98 form, signed by the identity key. The signed u tag is the full URL including the query string; the payload tag is the SHA-256 of the body; an event is good for one use and sixty seconds.

  • POST /api/connect {responseUrl} — approve a pending connection from a client that talked to https://indexer.pinthis.cloud.
  • GET /api/me — the plan and where the account stands in it.
  • GET /api/pins, POST /api/pins {cid, shareUrl, name}, DELETE /api/pins/<cid> — public pins from an archive the client already holds (a share link to it).
  • GET /api/plans — public; what the plans list reads.

A previously unseen signing key starts with the base free account. A key verified as a naming identity by the hns.one registry qualifies for the name plan. Individual operations still check the account's permissions and limits; public-pinning operations require a plan with public publishing enabled.

What runs underneath

PinThis stores files on its own servers, and places them on the Sia network across independent hosts as each account accumulates enough stored data to place. PinThis operates the storage coordinator, public gateway, IPFS provider integration, and account service. Public publishing and private storage are separate workflows: files in public pins are readable by anyone with their address, and private files are not — though PinThis holds their storage keys and can read them. A Wildroot backup is the exception: your device holds that key and PinThis cannot read a byte of it. Managed names use hns.one's registry under the pinthis namespace; they are not independently owned top-level domains. Wildroot is an optional client, not a requirement for browser uploads or media embeds.