There is no separate vision endpoint. Attach an image object to a
normal /api/tutor or /api/tutor/stream request and it
routes to the vision path. The image travels base64-encoded inside the JSON
body — there is no multipart upload and no file-id indirection.
| Field | Type | Notes |
|---|---|---|
image.mimeType | string | Required. One of image/png, image/jpeg, image/webp. |
image.data | string | Required. Base64, no data-URI prefix. Decoded size must be 1 byte – 10 MiB. |
image.kind | string | Optional. general (default) or handwritten_math, which runs OCR before the tutor answers. |
# Build the JSON with the base64 image inline, then POST it.
jq -n \
--arg data "$(base64 -w0 question.png)" \
'{
userId: "student_4821",
message: "حل هذا السؤال خطوة بخطوة",
plan: "normal",
modelTier: "basic",
image: { mimeType: "image/png", data: $data, kind: "handwritten_math" }
}' \
| curl -X POST https://api.oorr.ai/api/tutor \
-H "Content-Type: application/json" \
--data-binary @-
import { readFile } from "node:fs/promises";
const image = await readFile("question.png");
const res = await fetch("https://api.oorr.ai/api/tutor", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
userId: "student_4821",
message: "حل هذا السؤال خطوة بخطوة",
plan: "normal",
modelTier: "basic",
image: {
mimeType: "image/png",
data: image.toString("base64"),
kind: "handwritten_math",
},
}),
});
const data = await res.json();
console.log(data.answer, data.model);
import base64
import requests
with open("question.png", "rb") as f:
encoded = base64.b64encode(f.read()).decode("ascii")
res = requests.post(
"https://api.oorr.ai/api/tutor",
json={
"userId": "student_4821",
"message": "حل هذا السؤال خطوة بخطوة",
"plan": "normal",
"modelTier": "basic",
"image": {
"mimeType": "image/png",
"data": encoded,
"kind": "handwritten_math",
},
},
timeout=90,
)
data = res.json()
print(data["answer"], data["model"])
Size the payload, not just the file
The 10 MiB cap is on the decoded image. Base64 adds roughly
one third, and the server rejects an oversized request on the encoded length
before it allocates memory to decode — so an over-cap image fails fast with
400 INVALID_REQUEST.
oorr / api platform