Introduction
The YoloLabel AI API lets you run open-vocabulary object detection on any image. Submit a job with an image and a dot-separated prompt, poll until it succeeds, then fetch the bounding boxes.
All API endpoints accept and return application/json unless otherwise noted. Job submission uses multipart/form-data.
Base URL
https://api.yololabel.comhttps://api.yololabel.com
Authentication
Authenticate by passing your API key in the Authorization header as a Bearer token. API keys start with ylk_.
You can create and manage API keys from the dashboard. Keep your key secret — anyone with it can use your quota.
Never expose your API key in client-side code or public repositories.
curl https://api.yololabel.com/v1/jobs \
-H "Authorization: Bearer ylk_your_api_key"
Create Job
/v1/jobsSubmit a single image for object detection. The request body must bemultipart/form-data. The job is queued immediately — poll Get Job to track progress.
Body Parameters
imagefilerequiredThe image to process. Supported formats: JPEG, PNG, WebP. Max size 20 MB.
promptstringrequiredDot-separated class names to detect, e.g. person . car . dog. Up to 50 classes per request.
Response Fields
job_idintegerUnique identifier for this job. Use it to poll status and fetch the result.
statusstringInitial status, always queued on creation.
curl -X POST https://api.yololabel.com/v1/jobs \
-H "Authorization: Bearer ylk_your_api_key" \
-F "image=@photo.jpg" \
-F "prompt=person . car . dog . cat"
{
"job_id": 70,
"status": "queued"
}
Create Batch
/v1/jobs/batchSubmit multiple images in a single request. Each image becomes its own job with an independent ID. All jobs share the same prompt and are queued simultaneously.
Body Parameters
imagesfile[]requiredOne or more image files. Pass multiple images fields in the same multipart request. Max 50 images per batch.
promptstringrequiredApplied to every image in the batch.
Response Fields
job_idsinteger[]Array of job IDs, one per image, in submission order.
countintegerNumber of jobs created.
statusstringAlways queued.
curl -X POST https://api.yololabel.com/v1/jobs/batch \
-H "Authorization: Bearer ylk_your_api_key" \
-F "images=@image1.jpg" \
-F "images=@image2.jpg" \
-F "images=@image3.jpg" \
-F "prompt=person . car . dog"
{
"job_ids": [70, 71, 72],
"count": 3,
"status": "queued"
}
Get Job
/v1/jobs/{id}Retrieve a job's current status. Poll this endpoint every 1–3 seconds until status is succeeded or failed.
Path Parameters
idintegerrequiredThe job ID returned from Create Job or Create Batch.
Response Fields
job_idintegerThe job identifier.
statusstringOne of queued, running, succeeded, failed.
promptstringThe detection prompt used.
created_atstringISO 8601 timestamp of when the job was created.
started_atstring | nullWhen a worker began processing. Null if still queued.
finished_atstring | nullWhen the job completed (success or failure).
error_codestring | nullMachine-readable error code if the job failed.
error_messagestring | nullHuman-readable error description if the job failed.
curl https://api.yololabel.com/v1/jobs/70 \
-H "Authorization: Bearer ylk_your_api_key"
{
"job_id": 70,
"status": "succeeded",
"prompt": "person . car . dog",
"created_at": "2024-01-15T10:30:00Z",
"started_at": "2024-01-15T10:30:01Z",
"finished_at": "2024-01-15T10:30:03Z",
"error_code": null,
"error_message": null
}
Get Result
/v1/jobs/{id}/resultFetch the detection output for a completed job. Returns 404 if the job hasn't succeeded yet — only call this after confirming status === "succeeded".
Response Fields
detectionsDetection[]Array of detected objects. See Detection Format.
yolo_txtstringYOLO-format labels, one line per detection. See YOLO Labels.
image_widthintegerWidth of the processed image in pixels.
image_heightintegerHeight of the processed image in pixels.
compute_msintegerGPU inference time in milliseconds (excludes queue wait).
curl https://api.yololabel.com/v1/jobs/70/result \
-H "Authorization: Bearer ylk_your_api_key"
{
"detections": [
{
"label": "person",
"score": 0.94,
"bbox": [120, 45, 380, 620],
"class_id": 0
},
{
"label": "car",
"score": 0.87,
"bbox": [490, 210, 890, 480],
"class_id": 1
}
],
"yolo_txt": "0 0.3125 0.5031 0.6500 0.8813\n1 0.8398 0.4505 0.5208 0.3385",
"image_width": 1024,
"image_height": 768,
"compute_ms": 143
}
List Jobs
/v1/jobsReturns a paginated list of your jobs, newest first.
Query Parameters
limitintegerNumber of jobs to return. Default 20, max 100.
skipintegerNumber of jobs to skip for pagination. Default 0.
status_filterstringFilter by status. One of queued, running, succeeded, failed.
# List 20 most recent jobs
curl "https://api.yololabel.com/v1/jobs?limit=20&skip=0" \
-H "Authorization: Bearer ylk_your_api_key"
# Filter by status
curl "https://api.yololabel.com/v1/jobs?status_filter=succeeded" \
-H "Authorization: Bearer ylk_your_api_key"
[
{
"job_id": 71,
"status": "succeeded",
"prompt": "person . car",
"created_at": "2024-01-15T10:31:00Z",
"started_at": "2024-01-15T10:31:01Z",
"finished_at": "2024-01-15T10:31:02Z",
"error_code": null,
"error_message": null
},
...
]
Job Lifecycle
Jobs move through states asynchronously. Once created, poll GET /v1/jobs/{id} until the job reaches a terminal state.
Waiting for a worker
GPU inference in progress
Result ready
Check error_message
Recommended poll interval
2 seconds
Typical latency (GPU)
100–400 ms
Job timeout
5 minutes
Detection Format
Each detection in the detections array represents one detected object.
labelstringThe class name as specified in your prompt, e.g. person.
scorefloatConfidence score from 0.0 to 1.0. Higher is more confident.
bboxnumber[4]Bounding box as [x1, y1, x2, y2] in absolute pixels, where (x1, y1) is the top-left corner and (x2, y2) is the bottom-right corner.
class_idintegerZero-based index of the class in your prompt (left to right).
{
"label": "person",
"score": 0.94,
"bbox": [120, 45, 380, 620],
"class_id": 0
}
# bbox coordinates (absolute pixels):
# x1=120 y1=45 ← top-left
# x2=380 y2=620 ← bottom-right
#
# Box width = x2 - x1 = 260px
# Box height = y2 - y1 = 575px
YOLO Labels
The yolo_txt field is ready to save as a .txt annotation file — one line per detection, compatible with YOLOv5/v8 training pipelines.
Each line follows the format:
class_id — zero-based class index
cx, cy — center x/y, normalized 0–1
w, h — box width/height, normalized 0–1
# person at bbox [120,45,380,620]
# cx=(120+380)/2/1024=0.244 cy=(45+620)/2/768=0.433
# w=(380-120)/1024=0.254 h=(620-45)/768=0.749
0 0.2441 0.4329 0.2539 0.7487
# car at bbox [490,210,890,480]
# cx=(490+890)/2/1024=0.674 cy=(210+480)/2/768=0.449
# w=(890-490)/1024=0.391 h=(480-210)/768=0.352
1 0.6738 0.4492 0.3906 0.3516
Errors
All errors return a JSON body with a detail field. HTTP status codes follow standard conventions.
| HTTP | Code | Description |
|---|---|---|
| 401 | unauthorized | API key missing or invalid |
| 402 | quota_exceeded | Monthly image limit reached |
| 404 | not_found | Job ID does not exist |
| 422 | invalid_image | Unsupported file format or corrupt image |
| 422 | invalid_prompt | Prompt is empty or malformed |
| 429 | rate_limited | Too many requests — slow down |
| 500 | worker_error | Internal error during inference |
# 401 Unauthorized
{
"detail": "Invalid API key"
}
# 422 Unprocessable
{
"detail": "Unsupported image format. Use JPEG, PNG or WebP."
}
# 429 Rate limited
{
"detail": "Rate limit exceeded. Retry after 1s."
}
Rate Limits
Rate limits are enforced per API key. When exceeded the API returns HTTP 429. Implement exponential backoff and respect the Retry-After header.
| Plan | Requests / min | Images / month |
|---|---|---|
| Free | 10 | 100 |
| Pro | 100 | 5,000 |
| Enterprise | Custom | Unlimited |