Media
/v1/media/ingestCopy listing images from public https:// addresses (JPEG, PNG, WebP or GIF, decided from the image itself, so an address needs no file extension; at most 5 per call; each is resized to fit 1600px and stored as WebP) into TBBN-hosted URLs for a listing's images array. Every image is tried. If any can't be imported, the call returns 400 IMAGE_IMPORT_FAILED with details.images listing each one — ok, or the stage that failed (address, download, size, decode, store), whether retrying may work, and why — and details.retryable true when every failure is worth retrying. A refusal is not kept against your Idempotency-Key, so once the cause is fixed a retry with the same key runs again.
curl -X POST https://api.tbbnetwork.com/v1/media/ingest \
-H "Authorization: Bearer sk_sandbox_..." \
-H "Idempotency-Key: 5f2f...b91" \
-H "Content-Type: application/json" \
-d '{
"urls": [
"value"
]
}'Parameters
Request body
| Field | Type | Required |
|---|---|---|
| urls | string[] | yes |
Response (201)
| Field | Type | Required |
|---|---|---|
| images | object[] | — |
{
"images": [
{
"url": "https://example.com/resource",
"width": null,
"height": null
}
]
}Possible errors
Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.
{
"error": {
"code": "VALIDATION_ERROR",
"message": "A human-readable description of what went wrong.",
"requestId": "req_01hxyz..."
}
}/v1/media/uploadUpload a photo through TBBN, base64 in data — for when a direct upload to the presigned URL from POST /v1/media/upload-url isn't possible. The photo is resized to fit 1600px and stored as WebP. Same callers as upload-url.
curl -X POST https://api.tbbnetwork.com/v1/media/upload \
-H "Authorization: Bearer <session access token>" \
-H "Idempotency-Key: 5f2f...b91" \
-H "Content-Type: application/json" \
-d '{
"folder": "listings",
"data": "data",
"bookingId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"token": "tok_5f2f8b91a3c4"
}'Request body
| Field | Type | Required |
|---|---|---|
| folder | listings | spaces | bookings | merchants | blog | avatars | yes |
| data | string | yes |
| bookingId | string (uuid) | — |
| token | string | — |
Response (201)
| Field | Type | Required |
|---|---|---|
| publicUrl | string (uri) | — |
{
"publicUrl": "https://example.com/resource"
}Possible errors
Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.
{
"error": {
"code": "VALIDATION_ERROR",
"message": "A human-readable description of what went wrong.",
"requestId": "req_01hxyz..."
}
}/v1/media/upload-urlGet a short-lived upload URL for an image. The browser uploads the file directly to it. PUT the file to `uploadUrl` with the same Content-Type, then use `publicUrl` wherever an image URL is needed (e.g. a Listing's images array).
curl -X POST https://api.tbbnetwork.com/v1/media/upload-url \
-H "Authorization: Bearer <session access token>" \
-H "Idempotency-Key: 5f2f...b91" \
-H "Content-Type: application/json" \
-d '{
"contentType": "contentType",
"folder": "listings",
"bookingId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"token": "tok_5f2f8b91a3c4"
}'Request body
| Field | Type | Required |
|---|---|---|
| contentType | string | yes |
| folder | listings | spaces | bookings | merchants | blog | avatars | yes |
| bookingId | string (uuid) | — |
| token | string | — |
Response (201)
| Field | Type | Required |
|---|---|---|
| uploadUrl | string (uri) | — |
| publicUrl | string (uri) | — |
| key | string | — |
{
"uploadUrl": "https://example.com/resource",
"publicUrl": "https://example.com/resource",
"key": "key"
}Possible errors
Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.
{
"error": {
"code": "VALIDATION_ERROR",
"message": "A human-readable description of what went wrong.",
"requestId": "req_01hxyz..."
}
}