Backbone LabDocs
API

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 the X-API-Key header.

How it works

Every feature follows the same asynchronous pattern:

  1. Upload assets: POST /v1/assets declares the file and returns an assetId plus a presigned uploadUrl. PUT the bytes there, confirm with POST /v1/assets/:id/uploaded, and the asset is ready once ingest has normalized it.
  2. Submit an order: POST /v1/orders with your asset ids under inputs (1-5 brackets of one scene) and the feature options next to them. Returns an orderId; orders are asynchronous, not blocking.
  3. Follow it: stream GET /v1/orders/:id/events (SSE) or poll GET /v1/orders/:id. The SDKs multiplex a single WebSocket instead.
  4. Download the result: GET /v1/assets/:id with the order's outputAssetId and your API key returns data.url and data.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/features

The 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 fieldValues
formatRequired: jpeg, png or webp.
qualityOptional integer, 1–100; default 92. Controls JPEG/WebP compression.
max_edgeOptional 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

EndpointPurpose
GET /v1/featuresThe versioned feature catalog (public).
POST /v1/assetsDeclare an upload — returns a presigned URL.
POST /v1/ordersSubmit one order (one scene, any features).
POST /v1/batchesSubmit a whole shoot atomically.
POST /v1/orders/:id/cancelCancel a pending or running order.
POST /v1/batches/:id/cancelCancel unsettled scenes.
POST /v1/assets/:id/exportsExport another format or size.
GET /v1/presetsList active public presets and presets available to your key.
GET /v1/assets/:idGet an authenticated asset's signed download URL.
GET /v1/orders/:id/eventsSSE lifecycle stream of one order.
GET /v1/eventsSSE account feed — everything on your key.
POST /v1/api-keys/rotateRotate your key — see Authentication.

The machine-readable spec is at https://api.bkbn.ai/openapi.json.

Next steps