Vision API

Integration guide

Base URL

https://revisionafrica.com/visionapi/v1/

All endpoints are relative to this prefix. Requests and responses use Content-Type: application/json; charset=utf-8 unless noted.

CORS is enabled for browser-based tools. Preflight OPTIONS requests return 204.

Authentication

ContextHeadersBilling
Production Authorization: Bearer rv_live_…
or X-Api-Key: rv_live_…
1 call per successful ask / chat
Live demo / prototyping X-Vision-Demo: 1 (no API key) Not billed: for evaluation only
Public metadata None register, packages, voices, status

Invalid or missing credentials return 401. Disabled accounts return 403. Exhausted balance returns 402.

Response envelope

Every JSON response uses the same top-level shape:

{
  "success": true,
  "message": "OK",
  "data": { ... }
}

On failure, success is false, message describes the error, and data may include extra fields (e.g. calls_remaining: 0). HTTP status codes reflect the error class.

Successful vision responses do not include internal upstream payloads in production error paths beyond a generic upstream status when the vision service fails (502).

POST v1/register

POST Public: Create a developer account and receive an API key. Or use the registration page.

Request body

FieldRequiredDescription
organizationYesCompany or project name
contact_nameYesPrimary contact
emailYesValid email (unique per account)
phoneNoContact phone
websiteNoProject or company URL
curl -X POST "https://revisionafrica.com/visionapi/v1/register" \
  -H "Content-Type: application/json" \
  -d '{
    "organization": "My App",
    "contact_name": "Developer",
    "email": "you@company.com"
  }'

Success (201)

{
  "success": true,
  "message": "Registration successful",
  "data": {
    "api_key": "rv_live_…",
    "calls_remaining": 10,
    "email": "you@company.com",
    "organization": "My App"
  }
}

Store the API key immediately: treat it like a password. It is only returned at registration.

POST v1/ask

POST API key or demo: Send an image and question; receive a description.

Request body

FieldRequiredDescription
image or image_base64YesJPEG/PNG/WebP as raw base64 or data:image/…;base64,… data URI
question or textNoDefaults to: “What do you see? Describe it for a blind user.”
session_idNoYour conversation id; auto-generated if omitted
feedback_modeNotext (default), text_audio, or audio
voiceNoVoice id when audio is requested (default: sarah)
curl -X POST "https://revisionafrica.com/visionapi/v1/ask" \
  -H "Authorization: Bearer rv_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "What do you see?",
    "image_base64": "BASE64_JPEG_BYTES",
    "feedback_mode": "text_audio",
    "voice": "sarah"
  }'

Success (200)

{
  "success": true,
  "data": {
    "session_id": "keep-for-follow-ups",
    "type": "ask",
    "feedback_mode": "text_audio",
    "voice": "sarah",
    "answer": "A kitchen counter with…",
    "audio_base64": "…",
    "audio_mime": "audio/mpeg",
    "calls_remaining": 9
  }
}

POST v1/chat

POST API key or demo: Text-only follow-up in the same session.

Request body

FieldRequiredDescription
session_idYesSame value returned from ask
question or textYesFollow-up question (max 4000 chars)
feedback_mode, voiceNoSame as ask

You may also send session_id via header X-Session-Id.

Feedback modes & audio

feedback_modeText in responseAudio in response
text answer string None
text_audio answer string audio_base64 (MP3)
audio answer is null audio_base64 (MP3)

Aliases accepted: text_only, text_and_audio, audio_only.

When feedback_mode is text_audio and speech generation fails, the API still returns text with an audio_error field. Pure audio mode returns 502 if speech cannot be generated.

Decode audio_base64 and play as audio/mpeg. Do not log or persist audio in analytics without user consent.

GET v1/voices

GET Public: List available voices and feedback modes.

curl "https://revisionafrica.com/visionapi/v1/voices"

Returns voices (id + display label), feedback_modes, and defaults. 20 voices are available.

Sessions

  1. Call ask with an image: save session_id from the response.
  2. Call chat with the same session_id for follow-ups (no image needed).
  3. Start a new session_id when the user points the camera at a new scene.

Session ids are opaque strings (max 128 characters). Generate a UUID on the client or let the API assign one.

GET v1/history

GET API key: Fetch stored conversation history for your API key (no call charge).

Successful ask and chat requests are saved automatically with question, answer text, session, feedback mode, and voice. Images and audio are not stored: only metadata such as image_bytes and had_audio.

Query parameters

ParameterDescription
session_idFilter to one conversation (or header X-Session-Id)
typeask or chat
sinceISO date/time: entries on or after this time
limitPage size (default 50, max 200)
offsetPagination offset
sessions=1Return session summaries instead of individual entries
curl "https://revisionafrica.com/visionapi/v1/history?session_id=YOUR_SESSION&limit=20" \
  -H "Authorization: Bearer rv_live_YOUR_KEY"

Success (200)

{
  "success": true,
  "data": {
    "items": [
      {
        "id": 42,
        "session_id": "abc-123",
        "type": "ask",
        "question": "What do you see?",
        "answer": "A kitchen with…",
        "feedback_mode": "text_audio",
        "voice": "sarah",
        "had_audio": true,
        "image_bytes": 128400,
        "created_at": "2026-06-23 14:30:00"
      }
    ],
    "total": 1,
    "limit": 20,
    "offset": 0,
    "session_id": "abc-123"
  }
}

Each successful ask/chat response may include history_id referencing the saved row.

Billing endpoints

GET v1/account

GET API key: Returns calls_remaining, calls_used_total, usage summary, and recent payments. Web dashboard: /dashboard/.

GET v1/usage

GET API key: Paginated API request logs (endpoint, status, question preview, session, image size). Query: limit, offset, endpoint, success.

GET v1/packages

GET Public: Pricing packages and simulated test-card hint for the demo environment.

POST v1/purchase

POST API key: Add calls via simulated payment (demo gateway only). Send package with the code from the table below.

PackageCallsPrice (USD)
starter: Starter 1000 $1.00
growth: Growth 5000 $4.50
scale: Scale 10000 $8.00

Free tier: 10 calls when you register. Custom plans: info@revisionafrica.com. Full pricing: pricing page.

HTTP status codes

CodeMeaning
200Success
201Registered
400Invalid JSON or missing required fields
401Missing or invalid API key
402No calls remaining
403Account or key disabled
405Wrong HTTP method
409Email already registered
413Image too large
502Vision or speech service unavailable
503Server configuration incomplete

Limits

Security for integrators

  • Server-side keys: Proxy requests through your backend; never embed rv_live_ keys in mobile apps or public JavaScript.
  • HTTPS only: All production traffic must use TLS.
  • Rotate on leak: Contact support if a key is exposed; disable the account from the admin dashboard if needed.
  • User images: Images are sent to the vision service for processing; disclose this in your privacy policy. See ReVision Privacy Policy and Data Protection for our practices.
  • Demo header: X-Vision-Demo: 1 is for evaluation, not production load.
  • No path guessing: Implementation files and configuration are not web-accessible; use documented v1/ routes only.
What we never expose via the API or docs: database credentials, internal upstream service URLs, speech-provider API keys, or raw server stack traces in JSON responses.

Code examples

JavaScript (browser, demo header or your backend)

const res = await fetch("https://revisionafrica.com/visionapi/v1/ask", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer " + apiKeyFromYourServer,
    // Prototype only: "X-Vision-Demo": "1"
  },
  body: JSON.stringify({
    question: "Describe this for a blind user",
    image: dataUrlFromCamera,
    feedback_mode: "text_audio",
    voice: "nova"
  })
});
const { success, data, message } = await res.json();
if (success && data.audio_base64) {
  const audio = new Audio("data:audio/mpeg;base64," + data.audio_base64);
  audio.play();
}

Follow-up chat

await fetch("https://revisionafrica.com/visionapi/v1/chat", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer " + apiKey
  },
  body: JSON.stringify({
    session_id: sessionIdFromAsk,
    question: "What color is the largest object?",
    feedback_mode: "text"
  })
});

Android (Kotlin) via your backend

// Recommended: your server holds the API key and forwards to v1/ask.
// On device, POST to your endpoint with the image; never ship rv_live_ keys in the APK.

val body = JSONObject()
  .put("question", question)
  .put("image_base64", Base64.encodeToString(jpegBytes, Base64.NO_WRAP))
  .put("feedback_mode", "text_audio")
  .put("voice", "sarah")