How it works

Four moves: post, store, serve, share. Each one is a plain HTTP call you can make by hand.

  1. 1

    Declare the manifest

    The client hashes each file and posts the list — path, size, content type, SHA-256. The server replies with a version id and a signed upload URL for every blob it does not already have.

  2. 2

    Put the blobs

    Files are stored by hash. Posting a directory that shares 13 of 14 files with the last version uploads one file.

  3. 3

    Commit the version

    The commit makes the version current and returns the artifact’s name, sequence number, visibility and URL. Earlier versions stay addressable.

  4. 4

    Hand out a link

    A share link is created against the artifact with a TTL, an optional label and an optional password. It resolves at /s/{token}/ until it expires or you revoke it.

An engraved rookery: one bare tree carrying many stick nests
One host, many artifacts. A rookery is a colony — nests are added and occupied year after year in the same tree.

The same thing in curl

# 1. declare
curl -X POST https://share.c52.com/api/v1/artifacts \
  -H "Authorization: Bearer $SHARE_TOKEN" \
  -d '{"title":"Q3 margin review","files":[
        {"path":"index.html","size":4120,
         "contentType":"text/html; charset=utf-8",
         "sha256":"e3b0c442..."}]}'

# 2. put each returned upload URL
curl -X PUT "https://share.c52.com/api/v1/files/e3b0c442...?sid=...&exp=...&sig=..." \
  --data-binary @index.html

# 3. commit
curl -X POST https://share.c52.com/api/v1/artifacts/q3-margin-review/versions/$VID/commit \
  -H "Authorization: Bearer $SHARE_TOKEN"

Who can see what

Authorization has four cases and no fifth. The owner sees their own artifacts. A valid unexpired link sees the artifact it was made for. A valid link with a password sees it after the password. Everything else is a 404 — including artifacts that exist but are not yours, so probing tells you nothing.

What the recipient sees

Someone opening a link has no account and no context. Every state they can reach says plainly what happened and what to do next.

This link needs a passwordThe artifact is there. Enter the password the sender gave you.
This link is no longer activeAsk whoever sent it for a new one.
Not foundA wrong URL and a URL you may not see. Same page either way.

How you sign in

Passkey
The owner’s browser session. No password to phish.
Bearer token
How agents and scripts authenticate. Named, scoped, revocable.
Device code
share login prints a code; you approve it in the dashboard.

What the server is

A FastAPI application on Python 3.13, PostgreSQL over asyncpg, Redis for cache and rate limits, files on local disk. nginx or Caddy in front for TLS; the API serves artifact bytes itself if nothing is in front.

Point an agent at it Read the docs on GitHub