diff --git a/README.md b/README.md
index 19a008b..27d402d 100644
--- a/README.md
+++ b/README.md
@@ -724,6 +724,44 @@ corresponding to when the API was available for use.
```
+#### `answerCards`
+
+* Answer cards. Ease is between 1 (Again) and 4 (Easy). Will start the timer immediately before answering. Returns `true` if card exists, `false` otherwise.
+
+
+ Sample request:
+
+ ```json
+ {
+ "action": "answerCards",
+ "version": 6,
+ "params": {
+ "answers": [
+ {
+ "cardId": 1498938915662,
+ "ease": 2
+ },
+ {
+ "cardId": 1502098034048,
+ "ease": 4
+ }
+ ]
+ }
+ }
+ ```
+
+
+
+ Sample result:
+
+ ```json
+ {
+ "result": [true, true],
+ "error": null
+ }
+ ```
+
+
---
### Deck Actions
diff --git a/plugin/__init__.py b/plugin/__init__.py
index 73f4d81..5ca8514 100644
--- a/plugin/__init__.py
+++ b/plugin/__init__.py
@@ -1530,6 +1530,24 @@ class AnkiConnect:
self.stopEditing()
+ @util.api()
+ def answerCards(self, answers):
+ scheduler = self.scheduler()
+ success = []
+ for answer in answers:
+ try:
+ cid = answer['cardId']
+ ease = answer['ease']
+ card = self.getCard(cid)
+ card.start_timer()
+ scheduler.answerCard(card, ease)
+ success.append(True)
+ except NotFoundError:
+ success.append(False)
+
+ return success
+
+
@util.api()
def cardReviews(self, deck, startID):
return self.database().all(
diff --git a/tests/test_cards.py b/tests/test_cards.py
index 57705d4..0ce93b2 100755
--- a/tests/test_cards.py
+++ b/tests/test_cards.py
@@ -76,3 +76,18 @@ def test_forgetCards(setup):
def test_relearnCards(setup):
ac.relearnCards(cards=setup.card_ids)
+
+
+class TestAnswerCards:
+ def test_answerCards(self, setup):
+ ac.scheduler().reset()
+ answers = [
+ {"cardId": a, "ease": b} for a, b in zip(setup.card_ids, [2, 1, 4, 3])
+ ]
+ result = ac.answerCards(answers)
+ assert result == [True] * 4
+
+ def test_answerCards_with_invalid_card_id(self, setup):
+ ac.scheduler().reset()
+ result = ac.answerCards([{"cardId": 123, "ease": 2}])
+ assert result == [False]