# Spritekick API

> Generate the same private character references and transparent, game-ready animations as Spritekick Studio, from your own code.

- Base URL: `https://spritekick.com/api/v1`
- Authentication: `Authorization: Bearer YOUR_API_KEY`
- Machine-readable contract: https://spritekick.com/api/openapi.json (OpenAPI 3.1)
- This page in HTML: https://spritekick.com/api/docs
- This page in Markdown: https://spritekick.com/api/docs.md

## Get a key

An account holder creates one key at https://spritekick.com/account#api and can show, hide, copy, or revoke it there. A key
carries either read-only or read/write scope. Send it in the `Authorization: Bearer` header and nowhere else: the API
reads no cookie, no query parameter, and no body field.

## Quick start

Start with the catalog. It is the source of truth for every supported option.

```bash
curl https://spritekick.com/api/v1/catalog \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

Create a character with the same camera and style choices shown in Studio.

```bash
curl https://spritekick.com/api/v1/characters \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Kiko","description":"A fox courier","orientation":"platformer","style":"pixel"}'
```

After its reference job completes, create an animation.

```bash
curl https://spritekick.com/api/v1/characters/CHARACTER_ID/animations \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"pose":"walk","quality":"standard"}'
```

When the animation is ready, open its `links.viewer` URL to review the loop, adjust the clip, and download a PNG sheet
or a frame ZIP.

## Endpoints

Every path is relative to `https://spritekick.com/api/v1`.

| Method | Path | Action |
| --- | --- | --- |
| GET | `/catalog` | List cameras, styles, qualities, and animations. |
| GET | `/tokens` | Read the account token balance. |
| GET | `/characters` | List your characters. |
| POST | `/characters` | Create a character and generate its reference. |
| GET | `/characters/{characterId}` | Read one character and its reference status. |
| DELETE | `/characters/{characterId}` | Delete a character and all its animations. |
| POST | `/characters/{characterId}/reference` | Generate a missing or failed reference. |
| GET | `/characters/{characterId}/reference.png` | Download the private reference image. |
| GET | `/characters/{characterId}/animations` | List a character's animations. |
| POST | `/characters/{characterId}/animations` | Generate a standard, premium, or custom animation. |
| GET | `/animations/{animationId}` | Read one animation and its Studio viewer link. |
| PATCH | `/animations/{animationId}` | Name or favorite an animation. |
| DELETE | `/animations/{animationId}` | Delete an animation and its private assets. |
| POST | `/animations/{animationId}/revisions` | Generate a revision with a change note. |
| GET | `/jobs/{jobId}` | Read generation status and progress. |
| POST | `/jobs/{jobId}/feedback` | Rate a completed generation. |

## How generation works

- Generation is asynchronous. A `POST` that starts work answers `202 Accepted` with the job id and a `Location`
  header pointing at the resource to read next.
- `GET /jobs/{jobId}` reports `status` (`queued`, `generating`, `processing`, `complete`, `failed`, or
  `cancelled`), the current `stage`, and `progress` from 0 to 100.
- You do not have to poll. Every generation started through the API emails the account address when it lands or fails,
  with a link straight to it. Work started in Studio is not emailed: the page it was started on already follows it.
- Each request generates once. There is no reroll and no automatic retry, so a result is never silently replaced by a
  second attempt. Tell us about a bad one with `POST /jobs/{jobId}/feedback`.
- Characters, references, animations, and uploads are private to the account that made them.
- `GET /tokens` reads the balance. The API cannot buy or refill tokens; that happens in the web application.

## Errors

Every failure is JSON in one shape:

```json
{"error":{"code":"not_found","message":"Character not found."}}
```

| Status | Code | Meaning |
| --- | --- | --- |
| 400 | `invalid_request, invalid_json, invalid_image` | The body or a query parameter is wrong. The message names the field. |
| 401 | `unauthorized` | The key is missing, malformed, or revoked. |
| 402 | `insufficient_tokens` | The balance is too low for this generation. Refills happen in the web application. |
| 403 | `insufficient_scope` | The key is read-only and the call writes. |
| 404 | `not_found` | No such character, animation, job, or asset on this account. |
| 409 | `conflict` | The resource is in the wrong state, such as rating a generation that is still running. |
| 413 | `request_too_large` | The upload request is over 21 MiB. |
| 503 | `generation_start_failed` | The work could not be started and the tokens were returned to the account. |

## Paging and limits

- List endpoints take `limit` (1 to 100, default 50) and an opaque `cursor`, and return the next cursor in
  `links.next`, or `null` on the last page.
- A source image or style reference is uploaded as `multipart/form-data` and must be 10 MB or less, inside a request
  under 21 MiB.

## Help

Signed-in customers reach a person through https://spritekick.com/support.
