Skip to content

Image Uploads ​

Overview ​

The KOOB API provides a comprehensive attachment system for managing image uploads across various entities in the platform. Understanding how this system works is crucial to avoid accidentally losing existing images when updating entity attachments.

For detailed information about all endpoints, request/response schemas, and additional details, visit our complete API Reference.

On v3, one image at a time

The v3 image sub-resources — POST, PATCH and DELETE/api/v3/hotels/{id}/images/... — address each image by its own id, so adding, renaming or removing one leaves the rest alone. There is nothing to resend and nothing to lose. See Manage Hotels.

The rest of this page describes the older collection-sync behaviour, which still applies to the v1 endpoints below.

Critical (v1 endpoints)

When updating entity images through the v1 endpoints, the API replaces the entire image collection. Any existing images not included in your request will be deleted. Always include all images you want to keep, not just the ones you're adding or updating.

How Image Management Works ​

The KOOB API uses a synchronization approach for image management, which means:

  1. Complete Replacement: Each API call replaces the entire image collection for an entity
  2. Automatic Cleanup: Images not included in the request are automatically removed
  3. Smart Operations: The system determines whether to create, update, or delete images based on the provided data

Image Retrieval ​

Accessing Uploaded Images ​

Once uploaded, images are accessible through the entity's attachments imageUrl field. The URL points to the image stored in our cloud storage.

json
{
  "attachments": [
    {
      "id": "att-123",
      "displayName": "Hotel Exterior.jpg",
      "imageUrl": "https://storage.googleapis.com/bucket/attachments/Hotel/uuid.jpg",
      "isMainPicture": true
    }
  ]
}

Image Upload Methods ​

On the entity creation (POST) ​

When creating new entities with images, you only need to provide the new images:

Example - Creating a hotel with images:

json
{
  "attachments": [
    {
      "displayName": "Hotel Exterior.jpg",
      "imageUrl": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ...",
      "kind": "primary"
    },
    {
      "displayName": "Lobby View.jpg", 
      "imageUrl": "data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAB...",
      "kind": "secondary"
    }
  ],
}

On the entity update (PUT/PATCH) ​

When updating existing entities, you must include all images you want to keep:

Incorrect Approach (Will Delete Existing Images):

json
{
  "attachments": [
    {
      "displayName": "New Room Photo.jpg",
      "imageUrl": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..."
    }
  ]
}

This will delete all existing images and keep only the new one.

Correct Approach (Preserves Existing Images):

json
{
  "attachments": [
    {
      "id": "att-123",
      "displayName": "Existing Hotel Exterior.jpg"
    },
    {
      "id": "att-456", 
      "displayName": "Updated Lobby Name.jpg"
    },
    {
      "displayName": "New Room Photo.jpg",
      "imageUrl": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..."
    }
  ]
}

Sync Operations Explained ​

The API automatically determines the operation based on your request data:

1. Create New Images ​

Trigger: Attachments without an id field

json
{
  "displayName": "New Image.jpg",
  "imageUrl": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ...",
  "kind": "primary"
}

2. Update Existing Images ​

Trigger: Attachments with an id field

json
{
  "id": "existing-attachment-123",
  "displayName": "Updated Name.jpg",
  "kind": "secondary"
}

Image Modification

You cannot change the actual image file, only metadata like display name and kind.

If you need to change the image, you must delete the old image and create a new one with the updated file.

3. Delete Images ​

Trigger: Existing images not included in the request

If entity has images with IDs: att-123, att-456, att-789, and you only send the following:

json
{
  "attachments": [
    {
      "id": "att-123",
      "displayName": "Keep This Image.jpg"
    }
  ]
}

Images att-456 and att-789 will be deleted.

Image Data Formats ​

Base64 Data URLs (New Uploads) ​

json
{
  "imageUrl": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..."
}

Base64 Format Required

The imageUrl must be a valid Base64 data URL. External URLs are not processed and will be skipped.

Existing Images (Updates Only) ​

json
{
  "id": "att-123"
  // No imageUrl needed for existing images
}

Supported Image Formats ​

  • JPEG (.jpg, .jpeg)
  • PNG (.png)
  • GIF (.gif)
  • WebP (.webp)

Image Categories ​

The API supports different image kinds to categorize images based on their usage:

  • primary: Main entity image
  • secondary: Secondary entity image(s)
  • Custom kinds: Based on specific entity requirements

Custom Kinds

Unless stated otherwise, only primary and secondary kinds are supported for most entities.

These can be specified in the kind field of the attachment object.

Best Practices ​

1. Always Fetch Current Images Before Updates ​

bash
# Get current entity images
GET /api/v3/hotels/{id}

# Include all existing images in your update
PATCH /api/v3/hotels/{id}

2. Use Meaningful Display Names ​

json
{
  "displayName": "Hotel Exterior - Main Entrance.jpg",  // Good
  "displayName": "IMG_001.jpg"                          // Avoid
}

3. Optimize Images Before Upload ​

  • Compress images to reduce upload time and storage costs
  • Use appropriate resolution for the intended use case
  • Consider using WebP format for better compression

4. Handle Large Image Collections ​

For entities with many images, consider:

  • Paginating image updates
  • Processing images in batches
  • Implementing client-side preview before upload

Common Pitfalls ​

❌ Accidentally Deleting All Images ​

json
{
  "name": "Updated Hotel Name",
  "attachments": []  // This deletes all existing images!
}

For most entities, the attachments or pictures field is optional, but if you send an empty array, it will delete all existing images.

If you don't need to update images, simply omit the attachments field entirely.

❌ Forgetting Existing Images ​

json
{
  "attachments": [
    {
      "displayName": "Only New Image.jpg",
      "imageUrl": "data:image/jpeg;base64,..."
    }
    // Missing existing images - they will be deleted!
  ]
}

✅ Correct Full Update ​

json
{
  "attachments": [
    {
      "id": "att-123",
      "displayName": "Existing Image 1.jpg"
    },
    {
      "id": "att-456", 
      "displayName": "Existing Image 2.jpg"
    },
    {
      "displayName": "New Image.jpg",
      "imageUrl": "data:image/jpeg;base64,..."
    }
  ]
}