A content is a piece of study material in the library (“My contents”): class notes, a revision sheet, a textbook section. It holds a text (its body), and it is the source of the memocards and questions.
Good to know
POST /v1/contentsstores the text as is, without AI or credits. To turn it into memocards, then start a generation (at least 100 characters of text).GET /v1/contentsbrowses one folder (the root withoutfolderId); to look across the whole library, use search.inclusionssums up what the content holds: body, summary, number of memocards, questions, ready podcasts and sources.- Deleting a content deletes its memocards and questions.
The Content object
A content (study material, notes…) of the account the key acts for.
| Field | Type | Description |
|---|---|---|
id | string (uuid) | Content identifier (UUID). |
title | string | Title of the content. |
description | string | null | Short description, or null. |
language | string | null | Language code (fr, en, es, de, it…), or null when unknown. |
folderId | string | null | Folder holding the content, or null at the root. |
imageUrl | string | null | Cover image: a short-lived signed URL (download it, do not store it), or null. |
createdAt | string (date-time) | Creation instant (ISO 8601, UTC). |
updatedAt | string (date-time) | Last update instant (ISO 8601, UTC). |
inclusions | ContentMeasures | The six measures of a content. |
{
"id": "3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87",
"title": "Photosynthesis",
"description": "Light and dark reactions, chlorophyll, the Calvin cycle.",
"language": "en",
"folderId": "7a2d9c41-0b3e-4c5f-8e6a-1d2c3b4a5f60",
"imageUrl": null,
"createdAt": "2026-10-01T14:03:00.000Z",
"updatedAt": "2026-10-02T08:30:12.000Z",
"inclusions": {
"hasBody": true,
"hasSummary": false,
"memocardsCount": 12,
"questionsCount": 3,
"podcastsReadyCount": 0,
"sourcesCount": 1
}
}The ContentMeasures object
The six measures of a content.
| Field | Type | Description |
|---|---|---|
hasBody | boolean | The content has a body (its text). |
hasSummary | boolean | The content has a summary. |
memocardsCount | integer | Number of memocards (flashcards). |
questionsCount | integer | Number of practice questions. |
podcastsReadyCount | integer | Number of podcast episodes ready to play. |
sourcesCount | integer | Number of source documents. |
List the contents of a folder
/v1/contentsScope contents:readContents stored directly in the folder (the root when folderId is omitted), most recent first, paginated with limit and cursor. Only the contents of the account the API key acts for are visible.
Parameters
| Field | In | Type | Description |
|---|---|---|---|
folderId | query | string (uuid) | Folder to list (UUID). Omit it to list the root. |
limit | query | integerfrom 1 to 100 · default 20 | Number of items per page, 1 to 100 (default 20). |
cursor | query | stringat most 200 characters | Opaque cursor: the nextCursor of the previous page. Keep the same limit from one page to the next. |
Response 200
A page of contents — A page of Content { data, nextCursor, hasMore }
Errors
| HTTP | Meaning |
|---|---|
400 | validation_error or invalid_cursor |
401 | invalid_api_key or revoked_api_key |
403 | insufficient_scope, account_suspended, live_not_enabled or forbidden |
404 | not_found — the folder does not exist or is not visible to this key |
406 | not_acceptable — the Accept header excludes application/json |
429 | rate_limited or test_quota_exceeded — see the Retry-After and RateLimit-* headers |
500 | internal_error |
503 | unavailable — see the Retry-After header |
curl "https://api.memojin.com/v1/contents?limit=20" \
-H "Authorization: Bearer $MEMOJIN_API_KEY"{
"data": [
{
"id": "3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87",
"title": "Photosynthesis",
"description": "Light and dark reactions, chlorophyll, the Calvin cycle.",
"language": "en",
"folderId": "7a2d9c41-0b3e-4c5f-8e6a-1d2c3b4a5f60",
"imageUrl": null,
"createdAt": "2026-10-01T14:03:00.000Z",
"updatedAt": "2026-10-02T08:30:12.000Z",
"inclusions": {
"hasBody": true,
"hasSummary": false,
"memocardsCount": 12,
"questionsCount": 3,
"podcastsReadyCount": 0,
"sourcesCount": 1
}
}
],
"nextCursor": null,
"hasMore": false
}Create a content
/v1/contentsScope contents:writeCreates a content in a folder (or at the root), optionally with its body as plain text. No AI is involved and no credit is used. Answers 201 with the content and its Location.
Parameters
| Field | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Strongly recommended. A unique value per operation (UUID v4), reused unchanged on every retry. Within 24 hours, the same key and the same request replay the first response (Idempotent-Replayed: true) without a second effect or charge; another request with the same key → 422 idempotency_key_reused; still running → 409 idempotency_in_progress. |
Request body CreateContentRequest
A new content.
| Field | Type | Description |
|---|---|---|
titlerequired | string1 to 300 characters | Title of the content (1 to 300 characters). |
folderId | string (uuid) | null | Folder to store it in; omitted or null = the root. |
description | string | nullat most 2000 characters | Short description (2,000 characters at most). |
language | string | null | Language code (fr, en, es, de, it…), or null when unknown. |
text | stringat most 200000 characters | Body of the content, as plain text (paragraphs separated by blank lines; formulas between $…$). Written as is: no AI is involved and no credit is used. Omit it to create an empty content. |
Response 201
The content created — A Content object
Errors
| HTTP | Meaning |
|---|---|
400 | validation_error or bad_request |
401 | invalid_api_key or revoked_api_key |
403 | insufficient_scope, account_suspended, live_not_enabled or forbidden |
404 | not_found — the folder does not exist or is not visible to this key |
406 | not_acceptable — the Accept header excludes application/json |
409 | idempotency_in_progress — retry after Retry-After (1 s) |
413 | payload_too_large |
415 | unsupported_media_type |
422 | idempotency_key_reused, or a business rule (see the description) |
429 | rate_limited or test_quota_exceeded — see the Retry-After and RateLimit-* headers |
500 | internal_error |
503 | unavailable — see the Retry-After header |
curl -X POST "https://api.memojin.com/v1/contents" \
-H "Authorization: Bearer $MEMOJIN_API_KEY" \
-H "Idempotency-Key: 6f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87" \
-H "Content-Type: application/json" \
-d '{
"title": "Photosynthesis",
"folderId": "7a2d9c41-0b3e-4c5f-8e6a-1d2c3b4a5f60",
"language": "en",
"text": "Photosynthesis converts light energy into chemical energy."
}'{
"id": "3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87",
"title": "Photosynthesis",
"description": "Light and dark reactions, chlorophyll, the Calvin cycle.",
"language": "en",
"folderId": "7a2d9c41-0b3e-4c5f-8e6a-1d2c3b4a5f60",
"imageUrl": null,
"createdAt": "2026-10-01T14:03:00.000Z",
"updatedAt": "2026-10-02T08:30:12.000Z",
"inclusions": {
"hasBody": true,
"hasSummary": false,
"memocardsCount": 12,
"questionsCount": 3,
"podcastsReadyCount": 0,
"sourcesCount": 1
}
}Retrieve a content
/v1/contents/{contentId}Scope contents:readOne content of the account the API key acts for, with its six measures (inclusions). Answers 304 to a matching If-None-Match.
Parameters
| Field | In | Type | Description |
|---|---|---|---|
contentIdrequired | path | string (uuid) | Content identifier (UUID). |
Response 200
The content — A Content object
Errors
| HTTP | Meaning |
|---|---|
400 | validation_error — an identifier is not a UUID |
401 | invalid_api_key or revoked_api_key |
403 | insufficient_scope, account_suspended, live_not_enabled or forbidden |
404 | not_found |
406 | not_acceptable — the Accept header excludes application/json |
429 | rate_limited or test_quota_exceeded — see the Retry-After and RateLimit-* headers |
500 | internal_error |
503 | unavailable — see the Retry-After header |
curl "https://api.memojin.com/v1/contents/3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87" \
-H "Authorization: Bearer $MEMOJIN_API_KEY"{
"id": "3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87",
"title": "Photosynthesis",
"description": "Light and dark reactions, chlorophyll, the Calvin cycle.",
"language": "en",
"folderId": "7a2d9c41-0b3e-4c5f-8e6a-1d2c3b4a5f60",
"imageUrl": null,
"createdAt": "2026-10-01T14:03:00.000Z",
"updatedAt": "2026-10-02T08:30:12.000Z",
"inclusions": {
"hasBody": true,
"hasSummary": false,
"memocardsCount": 12,
"questionsCount": 3,
"podcastsReadyCount": 0,
"sourcesCount": 1
}
}Update a content
/v1/contents/{contentId}Scope contents:writeChanges the title, the description or the language. Send If-Match with the ETag you read to avoid overwriting a concurrent change.
Parameters
| Field | In | Type | Description |
|---|---|---|---|
contentIdrequired | path | string (uuid) | Content identifier (UUID). |
Request body UpdateContentRequest
The fields to change; the others stay as they are.
| Field | Type | Description |
|---|---|---|
title | string1 to 300 characters | New title (1 to 300 characters). |
description | string | nullat most 2000 characters | New description, or null to clear it. |
language | string | null | Language code (fr, en, es, de, it…), or null when unknown. |
Response 200
The content updated — A Content object
Errors
| HTTP | Meaning |
|---|---|
400 | validation_error or bad_request |
401 | invalid_api_key or revoked_api_key |
403 | insufficient_scope, account_suspended, live_not_enabled or forbidden |
404 | not_found |
406 | not_acceptable — the Accept header excludes application/json |
412 | precondition_failed — If-Match does not match the current ETag |
413 | payload_too_large |
415 | unsupported_media_type |
429 | rate_limited or test_quota_exceeded — see the Retry-After and RateLimit-* headers |
500 | internal_error |
503 | unavailable — see the Retry-After header |
curl -X PATCH "https://api.memojin.com/v1/contents/3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87" \
-H "Authorization: Bearer $MEMOJIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Photosynthesis (revised)"
}'{
"id": "3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87",
"title": "Photosynthesis",
"description": "Light and dark reactions, chlorophyll, the Calvin cycle.",
"language": "en",
"folderId": "7a2d9c41-0b3e-4c5f-8e6a-1d2c3b4a5f60",
"imageUrl": null,
"createdAt": "2026-10-01T14:03:00.000Z",
"updatedAt": "2026-10-02T08:30:12.000Z",
"inclusions": {
"hasBody": true,
"hasSummary": false,
"memocardsCount": 12,
"questionsCount": 3,
"podcastsReadyCount": 0,
"sourcesCount": 1
}
}Delete a content
/v1/contents/{contentId}Scope contents:writeDeletes the content with its memocards and questions. Answers 204 without a body.
Parameters
| Field | In | Type | Description |
|---|---|---|---|
contentIdrequired | path | string (uuid) | Content identifier (UUID). |
Response 204
Deleted — No response body.
Errors
| HTTP | Meaning |
|---|---|
400 | validation_error — an identifier is not a UUID |
401 | invalid_api_key or revoked_api_key |
403 | insufficient_scope, account_suspended, live_not_enabled or forbidden |
404 | not_found |
406 | not_acceptable — the Accept header excludes application/json |
412 | precondition_failed — If-Match does not match the current ETag |
429 | rate_limited or test_quota_exceeded — see the Retry-After and RateLimit-* headers |
500 | internal_error |
503 | unavailable — see the Retry-After header |
curl -X DELETE "https://api.memojin.com/v1/contents/3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87" \
-H "Authorization: Bearer $MEMOJIN_API_KEY"