GreatSprites is in preparation. Join early access for two free tests at launch.
GreatSprites Early access Open app

Docs

The API

Make animations from your own pipeline: keys, pictures, price checks, making, waiting, previews and exports, with curl or a one-file Node client.

Everything the app does goes through the same API, so your build server, pipeline or coding agent can make animations without opening the app. The address is https://greatsprites.com, and every answer is JSON unless it is a file.

1. Make a key

Sign in to the app and open API keys. Name the key after where it is used, such as "build server", copy it (it is shown once) and put it in your pipeline's secrets, never in a game or a repository. Send it with every call as Authorization: Bearer gs_…. A key spends this account's credits.

Keys are made and revoked in the app only: a key cannot make more keys or revoke others. Revoke one in the app and anything still using it is turned away at once.

2. The calls

CallWhat it does
POST /v1/picturesThe picture's bytes as the body: a PNG or WebP with a transparent background, at least 256 px on its shorter side, up to 10 MB. Answers { id, width, height }.
POST /v1/animations + "dry_run": trueThe price check: what it would cost, its length and what it adds to a phone's memory. Nothing is made or charged. Answers { plan }.
POST /v1/animationsStarts making it: 202 { job }, queued. Send an Idempotency-Key header: the same key never makes or charges twice, so a retry is safe.
GET /v1/jobs/{id}?wait=50The job. With wait the answer waits up to that many seconds (at most 60) for it to finish. state is queued, running, succeeded or failed, and a failed one's error says why.
GET /v1/jobs/{id}/previewThe finished animation as an animated WebP, to look at.
POST /v1/exportsThe game-ready files as a zip (books, runtime, AGENTS.md): { "jobs": [...] }, { "project": "prj_…" } or {} for everything.
POST /v1/exports/guideThe same AGENTS.md as markdown, for a coding agent.
GET /v1/jobs?limit=50&project=…Your animations, newest first.
PATCH /v1/jobs/{id}{ "clip": "big_win" } renames what your code calls it; { "project": "prj_…" } moves it to a folder.
DELETE /v1/jobs/{id}Deletes it; a queued one is cancelled and nothing is charged. POST /v1/jobs/{id}/restore brings it back.
GET /v1/creditsPlan, balance and recent credit history.
GET /v1/projects · POST /v1/projectsFolders: list them, or make one with { "name" }.

3. What an animation is made of

  • picture: the picture's id.
  • element: "object" for a symbol or an item, "character" for a character beside the reels.
  • brief: the motion in your own words, as you would tell an animator.
  • loop: true for a loop that keeps going while it is on screen; leave it out for a one-shot that lands back on your picture.
  • name: what your code calls it: 1 to 30 lowercase letters, digits, - or _, starting with a letter.
  • quality: "standard" (the default), "hd" or "premium", as your plan allows.
  • project: a folder's id, if you use folders.

4. With curl

KEY=gs_...   # from your secrets
curl -s -H "Authorization: Bearer $KEY" --data-binary @wild.png https://greatsprites.com/v1/pictures

curl -s -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: wild-win-1" \
  -d '{"picture":"pic_...","element":"object","name":"win","brief":"the lightning bolt flashes and the letters shine"}' \
  https://greatsprites.com/v1/animations

curl -s -H "Authorization: Bearer $KEY" "https://greatsprites.com/v1/jobs/job_...?wait=50"

curl -s -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"jobs":["job_..."]}' -o animations.zip https://greatsprites.com/v1/exports

5. With Node: one file, no dependencies

Put greatsprites.mjs in your tools (Node 18 or newer). It sends an Idempotency-Key with every make and tries a busy (429) or failed (5xx) call again, so a retry never makes or charges twice.

import fs from 'node:fs';
import { greatsprites } from './greatsprites.mjs';

const gs = greatsprites({ key: process.env.GREATSPRITES_KEY });
const pic = await gs.upload(fs.readFileSync('wild.png'));
const spec = { picture: pic.id, element: 'object', name: 'win', brief: 'the lightning bolt flashes and the letters shine' };

console.log((await gs.plan(spec)).plan);          // the price, nothing charged
const { job } = await gs.make(spec);
const done = await gs.wait(job.id);               // about half a minute
if (done.state !== 'succeeded') throw new Error(done.error);
fs.writeFileSync('animations.zip', await gs.exportZip({ jobs: [done.id] }));

6. Errors and limits

A call that does not work answers with a status and { "error": "…" } in plain words:

  • 400 the request is not right, and the message says what.
  • 401 no key, or a key that is not valid or was revoked.
  • 402 not enough credits, or the free tests are used.
  • 403 not on your plan (a quality), or a key that may not do this.
  • 404 not found, or not yours.
  • 409 a clash: a name already in use, or it is being made right now.
  • 413 too large.
  • 429 too many requests: a key may make 120 a minute.

An animation that fails our checks is made again once before you see it, and one that still fails is never charged.

← Instructions for coding agentsPlaying clips →