Errors

The JSON error format, the 25 stable error codes of the Memojin API with their HTTP status, and what to do: fix the request, wait, or retry.

api.memojin.com/v1 · Contract 1.0.0-beta.2 · Beta

Sections · Errors

Every error returns a 4xx or 5xx status and the same JSON body, whatever the operation: a stable code, to test in your code; a message for humans, in the language of Accept-Language, which may change; sometimes details.

Error body
{
  "error": {
    "code": "string",
    "message": "string",
    "details": "(optional)"
  }
}

Example: an invalid request

Response 400
{
  "error": {
    "code": "validation_error",
    "message": "The request is invalid: see `details.issues`.",
    "details": {
      "target": "json",
      "issues": [
        {
          "path": "front",
          "message": "Too small: expected string to have >=1 characters"
        }
      ]
    }
  }
}

details.target says where the problem is (json for the body, query, param for the path, header); details.issues lists each problem, with path (the field) and message. The Link: <…>; rel="help" header of an error points to its row in the reference’s table.

The 25 codes

HTTPCodeMeaningWhat to do
400validation_errorA parameter or the body is invalid; details.issues lists each problem (target, path, message).Fix the request; do not retry it unchanged
400bad_requestThe request cannot be understood (malformed JSON, for instance).Fix the request; do not retry it unchanged
400invalid_cursorThe cursor is unknown, expired, or was obtained with another limit: start again from the first page.Start the list again from the first page
401invalid_api_keyThe Authorization: Bearer mj_… header is missing, malformed, or unknown.Fix the request; do not retry it unchanged
401revoked_api_keyThis API key was revoked: ask for a new one.Write to us (key, scopes, organization)
402insufficient_creditsThe account the key acts for has no AI credits left for this generation.Wait for the account’s AI credits to renew, or change plans; nothing was used
403insufficient_scopeThe key lacks the scope this operation requires (details.required, details.granted).Write to us (key, scopes, organization)
403account_suspendedThe organization is suspended.Write to us (key, scopes, organization)
403live_not_enabledLive keys are not enabled yet for this organization: use a mj_test_ key.Write to us (key, scopes, organization)
403forbiddenThe account the key acts for may not do this (inactive subscription, or not the owner of the resource).Fix the request; do not retry it unchanged
404not_foundThe resource does not exist, or does not belong to the account the key acts for.Fix the request; do not retry it unchanged
406not_acceptableThe API only produces application/json: accept it in the Accept header.Fix the request; do not retry it unchanged
409idempotency_in_progressA request with the same Idempotency-Key is still running: retry after Retry-After.Retry after Retry-After
412precondition_failedIf-Match does not match the current ETag of the resource: read it again before changing it.Read the resource again (new ETag), then retry
413payload_too_largeThe body exceeds 1 MB.Fix the request; do not retry it unchanged
415unsupported_media_typeThe body must be JSON: send Content-Type: application/json.Fix the request; do not retry it unchanged
422idempotency_key_reusedThis Idempotency-Key was already used for a different request.Fix the request; do not retry it unchanged
422content_too_shortThe content body is too short (under 100 characters) to generate from.Fix the request; do not retry it unchanged
422nothing_to_generateEvery part of the content already has its memocards (details.existingMemocards).Fix the request; do not retry it unchanged
422no_memocardsThe content has no memocards to generate questions from.Fix the request; do not retry it unchanged
422all_memocards_have_questionsEvery memocard of the content already has questions.Fix the request; do not retry it unchanged
429rate_limitedToo many requests for this organization: retry after Retry-After seconds.Retry after Retry-After
429test_quota_exceededThe daily quota of mj_test_ calls is reached; it resets at midnight UTC.Retry after Retry-After
500internal_errorUnexpected error: quote the X-Request-Id header when contacting us.Retry with a growing delay and the same Idempotency-Key
503unavailableThe service is temporarily unavailable (maintenance): retry after Retry-After seconds.Retry after Retry-After

New codes may appear for new cases: handle an unknown code according to its HTTP status.

Retrying safely

  • 4xx: do not retry unchanged, fix first — except 429 and 409 idempotency_in_progress (wait for Retry-After) and 412 (read the resource again).
  • 500, 503, timeout or dropped connection: retry with a growing delay (1 s, 5 s, 30 s…), with the same Idempotency-Key. You do not know whether the first request went through; the key guarantees it runs only once.
  • An error never uses AI credits. Quote the X-Request-Id header when you write to us.