---
name: godrop
description: Upload a file to godrop.sh and get back a public URL, with no account and no key. Use whenever a file has to become a link, such as a screenshot for a pull request or an issue, a build log, a report, a diff too large to paste, or anything produced on a machine the reader cannot reach. Also covers shortening a file's life, deleting one, and asking what it allows.
metadata:
  source: https://godrop.sh
---

# GoDrop

Upload a file, get back a URL that anyone can open and nobody can guess.

Base URL: https://godrop.sh

No credentials are needed. Without a token a file may be up to 20 MB and
is deleted three days later, which is enough for the thing an
agent usually needs a link for.

## Upload a file

    curl -sS -F "file=@report.pdf" "https://godrop.sh/upload?format=url"
    https://godrop.sh/f/20260815-143022-.../report.pdf

The name travels with the file, so there is nothing to repeat in the URL, and
?format=url answers with the URL and nothing else. Put it straight in a
variable; there is no JSON to parse and no jq to have installed:

    url=$(curl -sS -F "file=@screenshot.png" "https://godrop.sh/upload?format=url")

Leave the parameter off and the answer is JSON instead, with the URL at
.files[0].url, which is the shape to read when several files went up at once
and you want their sizes too.

Send several parts named "file" to upload up to 20 at once. It is all or
nothing: if one is refused, none are stored. With ?format=url they come back
one URL per line.

## Upload something that was never a file

Anything on stdout can go straight up, and here the name is yours to give
because there is no file to take it from:

    go test ./... 2>&1 | curl -sS -X PUT --data-binary @- \
      "https://godrop.sh/upload/test-output.txt?format=url"

The extension decides the stored type, so name it sensibly.

## Put a picture in a pull request

GitHub has no API for attaching an image, so upload it and paste the URL. It
opens without a token, so GitHub renders it inline for everyone on the thread.
?format=md answers with the line itself, written so that an image renders and
anything else becomes a link:

    shot=$(curl -sS -F "file=@after.png" "https://godrop.sh/upload?format=md")
    gh pr comment 42 --body "After the fix:

$shot"

Without an account that link is gone three days later. Say so
when it matters, or use a key.

## Ask for a shorter life

    -H "X-Expires-In: 30m"      or      ?expires=30m

Minutes, hours and days: 45m, 2h, 7d. Worth doing for anything produced on the
way to something else. An ask longer than the plan keeps a file is cut to it,
and expires_at in the answer is the date that stuck.

## With a key

A key raises the ceiling to 50 MB, makes uploads last 30 days,
lets you delete them, and gives the account 5 GB of storage. One can be
made at https://godrop.sh/app, which is also where it goes on the paid plan:
100 MB a file, 100 GB, and nothing deleted on a schedule. The same
key works either way.

    curl -sS -F "file=@report.pdf" \
      -H "Authorization: Bearer $GODROP_TOKEN" "https://godrop.sh/upload?format=url"

    curl -sS -X DELETE -H "Authorization: Bearer $GODROP_TOKEN" "$url"

**Keep the key in the environment.** Do not write it into this file or into
anything a repository would carry: a key in a committed file is a key
published, and a download needs no key anyway.

## What to know

- Downloads need no token. Anyone with the URL can read it, and nobody can
  find it by guessing: the identifier carries 128 random bits.
- **There is no endpoint that lists files.** Keep the URL you were handed, or
  the file becomes unreachable. This is deliberate, not missing.
- A URL is unguessable, not secret. Treat anything uploaded as public.
- Largest file: 20 MB without a key, 50 MB with one.
- 507 means the account is full, 413 means the file is too big for the caller,
  429 means too many uploads from this address without an account.
- A large upload with no token can be weighed first: GET https://godrop.sh/limits needs
  no key and carries anon_bytes_today against anon_daily_bytes, which is the
  one ceiling here that moves during the day. A 507 with no token means that
  allowance is spent, not that an account is full. Under
  ?format=url and ?format=md those come back as one line of plain text, not
  JSON, so a refusal never lands in the variable the URL was meant for. Check
  the status rather than assuming the line is a URL.

## The rest of the API

    https://godrop.sh/llms.txt        the whole API in plain text
    https://godrop.sh/openapi.yaml    machine-readable schema
    https://godrop.sh/mcp             Model Context Protocol, for an agent with no shell

This file is generated by the service it describes, so the numbers in it are
the numbers actually enforced rather than numbers somebody typed. Fetch it
again after a limit moves and it says the new one.
