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.
Quick start#
Create an API key with the write scope under API Keys & Devices in the dashboard, keep it in an environment variable, and make your first request. This lists your decks:
The TypeScript examples on this page use the official TypeScript SDK, which makes the same requests. Agents can load the SDK skill or the REST skill.
Then add a card. A note belongs to a deck and a note type, which you name (ignoring case; a nested deck is Languages::German). The note's fields is an object keyed by each field's name in camelCase: the field Back Extra is backExtra. Every field of a note type shows its key in Get a note type. You can send notetypeId and deckId instead. Reading a note gives its fields in the same shape, and editing one takes the same object with only the fields that change.
The card is in your collection straight away and reaches Anki on its next sync.
Conventions#
Base URL and format#
Every endpoint lives under https://ankinize.com/api/v1. Requests and responses are JSON; send Content-Type: application/json on anything with a body. A request body can be up to 8 MiB, and the fields of a single note up to 5 MiB together. Ids are numbers (Anki uses millisecond timestamps), so keep them as integers.
Authentication and scopes#
Send your key as Authorization: Bearer <key>. Each endpoint below shows the scope it needs. A read key can call every GET; a write key can call everything. A key that only has the sync scope, and the keys used by devices, cannot use this API. See Authentication for how to create and limit keys.
Errors#
Failures use the HTTP status that fits and one JSON shape, so you can branch on error.code and show error.message to a person:
Rate limits#
Every call made with an API key counts against your plan. Free allows 30 requests a minute and 1,000 a day, Pro 120 a minute, and Max 600 a minute. Minutes start on the clock, and the day ends at 00:00 UTC. Every answer carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds) for the limit you are closest to using up. Past it, the API answers 429 rate_limited with a Retry-After header. Nothing was changed, so wait that long and send the same request again. A refused call does not count. Syncing with Anki is not limited this way, and a signed media link opened in a browser is not counted.
Retrying safely#
Networks fail halfway. Add an Idempotency-Key header (any unique string, a UUID is ideal) to a POST, PATCH or DELETE and a retry returns the first answer instead of doing the work twice. The answer is remembered for 24 hours, and a replay carries X-Idempotent-Replay: true. Reusing a key with a different body is a 422. Failures that are worth retrying for real (403, 423, 429, 5xx) are not remembered, so retrying them runs the request again.
Names and casing#
Every parameter and body field is camelCase (notetypeId, deckName, nextCursor), and so are the keys of a note's fields. A field's key is its name cut into words at spaces, punctuation and lower-to-upper changes, the first word in lower case and the others capitalised: The field is theField, ab_x is abX, URLText is urlText, and Question 1 is question1. A name with no letter or digit is its own key, and when two fields would get the same key they both keep their exact names. The exact name, in any case, always works as a key too, and a key the note type does not have is a 400 that lists the valid ones. The one exception to camelCase is the HTTP header Idempotency-Key, which keeps the standard header name; the SDK takes it as idempotencyKey and sends the header for you. Tag names go in the URL path, so percent-encode what a path cannot hold (a space is %20, a slash %2F); a tag called batch-create, batch-update or batch-delete can only be reached through the batch endpoints.
When Anki is syncing#
While one of your devices is syncing, or another change is being written, the collection is locked and the API answers 423 Locked with a Retry-After header (seconds). Nothing was changed, so wait that long and send the same request again.
Pagination#
GET /notes and GET /cards return pages in ascending id order. Take nextCursor from a response and pass it as cursor to get the next page; when it is null you have everything. limit is 1 to 100 and defaults to 50. A search with q can scan a bounded number of cards per request, so a page may be short or even empty while nextCursor is still set: keep following it.
Searching#
Every list takes one search, q, and nothing else narrows it. It is the text you would type in the Anki browser; leave it out for everything. GET /notes, GET /cards and the statistics read cards and notes; GET /decks, GET /tags and GET /notetypes read names (see below). A search Anki would refuse is 400 invalid_input with Anki's own explanation, and one may be at most 1000 characters and 50 terms.
Differences from desktop Anki#
- Regular expressions run on the RE2 engine. A
(?x)flag, class set operations such as[a-z&&[^aeiou]], backreferences and\Q..\Eare400 invalid_input, and\bmatches ASCII word characters only, so usew:for Unicode words. fz:is Ankinize's, not Anki's. The text and the note are cut into words (letters and digits, ignoring case and accents, with HTML and cloze markup removed), and every word of the search must match a word of the note, in any order. A word of up to 4 characters must match exactly, one of 5 to 8 may differ by one typo and a longer one by two; a typo is a missing, extra or wrong character, or two neighbours swapped.fz:japnesefinds Japanese, andfz:"dgo catt"finds a note with dog and cat only if both are close enough. It answers yes or no, in id order, never by relevance, for up to 8 words of up to 64 characters. It also works asfront:fz:textandtag:fz:text. As withtag:anddeck:, a field namedfzcan no longer be searched by name.
Notes and cards#
A card matches when it satisfies the whole search. A note matches when one of its cards does, so deck:Languages is:due finds notes with a card that is in the deck and due. A search that asks nothing of the cards (tag:, a field, plain text) looks at the notes alone, so it also finds a note that has no cards. A search that has to look at every card or note, such as a regular expression, prop:s or fz:, stops after about 10,000 and returns what it found with a nextCursor; keep following it (see Pagination).
Decks, tags and note types#
On GET /decks, GET /tags and GET /notetypes the search filters names. Plain text matches anywhere in the name, ignoring case, with * and _ as wildcards; re:, nc: and fz: work, and so does the list's own term: deck: on decks (deck:Languages is that deck and everything below it), tag: on tags (likewise) and note: on note types (note:Basic* matches whole names). A colon in plain text has to be escaped (Languages\:\:German). Any other term, such as is:due, is 400 invalid_input.
Changes that need everyone to re-sync#
Adding or reordering a field or a template changes the collection's schema, and Anki then asks every device to download the whole collection once. So the API stops and asks first: the request fails with 409 full_sync_required until you repeat it with ?acceptFullSync=true.
Removing a field, a template or a whole note type loses data, so it also needs Allow destructive schema changes via API to be switched on under Settings → Developer in the dashboard. Otherwise you get 403 destructive_change_disabled. Deleting decks and notes is not affected by that switch.
Endpoints#
Decks#
Decks group cards for study. Nest them with ::, for example Languages::German.
/api/v1/decksreadList decks#
Returns every deck in the collection, including the built-in Default deck and nested decks, or only the decks whose name q accepts. A nested deck's name is its full path, such as Languages::German.
Parameters
Example request
Response
200List of decks
- 401The
Authorizationheader is missing, or the key is invalid, disabled or expired. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/deckswriteCreate a deck#
Creates a deck and returns it. Use :: in the name to nest it under a parent, for example Languages::German.
Parameters
Request body
Example request
Response
201Deck created
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 401The
Authorizationheader is missing, or the key is invalid, disabled or expired. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 422The body does not match the earlier request that used this
Idempotency-Key(idempotency_conflict), or the body failed validation (validation_error). - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/decks/{id}readGet a deck by ID#
Returns one deck by its numeric id.
Parameters
Example request
Response
200Deck details
- 404No deck, note, note type or card has that id.
- 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/decks/{id}writeRename a deck#
Changes a deck's name. The deck keeps its id and its cards, and its subdecks are renamed with it.
Parameters
Request body
Example request
Response
200Deck renamed
- 404No deck, note, note type or card has that id.
- 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/decks/{id}writeDelete a deck and its subdecks#
Deletes the deck, all of its subdecks and every card in them. Notes left with no cards are removed too.
This cannot be undone. The response lists exactly which decks and cards were removed. Deleting is still allowed while the account is over its storage quota.
Parameters
Example request
Response
200Deck deleted
- 404No deck, note, note type or card has that id.
- 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
Notes#
A note holds the content (its fields and tags). Anki turns each note into one or more cards using the note type's templates.
/api/v1/notesreadSearch notes#
Returns the notes that match a search (q; every note when it is empty), in ascending id order, one page at a time. q is the search of Searching, including fz: for typos: the Anki browser's notes mode. A note is found when one of its cards satisfies the whole search, so deck:Languages is:due needs a card that is in the deck and due. A search that asks nothing of the cards (tag:, a field, plain text) looks at the notes alone, so it also finds a note that has no cards.
To read the next page, send the previous response's nextCursor as cursor. nextCursor is null on the last page. As for cards, a search that has to look at every note, such as a regular expression or a fuzzy search, stops after about 10,000 notes and returns what it found so far with a nextCursor, so keep following it until it is null.
Parameters
Example request
Response
200Paginated list of notes
- 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/noteswriteCreate a note and generate its cards#
Creates a note and generates its cards from the note type's templates.
Name the note type with notetypeName and the deck with deckName (compared ignoring case; a nested deck is Languages::German), or send notetypeId and deckId instead. Exactly one of notetypeName and notetypeId is needed; without a deck the note goes to the Default deck. A name that matches nothing is 404.
fields is an object with one entry per field of the note type, keyed by the field's name in camelCase: Back Extra is backExtra. Each field of a note type shows its key in Get a note type. The field's exact name works as a key too. A field you leave out is empty; a key that names no field is 400 invalid_input and lists the valid keys.
Send a guid only when you import notes from somewhere else and need to keep a stable identity; otherwise one is generated. All fields together may not exceed 5 MiB.
Parameters
Request body
Example request
Response
201Note created
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 422The body does not match the earlier request that used this
Idempotency-Key(idempotency_conflict), or the body failed validation (validation_error). - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/notes/batch-createwriteCreate many notes in one call#
Creates up to 200 notes in one call. It does what Create a note does for each entry (also naming note types and decks by name), but in one transaction and with the note types, decks and tags looked up once, so importing is far faster than one request per note.
The answer is 200 with one entry in results per note you sent, in the same order (index). An entry the collection refuses, such as an unknown deck or a key that names no field, is reported as ok: false with an error, and the others are still written. Send atomic: true to write all or nothing: if any entry is refused, nothing is written and the answer is 422 with the same body.
A batch counts as one request per 10 notes (at least one) against your plan's rate limit. At most 2 batches run at once on the server; when it is busy the answer is 503 with Retry-After, and nothing was changed.
Parameters
Request body
Example request
Response
200Every entry was handled; see `results`
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 422The body failed validation (
validation_error), or the call wasatomicand an entry was refused: then the body is the usual batch answer with every entry'serror, and nothing was written. - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
- 503Other batch operations are using the server. Wait the number of seconds in
Retry-Afterand retry; nothing was changed.
/api/v1/notes/batch-updatewriteEdit many notes in one call#
Edits up to 200 notes in one call. It does what Edit a note does for each entry, but in one transaction with note types, decks and tags looked up once. Each entry names a note by id and may send fields, tags, or the tag edits addTags and removeTags; what it leaves out stays as it was. tags replaces all tags and can not be sent with addTags or removeTags. removeTags works as in Anki: a tag is matched ignoring case, and removing lang also removes lang::de and the other tags below it (* is not a wildcard). A note may appear once per call.
The answer is 200 with one entry in results per entry you sent, in the same order (index). An entry the collection refuses, such as an unknown note or the wrong number of fields, is reported as ok: false with an error, and the others are still written. Send atomic: true to write all or nothing: if any entry is refused, nothing is written and the answer is 422 with the same body. changed counts notes that differed from what was stored.
A batch counts as one request per 10 entries (at least one) against your plan's rate limit.
Parameters
Request body
Example request
Response
200Every entry was handled; see `results`
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 422The body failed validation (
validation_error), or the call wasatomicand an entry was refused: then the body is the usual batch answer with every entry'serror, and nothing was written. - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
- 503Other batch operations are using the server. Wait the number of seconds in
Retry-Afterand retry; nothing was changed.
/api/v1/notes/batch-deletewriteDelete many notes in one call#
Deletes up to 1000 notes and every card made from them, in one transaction. Ids that do not exist are not an error; they are listed in missingNoteIds. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
A batch counts as one request per 10 ids (at least one) against your plan's rate limit.
Parameters
Request body
Example request
Response
200The notes that existed were deleted
- 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 422The body does not match the earlier request that used this
Idempotency-Key(idempotency_conflict), or the body failed validation (validation_error). - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
- 503Other batch operations are using the server. Wait the number of seconds in
Retry-Afterand retry; nothing was changed.
/api/v1/notes/{id}readGet note by ID with cards#
Returns one note, including the cards it produced.
Parameters
Example request
Response
200Note details
- 404No deck, note, note type or card has that id.
- 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/notes/{id}writeUpdate note fields or tags#
Changes a note's fields, its tags, or both. Anything you leave out stays as it was, including each field missing from fields: send only the fields that change. If the new field content makes a template produce a card it did not before, the new cards are returned in newCards.
changed is false when the request matched what was already stored, and nothing is written.
Parameters
Request body
Example request
Response
200Note updated
- 404No deck, note, note type or card has that id.
- 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/notes/{id}writeDelete a note and its cards#
Deletes a note and every card made from it. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
Parameters
Example request
Response
200Note deleted
- 404No deck, note, note type or card has that id.
- 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
Note types#
A note type is the template for notes: its fields, and the card templates that decide which cards a note produces.
/api/v1/note-typesreadList note types#
Returns the id and name of every note type, or only the ones whose name q accepts. Use Get a note type for its fields and templates.
Parameters
Example request
Response
200List of note types
- 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/note-typeswriteCreate note type (stock or custom)#
Creates a note type, either from one of Anki's stock designs or from your own fields and templates.
Send stock (basic, basic-and-reversed, basic-optional-reversed, basic-type-in-answer, cloze or image-occlusion) to start from a stock design, and optionally name to rename it. Or send fields and templates to define it yourself.
Parameters
Request body
Example request
Response
201Note type created
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/note-types/{id}readGet note type details with fields and templates#
Returns a note type with its fields and card templates, its CSS and its sort field.
Parameters
Example request
Response
200Note type details
- 404No deck, note, note type or card has that id.
- 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/note-types/{id}writeUpdate note type fields, templates, or styling#
Changes a note type's name, CSS, sort field, fields or templates.
Adding, reordering or renaming fields and templates is safe. Removing a field or template, or changing which fields a template needs, changes the collection's schema, so every device has to download the whole collection again on its next sync (a full sync). The request is refused with 409 full_sync_required until you add ?acceptFullSync=true.
Removing a field or template also needs Allow destructive schema changes via API turned on under Settings → Developer, or the answer is 403 destructive_change_disabled.
Parameters
Request body
Example request
Response
200Note type updated
- 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 404No deck, note, note type or card has that id.
- 409The change alters the collection's schema and needs
?acceptFullSync=true(full_sync_required), or the card is in a state that does not allow this (card_state_error: suspended, buried, in a filtered deck, or an unsupported scheduler). - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/note-types/{id}writeDelete a note type#
Deletes a note type and every note that uses it.
This changes the collection's schema, so it needs ?acceptFullSync=true (otherwise 409 full_sync_required) and Allow destructive schema changes via API turned on under Settings → Developer (otherwise 403 destructive_change_disabled).
Parameters
Example request
Response
200Note type deleted
- 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 404No deck, note, note type or card has that id.
- 409The change alters the collection's schema and needs
?acceptFullSync=true(full_sync_required), or the card is in a state that does not allow this (card_state_error: suspended, buried, in a filtered deck, or an unsupported scheduler). - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
Tags#
The labels notes carry. A tag is created when a note brings it, or here with no note yet. List them, rename a tag (its nested tags follow) or delete it from every note. Nested tags keep Anki's :: separator; a tag name is one path segment, so percent-encode it (Languages%3A%3AGerman). The names batch-create, batch-update and batch-delete belong to the batch endpoints: a tag with such a name can only be reached through them.
/api/v1/tagsreadList tags#
Returns every tag in the collection, sorted by name, or only the tags q accepts. A nested tag keeps Anki's :: separator, such as Languages::German; searching tag:Languages also finds the notes tagged with the nested ones.
Parameters
Example request
Response
200List of tags
- 401The
Authorizationheader is missing, or the key is invalid, disabled or expired. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/tagswriteCreate a tag#
Creates a tag without putting it on a note, as Anki registers a tag when a note brings it. A name that is already used (ignoring case) answers 200 with created: false and the spelling that is stored, so sending it twice is safe. A nested name keeps the spelling of a parent that exists, as in Anki.
A tag no note carries is removed by Anki's Check Database and Clear Unused Tags.
Parameters
Request body
Example request
Response
200The tag already existed
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 422The body does not match the earlier request that used this
Idempotency-Key(idempotency_conflict), or the body failed validation (validation_error). - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/tags/{name}readGet a tag by name#
Returns a tag and noteCount, the notes that carry it or one of its nested tags (the notes tag:name finds). A tag exists when it is in the list, when a nested tag is, or when a note carries it. The name in the path is the tag, percent-encoded, and is compared ignoring case.
Parameters
Example request
Response
200Tag details
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 404No deck, note, note type or card has that id.
- 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/tags/{name}writeRename a tag#
Renames a tag and every tag nested under it on all notes: renaming Languages to Lang makes Languages::German into Lang::German. The notes that change get a new modification time, so they sync. If the new name is already a tag, the two are merged, and a note that ends up with the tag twice keeps it once. Renaming a tag that no note carries renames it in the list.
notes is how many notes were looked at and changed.
Parameters
Request body
Example request
Response
200Tag renamed
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 404No deck, note, note type or card has that id.
- 422The body does not match the earlier request that used this
Idempotency-Key(idempotency_conflict), or the body failed validation (validation_error). - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/tags/{name}writeDelete a tag#
Removes a tag and the tags nested under it from every note and from the list. The notes keep everything else. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
Parameters
Example request
Response
200Tag deleted
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 404No deck, note, note type or card has that id.
- 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/tags/batch-createwriteCreate many tags in one call#
Creates up to 200 tags in one call, in one transaction. It does what Create a tag does for each name. The answer is 200 with one entry in results per name, in order; a name that is refused (such as one with a space) is ok: false with an error and the others are still created. Send atomic: true to write all or nothing: then the answer is 422 with the same body.
A batch counts as one request per 10 names against your plan's rate limit.
Parameters
Request body
Example request
Response
200Every entry was handled; see `results`
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 422The body failed validation (
validation_error), or the call wasatomicand an entry was refused: then the body is the usual batch answer with every entry'serror, and nothing was written. - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
- 503Other batch operations are using the server. Wait the number of seconds in
Retry-Afterand retry; nothing was changed.
/api/v1/tags/batch-updatewriteRename many tags in one call#
Renames up to 200 tags in one call, in one pass over the notes. Each entry names a tag by name and gives its newName, as Rename a tag does. Two entries may use the same newName (that merges the tags), but an entry that touches another one (a name that is, contains or lies inside another entry's name or newName) is refused with invalid_input, because the result would depend on the order. Entries are reported in results as in Create many notes; atomic: true writes all or nothing.
Parameters
Request body
Example request
Response
200Every entry was handled; see `results`
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 422The body failed validation (
validation_error), or the call wasatomicand an entry was refused: then the body is the usual batch answer with every entry'serror, and nothing was written. - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
- 503Other batch operations are using the server. Wait the number of seconds in
Retry-Afterand retry; nothing was changed.
/api/v1/tags/batch-deletewriteDelete many tags in one call#
Deletes up to 1000 tags, with the tags nested under them, from every note and from the list, in one transaction. Names that do not exist are not an error; they are listed in missingNames. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
Parameters
Request body
Example request
Response
200The tags that existed were deleted
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
- 503Other batch operations are using the server. Wait the number of seconds in
Retry-Afterand retry; nothing was changed.
Cards#
A card is one thing to review, made from a note. Change what a card shows by editing its note; here you can search, flag, suspend, bury, move and delete cards, render them for display, and answer them with Anki's v3 scheduler (SM-2 or FSRS, as the deck's preset says).
/api/v1/cardsreadSearch cards#
Returns the cards that match a search (q; every card when it is empty), in ascending id order, one page at a time. Narrow it by deck or note with deck:, did: and nid: in the search. Paginate with nextCursor as for notes, with one difference: a search that has to look at every card, such as a regular expression or prop:s, stops after about 10,000 cards and returns what it found so far together with a nextCursor. A page can therefore hold fewer than limit cards, or none, while nextCursor is not null; keep following it until it is.
Parameters
Example request
Response
200Paginated list of cards
- 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/cards/batch-updatewriteEdit many cards in one call#
Applies one change to up to 1000 cards, in one transaction: set a flag, move them to a deck, suspend or bury them. It does what Edit a card does for each id, with the same rules for patch.
The answer is 200 with one entry in results per distinct id. A card that does not exist, or that sits in a filtered deck and so can not be moved, is reported as ok: false, and the others are still changed. Send atomic: true to write all or nothing: if any card is refused, nothing is written and the answer is 422 with the same body. changed counts the cards that differed from what was stored.
A batch counts as one request per 10 ids (at least one) against your plan's rate limit.
Parameters
Request body
Example request
Response
200Every card was handled; see `results`
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 422The body failed validation (
validation_error), or the call wasatomicand an entry was refused: then the body is the usual batch answer with every entry'serror, and nothing was written. - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
- 503Other batch operations are using the server. Wait the number of seconds in
Retry-Afterand retry; nothing was changed.
/api/v1/cards/batch-deletewriteDelete many cards in one call#
Deletes up to 1000 cards in one transaction. A note whose last card is deleted is deleted with it. Ids that do not exist are not an error; they are listed in missingCardIds. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
A batch counts as one request per 10 ids (at least one) against your plan's rate limit.
Parameters
Request body
Example request
Response
200The cards that existed were deleted
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 422The body does not match the earlier request that used this
Idempotency-Key(idempotency_conflict), or the body failed validation (validation_error). - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
- 503Other batch operations are using the server. Wait the number of seconds in
Retry-Afterand retry; nothing was changed.
/api/v1/cards/{id}readGet card details by ID#
Returns one card with its scheduling state: queue, due, interval, ease factor, repetitions and lapses.
Parameters
Example request
Response
200Card details
- 404No deck, note, note type or card has that id.
- 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/cards/{id}writeEdit a card#
Changes a card's flag, moves it to another deck, or suspends or buries it. Anything you leave out stays as it was.
flag is 0 (none) to 7. suspended and buried cannot both be sent. Suspending keeps a card out of review until you send suspended: false; burying hides it only until the next day or until you unbury it. A suspended card is never buried. Moving a card clears its FSRS memory state; it is replayed from the review history with the new deck's parameters the next time the card is shown or answered. Cards in a filtered deck can neither be moved nor moved into one (409 card_state_error).
changed is false when the request matched what was already stored.
Parameters
Request body
Example request
Response
200Card updated
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 404No deck, note, note type or card has that id.
- 422The body does not match the earlier request that used this
Idempotency-Key(idempotency_conflict), or the body failed validation (validation_error). - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/cards/{id}writeDelete a card#
Deletes one card. If it was the last card of its note, the note is removed too. This cannot be undone. Deleting is still allowed while the account is over its storage quota.
Parameters
Example request
Response
200Card deleted
- 404No deck, note, note type or card has that id.
- 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/cards/{id}/renderreadRender a card's front and back#
Renders the card as Anki shows it: the note's fields are put into the card template, so the question and the answer are ready to display. The answer includes the question above a divider, as in Anki.
Everything is sanitized on the server before it is returned: scripts, event handlers, iframes, forms, javascript: links and remote styles are removed, and CSS is limited to a safe subset. The result is still content from your collection, so display it in a sandboxed <iframe sandbox> or srcdoc and not straight into your page.
With format=json (the default) you get question, answer and css. With format=html you get one complete HTML document, with a Content-Security-Policy that allows no script and the sandbox directive, which is meant for <iframe sandbox srcdoc>: fetch it with your key and put the text in srcdoc (an iframe's src cannot send the key, and this server refuses to be framed). Media in a card is referred to by file name and listed in media. The file names in the question and answer are turned into signed links to GET /api/v1/media/{name} that last an hour, so the card shows its pictures and plays its audio from a sandboxed frame; or pass mediaBaseUrl (an http(s) URL ending in /) to have them point at files you host instead.
Typing the answer. For {{type:Field}}, {{type:nc:Field}} (accents ignored) and {{type:cloze:Field}} the question holds <div class="typeans" data-field="Field"></div>, where your own input goes. Pass what the learner typed as typedAnswer (up to 1000 characters) and the answer shows the comparison Anki shows, computed the same way: a <code id="typeans"> with the typed text and the expected text as typeGood, typeBad and typeMissed spans around an arrow, in the font and size of the field. The classes carry no colors, so style them in your page. Without typedAnswer the answer shows the expected text. A text too long to compare is shown as one change.
Formulas. \(...\) and \[...\] are returned as written. Anki's [$]...[/$] and [$$]...[/$$] tags are rewritten to them, and [latex]...[/latex] becomes display math; images are not generated, because that needs a TeX installation. math is true when the question or the answer holds a formula. Typeset it in your page with MathJax 3 after inserting the HTML (format=html allows no script, so a formula stays as text there). TeX that is not math, such as packages or TikZ, is not supported.
A template that cannot be rendered is 422 render_error.
Parameters
Example request
Response
200The rendered card
- 404No deck, note, note type or card has that id.
- 422The card's template has a syntax error or refers to a field that does not exist (
render_error). - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/cards/{id}/schedulingreadPreview the four answer buttons#
Shows what each answer button would do, without answering: the time until the card would next be due after Again, Hard, Good and Easy. This is the preview Anki shows above its buttons.
Only the v3 scheduler is supported. The card must be answerable: not suspended or buried (409 card_state_error). A card in a filtered deck is previewed as Anki does: in a deck that reschedules, the buttons are the home deck preset's, and a review that comes before it was due is scheduled from the days it was early; in a deck that does not reschedule, the buttons are the preview delays (Again, Hard and Good come back after the deck's delays, a delay of 0 ends the preview, and Easy always ends it) and show 0 seconds when they end it.
Review intervals are fuzzed and load balanced like Anki's: the day is drawn within the fuzz range, weighted towards days with fewer cards of the same preset due, the preset's Easy Days and (if it buries siblings) days away from the card's siblings. The draw is fixed by the card and its review count, so the preview, the answer and a repeat of either agree.
Parameters
Example request
Response
200What each answer would do
- 404No deck, note, note type or card has that id.
- 409The change alters the collection's schema and needs
?acceptFullSync=true(full_sync_required), or the card is in a state that does not allow this (card_state_error: suspended, buried, in a filtered deck, or an unsupported scheduler). - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/cards/{id}/answerwriteAnswer (review) a card#
Answers a card, the same as pressing a button in Anki's reviewer. The card is rescheduled with the deck preset's v3 scheduler (or FSRS when the preset turns it on), a review-log entry is written, the deck's daily counts go up, and siblings are buried if the preset says so. A card that reaches the leech threshold gets the leech tag and, if the preset says so, is suspended.
rating is again, hard, good or easy (or 1 to 4). timeTakenMs is how long the learner looked at the card, capped by the preset. Send an Idempotency-Key so a retry does not answer twice.
The card must not be suspended or buried, and the collection must use the v3 scheduler; otherwise the answer is 409 card_state_error. A card in a filtered deck is answered as Anki does. The preset, the answer-time cap and burying come from the card's home deck, the daily counts go to the filtered deck and its parents, and the review log records an answer given before the card was due (or in a deck that does not reschedule) with type 3 (filtered). In a deck that reschedules, a review card that is passed returns to its home deck, and a learning card stays in the filtered deck until it graduates; in a deck that does not reschedule, nothing is rescheduled: Again, Hard and Good bring the card back after the deck's preview delay, and the card returns to its home deck in its old state when the preview ends. The legacy schedulers are not supported. A card that has no FSRS memory state yet (for example one that was just moved into an FSRS deck) gets one replayed from its review history, as Anki does, and from its SM-2 ease and interval when the history is too short.
The load balancer is applied to review intervals as in Anki (see GET /api/v1/cards/{id}/scheduling). It reads the cards due in the next 99 days when the card is answered (Anki reads them once when it builds a queue), and the weekday used for Easy Days is taken in the collection's localOffset (UTC when unset).
Parameters
Request body
Example request
Response
200The card was scheduled and the review logged
- 404No deck, note, note type or card has that id.
- 409The change alters the collection's schema and needs
?acceptFullSync=true(full_sync_required), or the card is in a state that does not allow this (card_state_error: suspended, buried, in a filtered deck, or an unsupported scheduler). - 422The body does not match the earlier request that used this
Idempotency-Key(idempotency_conflict), or the body failed validation (validation_error). - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
Study#
What to study next. The study queue is built the way Anki builds it, from the deck presets, daily limits and the current time.
/api/v1/queuereadGet the study queue of a deck#
Returns the cards Anki would show next in a deck, in the order it would show them: the deck (and its subdecks) is searched for learning cards due now, then reviews and day-learning cards, then new cards, under the daily limits of every deck preset and deck (including New cards ignore review limit and Apply all parent limits), with new-card gather and sort order, review order, FSRS orders, burying of siblings and the mixes of new cards and day-learning cards with reviews. The result matches the desktop client's queue for the same collection and moment.
counts is what Anki shows above the buttons (new, learning, review). cards holds the first limit cards, each with a kind of new, learning or review; total is the length of the whole queue. Learning cards that are due within the preset's learn-ahead limit are listed at the end. Nothing is written, so asking again before you answer gives the same queue; after POST /api/v1/cards/{id}/answer ask again.
Without deckId the collection's current deck is used. Only the v3 scheduler is supported (409 card_state_error otherwise). A filtered deck is queued with unlimited counts, in the order it was built in Anki (its cards keep that position).
Parameters
Example request
Response
200The next cards to study, in order
- 404No deck, note, note type or card has that id.
- 409The change alters the collection's schema and needs
?acceptFullSync=true(full_sync_required), or the card is in a state that does not allow this (card_state_error: suspended, buried, in a filtered deck, or an unsupported scheduler). - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/statsreadGet the statistics of a search#
Returns the graphs of Anki's statistics screen for the cards a search matches (q, default every card) and the last days days of review history (0, the default, is all of it). The numbers are Anki's: the same counts, buckets and averages the desktop client draws, computed from the review log and the cards in place. Nothing is copied into another database. A request reads the review log once, so a big collection takes a moment; one that takes longer than 20 seconds is refused with 400 invalid_input (narrow the search or the days). The server keeps the graphs of a search in memory for up to five minutes, and never past the end of the day, while the collection is unchanged, so a repeat request is answered without reading the collection again; any change to the collection ends that.
Days are counted from the end of the current day, so 0 is today, -1 yesterday and 1 tomorrow; a day starts at the collection's rollover hour and is read in its localOffset (UTC when unset), as timing says. buttons, hours and trueRetention count answers over a month, three months, a year and all time. cardCounts counts cards by kind, with suspended and buried cards counted separately or together. eases (SM-2) and difficulty, stability and retrievability (FSRS) cover the cards that have the data; fsrs says whether the collection has FSRS turned on. retrievability is the chance of recalling each card now, from its memory state and the time since its last review. Keys of the count objects are numbers: a day, a percent bin or an interval in days.
Parameters
Example request
Response
200The graphs of Anki's statistics screen
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
Media#
The images, audio and video your cards refer to. They are the same files the Anki desktop and mobile clients sync: a file you put here reaches your devices on their next media sync, and a file synced from a device can be read here.
/api/v1/mediareadList media files#
Lists the collection's media files by name, 100 at a time (limit up to 1000). prefix keeps only the names that start with it. When nextCursor is not null, pass it as cursor to get the next page. Each item has the file's size, its sha1 and sha256, the contentType it is served as, and the usn of its last change, which is the number the Anki media sync uses.
Parameters
Example request
Response
200A page of media files, in name order
- 400The request was understood but is not valid, for example an unknown deck or a
fieldskey that names no field of the note type. The code isinvalid_input,deck_errororcard_type_error. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/media/{name}readDownload a media file#
Returns the file's bytes. The type comes from the file name's extension only, never from the bytes, and every response says X-Content-Type-Options: nosniff and a Content-Security-Policy with sandbox, so a file from your collection cannot run script on this origin. Images, audio, video and fonts are shown inline; SVG, PDF and any other type are offered as downloads (Content-Disposition: attachment).
The ETag is the file's SHA-256, so If-None-Match answers 304. Range: bytes=... (one range) answers 206, which lets a browser seek in audio and video; a range past the end is 416.
Instead of a key, the request may carry the u, exp and sig query parameters of a signed link. A signed link opens that one file for reading until it expires, which is how a card shown in a sandboxed frame loads its pictures: GET /api/v1/cards/{id}/render puts such links into the card unless you pass mediaBaseUrl. The links last an hour.
Parameters
Example request
Response
200The file
- 304The ETag still matches
- 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 404No deck, note, note type or card has that id.
- 416The range is not inside the file
- 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/media/{name}readGet a media file's headers#
Like GET, without the body: the headers tell the size, type and ETag.
Parameters
Example request
Response
200The file's headers
- 304The ETag still matches
- 404No deck, note, note type or card has that id.
- 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/media/{name}writeStore a media file#
Stores the request body as the file, creating it or replacing it. Send the bytes as they are (any Content-Type) with a Content-Length header; chunked uploads are refused with 411. A file is at most 100 MiB and not empty.
The name must be one Anki clients would keep as it is: at most 120 bytes of UTF-8, in Unicode NFC, with none of [ ] < > : " / ? * ^ \ | or control characters, no Windows device name (CON, NUL, LPT1...), and not ending in a space or a dot. A client rewrites any other name when it syncs, so the file would never settle between devices; the 422 invalid_media_name says the name to use. Thumbs.db and .DS_Store are never synced and are refused as well.
201 means the file is new; 200 means it replaced a file (created is false) or the bytes were the same (unchanged is true, and the usn stays). A new or changed file gets the next usn, so the media sync sends it to your devices. A file that would take the storage over the quota is 403 over_quota, and a collection already holding the most file names it may (deleted names count) is 403 media_entry_limit; replacing a name never adds one.
Parameters
Example request
Response
200The file replaced one, or the bytes were the same
- 400The file name cannot be decoded (
invalid_media_name), or the body is not as long asContent-Lengthsays (length_mismatch) - 403The key lacks the
writescope, the account is suspended or unverified, the file would take the storage over its quota (over_quota), or the collection already holds the most file names it may (media_entry_limit) - 411No Content-Length header (length_required)
- 413A media file is larger than 100 MiB (
payload_too_large). - 422The name is not one Anki clients keep as it is (
invalid_media_name), or the file is empty (empty_file) - 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.
/api/v1/media/{name}writeDelete a media file#
Deletes the file. Your devices are told on their next media sync, as when a file is deleted in Anki. The storage it used is freed once no other name uses the same bytes. A name that is not there is 404.
Parameters
Example request
Response
200The file was deleted
- 403The key lacks the scope, the account is suspended or its email unverified, the account is over its storage quota (
over_quota; deleting is still allowed), or a destructive schema change is switched off (destructive_change_disabled). - 404No deck, note, note type or card has that id.
- 423Another write or an Anki sync is using the collection. Wait the number of seconds in
Retry-Afterand retry; nothing was changed. - 429The plan's rate limit is used up: a limit per minute on every plan, and a limit per day on Free. Nothing was changed. Wait Retry-After seconds and send the same request again.