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
Idealista Endpoints
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.

POST 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

Parameters: list_listings
NameTypeDescription
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
curl -X POST https://cotlet.dev/api/v1/idealista/list_listings \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("idealista", "list_listings")
Node.js
const result = await cotlet.call('idealista', 'list_listings');
CLI
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
}

POST 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

Parameters: get_listing
NameTypeDescription
listing_id required string Listing ID from list_listings.

Request

cURL
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"}'
Python
result = client.call("idealista", "get_listing", {"listing_id":"listing_8c41d2"})
Node.js
const result = await cotlet.call('idealista', 'get_listing', {"listing_id":"listing_8c41d2"});
CLI
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/"
}

POST 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

Parameters: get_listing_stats
NameTypeDescription
listing_id required string Listing ID from list_listings.
period enum 7d, 30d or 90d. Default: 30d.

Request

cURL
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"}'
Python
result = client.call("idealista", "get_listing_stats", {"listing_id":"108274561","period":"30d"})
Node.js
const result = await cotlet.call('idealista', 'get_listing_stats', {"listing_id":"108274561","period":"30d"});
CLI
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
}

POST 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

Parameters: list_contacts
NameTypeDescription
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
curl -X POST https://cotlet.dev/api/v1/idealista/list_contacts \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("idealista", "list_contacts")
Node.js
const result = await cotlet.call('idealista', 'list_contacts');
CLI
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
}

POST 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

Parameters: get_conversation
NameTypeDescription
contact_id required string Contact ID from list_contacts.

Request

cURL
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"}'
Python
result = client.call("idealista", "get_conversation", {"contact_id":"contact_8c41d2"})
Node.js
const result = await cotlet.call('idealista', 'get_conversation', {"contact_id":"contact_8c41d2"});
CLI
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": []
}

POST 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

Parameters: list_demands
NameTypeDescription
operation enum sale, rent or all. Default: all.
limit integer 1 to 100. Default: 50.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/idealista/list_demands \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("idealista", "list_demands")
Node.js
const result = await cotlet.call('idealista', 'list_demands');
CLI
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
    }
  ]
}

Update listing

write Confirm

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

Parameters: update_listing
NameTypeDescription
listing_id required string Listing ID from list_listings.
fields required object Any of price, description, size_m2, rooms, bathrooms, features.

Request

cURL
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}}'
Python
result = client.call("idealista", "update_listing", {"listing_id":"108274575","fields":{"price":245000}})
Node.js
const result = await cotlet.call('idealista', 'update_listing', {"listing_id":"108274575","fields":{"price":245000}});
CLI
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"
}

POST 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

Parameters: deactivate_listing
NameTypeDescription
listing_id required string Listing ID from list_listings.

Request

cURL
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"}'
Python
result = client.call("idealista", "deactivate_listing", {"listing_id":"108274590"})
Node.js
const result = await cotlet.call('idealista', 'deactivate_listing', {"listing_id":"108274590"});
CLI
cotlet call idealista deactivate_listing --data '{"listing_id":"108274590"}'

Example response

{
  "listing_id": "108274561",
  "status": "inactive"
}

Reactivate listing

write Confirm

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

Parameters: reactivate_listing
NameTypeDescription
listing_id required string Listing ID from list_listings.

Request

cURL
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"}'
Python
result = client.call("idealista", "reactivate_listing", {"listing_id":"listing_8c41d2"})
Node.js
const result = await cotlet.call('idealista', 'reactivate_listing', {"listing_id":"listing_8c41d2"});
CLI
cotlet call idealista reactivate_listing --data '{"listing_id":"listing_8c41d2"}'

Example response

{
  "listing_id": "108274561",
  "status": "active"
}

Reply to contact

write Confirm

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

Parameters: reply_to_contact
NameTypeDescription
contact_id required string Contact ID from list_contacts.
body required string Message text.

Request

cURL
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."}'
Python
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."})
Node.js
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."});
CLI
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"
}

Send listings to contact

write Confirm

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

Parameters: send_listings_to_contact
NameTypeDescription
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
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"]}'
Python
result = client.call("idealista", "send_listings_to_contact", {"contact_id":"contact_8c41d2","listing_ids":["listing ids"]})
Node.js
const result = await cotlet.call('idealista', 'send_listings_to_contact', {"contact_id":"contact_8c41d2","listing_ids":["listing ids"]});
CLI
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"
}

POST 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

Parameters: mark_contact_handled
NameTypeDescription
contact_id required string Contact ID from list_contacts.

Request

cURL
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"}'
Python
result = client.call("idealista", "mark_contact_handled", {"contact_id":"contact_8c41d2"})
Node.js
const result = await cotlet.call('idealista', 'mark_contact_handled', {"contact_id":"contact_8c41d2"});
CLI
cotlet call idealista mark_contact_handled --data '{"contact_id":"contact_8c41d2"}'

Example response

{
  "contact_id": "c_83920417",
  "state": "handled"
}

POST 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

Parameters: add_contact_note
NameTypeDescription
contact_id required string Contact ID from list_contacts.
note required string Note text.

Request

cURL
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"}'
Python
result = client.call("idealista", "add_contact_note", {"contact_id":"contact_8c41d2","note":"note"})
Node.js
const result = await cotlet.call('idealista', 'add_contact_note', {"contact_id":"contact_8c41d2","note":"note"});
CLI
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"
}

POST 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

Parameters: archive_conversation
NameTypeDescription
contact_id required string Contact ID from list_contacts.

Request

cURL
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"}'
Python
result = client.call("idealista", "archive_conversation", {"contact_id":"contact_8c41d2"})
Node.js
const result = await cotlet.call('idealista', 'archive_conversation', {"contact_id":"contact_8c41d2"});
CLI
cotlet call idealista archive_conversation --data '{"contact_id":"contact_8c41d2"}'

Example response

{
  "contact_id": "c_83920417",
  "state": "archived"
}