PiiBlur API Reference
The PiiBlur API queues asynchronous PII redaction jobs for images and videos. Upload media, poll for status, then download the redacted output when processing completes.
The OpenAPI 3.1 contract is available at /openapi/v1.json.
How do I blur faces with an API?
- 1. Create an API key in the PiiBlur dashboard and send it as a Bearer token.
- 2. Upload the image or video to
/media/redactwithcategories[]=heads. - 3. Poll
/media/{mediaId}or configure webhooks, then download the redacted file when processing is complete.
Base URL
https://piiblur.com/api/v1Authentication
All API requests require a Bearer API key from the API section of your dashboard.
curl https://piiblur.com/api/v1/media \ -H "Authorization: Bearer YOUR_API_KEY"Rate Limits
Rate limits vary by plan. When exceeded, the API returns 429 Too Many Requests.
| Plan | Requests / minute |
|---|---|
| Free | 60 |
| Starter | 120 |
| Pro | 300 |
| Scale | 1,000 |
| Enterprise | Custom |
Metered plans include standard rate limit headers on API responses:
X-RateLimit-Limit- Maximum requests per minuteX-RateLimit-Remaining- Requests remaining in the current windowX-RateLimit-Reset- Unix timestamp when the window resetsRetry-After- Seconds to wait before retrying after a rate-limit429
Errors
All API JSON errors use the same envelope and include a request id for support and log correlation.
{ "error": { "code": "validation_failed", "message": "The given data was invalid.", "details": { "file": ["The file field is required."] } }, "request_id": "req_abc123"}| Status | Common code |
|---|---|
| 401 | unauthorized |
| 404 | not_found |
| 409 | conflict |
| 422 | validation_failed |
| 429 | quota_exceeded or rate_limit_exceeded |
| 500 | server_error |
POST /media/redact
Upload a file and queue redaction in a multipart request. Processing is asynchronous.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
Authorization | string | Required | Bearer YOUR_API_KEY |
Idempotency-Key | string | Optional | Reuse the same key when retrying the same upload after a network failure |
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
file | file | Required | The image or video file to redact |
categories | string[] | Required | PII categories to detect. Values: heads, license_plates, screens, writing, street_signs, id_cards, passports, credit_cards, name_badges, qr_codes, barcodes, documents, tattoos |
redaction_method | string | Optional | blur (default) or pixelation |
Request
curl -X POST https://piiblur.com/api/v1/media/redact \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Idempotency-Key: upload-2026-03-17-001" \ -F "categories[]=heads" \ -F "categories[]=license_plates" \ -F "redaction_method=blur"Response
{ "id": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "status": "queued", "filename": "photo.jpg", "media_type": "image", "categories": ["heads", "license_plates"], "redaction_method": "blur", "file_size_bytes": 482391, "duration_seconds": null, "created_at": "2026-03-17T10:30:00+00:00", "processed_at": null, "failed_at": null}409 conflict. Idempotency keys expire after 24 hours.GET /media/{mediaId}
Get the status and public details for one media item.
curl https://piiblur.com/api/v1/media/9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c \ -H "Authorization: Bearer YOUR_API_KEY"Completed response
{ "id": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "status": "completed", "filename": "photo.jpg", "media_type": "image", "categories": ["heads", "license_plates"], "redaction_method": "blur", "file_size_bytes": 482391, "duration_seconds": null, "created_at": "2026-03-17T10:30:00+00:00", "processed_at": "2026-03-17T10:30:15+00:00", "failed_at": null, "download_url": "https://piiblur.com/api/v1/media/9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c/download"}download_url appears only for completed media with a redacted output.GET /media/{mediaId}/download
Download the processed redacted file. Returns 404 until processing is completed.
curl -O -J https://piiblur.com/api/v1/media/9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c/download \ -H "Authorization: Bearer YOUR_API_KEY"GET /media
List media with optional filters.
| Name | Type | Required | Description |
|---|---|---|---|
status | string | Optional | pending, queued, processing, completed, failed, or quota_exceeded |
media_type | string | Optional | image or video |
page | integer | Optional | Page number |
per_page | integer | Optional | Items per page, max 100 |
{ "data": [ { "id": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "status": "completed", "filename": "photo.jpg", "media_type": "image", "categories": ["heads", "license_plates"], "redaction_method": "blur", "file_size_bytes": 482391, "duration_seconds": null, "created_at": "2026-03-17T10:30:00+00:00", "processed_at": "2026-03-17T10:30:15+00:00", "failed_at": null, "download_url": "https://piiblur.com/api/v1/media/9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c/download" } ], "pagination": { "page": 1, "per_page": 20, "total": 98, "total_pages": 5 }, "links": { "next": "https://piiblur.com/api/v1/media?page=2", "previous": null }}DELETE /media/{mediaId}
Delete a media item and any stored files associated with it. Returns 204 No Content.
GET /usage
Get current billing period usage and limits.
{ "plan": "pro", "period_start": "2026-03-01", "period_end": "2026-03-31", "images": { "used": 1250, "limit": 25000 }, "video_minutes": { "used": 45, "limit": 60 }}Webhooks
Webhooks notify your server when media processing completes, fails, or when retained source media is deleted. Configure endpoints in the API section of your dashboard.
| Event | Description |
|---|---|
| media.processed | Media processing completed |
| media.failed | Media processing failed |
| media.source_deleted | Retained source media has been deleted |
Signature Verification
Each webhook request includes an X-PiiBlur-Signature header containing an HMAC-SHA256 signature of the raw request body.
X-PiiBlur-Signature: sha256=HMAC_SHA256(payload, secret)Payload: media.processed
{ "id": "evt_2f6ad0f3-52a1-4ce6-b2e2-0f9bd07d4422", "event": "media.processed", "timestamp": "2026-03-17T10:30:15+00:00", "media_id": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "status": "completed", "processed_at": "2026-03-17T10:30:15+00:00", "failed_at": null, "media": { "id": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "status": "completed", "filename": "photo.jpg", "media_type": "image", "categories": ["heads", "license_plates"], "redaction_method": "blur", "file_size_bytes": 482391, "duration_seconds": null, "created_at": "2026-03-17T10:30:00+00:00", "processed_at": "2026-03-17T10:30:15+00:00", "failed_at": null, "download_url": "https://piiblur.com/api/v1/media/9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c/download" }}Payload: media.failed
{ "id": "evt_52fd9716-1181-4a2f-b719-261b2ec3cb47", "event": "media.failed", "timestamp": "2026-03-17T10:30:15+00:00", "media_id": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "status": "failed", "processed_at": null, "failed_at": "2026-03-17T10:30:15+00:00", "media": { "id": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "status": "failed", "filename": "photo.jpg", "media_type": "image", "categories": ["heads", "license_plates"], "redaction_method": "blur", "file_size_bytes": 482391, "duration_seconds": null, "created_at": "2026-03-17T10:30:00+00:00", "processed_at": null, "failed_at": "2026-03-17T10:30:15+00:00" }}