simplesharingagent guide

for people

Let your agent set up SimpleSharing for you.

Copy the prompt, paste it into Claude Code, Cursor, nekko-agent, or any agent that can read a URL. It will create your account, ask you for the 6-digit code that lands in your inbox, and hand you back an account id and a token.

Beta: your account waits for an invite code.
Create me a SimpleSharing account at https://simplesharing.app (source: docs, copied from the docs).
Read https://simplesharing.app/llms-full.txt and follow the agent signup guide exactly.
Use my email address (ask me for it if you do not have it), send the signup request with source "docs", and tell me when you need the 6-digit code from my inbox (or give me the claim URL as a fallback).
When the account is active, save the API token where I keep my tokens, then tell me the accountId, the account status, and what I can do next.

for agents

SimpleSharing: the complete agent guide

SimpleSharing (https://simplesharing.app) lets people and their agents share and co-edit the things agents make: HTML pages, markdown, Claude skills, and soon PDFs, Mermaid diagrams, and design files. An agent can create the account, verify it, upload, share, check limits, and (soon) manage the plan and payment, all through the HTTP API, the MCP server, or the CLI. By Nekko Labs.

This file is the whole protocol. If you are an agent that was asked to "create me a SimpleSharing account", start at section 2 and follow it top to bottom. Every API response and every error tells you what to call next in a next field, so you never have to guess.

Base URL: https://api.simplesharing.app (self-hosted and local installs differ; the person or the prompt that sent you here will say). All bodies are JSON. Authenticated calls send Authorization: Bearer <token>.

Machine-readable schema: https://simplesharing.app/openapi.json (OpenAPI 3.1, generated from the same validators the server runs).

1. The two things to know

  1. Accounts have a status. pending (created, not yet verified), waitlist (verified, waiting for a beta invite), active (usable), suspended, deleted. During the beta a new account lands on waitlist unless its email has an invite code redeemed or was approved.
  2. Every error has a next. Error bodies look like:
{ "error": { "code": "code_expired", "message": "That code has expired. Request a new one.",
             "next": { "action": "resend_code", "method": "POST", "path": "/v1/auth/resend",
                       "description": "Request a fresh code with POST /v1/auth/resend {email} ..." } } }

Act on next. A 429 also carries a retry-after header in seconds: wait that long, then retry once.

2. Create an account for a person (the signup flow)

You need the person's email address. You do not need a browser, a password, or OAuth.

Step 1: signup

POST /v1/auth/signup
Content-Type: application/json

{ "email": "person@example.com", "source": "landing", "agent": "report-writer" }
  • source is where the request came from. Use the value in the prompt that sent you (for example landing, docs, nekko-agent, partner:<name>), or mcp / cli / unknown.
  • agent is an optional label for yourself; it names the token.

Response 201:

{
  "accountId": "9b2e…",
  "status": "pending",
  "token": "sst_<id>_<secret>",
  "tokenExpiresAt": "2026-10-20T00:00:00.000Z",
  "claimUrl": "https://simplesharing.app/claim/<48 hex>",
  "codeSent": true,
  "expiresAt": "2026-10-26T00:00:00.000Z",
  "quota": { "files": 5, "bytes": 5242880 },
  "beta": "waitlisted",
  "next": { "action": "verify_code", "method": "POST", "path": "/v1/auth/verify", "description": "…" }
}

What you now hold:

  • accountId: the account. Report it to the person.
  • token: a 24-hour token limited to the pending quota (5 files, 5 MB total). You can already upload and share small things with it (section 3) so you can finish your task before the person verifies.
  • claimUrl: an alternative to the code. If the person opens it in a browser while signed in to SimpleSharing with the same email, the account activates without a code. Show it to them as a fallback.
  • codeSent: a 6-digit code was emailed to the address. If false, a code was sent less than 60 seconds ago; use that one.
  • expiresAt: unverified pending accounts are deleted after 7 days.

If the response is 409 account_exists, the email already has a verified account: follow next (log in, or redeem an invite if it is waitlisted). If it is 201 with "token": null, a pending account already existed; the code was re-sent and you should verify it (section 2, step 2) to get a full token.

Step 2: get the code

Tell the person: "I created your SimpleSharing account. A 6-digit code was emailed to person@example.com. Paste it here, or open while signed in." If you own the inbox (an agent mailbox), read the code yourself. The email subject is <code> is your SimpleSharing code.

Codes expire after 10 minutes and lock after 5 wrong attempts. To get a fresh one:

POST /v1/auth/resend
{ "email": "person@example.com" }

(60-second cooldown; 429 with retry-after if too soon.)

Step 3: verify

POST /v1/auth/verify
{ "email": "person@example.com", "code": "123456", "agent": "report-writer" }

Response 200:

{
  "accountId": "9b2e…",
  "status": "waitlist",
  "token": "sst_<id>_<secret>",
  "scopes": ["account", "beta"],
  "beta": "waitlisted",
  "next": { "action": "wait_or_redeem", "method": "POST", "path": "/v1/beta/redeem", "description": "…" }
}
  • Save token. It is long-lived. The pending token from step 1 is revoked at this point. Give the token to the person (or store it where they asked, for example SS_TOKEN in their environment) and never log it.
  • status is active when the email is approved for the beta, otherwise waitlist.

Step 4: the beta

During the beta a waitlist account cannot upload. Two ways in:

  • The person has an invite code: POST /v1/beta/redeem { "code": "ABCDE-FGHJK" } with the token (or { code, email } without one). The account becomes active immediately. Codes are case-insensitive. Redeeming for an already-approved email does not consume a use.
  • No code: check standing with GET /v1/beta/status (token) or GET /v1/beta/status?email=… and report the waitlist position. Tell the person they will be emailed when approved; nothing else to do.

An email can also be approved before the account exists (an invite redeemed on the website, or an admin approval). That approval carries into signup, so verification lands straight on active.

Step 5: confirm

GET /v1/account
Authorization: Bearer <token>
{ "account": { "id": "…", "email": "…", "status": "active", "plan": "free", "source": "landing", "createdBy": "agent", … },
  "usage": { "files": 0, "bytes": 0 },
  "limits": { "files": 50, "bytes": 52428800 },
  "beta": "approved",
  "next": { "action": "use_account", … } }

Report status, plan, and limits to the person. You are done with signup.

Alternative: the claim URL

If the person prefers a browser: they sign in at https://simplesharing.app/login with the same email (email + 6-digit code) and open the claimUrl. That activates the pending account for them. You can preview what they will see with GET /v1/auth/claim/<token> (masked email, source, status, expiry). The claim endpoint needs their web session, so it is not something you call.

3. Upload and share

POST /v1/shares
Authorization: Bearer <token>
{ "filename": "report.html", "content": "<!doctype html>…" }

201 { "id": "k3…", "url": "/s/k3…", "kind": "html" }. The public link is https://simplesharing.app + url. Anyone with the link can view; no account is needed to view.

  • Accepted today: .md, .html / .htm, and SKILL.md (rendered as a Claude skill). PDFs, Mermaid, and binary files follow.
  • Each file is limited to 1 MB until object storage lands.
  • Quota by status: pending 5 files / 5 MB, waitlist nothing, active free plan 50 files / 50 MB. 403 quota_exceeded or 403 beta_waitlist tell you what to do.
  • GET /v1/shares/<id> reads a share back, with the version it serves.

Protect a link: password, expiry, revoke

The account that uploaded a share owns it and can lock it down. Omitted fields stay as they are; null clears.

PATCH /v1/shares/<id>/settings
Authorization: Bearer <token>
{ "password": "blue-otter-42", "expiresIn": "7d" }

200 { "shareId", "hasPassword": true, "expiresAt": "…", "revoked": false, "pinnedVersion": null, "updatedAt" }. The password is never returned; tell the person what you set.

  • expiresIn: 1h, 1d, 7d, or 30d; or expiresAt as an ISO date up to one year away; expiresAt: null never expires. The owner can extend at any time.
  • password: null removes the password. Changing it signs every viewer out.
  • revoked: true kills the link at once; revoked: false brings it back.
  • Works on every plan. The owner always sees their own share, expired or not.

A viewer (or another agent) with the password unlocks, then reads with the token:

POST /v1/shares/<id>/unlock   { "password": "blue-otter-42" }
→ 200 { "token": "…", "expiresAt": "…" }
GET /v1/shares/<id>
x-share-token: <token>

The token lasts 12 hours, or until the link expires if sooner. Ten wrong guesses from one client in 15 minutes return 429. No content is ever sent before the check passes: a locked link answers 401 password_required, an expired one 410 share_expired, a revoked one 410 share_revoked.

Pin a version, keep editing

A link serves the latest version by default, so it never goes stale. To freeze what a client sees while you keep working, pin it:

GET /v1/shares/<id>/versions            → [{ "version", "author", "createdAt" }, …] newest first
PATCH /v1/shares/<id>/settings          { "pinnedVersion": "<version>" }
PUT /v1/shares/<id>/content             { "content": "<!doctype html>…" }

PUT …/content publishes a new version (owner only, same file type). While pinned, viewers keep the pinned version and the response says "servedToViewers": false; { "pinnedVersion": "latest" } follows the newest again. A republish is refused with 409 document_leased while anyone holds a section lease on the document (section 4): finish or release the lease first.

4. Edit together without collisions

When several agents or people edit one document, lease the section first:

POST /v1/leases   { "documentId": "…", "section": "intro", "holderId": "report-writer", "ttlSeconds": 300 }

Every outcome is 200 with { "status": "granted" | "queued" | "denied", "lease", "reason" }. granted: edit, then POST /v1/leases/<id>/release. queued: someone holds it, you are in a FIFO queue; do other work. denied (human_editing): a person is editing it; pick another section. Sections are keyed by heading slugs (## Setup → setup). Full protocol: https://github.com/nekko-labs/simplesharing-server/blob/main/docs/agent-collaboration.md

5. Plan, billing, and payment

Billing ships in the next slice. The endpoints will be GET /v1/account/limits, POST /v1/billing/checkout (returns a Stripe-hosted URL to hand to the person; card data never touches you), GET /v1/billing/portal, and discount-code application. Until then every account is on the free plan and GET /v1/account reports the limits.

6. Error codes you will meet

code HTTP meaning do
invalid_input 400 body failed validation fix the body per the message
email_domain_blocked 400 disposable email domain ask for a real inbox
account_exists 409 email already verified follow next (login / redeem)
signup_rate_limited 429 too many signups from this IP, email, or domain wait retry-after seconds
code_invalid 400 wrong code ask again; attempts left in the message
code_expired 410 older than 10 minutes POST /v1/auth/resend
code_attempts_exceeded 429 5 wrong attempts POST /v1/auth/resend
resend_cooldown 429 resent less than 60 s ago wait retry-after
no_pending_code 400 nothing outstanding POST /v1/auth/resend
account_not_pending 404/409 nothing to verify follow next
claim_invalid 404 bad claim link start over with signup
claim_email_mismatch 403 signed-in email differs sign in with the account email
invite_invalid / invite_expired / invite_exhausted 400/410 the invite code cannot be used ask the person for another or wait
beta_waitlist 403 uploads are locked until approved redeem an invite or wait
password_required 401 the link has a password POST /v1/shares/<id>/unlock, then send x-share-token
invalid_password / invalid_unlock_token 401 wrong password, or the token expired or the password changed ask the person for the password and unlock again
share_expired / share_revoked 410 the owner ended the link ask the owner for a new link
not_owner 403 only the uploading account can change a share use the owner's token
invalid_expiry / unknown_version 400 expiry in the past or over a year away; version not in this share's history fix per the message; list versions first
document_leased 409 someone holds a section lease wait, or edit through a lease
quota_exceeded 403 status/plan allowance used verify (pending) or wait for billing
unauthorized / unauthenticated 401 missing or bad token use the token from verify
forbidden 403 token lacks a scope you are calling an admin endpoint
rate_limited 429 general window wait retry-after
not_found 404 unknown id check the id

7. Other entry points

MCP server

npx simplesharing-mcp (stdio). Tools: account_signup, account_verify, account_status, beta_redeem, create_share, read_share (unlocks with a password), protect_share, pin_share, list_share_versions, republish_share, request_lease, release_lease (plus read_document, submit_edit when editing lands). The account tools work before any token exists; account_signup and account_verify return the token, and every tool takes an optional token argument that overrides SS_TOKEN. Config: SS_TOKEN, SS_API_URL.

CLI

export SS_TOKEN=sst_...
ss share ./report.html      # prints the share link
ss get <shareId>
ss lease <docId> <section> --holder me
ss release <leaseId>
ss sync ./my-library --library <id>  # two-way git sync of a folder with a library

Discovery

  • https://simplesharing.app/llms.txt: the short version.
  • https://simplesharing.app/llms-full.txt: this file.
  • https://simplesharing.app/openapi.json: OpenAPI 3.1.
  • https://simplesharing.app/.well-known/agent-card.json: the A2A agent card.
  • https://simplesharing.app/docs/agents: the human-readable twin of this guide.

8. Rules for a well-behaved agent

  • Never log, print, or share a token or a verification code beyond the person who owns the account.
  • Use the source you were given; it tells us which surfaces work.
  • Honor retry-after; never loop on a 429 or a queued lease.
  • Report the accountId, the account status, and the next step to the person in plain words.
  • If the person did not ask for an account, do not create one.