API Reference
Programmatically create decks, add flashcards, and import files. Works with ChatGPT, Claude, and any tool that speaks HTTP.
Quick Start
# Add a flashcard to your deck curl -X POST https://www.iwill.study/api/v1/cards \ -H "Authorization: Bearer isk_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{"deck":"Spanish B1","cards":[{"front":"however","back":"sin embargo"}]}'
Authentication
REST API requests require a Bearer token. Generate an API key in Settings → API Keys.
Authorization: Bearer isk_your_api_key_here
The full key is shown only once when it is created. Store it securely, never put it in client-side source code, and use a dedicated key for each integration. Deck/language scope controls where new cards are written; it is not a general permission boundary.
Base URL
https://www.iwill.study/api/v1
Rate Limits
| Plan | Cards via API | Decks |
|---|---|---|
| Free | 100 cards/day | 5 decks |
| Pro | Unlimited | Unlimited |
Generate cards with OpenAI
Paste this prompt into ChatGPT or send it as the user input in an OpenAI API request. It defines the outcome, quality bar, JSON contract, and validation rules expected by the cards endpoint.
Create 20 high-quality flashcards for learning [LANGUAGE] at [LEVEL] level.
Outcome:
- Focus on practical, high-frequency vocabulary and phrases.
- Make each front a single, unambiguous recall cue.
- Make each back a concise translation or answer.
- Include one natural usage example in "context".
- Add 1-3 useful lowercase tags per card.
- Do not create duplicate or near-duplicate cards.
Return exactly one valid JSON object matching this shape:
{
"deck": "[Language] [Level]",
"cards": [
{
"front": "word, phrase, or question",
"back": "translation or answer",
"context": "one natural example with a short clarification if needed",
"tags": ["level", "topic"]
}
]
}
Output rules:
- Return JSON only: no Markdown fences, commentary, or trailing commas.
- Use double quotes for every key and string.
- Replace every placeholder with real content.
- Verify the JSON is valid before responding.Replace the bracketed values before sending. Then POST the returned JSON to /api/v1/cards using the Bearer key shown in the request examples below.
OpenAI Responses API with the MCP server
Server-side OpenAI requests can pass the iwill.study key in an HTTP header, so it does not need to appear in the connector URL. Keep both keys in environment variables or a server-side secret manager.
curl https://api.openai.com/v1/responses \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"input": "Use the iwill.study app to create 20 [LANGUAGE] flashcards at [LEVEL] level about [TOPIC]. Use concise recall cues, accurate answers, one natural usage example per card, and useful tags. Avoid duplicates. Save the cards to a deck named \"[Language] [Level] — [Topic]\" and report how many were created or skipped.",
"tools": [
{
"type": "mcp",
"server_label": "iwill_study",
"server_description": "Create and manage language-learning flashcards in iwill.study.",
"server_url": "https://www.iwill.study/api/mcp",
"headers": {
"Authorization": "Bearer isk_your_api_key_here"
},
"require_approval": "always"
}
]
}'AI connectors (MCP)
Connect ChatGPT or Claude directly to your iwill.study account. The remote MCP server exposes read and write tools for decks and cards.
ChatGPT / OpenAI
- In an eligible ChatGPT workspace, enable developer mode under Settings → Apps → Advanced settings.
- Open Settings → Apps → Create, name the app
iwill.study, and use the generated MCP URL below. - Choose no additional authentication because the dedicated key is already part of this MCP URL, then scan the tools.
Claude
- Open Settings → Integrations → Add custom connector.
- Set the name to
iwill.study. - Use the generated URL as the remote MCP server URL.
Keys are shown only once when created, so saved keys cannot be filled in here. This field stays in your browser. Use a dedicated key, optionally scope its card destination, and revoke it if the connector URL is exposed.
https://www.iwill.study/api/mcp?key=isk_your_api_key_hereAvailable tools
| Tool | Description |
|---|---|
list_decks | List all your decks with card counts |
add_cards | Add flashcards to a deck (auto-creates deck if needed, deduplicates) |
get_cards | Fetch all cards from a specific deck |
create_deck | Create a new empty deck |
Prompt after connecting
Use the iwill.study app to create 20 [LANGUAGE] flashcards at [LEVEL] level about [TOPIC]. Use concise recall cues, accurate answers, one natural usage example per card, and useful tags. Avoid duplicates. Save the cards to a deck named "[Language] [Level] — [Topic]" and report how many were created or skipped.
Endpoints
/api/v1/decksList all decks belonging to the authenticated user, with card counts.
Authentication
Bearer token (API key)
Example Request
curl https://www.iwill.study/api/v1/decks \ -H "Authorization: Bearer isk_your_api_key_here"
Response
{
"decks": [
{
"id": "uuid",
"title": "Spanish B1",
"description": "",
"language": "Spanish",
"source": "api",
"created_at": "2026-03-14T...",
"card_count": 42
}
]
}/api/v1/decksCreate a new empty deck.
Authentication
Bearer token (API key)
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Deck title (max 200 chars) |
description | string | No | Deck description |
language | string | No | Target language (e.g. "Spanish") |
Example Request
curl -X POST https://www.iwill.study/api/v1/decks \
-H "Authorization: Bearer isk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"title":"Spanish B1","description":"Writing connectors","language":"Spanish"}'Response
{
"deck": {
"id": "uuid",
"title": "Spanish B1",
"description": "",
"language": "Spanish",
"source": "api",
"created_at": "2026-03-14T..."
}
}/api/v1/decksDelete a deck and all its cards.
Authentication
Bearer token (API key)
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Deck ID to delete |
Example Request
curl -X DELETE "https://www.iwill.study/api/v1/decks?id=DECK_ID" \ -H "Authorization: Bearer isk_your_api_key_here"
Response
{ "success": true }/api/v1/cardsList all cards in a specific deck.
Authentication
Bearer token (API key)
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
deck_id | string | Yes | Deck ID to fetch cards from |
Example Request
curl "https://www.iwill.study/api/v1/cards?deck_id=DECK_ID" \ -H "Authorization: Bearer isk_your_api_key_here"
Response
{
"cards": [
{
"id": "uuid",
"front": "however",
"back": "sin embargo",
"tags": ["b1", "connectors"],
"context": "Formal writing: 'The results, however, were unexpected.'",
"source": "api",
"created_at": "2026-03-14T..."
}
]
}/api/v1/cardsAdd cards to a deck. Specify an existing deck by ID, or provide a title to find-or-create a deck.
Authentication
Bearer token (API key)
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
deck_id | string | No | Existing deck UUID. Use this to add cards to a specific deck. |
deck | string | No | Deck title (max 200 chars). Creates deck if not found. Required if deck_id is not provided. |
source | string | No | Optional source label: web, mobile, api, chatgpt, claude-mcp, import, or preset |
cards | array | Yes | Array of card objects (max 500 per request) |
cards[].front | string | Yes | Front side text (max 5000 chars) |
cards[].back | string | Yes | Back side text (max 5000 chars) |
cards[].tags | string[] | No | Optional tags for the card |
cards[].context | string | No | Usage examples, cultural notes, or contextual info (max 10,000 chars) |
Example Request
curl -X POST https://www.iwill.study/api/v1/cards \
-H "Authorization: Bearer isk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"deck": "Spanish B1",
"source": "chatgpt",
"cards": [
{
"front": "however",
"back": "sin embargo",
"context": "The results, however, were unexpected.",
"tags": ["b1", "connectors"]
}
]
}'Response
{
"deck_id": "uuid",
"created": 2,
"skipped": 1,
"rate_limited": 0
}Duplicates are automatically skipped — cards with the same front text (case-insensitive) already in the deck won't be added again. Provide deck_id for an existing deck or deck to find/create by title; if both are sent, deck_id takes precedence. A scoped key overrides the requested deck. Free plan: max 100 cards/day via API.
/api/v1/cardsUpdate or move cards. Use this to move cards between decks (preserving review history), edit card content, or update context and tags.
Authentication
Bearer token (API key)
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
card_ids | string[] | Yes | Array of card UUIDs to update (max 500) |
updates.deck_id | string | No | Target deck UUID — moves cards to this deck |
updates.front | string | No | New front text (max 5,000 chars) |
updates.back | string | No | New back text (max 5,000 chars) |
updates.tags | string[] | No | New tags array |
updates.context | string | null | No | New context/examples (max 10,000 chars), or null to clear |
Example Request
curl -X PATCH https://www.iwill.study/api/v1/cards \
-H "Authorization: Bearer isk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"card_ids": ["CARD_ID"],
"updates": {"deck_id": "TARGET_DECK_ID"}
}'Response
{ "updated": 3 }Moving cards between decks preserves all FSRS review history. You can combine a move with field updates in a single request.
/api/v1/importImport flashcards from an Anki (.apkg) or CSV/TSV file.
Authentication
Bearer token (API key)
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
file | File | Yes | Upload via multipart/form-data. Accepted: .apkg, .csv, .tsv, .txt |
Example Request
curl -X POST https://www.iwill.study/api/v1/import \ -H "Authorization: Bearer isk_your_api_key_here" \ -F "file=@my_deck.csv"
Response
{
"deck_id": "uuid",
"imported": 150
}CSV files should have two columns: front and back. The filename (without extension) is used as the deck name.
Error Codes
| Status | Meaning |
|---|---|
400 | Bad request — invalid or missing parameters |
401 | Unauthorized — missing or invalid API key |
403 | Forbidden — plan limit reached or operation is not allowed |
404 | Not found — resource doesn't exist or doesn't belong to you |
429 | Rate limited — daily card limit exceeded (free plan) |
500 | Server error — please try again or contact support |