REST API reference
Idealista API
14 endpoints for Idealista. Each one is a POST with a JSON body, called with your API key.
- Base URL
- https://cotlet.dev/api/v1/idealista
- Connects with
- Your Idealista account, as a private advertiser or an idealista/tools agency user
- Integration page
- Idealista
| Endpoint | Access | Description |
|---|---|---|
| list_listings | read | Your ads with status, operation, price, address and quality score. |
| get_listing | read | Full ad: price, size, rooms, features, description, photos count, URL and quality score. |
| get_listing_stats | read | Visits, contacts and favorites of a listing for a period. |
| list_contacts | read | People who contacted you in Inbox, with the listing, last message and unread count. |
| get_conversation | read | All messages with one contact, with dates, notes and the listing they asked about. |
| list_demands | read | Demands created from your contacts in idealista/tools, with what each person is looking for. |
| update_listing | write | Change the price, description or features of one of your ads. |
| deactivate_listing | write | Take an ad off search results. It stays in your account and can be reactivated. |
| reactivate_listing | write | Put an expired or deactivated ad back in search results. |
| reply_to_contact | write | Send a chat message as you to a contact in Inbox. |
| send_listings_to_contact | write | Share other properties from your portfolio in the conversation. |
| mark_contact_handled | write | Mark a contact as handled, for example after a phone call. |
| add_contact_note | write | Private note on a conversation, only visible to you and your team. |
| archive_conversation | write | Move a finished conversation out of the active list. |
List listings
readPOST https://cotlet.dev/api/v1/idealista/list_listings
Lists the ads in your account, newest first. Use the listing_id of each item in the other tools. Filter by status to see deactivated ads and by operation to separate sales from rentals. Pages hold up to 100 ads; pass next_cursor back as cursor for the next page.
Parameters
| Name | Type | Description |
|---|---|---|
| status | enum | active, inactive or all. Default: active. |
| operation | enum | sale, rent or all. Default: all. |
| limit | integer | 1 to 100. Default: 50. |
| cursor | string | Next page cursor from the previous call. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/list_listings \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("idealista", "list_listings") const result = await cotlet.call('idealista', 'list_listings'); cotlet call idealista list_listings Example response
{
"listings": [
{
"listing_id": "108274561",
"title": "Flat in Malasana, Madrid",
"operation": "rent",
"status": "active",
"price": 1450,
"currency": "EUR",
"quality_score": 82,
"url": "https://www.idealista.com/inmueble/108274561/"
}
],
"next_cursor": null
} Get listing
readPOST https://cotlet.dev/api/v1/idealista/get_listing
Returns one ad as it appears on Idealista, with its description, features and number of photos. Use it before update_listing to see the current values, and after it to confirm the change.
Parameters
| Name | Type | Description |
|---|---|---|
| listing_id required | string | Listing ID from list_listings. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/get_listing \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"listing_id":"listing_8c41d2"}' result = client.call("idealista", "get_listing", {"listing_id":"listing_8c41d2"}) const result = await cotlet.call('idealista', 'get_listing', {"listing_id":"listing_8c41d2"}); cotlet call idealista get_listing --data '{"listing_id":"listing_8c41d2"}' Example response
{
"listing_id": "108274561",
"operation": "rent",
"status": "active",
"price": 1450,
"currency": "EUR",
"size_m2": 68,
"rooms": 2,
"bathrooms": 1,
"features": [
"lift",
"air conditioning"
],
"description": "Bright two-bedroom flat near Calle Fuencarral.",
"photos": 14,
"quality_score": 82,
"url": "https://www.idealista.com/inmueble/108274561/"
} Get listing stats
readPOST https://cotlet.dev/api/v1/idealista/get_listing_stats
Returns the number of visits, contacts and favorites an ad received in the period, as the statistics of your account show them. One listing per call.
Parameters
| Name | Type | Description |
|---|---|---|
| listing_id required | string | Listing ID from list_listings. |
| period | enum | 7d, 30d or 90d. Default: 30d. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/get_listing_stats \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"listing_id":"108274561","period":"30d"}' result = client.call("idealista", "get_listing_stats", {"listing_id":"108274561","period":"30d"}) const result = await cotlet.call('idealista', 'get_listing_stats', {"listing_id":"108274561","period":"30d"}); cotlet call idealista get_listing_stats --data '{"listing_id":"108274561","period":"30d"}' Example response
{
"listing_id": "108274561",
"period": "30d",
"visits": 912,
"contacts": 14,
"favorites": 37
} List contacts
readPOST https://cotlet.dev/api/v1/idealista/list_contacts
Lists contacts in your Inbox, most recent first, each with the listing it is about, the last message and the number of unread messages. State matches the Inbox lists: active, unread, handled or archived. Pages hold up to 50 contacts; pass next_cursor back as cursor.
Parameters
| Name | Type | Description |
|---|---|---|
| listing_id | string | Only contacts about this listing. |
| state | enum | active, unread, handled or archived. Default: active. |
| since | date | Only contacts with messages on or after this date. |
| cursor | string | Next page cursor from the previous call. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/list_contacts \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("idealista", "list_contacts") const result = await cotlet.call('idealista', 'list_contacts'); cotlet call idealista list_contacts Example response
{
"contacts": [
{
"contact_id": "c_83920417",
"name": "Marta R.",
"listing_id": "108274561",
"state": "unread",
"unread": 1,
"last_message": "Is it still available?",
"updated_at": "2026-10-10T17:55:00+02:00"
}
],
"next_cursor": null
} Get conversation
readPOST https://cotlet.dev/api/v1/idealista/get_conversation
Returns the messages of one conversation, oldest first, with your private notes and the listing the contact asked about. Your agent should read it before replying.
Parameters
| Name | Type | Description |
|---|---|---|
| contact_id required | string | Contact ID from list_contacts. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/get_conversation \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contact_id":"contact_8c41d2"}' result = client.call("idealista", "get_conversation", {"contact_id":"contact_8c41d2"}) const result = await cotlet.call('idealista', 'get_conversation', {"contact_id":"contact_8c41d2"}); cotlet call idealista get_conversation --data '{"contact_id":"contact_8c41d2"}' Example response
{
"contact_id": "c_83920417",
"listing_id": "108274561",
"messages": [
{
"from": "contact",
"body": "Is it still available?",
"sent_at": "2026-10-10T17:55:00+02:00"
}
],
"notes": []
} List demands
readPOST https://cotlet.dev/api/v1/idealista/list_demands
Lists the demands you created from contacts in idealista/tools, each with the operation, area and budget the person is looking for. Use it to match new listings to people already waiting. Agency accounts in idealista/tools only.
Parameters
| Name | Type | Description |
|---|---|---|
| operation | enum | sale, rent or all. Default: all. |
| limit | integer | 1 to 100. Default: 50. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/list_demands \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("idealista", "list_demands") const result = await cotlet.call('idealista', 'list_demands'); cotlet call idealista list_demands Example response
{
"demands": [
{
"demand_id": "d_2210",
"contact_id": "c_83920417",
"operation": "rent",
"area": "Malasana",
"max_price": 1600,
"currency": "EUR",
"rooms": 2
}
]
} POST https://cotlet.dev/api/v1/idealista/update_listing
Changes the fields you pass and leaves the rest as they are. The new price and text are public once saved. Returns the ad as saved, so your agent can check it. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| listing_id required | string | Listing ID from list_listings. |
| fields required | object | Any of price, description, size_m2, rooms, bathrooms, features. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/update_listing \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"listing_id":"108274575","fields":{"price":245000}}' result = client.call("idealista", "update_listing", {"listing_id":"108274575","fields":{"price":245000}}) const result = await cotlet.call('idealista', 'update_listing', {"listing_id":"108274575","fields":{"price":245000}}); cotlet call idealista update_listing --data '{"listing_id":"108274575","fields":{"price":245000}}' Example response
{
"listing_id": "108274561",
"status": "active",
"price": 245000,
"currency": "EUR",
"updated_at": "2026-10-10T18:20:00+02:00"
} Deactivate listing
writePOST https://cotlet.dev/api/v1/idealista/deactivate_listing
Deactivates one ad, so it no longer shows in search results. The ad stays in your account. deactivate_listing runs without asking first: it messages no one and reactivate_listing undoes it.
Parameters
| Name | Type | Description |
|---|---|---|
| listing_id required | string | Listing ID from list_listings. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/deactivate_listing \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"listing_id":"108274590"}' result = client.call("idealista", "deactivate_listing", {"listing_id":"108274590"}) const result = await cotlet.call('idealista', 'deactivate_listing', {"listing_id":"108274590"}); cotlet call idealista deactivate_listing --data '{"listing_id":"108274590"}' Example response
{
"listing_id": "108274561",
"status": "inactive"
} POST https://cotlet.dev/api/v1/idealista/reactivate_listing
Reactivates one ad that expired or was deactivated, so it shows in search results again. An ad cannot be reactivated if the account was closed together with it. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| listing_id required | string | Listing ID from list_listings. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/reactivate_listing \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"listing_id":"listing_8c41d2"}' result = client.call("idealista", "reactivate_listing", {"listing_id":"listing_8c41d2"}) const result = await cotlet.call('idealista', 'reactivate_listing', {"listing_id":"listing_8c41d2"}); cotlet call idealista reactivate_listing --data '{"listing_id":"listing_8c41d2"}' Example response
{
"listing_id": "108274561",
"status": "active"
} POST https://cotlet.dev/api/v1/idealista/reply_to_contact
Sends a message in the Inbox conversation with one contact, under your name. It appears next to the messages you wrote by hand. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| contact_id required | string | Contact ID from list_contacts. |
| body required | string | Message text. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/reply_to_contact \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contact_id":"c_83920417","body":"Hi, the flat is still available. I can show it on Saturday at 11:00 or 12:30."}' result = client.call("idealista", "reply_to_contact", {"contact_id":"c_83920417","body":"Hi, the flat is still available. I can show it on Saturday at 11:00 or 12:30."}) const result = await cotlet.call('idealista', 'reply_to_contact', {"contact_id":"c_83920417","body":"Hi, the flat is still available. I can show it on Saturday at 11:00 or 12:30."}); cotlet call idealista reply_to_contact --data '{"contact_id":"c_83920417","body":"Hi, the flat is still available. I can show it on Saturday at 11:00 or 12:30."}' Example response
{
"contact_id": "c_83920417",
"message_id": "m_552019384",
"status": "sent",
"sent_at": "2026-10-10T18:42:00+02:00"
} POST https://cotlet.dev/api/v1/idealista/send_listings_to_contact
Attaches up to 5 of your listings to the conversation with one contact, with an optional message, like the clip icon in Inbox. The contact sees them under your name. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| contact_id required | string | Contact ID from list_contacts. |
| listing_ids required | string[] | Up to 5 listing IDs from list_listings. |
| body | string | Message sent with the properties. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/send_listings_to_contact \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contact_id":"contact_8c41d2","listing_ids":["listing ids"]}' result = client.call("idealista", "send_listings_to_contact", {"contact_id":"contact_8c41d2","listing_ids":["listing ids"]}) const result = await cotlet.call('idealista', 'send_listings_to_contact', {"contact_id":"contact_8c41d2","listing_ids":["listing ids"]}); cotlet call idealista send_listings_to_contact --data '{"contact_id":"contact_8c41d2","listing_ids":["listing ids"]}' Example response
{
"contact_id": "c_83920417",
"message_id": "m_552019390",
"listing_ids": [
"108274562",
"108274563"
],
"status": "sent"
} Mark contact as handled
writePOST https://cotlet.dev/api/v1/idealista/mark_contact_handled
Marks one contact as handled, the green check in Inbox, for example after you dealt with it by phone. It messages no one and is undone from Inbox. mark_contact_handled runs without asking first.
Parameters
| Name | Type | Description |
|---|---|---|
| contact_id required | string | Contact ID from list_contacts. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/mark_contact_handled \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contact_id":"contact_8c41d2"}' result = client.call("idealista", "mark_contact_handled", {"contact_id":"contact_8c41d2"}) const result = await cotlet.call('idealista', 'mark_contact_handled', {"contact_id":"contact_8c41d2"}); cotlet call idealista mark_contact_handled --data '{"contact_id":"contact_8c41d2"}' Example response
{
"contact_id": "c_83920417",
"state": "handled"
} Add contact note
writePOST https://cotlet.dev/api/v1/idealista/add_contact_note
Adds a note to the conversation detail. The contact never sees it. add_contact_note runs without asking first, because it reaches no one.
Parameters
| Name | Type | Description |
|---|---|---|
| contact_id required | string | Contact ID from list_contacts. |
| note required | string | Note text. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/add_contact_note \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contact_id":"contact_8c41d2","note":"note"}' result = client.call("idealista", "add_contact_note", {"contact_id":"contact_8c41d2","note":"note"}) const result = await cotlet.call('idealista', 'add_contact_note', {"contact_id":"contact_8c41d2","note":"note"}); cotlet call idealista add_contact_note --data '{"contact_id":"contact_8c41d2","note":"note"}' Example response
{
"contact_id": "c_83920417",
"note_id": "n_4410",
"status": "saved"
} Archive conversation
writePOST https://cotlet.dev/api/v1/idealista/archive_conversation
Archives one conversation, so it leaves the active list. Idealista lets you reactivate an archived request from the conversation, so nothing is lost. archive_conversation runs without asking first: it messages no one.
Parameters
| Name | Type | Description |
|---|---|---|
| contact_id required | string | Contact ID from list_contacts. |
Request
curl -X POST https://cotlet.dev/api/v1/idealista/archive_conversation \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contact_id":"contact_8c41d2"}' result = client.call("idealista", "archive_conversation", {"contact_id":"contact_8c41d2"}) const result = await cotlet.call('idealista', 'archive_conversation', {"contact_id":"contact_8c41d2"}); cotlet call idealista archive_conversation --data '{"contact_id":"contact_8c41d2"}' Example response
{
"contact_id": "c_83920417",
"state": "archived"
}