# Upload property photos

Adds the cover photo and the gallery photos of a property that already exists.

Source: https://dev.alterestate.com/properties/photos
Last updated: 2026-10-26

Create a property does not accept files. After that call returns a uid, upload the cover and the gallery with the two requests below. The cover is the featured image on cards and the public listing. The gallery is the rest of the photos.

> Send multipart/form-data. Do not put the file in JSON and do not set Content-Type yourself: the client adds the multipart boundary. Each file must be a JPEG, PNG or WebP of at most 15 MB, with no side longer than 10000 px. AlterEstate re-encodes it to JPEG and discards the original filename. SVG, GIF, PDF, HTML, scripts and archives are rejected. An upload that does not come from the AlterEstate dashboard is recorded for support, with the property and how many photos were saved. Do not send a dashboard client header.

## Featured image

```http
PATCH https://secure.alterestate.com/api/v1/properties/photos/featured/{uid}/
```

Authentication: `Authorization: Token your_api_key_here`

> **Server-side only.** Call this endpoint from your backend only. The account token acts as the user who owns it and can read and change the agency’s contacts, deals and properties. Never put it in a website, a mobile app or any code that runs in the browser: anyone can open the developer tools and copy it. Have your frontend call your own server, and let your server call AlterEstate.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uid` | path | string | yes | Property uid from Create a property or List properties. Example: cid 292960, uid JSORJ9S5AY. |
| `featured_image` | body | file | yes | The cover photo. One JPEG, PNG or WebP. A later call with a new file replaces the cover. |

Example request:

```bash
curl --request PATCH \
  --url 'https://secure.alterestate.com/api/v1/properties/photos/featured/JSORJ9S5AY/' \
  --header 'Authorization: Token your_api_key_here' \
  --header 'Accept: application/json' \
  --form 'featured_image=@cover.jpg;type=image/jpeg'
```

Response 200 OK:

```json
{
  "id": 12011,
  "uid": "JSORJ9S5AY",
  "slug": "modern-apartment-in-naco-292960",
  "design": 1,
  "featured_image": "https://d2p0bx8wfdkjkb.cloudfront.net/static/properties/example/featured.jpg"
}
```

Response 400 Bad Request:

```json
{
  "error": "Este archivo no es una imagen JPG, PNG o WebP válida."
}
```

Response 404 Not Found:

```json
{
  "detail": "Not found."
}
```

## Gallery photos

```http
POST https://secure.alterestate.com/api/v1/properties/photos/{uid}/
```

Authentication: `Authorization: Token your_api_key_here`

> **Server-side only.** Call this endpoint from your backend only. The account token acts as the user who owns it and can read and change the agency’s contacts, deals and properties. Never put it in a website, a mobile app or any code that runs in the browser: anyone can open the developer tools and copy it. Have your frontend call your own server, and let your server call AlterEstate.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uid` | path | string | yes | Property uid. The same value used in the featured-image URL. |
| `gallery` | body | number | no | Gallery number. Send 2, the value the dashboard uses for listing photos. |
| `image0` | body | file | yes | First gallery photo. JPEG, PNG or WebP. This does not replace the cover. |
| `image1` | body | file | no | Next gallery photo. Continue with image2, image3, and so on, with no gaps. Maximum 10 photos per request. Send more in another request. |

Example request:

```bash
curl --request POST \
  --url 'https://secure.alterestate.com/api/v1/properties/photos/JSORJ9S5AY/' \
  --header 'Authorization: Token your_api_key_here' \
  --header 'Accept: application/json' \
  --form 'gallery=2' \
  --form 'image0=@photo-1.jpg;type=image/jpeg' \
  --form 'image1=@photo-2.jpg;type=image/jpeg'
```

Response 201 Created:

```json
[
  {
    "id": 88421,
    "uid": "PH0T0UID01",
    "parent": "JSORJ9S5AY",
    "gallery": 2,
    "order": 3,
    "title": "",
    "description": "",
    "image": "https://d2p0bx8wfdkjkb.cloudfront.net/static/properties/example/gallery-1.jpg"
  }
]
```

Response 400 Bad Request:

```json
{
  "error": "Este archivo no es una imagen JPG, PNG o WebP válida."
}
```

Response 404 Not Found:

```json
{
  "detail": "Not found."
}
```

## Cover and gallery

| Photo | Request | What it changes |
| --- | --- | --- |
| Featured image | PATCH /api/v1/properties/photos/featured/{uid}/ | The cover. One file in featured_image. Sending it again replaces the cover. |
| Gallery | POST /api/v1/properties/photos/{uid}/ | The other photos. Files image0, image1, … are appended. Existing gallery photos stay. |

## Accepted files

| Rule | Limit |
| --- | --- |
| Format | JPEG, PNG or WebP. The stored file is JPEG. |
| Size | 15 MB per file. |
| Dimensions | At most 10000 px on each side, and at most 40 megapixels. |
| Gallery batch | At most 10 photos per request, named image0 through image9 with no gaps. Send more photos in another request; there is no limit per property. |
| Rejected | SVG, GIF, PDF, HTML, scripts, archives and any other type. |

## Status codes

| Status | Meaning |
| --- | --- |
| 200 | The cover was saved. The body includes featured_image. |
| 201 | The gallery photos were saved. The body is the property’s gallery, not only the new files. |
| 400 | A file, the field names or gallery is invalid. error explains which rule failed. |
| 401 | The account token is missing or invalid. |
| 404 | No property with that uid belongs to this agency. |

- Use the account token from POST /api/v1/login/. The public aetoken cannot upload files.
- The property must belong to the agency of that token.
- A file that is not a JPEG, PNG or WebP returns 400 and is not stored. The original filename is not kept.
- Other 400 messages are "La imagen supera el tamaño máximo de 15 MB." and "La imagen supera las dimensiones máximas permitidas (10000 px por lado)."
- The property uid is in the URL. gallery is optional. Send 2 for the listing gallery. Omit it and the photos are still attached to the property.
- An upload from outside the AlterEstate dashboard is stored as a support log on that property. The log records the cover or the gallery, the outcome and the number of photos. It does not store the file.

- [Create the property first](https://dev.alterestate.com/properties/create)
- [Read the cover and gallery after upload](https://dev.alterestate.com/properties/retrieve)

## FAQ

### How do I set the featured image?

PATCH /api/v1/properties/photos/featured/{uid}/ with multipart field featured_image set to one JPEG, PNG or WebP. That file becomes the cover. Call it again to replace the cover.

### How do I add gallery photos?

POST /api/v1/properties/photos/{uid}/ with gallery set to 2 and the files in image0, image1, and so on. The uid in the URL is the property. Those photos are added after the ones already there. They do not replace the cover.

### Can I upload an SVG, a PDF or a script?

No. Only JPEG, PNG and WebP are accepted, up to 15 MB and 10000 px per side. Anything else returns 400 and is not stored.
