API overview
The Backbone Lab API is a REST API at https://api.bkbn.ai for AI photo editing of real-estate listings: HDR develop, perspective correction, signature tone, sky replacement, decluttering, virtual staging, magic eraser. You upload photos, submit orders against a fixed catalog of features, follow them in realtime, and download the results.
Prerequisites
To use the API, you need:
- A workspace with API access (request a key).
- An API key (starts with
sk-), passed in theX-API-Keyheader.
How it works
Every feature follows the same asynchronous pattern:
- Upload assets:
POST /v1/assetsdeclares the file and returns anassetIdplus a presigneduploadUrl. PUT the bytes there, confirm withPOST /v1/assets/:id/uploaded, and the asset isreadyonce ingest has normalized it. - Submit an order:
POST /v1/orderswith your asset ids underinputs(1-5 brackets of one scene) and the feature options next to them. Returns anorderId; orders are asynchronous, not blocking. - Follow it: stream
GET /v1/orders/:id/events(SSE) or pollGET /v1/orders/:id. The SDKs multiplex a single WebSocket instead. - Download the result:
GET /v1/assets/:idwith the order'soutputAssetIdand your API key returnsdata.urlanddata.expiresIn. Fetch that signed URL without the API key to download the image bytes.
Shooting a whole property? Batches submit every scene in one call, with shared defaults and per-scene overrides.
SDKs
Official clients for JavaScript/TypeScript (@bkbnlab/api), Python (bkbnlab) and Kotlin/JVM (ai.bkbnlab:api-kotlin) share the same surface: upload, order, batch, wait, watch. They hide the upload dance, hold one multiplexed WebSocket per client for realtime, fall back to polling on restrictive networks, and raise typed errors. Every feature page shows the same example in all three languages plus curl.
Request and response format
Requests with a body are JSON. Every JSON response is wrapped in a data envelope:
{ "data": { "orderId": "8a4f…", "inputCount": 1 } } Failures use an error envelope with the HTTP status and a human-readable reason — see Errors:
{ "error": { "status": 400, "reason": "each value in inputs must be a UUID" } }The feature catalog
Features are versioned — each one carries the semver of the recipe it currently delivers, so quality improvements are visible without any interface change. The live catalog is public:
curl https://api.bkbn.ai/v1/featuresThe full reference, grouped by category, lives in Features:
- Enhancement: enhancer, auto HDR, sky replacement, declutter, mess cleaner, privacy blur.
- Staging: indoor and outdoor staging.
- Inpainting: magic eraser.
Exports: another format or size
POST /v1/assets/:id/exports packages a ready image you own into another format or size. Use a completed order's outputAssetId or a ready image upload. Camera RAW must first be developed through an order. Exporting repackages the source image; it does not rerun the editing features.
| REST field | Values |
|---|---|
format | Required: jpeg, png or webp. |
quality | Optional integer, 1–100; default 92. Controls JPEG/WebP compression. |
max_edge | Optional integer, 16–10,000 pixels. Bounds the longest edge, keeps aspect ratio and never enlarges. Omit to retain source dimensions. |
The response contains data.assetId and data.status. While it is processing, repeat the same POST with the same options until ready. A ready export is reused; repeating a request for a failed export starts another packaging attempt. Once ready, fetch its signed download URL with GET /v1/assets/:id, then download without an API key.
The SDK export methods wait until ready. REST's max_edge is longEdge in JavaScript/Kotlin and long_edge in Python. These examples continue from the completed Quickstart.
// Continue with the completed result from the Quickstart
const webp = await bkbn.export(result.outputAssetId, {
format: 'webp', quality: 80, longEdge: 2048,
})
await webp.save('listing.webp')Delivery and export IDs are currently not accepted directly as order inputs. To edit a result again, download and upload it as a new asset. See Limits for accepted formats and resolution.
Endpoints at a glance
| Endpoint | Purpose |
|---|---|
GET /v1/features | The versioned feature catalog (public). |
POST /v1/assets | Declare an upload — returns a presigned URL. |
POST /v1/orders | Submit one order (one scene, any features). |
POST /v1/batches | Submit a whole shoot atomically. |
POST /v1/orders/:id/cancel | Cancel a pending or running order. |
POST /v1/batches/:id/cancel | Cancel unsettled scenes. |
POST /v1/assets/:id/exports | Export another format or size. |
GET /v1/presets | List active public presets and presets available to your key. |
GET /v1/assets/:id | Get an authenticated asset's signed download URL. |
GET /v1/orders/:id/events | SSE lifecycle stream of one order. |
GET /v1/events | SSE account feed — everything on your key. |
POST /v1/api-keys/rotate | Rotate your key — see Authentication. |
The machine-readable spec is at https://api.bkbn.ai/openapi.json.
Next steps
- Quickstart: first order, end to end.
- Features: every feature and its options.
- Limits: file size, resolution, accepted formats and input grouping.
- Rate limits, Streaming, Errors: production concerns.