Developers
creator api
Effective Date: v1, a rest api for publishing and managing gather drops with a creator api key
overview
the gather creator api lets a creator's ai agent create, publish and manage drops on the creator's behalf, over plain https and json. it wraps the exact publish pipeline the gather app uses, so a drop published here behaves exactly like a drop a human creates in the app: same validation, same tier caps, same claim mechanics, same supply math. one key acts as one creator, and every drop it publishes is tagged publishedVia: api_key for provenance.
the surface today is sixteen operations: reading your identity and live limits, uploading media (images and gif), creating and publishing drops in all six shapes (direct, pack and choice, each tiered or untiered, with 1-of-1 editions via choice), scheduling, event-gated drops with short-lived qr claim tokens, a reusable card-template library, and full management of what you published: list, read, edit, pause, unpause, delete, and pin a drop to your profile. everything is versioned under /v1; changes within v1 are additive only.
the api is server-side only. there is no cors, and a gth_ key must never ship inside a browser page or a mobile client. call it from your backend, a script, or an agent runtime.
status: early access
the creator api is rolling out gradually. key generation appears in the gather app (settings > ai access) as it is enabled per environment, and the production base url goes live with the public launch. where the api is deployed, publishing itself can still be switched off for an environment: a valid key then gets 503 publishing_disabled from POST /drops while uploads, reads and management keep working. GET /me is always the authoritative answer for what your key and your environment can do right now; do not infer availability from this page.
get a key
the human creator generates the key inside the gather app under settings > ai access. one active key at a time; revoke to rotate. keys cannot be minted or revoked through the api, by design, so a creator can cut off their integration at any moment. revoking takes effect within about a minute everywhere.
the key is shown once at creation and looks like gth_ followed by a long random string. store it like a password.
base url and auth
all endpoints live under a versioned base url. at public launch the base is https://api.gather.fan/v1; before then, use the environment url you were given with your access, of the form https://<api-id>.execute-api.us-east-1.amazonaws.com/v1.
every request except GET /openapi.json sends the key as a bearer token (the Bearer prefix is required) and speaks json:
export GATHER_API="https://<your-environment-base>/v1"
export GATHER_KEY="gth_xxxxxxxx"
curl -sS "$GATHER_API/me" -H "Authorization: Bearer $GATHER_KEY"a working key returns your creator id, your verification state, and the live limits your drops must fit inside. every response carries an X-Request-Id header; include it whenever you report a problem.
quickstart
six calls from key to live drop:
# 1. confirm the key + read your live limits
curl -sS "$GATHER_API/me" -H "Authorization: Bearer $GATHER_KEY"
# 2. request a presigned upload url per image
curl -sS -X POST "$GATHER_API/uploads" \
-H "Authorization: Bearer $GATHER_KEY" \
-H "Content-Type: application/json" \
-d '{"files":[{"filename":"hero.png","purpose":"card"}]}'
# 3. put the bytes to uploadUrl (replay the returned headers verbatim)
curl -sS -X PUT "<uploadUrl>" \
-H "Content-Type: image/png" \
-H "Content-Disposition: attachment" \
-H "Cache-Control: public, max-age=31536000, immutable" \
--data-binary @hero.png
# 4. poll until the upload is valid
curl -sS "$GATHER_API/uploads/<uploadId>" -H "Authorization: Bearer $GATHER_KEY"
# 5. create + publish the drop (returns 202 accepted)
curl -sS -X POST "$GATHER_API/drops" \
-H "Authorization: Bearer $GATHER_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pub_9f2c7a1b6d4e8035c1af22e9b7d40e6a" \
-d '{
"name": "midnight run",
"type": "direct",
"perFanLimit": 1,
"totalSupply": 250,
"cards": [
{ "name": "night owl", "rarity": "COMMON", "imageUrl": "<publicUrl-1>" },
{ "name": "first light","rarity": "RARE", "imageUrl": "<publicUrl-2>" },
{ "name": "the run", "rarity": "LEGENDARY", "imageUrl": "<publicUrl-3>" }
]
}'
# 6. poll until status is live or publish_failed
curl -sS "$GATHER_API/drops/<dropId>" -H "Authorization: Bearer $GATHER_KEY"that is the whole flow. every card carries its own short name (up to 25 utf-8 bytes, it is minted on-chain). on a tiered drop, send totalSupply and the api splits editions across cards by rarity with the same algorithm the app uses; rarer means fewer, every card gets at least one copy, and the supplies always sum exactly to the pool.
what you can do
the sixteen operations, grouped:
- identity and limits:
GET /me, your caps, headroom and per-environment capabilities. read it first, cache it briefly, never hardcode the numbers. - media:
POST /uploads(batched presigned urls, images and gif) andGET /uploads/{uploadId}(the validation verdict). - publishing:
POST /drops, the one rationed call: direct, pack or choice, tiered or untiered, scheduled or immediate (end dates up to 365 days out), optionally event-gated, with idempotent retries viaIdempotency-Key. - card templates:
GET /card-templatesandPOST /card-templates, a reusable library of card art you can publish from without re-uploading. - management:
GET /drops,GET /drops/{dropId},PATCH /drops/{dropId}(name, description, cover, schedule), pause, unpause and delete, plusGET /me/pinned-drop,PUT /me/pinned-dropandDELETE /me/pinned-dropfor your profile's pinned drop. - live events:
GET /drops/{dropId}/qr-token, a short-lived qr claim credential for event-gated drops.
the contract
the machine-readable contract is served by the api itself, without a key, at GET /openapi.json. generate clients from it. unknown fields are rejected with 400 invalid_request, never silently dropped, so a request that validates today keeps meaning the same thing tomorrow.
errors arrive in one stable envelope with a machine-readable code and, where useful, a details object naming the exact rule. retry only 429 and 503 temporarily_unavailable, always with the same Idempotency-Key and after the Retry-After. every other code means fix something first. pace yourself at roughly one request per second.
changelog
1.1 (2026-08): the management half. drop editing, pause, unpause, delete and profile pinning; the card-template library; choice drops with per-card supplies and 1-of-1 editions; untiered cards; scheduling with end dates up to 365 days; event gates with qr claim tokens. card names became required (25 utf-8 bytes) and automatic card naming was removed.
1.0 (2026-07): initial release. seven endpoints, image and gif media, direct and pack drops, both supply modes, idempotent publishing, per-key daily caps, and the stuck-drop sweeper.