---
name: ankinize-api
description: Read and change an Anki collection through the Ankinize REST API: decks, notes, note types, cards, tags, media and the study queue. Use when asked to add, find, edit or review Anki cards on an Ankinize server, from any language or with plain HTTP.
---

# Ankinize REST API

Read and change your Anki collection over HTTP. Everything here edits the same collection that Anki syncs, on Anki schema 18, so a note created through the API appears in Anki on its next sync and the other way round.

Every request is made as one user with an API key. While Anki is syncing that user's collection, writes wait: you get `423 Locked` with a `Retry-After` header, and nothing is lost if you retry.

## Connect

- Base URL: `https://ankinize.com/api/v1`. The machine-readable description is `https://ankinize.com/api/v1/openapi.json`; read it for exact parameters and response shapes.
- Authenticate every request with an API key: `Authorization: Bearer $ANKINIZE_API_KEY`. The user creates the key in the dashboard under *API Keys & Devices*; it is shown once. Never put it in a URL or in source code.
- Scopes: `read` allows every `GET`; `write` allows everything; a key with only `sync` cannot use this API. Ask for the fewest the task needs.

## Conventions

- JSON in, JSON out. Send `Content-Type: application/json` on anything with a body.
- Every parameter and body field is camelCase. A note's `fields` is an object keyed by each field's camelCase name (`Back Extra` is `backExtra`). Name a note type or deck with `notetypeName` and `deckName` (a nested deck is `Languages::German`), or use `notetypeId` and `deckId`.
- Ids are numbers (millisecond timestamps in Anki): keep them as integers.
- Lists are paged: pass `nextCursor` back as `cursor` until it is `null`. A search may return a short or empty page while `nextCursor` is still set; keep following it.
- Errors are `{ "error": { "code", "message" } }` with the fitting HTTP status. Branch on `code`.
- `423 locked` (Anki is syncing) and `429 rate_limited` change nothing: wait `Retry-After` seconds and send the same request again.
- Add an `Idempotency-Key` header (a UUID) to a `POST`, `PATCH` or `DELETE` so a retry returns the first answer instead of repeating the work.
- Changing a note type's fields or templates forces a full sync on every device, so the API answers `409 full_sync_required` until the request is repeated with `?acceptFullSync=true`. Do that only when the user agrees. Removing a field, template or note type also needs *Allow destructive schema changes via API* switched on in the dashboard.
- Rate limits by plan: Free 30 requests a minute and 1000 a day, Pro 120 a minute, Max 600 a minute. Every response carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`.

## Endpoints

| Method | Path | What it does | Scope |
| --- | --- | --- | --- |
| `GET` | `/api/v1/decks` | List decks | `read` |
| `POST` | `/api/v1/decks` | Create a deck | `write` |
| `GET` | `/api/v1/decks/{id}` | Get a deck by ID | `read` |
| `PATCH` | `/api/v1/decks/{id}` | Rename a deck | `write` |
| `DELETE` | `/api/v1/decks/{id}` | Delete a deck and its subdecks | `write` |
| `GET` | `/api/v1/notes` | Search notes | `read` |
| `POST` | `/api/v1/notes` | Create a note and generate its cards | `write` |
| `POST` | `/api/v1/notes/batch-create` | Create many notes in one call | `write` |
| `POST` | `/api/v1/notes/batch-update` | Edit many notes in one call | `write` |
| `POST` | `/api/v1/notes/batch-delete` | Delete many notes in one call | `write` |
| `GET` | `/api/v1/notes/{id}` | Get note by ID with cards | `read` |
| `PATCH` | `/api/v1/notes/{id}` | Update note fields or tags | `write` |
| `DELETE` | `/api/v1/notes/{id}` | Delete a note and its cards | `write` |
| `GET` | `/api/v1/note-types` | List note types | `read` |
| `POST` | `/api/v1/note-types` | Create note type (stock or custom) | `write` |
| `GET` | `/api/v1/note-types/{id}` | Get note type details with fields and templates | `read` |
| `PATCH` | `/api/v1/note-types/{id}` | Update note type fields, templates, or styling | `write` |
| `DELETE` | `/api/v1/note-types/{id}` | Delete a note type | `write` |
| `GET` | `/api/v1/queue` | Get the study queue of a deck | `read` |
| `GET` | `/api/v1/tags` | List tags | `read` |
| `POST` | `/api/v1/tags` | Create a tag | `write` |
| `GET` | `/api/v1/tags/{name}` | Get a tag by name | `read` |
| `PATCH` | `/api/v1/tags/{name}` | Rename a tag | `write` |
| `DELETE` | `/api/v1/tags/{name}` | Delete a tag | `write` |
| `POST` | `/api/v1/tags/batch-create` | Create many tags in one call | `write` |
| `POST` | `/api/v1/tags/batch-update` | Rename many tags in one call | `write` |
| `POST` | `/api/v1/tags/batch-delete` | Delete many tags in one call | `write` |
| `GET` | `/api/v1/stats` | Get the statistics of a search | `read` |
| `GET` | `/api/v1/media` | List media files | `read` |
| `GET` | `/api/v1/media/{name}` | Download a media file | `read` |
| `HEAD` | `/api/v1/media/{name}` | Get a media file's headers | `read` |
| `PUT` | `/api/v1/media/{name}` | Store a media file | `write` |
| `DELETE` | `/api/v1/media/{name}` | Delete a media file | `write` |
| `GET` | `/api/v1/cards` | Search cards | `read` |
| `POST` | `/api/v1/cards/batch-update` | Edit many cards in one call | `write` |
| `POST` | `/api/v1/cards/batch-delete` | Delete many cards in one call | `write` |
| `GET` | `/api/v1/cards/{id}` | Get card details by ID | `read` |
| `PATCH` | `/api/v1/cards/{id}` | Edit a card | `write` |
| `DELETE` | `/api/v1/cards/{id}` | Delete a card | `write` |
| `GET` | `/api/v1/cards/{id}/render` | Render a card's front and back | `read` |
| `GET` | `/api/v1/cards/{id}/scheduling` | Preview the four answer buttons | `read` |
| `POST` | `/api/v1/cards/{id}/answer` | Answer (review) a card | `write` |

## Example

```bash
# Add one card to a deck.
curl -X POST "https://ankinize.com/api/v1/notes" \
  -H "Authorization: Bearer $ANKINIZE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "notetypeName": "Basic", "deckName": "Languages::German", "fields": { "front": "der Hund", "back": "the dog" }, "tags": ["german"] }'
```

## More

- Writing TypeScript or JavaScript? Use the SDK instead of hand-written requests: skill `ankinize-sdk` at https://ankinize.com/.well-known/agent-skills/ankinize-sdk/SKILL.md.
- Guides: [https://ankinize.com/docs](https://ankinize.com/docs), including [authentication](https://ankinize.com/docs/authentication) and the [API reference](https://ankinize.com/docs/api).
- Everything on this site as Markdown: [https://ankinize.com/llms-full.txt](https://ankinize.com/llms-full.txt).
