POST /v1/ocr renvoie le texte d’un PDF ou d’une image, page par page, en Markdown. Une page qui a déjà une couche de texte (un PDF exporté depuis un traitement de texte) est lue directement ; une page scannée ou une photo est lue par reconnaissance de caractères.
POST https://api.realmoon.ai/v1/ocr- Authentification : clé
sk-moon-…avec la portéeinference(voir Authentification). - Corps :
multipart/(avec l’en-têteform-data Content-Length) ou JSON, dans la forme de l’API OCR de Mistral. - Réponse : le texte de chaque page lue.
Le seul modèle est moon-ocr-1. Il tourne sur nos serveurs en France : le document n’est envoyé à aucun fournisseur et n’est pas gardé une fois la réponse donnée.
ParamètresLien vers la section Paramètres
En multipartLien vers la section En multipart
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
file (ou document) | fichier | oui | Le PDF ou l’image (PNG, JPEG, WebP, GIF), 30 Mo au plus. Un seul fichier. |
model | chaîne | non | moon-ocr-1 (par défaut). |
pages | chaîne | non | Les pages à lire, numérotées à partir de 0 et séparées par des virgules : 0,2,5. |
En JSONLien vers la section En JSON
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
document | objet ou chaîne | oui | {"type": ou {"type": . Une chaîne seule (URL data: ou base64) est aussi acceptée. |
model | chaîne | non | moon-ocr-1 (par défaut). |
pages | tableau d’entiers | non | Les pages à lire, à partir de 0. |
include_image_base64 | booléen | non | Seule la valeur false est acceptée : les images des pages ne sont pas renvoyées. |
id | chaîne | non | Accepté, sans effet. |
En JSON, tout autre paramètre est refusé avec 400 .
PagesLien vers la section Pages
- Sans
pages, tout le document est lu, jusqu’à 50 pages. Au-delà, l’API répond400: choisissez les pages, et faites plusieurs requêtes pour un long document.too_many_pages - Une image a une seule page, la page 0.
- Une page déjà demandée n’est lue qu’une fois.
ExempleLien vers la section Exemple
Les SDK d’OpenAI n’ont pas de méthode pour ce point d’accès : appelez-le en HTTP.
curl https://api.realmoon.ai/v1/ocr \
-H "Authorization: Bearer $MOONAI_API_KEY" \
-F model=moon-ocr-1 \
-F file=@facture.pdf \
-F pages=0,1import os
import requests
with open("facture.pdf", "rb") as document:
response = requests.post(
"https://api.realmoon.ai/v1/ocr",
headers={"Authorization": f"Bearer {os.environ['MOONAI_API_KEY']}"},
data={"model": "moon-ocr-1", "pages": "0,1"},
files={"file": ("facture.pdf", document, "application/pdf")},
timeout=100,
)
response.raise_for_status()
for page in response.json()["pages"]:
print(page["index"], page["source"])
print(page["markdown"])import fs from 'node:fs';
const form = new FormData();
form.append('model', 'moon-ocr-1');
form.append('pages', '0,1');
form.append('file', new Blob([fs.readFileSync('facture.pdf')], { type: 'application/pdf' }), 'facture.pdf');
const response = await fetch('https://api.realmoon.ai/v1/ocr', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.MOONAI_API_KEY}` },
body: form,
});
const result = await response.json();
for (const page of result.pages) console.log(page.index, page.source, page.markdown);Le même appel en JSON, avec le document en base64 :
curl https://api.realmoon.ai/v1/ocr \
-H "Authorization: Bearer $MOONAI_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"model\": \"moon-ocr-1\", \"document\": {\"type\": \"document_url\", \"document_url\": \"data:application/pdf;base64,$(base64 -w0 facture.pdf)\"}, \"pages\": [0, 1]}"RéponseLien vers la section Réponse
{
"model": "moon-ocr-1",
"pages": [
{
"index": 0,
"markdown": "# Facture n° 2026-118\n\nDate : 4 novembre 2026\n\n| Désignation | Montant |\n| --- | --- |\n| Prestation | 1 200,00 € |",
"source": "text",
"images": [],
"dimensions": null
},
{
"index": 1,
"markdown": "Conditions de paiement : 30 jours.",
"source": "ocr",
"images": [],
"dimensions": null
}
],
"usage_info": { "pages_processed": 2, "doc_size_bytes": 184320 },
"usage": { "pages": 2, "pages_not_read": 0, "credits": 0 }
}La valeur de credits est fictive.
| Champ | Type | Description |
|---|---|---|
model | chaîne | Toujours moon-ocr-1. |
pages[].index | entier | Numéro de la page, à partir de 0. |
pages[].markdown | chaîne | Le texte de la page, en Markdown. |
pages[].source | chaîne | text : lue dans la couche de texte du PDF. ocr : lue par reconnaissance de caractères. |
pages[].images, pages[].dimensions | tableau, null | Toujours [] et null, gardés pour la compatibilité avec la forme de Mistral. |
usage_info.pages_processed, usage_info.doc_size_bytes | entier | Pages lues et taille du document en octets, comme chez Mistral. |
usage.pages | entier | Pages lues et facturées. |
usage.pages_not_read | entier | Pages demandées que le temps de la requête n’a pas permis de lire. Elles ne sont ni renvoyées ni facturées. |
usage.credits | entier | Crédits facturés. |
| En-tête | Valeur |
|---|---|
X-Moon-Hosting | fr : document lu sur nos serveurs en France. |
X-Moon-Blur | not_needed : le document ne quitte pas nos serveurs, Moon Blur n’est pas nécessaire. |
X-Moon-Request-Id, X-Moon-Prompt-Storage | Comme pour toute requête. |
CoûtsLien vers la section Coûts
Le prix est fixe par page lue ; il figure dans GET / (pricing.credits_per_unit, billing: ) et dans l’onglet « Modèles » du portail. La requête retient le prix des pages demandées, puis ne facture que les pages réellement lues. Un document illisible ou une requête qui échoue ne coûte rien.
LimitesLien vers la section Limites
| Limite | Valeur |
|---|---|
| Taille du document | 30 Mo |
| Pages par requête | 50 |
| Durée d’une requête | 85 secondes environ ; les pages non lues à temps ne sont ni renvoyées ni facturées |
| Requêtes en cours par workspace | 2 |
Le service de lecture est partagé : quand il est occupé par d’autres requêtes, l’API répond 429 ou 503 ocr_busy. Pour un gros document, envoyez quelques pages à la fois et lancez les requêtes l’une après l’autre.
ErreursLien vers la section Erreurs
| HTTP | code | Signification |
|---|---|---|
| 400 | missing_required_parameter | Fichier ou document absent. |
| 400 | unknown_parameter | Paramètre inconnu (en JSON). |
| 400 | unsupported_parameter | include_image_base64 à true. |
| 400 | url_not_supported | Document donné par une adresse https://. |
| 400 | unsupported_format | Ni un PDF, ni une image PNG, JPEG, WebP ou GIF. |
| 400 | invalid_image | Image illisible, ou de plus de 40 mégapixels. |
| 400 | encrypted_document | PDF protégé par un mot de passe. |
| 400 | invalid_document | PDF sans aucune page. |
| 400 | too_many_pages | Plus de 50 pages sans pages. |
| 400 | null | Numéro de page qui n’existe pas, page autre que 0 pour une image, document vide, base64 invalide (param le nomme). |
| 403 | org_policy | Les règles de votre organisation refusent l’API ou ce modèle. |
| 404 | model_not_found | Modèle autre que moon-ocr-1. |
| 411 | length_required | Envoi multipart sans en-tête Content-Length. |
| 413 | file_too_large, request_too_large | Document de plus de 30 Mo. |
| 422 | unreadable_document | Document illisible ou trop lourd à lire. |
| 429 | too_many_concurrent | Trop de requêtes OCR en cours pour ce workspace, ou pour le service. |
| 503 | ocr_busy | Service de lecture occupé : réessayez après Retry-After (10 secondes). |
| 504 | ocr_timeout | Lecture trop longue : envoyez moins de pages. |
Les erreurs de clé, de solde et de plafonds sont dans Erreurs.
Voir aussiLien vers la section Voir aussi
- Confidentialité : ce que Moon AI garde, et ne garde pas, d’un document.
- Modèles : les champs
max_pagesetmax_file_mb.