L’IA de Memojin génère des cartes mémo à partir du texte d’un contenu, puis des questions à partir de ses cartes. Une génération est asynchrone : l’API répond aussitôt 202 Accepted avec un travail, que vous suivez avec GET /v1/jobs/{jobId}.
Déroulement
- Lancez la génération :
202, avecjobIdet l’estimation des crédits IA (estimate.units, en-têteMemojin-Credits-Estimate). - Interrogez le travail toutes les 5 secondes environ :
pending, puisrunning(avecprogressde 0 à 100). - À
succeeded, listez les cartes ou les questions du contenu. Àfailed(error: "generation_failed") oucancelled, rien n’est à lire ; citez l’identifiant du travail si vous nous écrivez.
La boucle complète
import os, time, uuid, requests
API = "https://api.memojin.com/v1"
H = {"Authorization": f"Bearer {os.environ['MEMOJIN_API_KEY']}"}
# 1. Start the generation: 202 Accepted
job = requests.post(
f"{API}/contents/{content_id}/memocard-generations",
headers={**H, "Idempotency-Key": str(uuid.uuid4())},
timeout=30,
)
job.raise_for_status()
job = job.json() # {"jobId": ..., "status": "pending", "estimate": {"operation": "ai_card", "units": 12}}
# 2. Poll the job every 5 seconds until it is finished
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)
# 3. Read the memocards of the content
if state["status"] == "succeeded":
cards = requests.get(f"{API}/contents/{content_id}/memocards", params={"limit": 100}, headers=H, timeout=30).json()["data"]Refus avant toute génération
422 content_too_short: le texte du contenu fait moins de 100 caractères.422 nothing_to_generate: chaque partie du contenu a déjà ses cartes mémo.422 no_memocards: le contenu n’a pas de carte mémo d’où tirer des questions.422 all_memocards_have_questions: chaque carte a déjà ses questions.402 insufficient_credits: le compte n’a plus assez de crédits IA.
En bac à sable
Avec une clé mj_test_, la génération est simulée : travail aussitôt succeeded, aucune carte créée, aucun crédit consommé (voir bac à sable). La fin d’un travail signalée par webhook Bientôt.
L’objet GenerationAccepted
Une génération acceptée pour un traitement asynchrone.
| Champ | Type | Description |
|---|---|---|
jobId | string (uuid) | Travail à suivre avec GET /v1/jobs/{jobId}. |
status | "pending" | "succeeded" | pending à l’acceptation ; succeeded aussitôt dans le bac à sable (mj_test_), où rien n’est généré. |
estimate | object | Ce que la génération prévoit de consommer (repris dans l’en-tête Memojin-Credits-Estimate). |
{
"jobId": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"status": "pending",
"estimate": {
"operation": "ai_card",
"units": 12
}
}L’objet Job
Un travail asynchrone (une génération IA).
| Champ | Type | Description |
|---|---|---|
id | string (uuid) | Identifiant du travail (UUID). |
type | string | Ce que fait le travail : memocard_generation, question_generation ou other. De nouvelles valeurs peuvent apparaître. |
status | string | pending, running, succeeded, failed ou cancelled. Interrogez jusqu’à succeeded, failed ou cancelled. |
progress | integerde 0 à 100 | Avancement, de 0 à 100. |
contentId | string | null | Contenu sur lequel porte le travail, ou null. |
error | string | null | Code d’erreur quand le travail a échoué (generation_failed), ou null. Le détail reste interne : citez l’identifiant du travail si vous nous contactez. |
createdAt | string (date-time) | Instant de création (ISO 8601, UTC). |
updatedAt | string (date-time) | Instant de la dernière modification (ISO 8601, UTC). |
{
"id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"type": "memocard_generation",
"status": "running",
"progress": 40,
"contentId": "3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87",
"error": null,
"createdAt": "2026-10-04T10:00:00.000Z",
"updatedAt": "2026-10-04T10:00:20.000Z"
}Générer des cartes mémo à partir d’un contenu
/v1/contents/{contentId}/memocard-generationsScope generations:writeGénère des cartes mémo à partir des parties du corps du contenu qui n’en ont pas encore. Asynchrone : répond 202 avec un jobId à interroger par GET /v1/jobs/{jobId}. Consomme les crédits IA du compte (une unité ai_card par carte mémo, voyez estimate.units et l’en-tête Memojin-Credits-Estimate) ; 402 insufficient_credits quand ils sont épuisés. Refus métier : 422 content_too_short, 422 nothing_to_generate. Avec une clé mj_test_, rien n’est généré et aucun crédit n’est consommé.
Paramètres
| Champ | Où | Type | Description |
|---|---|---|---|
contentIdobligatoire | chemin | string (uuid) | Identifiant du contenu (UUID). |
Idempotency-Key | en-tête | string | Fortement recommandée. Une valeur unique par opération (UUID v4), réutilisée telle quelle à chaque nouvelle tentative. Pendant 24 heures, la même clé et la même requête rejouent la première réponse (Idempotent-Replayed: true) sans second effet ni second débit ; une autre requête avec la même clé → 422 idempotency_key_reused ; encore en cours → 409 idempotency_in_progress. |
Réponse 202
Génération acceptée — Un objet GenerationAccepted
Erreurs
| HTTP | Signification |
|---|---|
400 | validation_error — contentId n’est pas un UUID |
401 | invalid_api_key ou revoked_api_key |
402 | insufficient_credits |
403 | insufficient_scope, account_suspended, live_not_enabled ou forbidden |
404 | not_found |
406 | not_acceptable — l’en-tête Accept exclut application/json |
409 | idempotency_in_progress — réessayez après Retry-After (1 s) |
422 | idempotency_key_reused, ou une règle métier (voyez la description) |
429 | rate_limited ou test_quota_exceeded — voyez les en-têtes Retry-After et RateLimit-* |
500 | internal_error |
503 | unavailable — voyez l’en-tête Retry-After |
curl -X POST "https://api.memojin.com/v1/contents/3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87/memocard-generations" \
-H "Authorization: Bearer $MEMOJIN_API_KEY" \
-H "Idempotency-Key: 6f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87"{
"jobId": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"status": "pending",
"estimate": {
"operation": "ai_card",
"units": 12
}
}Générer des questions à partir d’un contenu
/v1/contents/{contentId}/question-generationsScope generations:writeGénère des questions d’entraînement pour les cartes mémo du contenu qui n’en ont pas encore. Asynchrone : répond 202 avec un jobId à interroger par GET /v1/jobs/{jobId}. Consomme les crédits IA du compte (une unité ai_card par question, voyez estimate.units et l’en-tête Memojin-Credits-Estimate) ; 402 insufficient_credits quand ils sont épuisés. Refus métier : 422 no_memocards, 422 all_memocards_have_questions. Avec une clé mj_test_, rien n’est généré et aucun crédit n’est consommé.
Paramètres
| Champ | Où | Type | Description |
|---|---|---|---|
contentIdobligatoire | chemin | string (uuid) | Identifiant du contenu (UUID). |
Idempotency-Key | en-tête | string | Fortement recommandée. Une valeur unique par opération (UUID v4), réutilisée telle quelle à chaque nouvelle tentative. Pendant 24 heures, la même clé et la même requête rejouent la première réponse (Idempotent-Replayed: true) sans second effet ni second débit ; une autre requête avec la même clé → 422 idempotency_key_reused ; encore en cours → 409 idempotency_in_progress. |
Réponse 202
Génération acceptée — Un objet GenerationAccepted
Erreurs
| HTTP | Signification |
|---|---|
400 | validation_error — contentId n’est pas un UUID |
401 | invalid_api_key ou revoked_api_key |
402 | insufficient_credits |
403 | insufficient_scope, account_suspended, live_not_enabled ou forbidden |
404 | not_found |
406 | not_acceptable — l’en-tête Accept exclut application/json |
409 | idempotency_in_progress — réessayez après Retry-After (1 s) |
422 | idempotency_key_reused, ou une règle métier (voyez la description) |
429 | rate_limited ou test_quota_exceeded — voyez les en-têtes Retry-After et RateLimit-* |
500 | internal_error |
503 | unavailable — voyez l’en-tête Retry-After |
curl -X POST "https://api.memojin.com/v1/contents/3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87/question-generations" \
-H "Authorization: Bearer $MEMOJIN_API_KEY" \
-H "Idempotency-Key: 6f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87"{
"jobId": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"status": "pending",
"estimate": {
"operation": "ai_card",
"units": 12
}
}Lire un travail
/v1/jobs/{jobId}Scope jobs:readÉtat et avancement d’une génération asynchrone. Interrogez-le toutes les quelques secondes (5 s est un bon rythme) jusqu’à ce que status vaille succeeded, failed ou cancelled ; listez ensuite les cartes mémo ou les questions du contenu.
Paramètres
| Champ | Où | Type | Description |
|---|---|---|---|
jobIdobligatoire | chemin | string (uuid) | Identifiant du travail (UUID), tel que rendu par une génération. |
Réponse 200
Le travail — Un objet Job
Erreurs
| HTTP | Signification |
|---|---|
400 | validation_error — un identifiant n’est pas un UUID |
401 | invalid_api_key ou revoked_api_key |
403 | insufficient_scope, account_suspended, live_not_enabled ou forbidden |
404 | not_found |
406 | not_acceptable — l’en-tête Accept exclut application/json |
429 | rate_limited ou test_quota_exceeded — voyez les en-têtes Retry-After et RateLimit-* |
500 | internal_error |
503 | unavailable — voyez l’en-tête Retry-After |
curl "https://api.memojin.com/v1/jobs/9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d" \
-H "Authorization: Bearer $MEMOJIN_API_KEY"{
"id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"type": "memocard_generation",
"status": "running",
"progress": 40,
"contentId": "3f1c2b0e-8d4a-4f7e-9a51-3c2d1e0f9b87",
"error": null,
"createdAt": "2026-10-04T10:00:00.000Z",
"updatedAt": "2026-10-04T10:00:20.000Z"
}