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
| Context | Headers | Billing |
|---|---|---|
| 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
| Field | Required | Description |
|---|---|---|
organization | Yes | Company or project name |
contact_name | Yes | Primary contact |
email | Yes | Valid email (unique per account) |
phone | No | Contact phone |
website | No | Project 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
| Field | Required | Description |
|---|---|---|
image or image_base64 | Yes | JPEG/PNG/WebP as raw base64 or data:image/…;base64,… data URI |
question or text | No | Defaults to: “What do you see? Describe it for a blind user.” |
session_id | No | Your conversation id; auto-generated if omitted |
feedback_mode | No | text (default), text_audio, or audio |
voice | No | Voice 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
| Field | Required | Description |
|---|---|---|
session_id | Yes | Same value returned from ask |
question or text | Yes | Follow-up question (max 4000 chars) |
feedback_mode, voice | No | Same as ask |
You may also send session_id via header X-Session-Id.
Feedback modes & audio
feedback_mode | Text in response | Audio 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
- Call
askwith an image: savesession_idfrom the response. - Call
chatwith the samesession_idfor follow-ups (no image needed). - Start a new
session_idwhen 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
| Parameter | Description |
|---|---|
session_id | Filter to one conversation (or header X-Session-Id) |
type | ask or chat |
since | ISO date/time: entries on or after this time |
limit | Page size (default 50, max 200) |
offset | Pagination offset |
sessions=1 | Return 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.
| Package | Calls | Price (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
| Code | Meaning |
|---|---|
200 | Success |
201 | Registered |
400 | Invalid JSON or missing required fields |
401 | Missing or invalid API key |
402 | No calls remaining |
403 | Account or key disabled |
405 | Wrong HTTP method |
409 | Email already registered |
413 | Image too large |
502 | Vision or speech service unavailable |
503 | Server configuration incomplete |
Limits
- Maximum image size: 8 MB
- Maximum question length: 4000 characters
- Free tier on registration: 10 calls
- Request timeout: up to 90 seconds for vision processing
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: 1is for evaluation, not production load. - No path guessing: Implementation files and configuration are not web-accessible; use documented
v1/routes only.
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")