Documentation

The VisionPlate REST API recognizes Iraqi license plates in vehicle photos. For the full, interactive schema, see the API reference.

Getting started

Create an account, buy credits and create an API key in your account. Every request needs the key in the X-Api-Key header. Keys look like vp_live_… and are shown only once when created, so store yours securely and keep it on the server side, not in browser code. Send the image as multipart/form-data.

cURL
curl -X POST https://your-domain/api/v1/recognize \
  -H "X-Api-Key: vp_live_your_key" \
  -F "image=@car.jpg"

Recognize a plate

POST /api/v1/recognize takes a single file field named image (JPEG, PNG, WebP or BMP). Add ?includeCrop=true to also receive the cropped plate as a base64 PNG. When no plate is found, the request still succeeds with "detected": false and uses one credit.

200 OK
{
  "success": true,
  "data": {
    "id": "0199a0c4-6f1e-7c2b-9d3a-5b8f1e2d4c6a",
    "detected": true,
    "plateNumber": "12 A 34567",
    "province": "baghdad",
    "provinceCode": 1,
    "vehicleType": "private",
    "vehicleCode": 1,
    "plateType": "New",
    "boundingBox": { "x": 412, "y": 530, "width": 220, "height": 64 },
    "fileName": "car.jpg",
    "processingMs": 84.3,
    "createdAtUtc": "2026-09-30T10:15:00Z",
    "croppedPlatePng": null
  },
  "error": null,
  "meta": null
}

Response fields

Field Description
id Unique ID of this recognition in your history.
detected false when no plate was found in the image.
plateNumber Recognized plate text.
province / provinceCode Governorate name and numeric code, when readable.
vehicleType / vehicleCode Vehicle category (e.g. private, public, cargo) and numeric code.
plateType Plate design: Kurdistan (old), Nineties, Germany or New.
boundingBox Plate location in the original image, in pixels.
processingMs Processing time for this image.
croppedPlatePng Base64 PNG of the plate. Only returned with includeCrop=true.

Batch recognition

POST /api/v1/recognize/batch accepts up to 10 files, each in a field named images. Each item in the response has its own success flag. Files that fail validation return an error for that item only and use no credits.

cURL
curl -X POST https://your-domain/api/v1/recognize/batch \
  -H "X-Api-Key: vp_live_your_key" \
  -F "images=@car1.jpg" \
  -F "images=@car2.jpg"

History

GET /api/v1/recognitions returns your key's past recognitions, newest first. You can filter with plate (partial match), from and to (ISO-8601 UTC), and page with page and pageSize (max 100). Paging info is returned in meta. Fetch a single entry with GET /api/v1/recognitions/{id}.

cURL
curl "https://your-domain/api/v1/recognitions?page=1&pageSize=20&plate=12345" \
  -H "X-Api-Key: vp_live_your_key"

Usage & limits

Requests are paid from your account's prepaid credits: each image recognized uses one credit, and all your keys share the balance. Buy credit packages in your account. GET /api/v1/usage shows your balance and this key's usage this month, and recognition responses include an X-Credits-Remaining header. Each key also has a per-minute rate limit (429 rate_limited with a Retry-After header). With no credits left you get 402 insufficient_credits.

Errors

Every error uses the same envelope. Use the code field in your code; the message is for humans and may change.

{
  "success": false,
  "data": null,
  "error": { "code": "insufficient_credits", "message": "Not enough credits for this request..." },
  "meta": null
}
Status Code Meaning
400 missing_image No file was sent in the expected field.
400 invalid_image The file isn't a readable image.
400 unsupported_format Use JPEG, PNG, WebP or BMP.
400 image_too_large File size or pixel count is over the limit.
400 batch_too_large More files than the batch limit.
401 unauthorized Missing, unknown or revoked API key.
404 not_found The resource doesn't exist or isn't yours.
429 rate_limited Per-minute limit hit; check Retry-After.
402 insufficient_credits No credits left; buy a package.
500 server_error Unexpected failure. Safe to retry.

Code examples

C#
using var http = new HttpClient { BaseAddress = new Uri("https://your-domain/") };
http.DefaultRequestHeaders.Add("X-Api-Key", "vp_live_your_key");

using var form = new MultipartFormDataContent();
var file = new ByteArrayContent(await File.ReadAllBytesAsync("car.jpg"));
file.Headers.ContentType = new("image/jpeg");
form.Add(file, "image", "car.jpg");

var response = await http.PostAsync("api/v1/recognize", form);
var json = await response.Content.ReadAsStringAsync();
Console.WriteLine(json);
JavaScript (server-side / Node)
const form = new FormData();
form.append("image", fileInput.files[0]);

const res = await fetch("https://your-domain/api/v1/recognize", {
  method: "POST",
  headers: { "X-Api-Key": "vp_live_your_key" },
  body: form,
});
const { success, data, error } = await res.json();
console.log(success ? data.plateNumber : error.message);