Memojin, built into your tools.
A complete REST API that connects your platforms to Memojin: contents, folders, memocards and questions to read and write, AI generation, search, spaces and learning progress. Designed for learning platforms, LMS vendors, publishers and the technical teams of schools and universities.
Access is granted by our team, one organization at a time
28 operations · 14 scopes · OpenAPI 3.1
curl "https://api.memojin.com/v1/contents?limit=20" \
-H "Authorization: Bearer $MEMOJIN_API_KEY" \
-H "Accept-Language: fr"{
"data": [
{
"id": "3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87",
"title": "Photosynthesis",
"description": null,
"language": "en",
"folderId": null,
"imageUrl": null,
"createdAt": "2026-09-28T17:04:51.000Z",
"updatedAt": "2026-10-02T08:30:12.000Z",
"inclusions": {
"hasBody": true,
"hasSummary": true,
"memocardsCount": 42,
"questionsCount": 18,
"podcastsReadyCount": 1,
"sourcesCount": 2
}
}
],
"nextCursor": "eyJvIjoyMH0",
"hasMore": true
}Four ways to plug in Memojin.
A key acts on behalf of one Memojin account, with exactly its rights: you integrate what that account sees, nothing more.
Bring review to where your students already work
Moodle, a regional platform or your own: show a teacher account’s contents with their memocards and questions, without leaving your platform.
Connect Memojin to your information system
Find your teachers’ contents, folders and spaces in your dashboards and teaching tools, with no retyping.
Extend your resources with active recall
Import your resources as contents, add your own memocards and questions, or let the AI generate them.
Automate what is still done by hand
Scripts, reports, syncs: your tools read the OpenAPI 3.1 contract and generate a typed client from it, and idempotency makes every retry safe.
Nine resources, one scope per action.
Everything in this table answers today, with the scope shown. Every operation is described, parameter by parameter, in the reference.
Contents
contents:readcontents:writeList the contents of a folder; read a content with its six measures (body, summary, number of memocards, questions, ready podcast episodes and sources); create one from a title or a text, stored as is; update it, delete it.
- GET/v1/contents
- POST/v1/contents
- GET/v1/contents/{contentId}
- PATCH/v1/contents/{contentId}
- DELETE/v1/contents/{contentId}
Folders
folders:readfolders:writeBrowse a library’s folder tree, create a folder (up to five levels), update or delete it.
- GET/v1/folders
- POST/v1/folders
- GET/v1/folders/{folderId}
- PATCH/v1/folders/{folderId}
- DELETE/v1/folders/{folderId}
Memocards
memocards:readmemocards:writeList a content’s memocards, with the account’s retention and last review; add a memocard (front, back, explanation), update it, delete it.
- GET/v1/contents/{contentId}/memocards
- POST/v1/contents/{contentId}/memocards
- GET/v1/memocards/{memocardId}
- PATCH/v1/memocards/{memocardId}
- DELETE/v1/memocards/{memocardId}
Questions
questions:readquestions:writeList a content’s questions; create four types (free text, true or false, single choice, multiple choice); update the prompt, explanation, difficulty or points; delete them.
- GET/v1/contents/{contentId}/questions
- POST/v1/contents/{contentId}/questions
- GET/v1/questions/{questionId}
- PATCH/v1/questions/{questionId}
- DELETE/v1/questions/{questionId}
AI generation
generations:writejobs:readGenerate memocards from a content, or questions from its memocards: an immediate answer (202), then follow the job to its result. The planned AI credits are stated in the answer.
- POST/v1/contents/{contentId}/memocard-generations
- POST/v1/contents/{contentId}/question-generations
- GET/v1/jobs/{jobId}
Search
search:readSearch the account’s contents and folders, ignoring case and accents.
- GET/v1/search
Spaces
spaces:readRead the spaces (classes, groups) the account owns, archived ones included on request. No member is exposed.
- GET/v1/spaces
- GET/v1/spaces/{spaceId}
Study sessions
study-sessions:readList the account’s review and practice sessions, most recent first, with their counters, filtered by status or space.
- GET/v1/study-sessions
Learning statistics
learning-stats:readMastered memocards, study time, 30-day success rate and completed sessions of the account.
- GET/v1/learning-stats
In preparation
- Coming soonMCP server
The API’s operations offered to MCP-compatible AI assistants, with the same keys and the same scopes.
- Coming soonDeveloper space
Create your keys, choose their scopes and follow your usage from your account, self-service.
- Coming soonOutgoing webhooks
Get a signed call on your server, for instance when a generation ends, instead of polling.
- Coming soonAccess included in plans
The API opened directly with some teacher and institution plans, with no prior request.
From sandbox to production, in three steps.
Every organization starts in the sandbox. Production opens once your integration is ready.
You request access
Tell us about your project. We create your organization, linked to the Memojin account it will act for, and hand you a test key.
You build in the sandbox
An mj_test_ key reads and writes the same data, with a quota of 100 calls a day. AI generation is simulated: nothing is sent or counted.
You go live
Once our team has approved your integration, you receive an mj_live_ key. It is shown only once: store it in your secrets vault.
One key, its scopes
Each operation requires a scope shaped resource:read or resource:write, shown in the table above. A key only carries the scopes you asked for, and write does not imply read; without the right one, the API answers 403 insufficient_scope, naming the scope it expects.
The key stays in an environment variable on your server: the API does not answer browser calls.
Your first call
curl "https://api.memojin.com/v1/contents?limit=20" \
-H "Authorization: Bearer $MEMOJIN_API_KEY" \
-H "Accept-Language: fr"const res = await fetch("https://api.memojin.com/v1/contents?limit=20", {
headers: { Authorization: `Bearer ${process.env.MEMOJIN_API_KEY}` },
});
if (!res.ok) {
const { error } = await res.json();
throw new Error(`${error.code}: ${error.message}`);
}
const { data, nextCursor, hasMore } = await res.json();import os, requests
res = requests.get(
"https://api.memojin.com/v1/contents",
params={"limit": 20},
headers={"Authorization": f"Bearer {os.environ['MEMOJIN_API_KEY']}"},
timeout=10,
)
if not res.ok:
error = res.json()["error"]
raise RuntimeError(f"{error['code']}: {error['message']}")
page = res.json() # { "data": [...], "nextCursor": ..., "hasMore": ... }HTTP, by the book.
No house convention to learn: the headers your HTTP libraries already know, set by the API on every response they apply to.
ETagIf-None-Match304Conditional reads
Every GET returns an ETag; sent back in If-None-Match, it gets a bodiless 304 when nothing changed.
If-Match412Conflict-free writes
Send the ETag you read in If-Match: if the resource changed meanwhile, PATCH and DELETE answer 412 and change nothing.
Idempotency-KeyIdempotent-ReplayedIdempotency
Every POST accepts an Idempotency-Key: replayed within 24 hours, the request returns the first response, marked Idempotent-Replayed, with nothing created or counted twice.
RateLimit-LimitRateLimit-RemainingRateLimit-ResetRetry-AfterAnnounced limits
Every response tells where you stand in your rate-limit window; a 429 or a 503 says in Retry-After when to try again.
LocationLinkLinks
A creation answers 201 with Location; a page carries Link rel="next"; every error, a Link rel="help" to the documentation of its code.
Memojin-VersionDeprecationSunsetVersions and retirement
Memojin-Version tells which contract served the request; Deprecation and Sunset (RFC 9745, RFC 8594) are ready to flag an operation at end of life.
Memojin-Credits-EstimateCredits stated upfront
A generation states in its header, as in its body, the AI credit units it plans to use.
X-Request-IdAccept-LanguageTraceability and languages
Every call carries an X-Request-Id, yours or ours; Accept-Language picks the language of error messages among five.
One error shape, { error: { code, message, details } }, and 25 stable codes, each explained in the public error table.
Start, follow, collect.
Generating memocards or questions takes from a few seconds to a few minutes. The API answers at once, then you follow the job at your own pace.
One ai_card unit per memocard or question generated, taken from the account’s AI credits, as in the app. A refused or replayed request costs nothing.
Poll GET /v1/jobs/{jobId} about every five seconds until succeeded, failed or cancelled, then read the content’s memocards or questions.
With an mj_test_ key, nothing is generated or counted: the job is finished at once, and you test the whole flow at no cost.
curl -X POST "https://api.memojin.com/v1/contents/$CONTENT_ID/memocard-generations" \
-H "Authorization: Bearer $MEMOJIN_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"
HTTP/1.1 202 Accepted
Memojin-Credits-Estimate: ai_card=12
{
"jobId": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"status": "pending",
"estimate": { "operation": "ai_card", "units": 12 }
}curl "https://api.memojin.com/v1/jobs/$JOB_ID" \
-H "Authorization: Bearer $MEMOJIN_API_KEY"
{
"id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"type": "memocard_generation",
"status": "succeeded",
"progress": 100,
"contentId": "3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87",
"error": null,
"createdAt": "2026-10-04T10:00:00.000Z",
"updatedAt": "2026-10-04T10:00:41.000Z"
}import os, time, uuid, requests
API = "https://api.memojin.com/v1"
H = {"Authorization": f"Bearer {os.environ['MEMOJIN_API_KEY']}"}
job = requests.post(
f"{API}/contents/{content_id}/memocard-generations",
headers={**H, "Idempotency-Key": str(uuid.uuid4())},
timeout=30,
).json() # 202 : {"jobId": ..., "status": "pending", "estimate": {...}}
while True:
state = requests.get(f"{API}/jobs/{job['jobId']}", headers=H, timeout=10).json()
if state["status"] in ("succeeded", "failed", "cancelled"):
break
time.sleep(5)
cards = requests.get(f"{API}/contents/{content_id}/memocards", headers=H, timeout=10).json()Trustworthy by design.
The rules that protect your data and your users’ data live in the code, not only in a contract.
Secret keys
We only store the SHA-256 fingerprint of your key, never the key itself. A revoked key is refused within a minute.
Server to server
The API refuses browser calls (CORS closed): your key never leaves your server.
One account’s rights
A key acts on behalf of one Memojin account and sees exactly what it sees. Another account’s resource answers 404, revealing nothing.
Least-privilege scopes
Read and write kept apart, resource by resource: a key only carries the scopes you ask for.
A sealed sandbox
An mj_test_ key never touches the real world: simulated generation, no credit used, nothing sent, 100 calls a day.
A verified contract
The reference and the OpenAPI contract are generated from the very schemas the API validates every request with.
Compatibility
Under /v1, only compatible additions. A breaking change will ship as /v2, and /v1 will keep running for at least 12 months.
Hosted in France
The API, the database and the files run on our own servers, hosted in France. The call log keeps neither content nor IP address.
Subprocessors, retention periods and your rights are detailed in our privacy policy.
Everything is written down, in English and French.
The reference describes every operation, parameter and error code, with examples. It is generated from the contract the API enforces, so it cannot contradict it.
The full documentation
Quick start, keys, sandbox, every resource and operation, errors, limits, AI credits: it is all on the site, in English and French, with curl, JavaScript and Python examples.
Interactive reference
In English: operations, schemas, guides, sample requests and responses.
/v1/docsOpen the referenceFrench reference
The same reference, guides included, fully in French.
/v1/docs/frOpen in FrenchOpenAPI 3.1 contract
openapi.json (and openapi.fr.json), to generate a typed client in your language.
/v1/openapi.jsonOpen the contractError table
Every error code, its HTTP status and what it means.
/v1/docs/errorsOpen the tableBefore you start.
How do I get a key?
Write to contact@memojin.com describing your organization and your project. Access is granted by our team: a test key first, then a production key once approved.
What can the API do today?
Read and write an account’s library (contents, folders, memocards, questions), start AI generation of memocards and questions and follow their jobs, search, and read spaces, study sessions and learning statistics. Every operation is described in the reference.
How much does the API cost?
During the beta, access is granted on request. Reading and writing use no AI credit; only generation uses the AI credits of the account the key acts for, as in the app: one unit per memocard or question generated, stated in the 202 response.
Do I need a Memojin subscription?
Yes: the key acts on behalf of a Memojin account, and most operations require that account to have an active plan, as in the app. API access included in some plans is in preparation.
Can I call the API from a browser or a mobile app?
No: the key is secret and the API refuses browser calls. Call it from your server, which then passes your interface what it needs.
Where is the data processed?
On our own servers, hosted in France. A key only reaches the data of the account it acts for, and the call log keeps neither content nor IP address.
Let’s talk about your integration.
Tell us in a few lines who you are, what you want to connect and the expected volume. We will get back to you to open your sandbox.
- Sandbox first, no commitment
- Reference in English and French
- Data hosted in France