REST API reference
Zoopla API
12 endpoints for Zoopla. Each one is a POST with a JSON body, called with your API key.
- Base URL
- https://cotlet.dev/api/v1/zoopla
- Connects with
- Your own ZooplaPro agent account (listing changes work for manual uploaders, not for listings sent by a property software feed)
- Integration page
- Zoopla
| Endpoint | Access | Description |
|---|---|---|
| list_listings | read | Your listings in one department, with address, price, site status, listing status and upload method. |
| get_listing | read | Full listing: address, price, property details, description, features, photos, utilities, EPC and floorplans. |
| get_listing_performance | read | Listing performance report: daily page views, price changes, Featured Properties upgrades, similar listings benchmark and a shareable link for the vendor or landlord. |
| get_performance_overview | read | Listings live per department, email and phone lead counts, and Premium Listings in use for a date range. |
| list_leads | read | Leads from the Leads report: email enquiries with message and listing, phone calls with time, caller number and result. |
| get_featured_properties_report | read | How each of your Featured Properties is performing on Zoopla, listing by listing. |
| get_upgrade_credits | read | Premium Listings and Weekly Featured Property credits left, their expiry, and which listings use them. |
| create_listing | write | New listing in a department, saved as Private so it is not on Zoopla until you publish it. Manual uploaders only. |
| update_listing | write | Change price, description, features, photos, video or floorplan links. Normally live on Zoopla within the hour. Manual uploaders only. |
| set_listing_status | write | Publish, hide or delete a listing, or mark it under offer, sold, let agreed or let. Manual uploaders only. |
| upgrade_to_premium | write | Make a listing Premium for 12 months, using one credit, with 2 highlights. Needs 3 photos and a 200 character description. |
| feature_listing | write | Upgrade a listing to Weekly Featured Property, using one credit. |
List listings
readPOST https://cotlet.dev/api/v1/zoopla/list_listings
Lists the listings of one department as ZooplaPro shows them. Each item has the upload method (manual or feed), which tells you whether the write tools can change it. Pages hold up to 100 listings; pass next_cursor back as cursor for the next page.
Parameters
| Name | Type | Description |
|---|---|---|
| department required | enum | residential_sales, residential_lettings, commercial_sales, commercial_lettings or overseas. |
| site_status | enum | public, private or all. Default: public. |
| 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/zoopla/list_listings \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"department":"residential_sales"}' result = client.call("zoopla", "list_listings", {"department":"residential_sales"}) const result = await cotlet.call('zoopla', 'list_listings', {"department":"residential_sales"}); cotlet call zoopla list_listings --data '{"department":"residential_sales"}' Example response
{
"listings": [
{
"listing_id": "67251984",
"address": "14 Elm Road, Bristol BS7 8AB",
"price": 375000,
"site_status": "public",
"listing_status": "for_sale",
"upload_method": "manual",
"premium": false
},
{
"listing_id": "67251990",
"address": "22 Park Street, Bath BA1 2EX",
"price": 350000,
"site_status": "public",
"listing_status": "for_sale",
"upload_method": "manual",
"premium": true
},
{
"listing_id": "67252011",
"address": "3 Mill Lane, Bristol BS6 5JD",
"price": 325000,
"site_status": "public",
"listing_status": "for_sale",
"upload_method": "manual",
"premium": false
}
],
"next_cursor": null
} Get listing
readPOST https://cotlet.dev/api/v1/zoopla/get_listing
Returns one listing with the fields you see when you edit it in ZooplaPro. Use it before update_listing so your agent changes only what you asked for.
Parameters
| Name | Type | Description |
|---|---|---|
| listing_id required | string | Listing ID from list_listings. |
Request
curl -X POST https://cotlet.dev/api/v1/zoopla/get_listing \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"listing_id":"listing_8c41d2"}' result = client.call("zoopla", "get_listing", {"listing_id":"listing_8c41d2"}) const result = await cotlet.call('zoopla', 'get_listing', {"listing_id":"listing_8c41d2"}); cotlet call zoopla get_listing --data '{"listing_id":"listing_8c41d2"}' Example response
{
"listing_id": "67251984",
"department": "residential_sales",
"address": "14 Elm Road, Bristol BS7 8AB",
"price": 375000,
"site_status": "public",
"listing_status": "for_sale",
"upload_method": "manual",
"details": {
"bedrooms": 3,
"bathrooms": 1,
"receptions": 2,
"property_type": "terraced",
"tenure": "freehold"
},
"full_description": "A bright three bedroom terraced house close to the park, with a south facing garden and off street parking.",
"features": [
"South facing garden",
"Off street parking"
],
"photo_urls": [
"https://example.com/photos/elm-road-1.jpg",
"https://example.com/photos/elm-road-2.jpg",
"https://example.com/photos/elm-road-3.jpg"
],
"floorplan_urls": []
} POST https://cotlet.dev/api/v1/zoopla/get_listing_performance
Returns the listing performance report you generate from the ZooplaPro Dashboard for one property. Daily page views run oldest first, and the same chart marks price changes and Featured Properties upgrades. The share link gives the vendor or landlord a live snapshot that Zoopla updates daily. The tool only reads and sends nothing to the vendor.
Parameters
| Name | Type | Description |
|---|---|---|
| listing_id required | string | Listing ID from list_listings. |
Request
curl -X POST https://cotlet.dev/api/v1/zoopla/get_listing_performance \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"listing_id":"67252011"}' result = client.call("zoopla", "get_listing_performance", {"listing_id":"67252011"}) const result = await cotlet.call('zoopla', 'get_listing_performance', {"listing_id":"67252011"}); cotlet call zoopla get_listing_performance --data '{"listing_id":"67252011"}' Example response
{
"listing_id": "67252011",
"address": "3 Mill Lane, Bristol BS6 5JD",
"from": "2026-10-05",
"to": "2026-10-11",
"page_views": {
"total": 321,
"daily": [
41,
38,
52,
47,
60,
44,
39
]
},
"price_changes": [],
"featured_upgrades": [],
"similar_listings": {
"average_page_views": 388
},
"share_url": "https://www.zoopla.co.uk/pro/example-report/3f9c2a"
} POST https://cotlet.dev/api/v1/zoopla/get_performance_overview
Returns the headline numbers of the ZooplaPro Dashboard for a date range: listings live per department, lead counts by type and the number of Premium Listings in use. Use list_leads for the individual leads behind the counts.
Parameters
| Name | Type | Description |
|---|---|---|
| from | date | Start of the date range. Default: 7 days ago. |
| to | date | End of the date range. Default: today. |
Request
curl -X POST https://cotlet.dev/api/v1/zoopla/get_performance_overview \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("zoopla", "get_performance_overview") const result = await cotlet.call('zoopla', 'get_performance_overview'); cotlet call zoopla get_performance_overview Example response
{
"from": "2026-10-05",
"to": "2026-10-11",
"listings_live": {
"residential_sales": 18,
"residential_lettings": 11
},
"leads": {
"sales_email": 24,
"lettings_email": 19,
"valuation_email": 6,
"phone": 11,
"total": 60
},
"premium_listings_in_use": 4
} List leads
readPOST https://cotlet.dev/api/v1/zoopla/list_leads
Returns the leads of the ZooplaPro Leads report for a date range, newest first. Email leads have the enquirer's message and the listing; phone leads have the call time, the caller's number and whether it was answered or missed. Totals count all leads in the range, not only this page. Set listing_id to see one property.
Parameters
| Name | Type | Description |
|---|---|---|
| type | enum | for_sale_email, to_rent_email, valuation_email, phone or all. Default: all. |
| listing_id | string | Only leads for this listing. |
| from | date | Start of the date range. Default: 7 days ago. |
| to | date | End of the date range. Default: today. |
| cursor | string | Next page cursor from the previous call. |
Request
curl -X POST https://cotlet.dev/api/v1/zoopla/list_leads \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"type":"phone","from":"2026-10-05","to":"2026-10-11"}' result = client.call("zoopla", "list_leads", {"type":"phone","from":"2026-10-05","to":"2026-10-11"}) const result = await cotlet.call('zoopla', 'list_leads', {"type":"phone","from":"2026-10-05","to":"2026-10-11"}); cotlet call zoopla list_leads --data '{"type":"phone","from":"2026-10-05","to":"2026-10-11"}' Example response
{
"from": "2026-10-05",
"to": "2026-10-11",
"totals": {
"sales_email": 24,
"lettings_email": 19,
"valuation_email": 6,
"phone": 11,
"total": 60
},
"leads": [
{
"lead_id": "l_90c1",
"type": "sales_email",
"received_at": "2026-10-10T16:42:00+01:00",
"listing_id": "67251984",
"address": "14 Elm Road, Bristol BS7 8AB",
"name": "Sam",
"message": "Is the garden south facing, and can we view on Saturday?"
},
{
"lead_id": "l_90b7",
"type": "phone",
"received_at": "2026-10-10T11:05:00+01:00",
"listing_id": "67251990",
"address": "22 Park Street, Bath BA1 2EX",
"caller_number": "07700 900123",
"result": "answered"
}
],
"next_cursor": "eyJvZmZzZXQiOjIwfQ"
} POST https://cotlet.dev/api/v1/zoopla/get_featured_properties_report
Returns the Featured Property report of ZooplaPro for a date range, one row per Featured listing. It is available when your package includes Featured Property. Use get_listing_performance for the full report of a single property.
Parameters
| Name | Type | Description |
|---|---|---|
| from | date | Start of the date range. Default: 7 days ago. |
| to | date | End of the date range. Default: today. |
Request
curl -X POST https://cotlet.dev/api/v1/zoopla/get_featured_properties_report \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("zoopla", "get_featured_properties_report") const result = await cotlet.call('zoopla', 'get_featured_properties_report'); cotlet call zoopla get_featured_properties_report Example response
{
"from": "2026-10-05",
"to": "2026-10-11",
"listings": [
{
"listing_id": "67251990",
"address": "22 Park Street, Bath BA1 2EX",
"featured_from": "2026-10-06",
"featured_until": "2026-10-13",
"page_views": 412
}
]
} Get upgrade credits
readPOST https://cotlet.dev/api/v1/zoopla/get_upgrade_credits
Returns the upgrade credits of your account and the listings that use them. Check it before upgrade_to_premium or feature_listing, because each upgrade uses one credit.
Parameters
No parameters.
Request
curl -X POST https://cotlet.dev/api/v1/zoopla/get_upgrade_credits \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("zoopla", "get_upgrade_credits") const result = await cotlet.call('zoopla', 'get_upgrade_credits'); cotlet call zoopla get_upgrade_credits Example response
{
"premium_listings": {
"credits_left": 3,
"used_by": [
"67251990"
]
},
"weekly_featured": {
"credits_left": 2,
"used_by": []
}
} Create listing
writePOST https://cotlet.dev/api/v1/zoopla/create_listing
Creates a listing and saves it as Private, so it is not on Zoopla and reaches no one. Publish it with set_listing_status, which asks for your OK. Because nothing goes public and set_listing_status can delete it, create_listing runs without asking first. Use copy_from_listing_id to start from an existing or deleted listing, like Create similar in ZooplaPro.
Parameters
| Name | Type | Description |
|---|---|---|
| department required | enum | residential_sales, residential_lettings, commercial_sales, commercial_lettings or overseas. |
| address required | object | Street, town and postcode. |
| price required | integer | Sale price or rent in pounds, numbers only. |
| details required | object | Bedrooms, bathrooms, receptions, property type, tenure, council tax band and other required fields. |
| full_description required | string | Full description shown on the listing. |
| photo_urls | string[] | Photos in display order. |
| copy_from_listing_id | string | Start from an existing or deleted listing, like Create similar. |
Request
curl -X POST https://cotlet.dev/api/v1/zoopla/create_listing \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"department":"residential_sales","address":"address","price":1,"details":"details","full_description":"full description"}' result = client.call("zoopla", "create_listing", {"department":"residential_sales","address":"address","price":1,"details":"details","full_description":"full description"}) const result = await cotlet.call('zoopla', 'create_listing', {"department":"residential_sales","address":"address","price":1,"details":"details","full_description":"full description"}); cotlet call zoopla create_listing --data '{"department":"residential_sales","address":"address","price":1,"details":"details","full_description":"full description"}' Example response
{
"listing_id": "67252040",
"department": "residential_sales",
"address": "9 Orchard Close, Bristol BS9 3QE",
"price": 410000,
"site_status": "private",
"listing_status": "for_sale"
} POST https://cotlet.dev/api/v1/zoopla/update_listing
Changes the fields you pass on one listing and leaves the others as they are. Edits on a public listing normally go live on Zoopla within 1 hour, and a price change appears as a mark in the listing performance chart. Listings sent by a property software feed cannot be changed here. 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, price_modifier, full_description, features, photo_urls, video_urls, floorplan_urls. |
Request
curl -X POST https://cotlet.dev/api/v1/zoopla/update_listing \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"listing_id":"listing_8c41d2","fields":"fields"}' result = client.call("zoopla", "update_listing", {"listing_id":"listing_8c41d2","fields":"fields"}) const result = await cotlet.call('zoopla', 'update_listing', {"listing_id":"listing_8c41d2","fields":"fields"}); cotlet call zoopla update_listing --data '{"listing_id":"listing_8c41d2","fields":"fields"}' Example response
{
"listing_id": "67251990",
"address": "22 Park Street, Bath BA1 2EX",
"price_before": 350000,
"price": 340000,
"live_on_zoopla": "within 1 hour"
} POST https://cotlet.dev/api/v1/zoopla/set_listing_status
Changes the site status or the listing status of one listing, or both. Listing status shows the buyer or tenant what stage the property is at. Changes normally go live on Zoopla within 1 hour. Listings sent by a property software feed cannot be changed here. 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. |
| site_status | enum | public, private or deleted. |
| listing_status | enum | for_sale, sale_under_offer, sold, to_rent, let_agreed or let. |
Request
curl -X POST https://cotlet.dev/api/v1/zoopla/set_listing_status \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"listing_id":"67251984","listing_status":"sale_under_offer"}' result = client.call("zoopla", "set_listing_status", {"listing_id":"67251984","listing_status":"sale_under_offer"}) const result = await cotlet.call('zoopla', 'set_listing_status', {"listing_id":"67251984","listing_status":"sale_under_offer"}); cotlet call zoopla set_listing_status --data '{"listing_id":"67251984","listing_status":"sale_under_offer"}' Example response
{
"listing_id": "67251984",
"department": "residential_sales",
"address": "14 Elm Road, Bristol BS7 8AB",
"site_status": "public",
"listing_status": "sale_under_offer",
"live_on_zoopla": "within 1 hour",
"url": "https://www.zoopla.co.uk/for-sale/details/67251984/"
} POST https://cotlet.dev/api/v1/zoopla/upgrade_to_premium
Upgrades one listing to Premium, which lasts 12 months or until the listing is removed. It uses one Premium Listings credit and fails if the listing has fewer than 3 photos or a full description under 200 characters. Pick the 2 highlights from the Premium Listings highlights chart. 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. |
| highlight_ids | string[] | Up to 2 highlights from the Premium Listings highlights chart. |
Request
curl -X POST https://cotlet.dev/api/v1/zoopla/upgrade_to_premium \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"listing_id":"67252040","highlight_ids":["garden","garage"]}' result = client.call("zoopla", "upgrade_to_premium", {"listing_id":"67252040","highlight_ids":["garden","garage"]}) const result = await cotlet.call('zoopla', 'upgrade_to_premium', {"listing_id":"67252040","highlight_ids":["garden","garage"]}); cotlet call zoopla upgrade_to_premium --data '{"listing_id":"67252040","highlight_ids":["garden","garage"]}' Example response
{
"listing_id": "67251984",
"premium": true,
"premium_until": "2027-10-11",
"highlights": [
"garden",
"parking"
],
"credits_left": 2
} POST https://cotlet.dev/api/v1/zoopla/feature_listing
Upgrades one listing to Weekly Featured Property for a week and uses one Weekly Featured Property credit. It works when your package includes Featured Property. 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/zoopla/feature_listing \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"listing_id":"listing_8c41d2"}' result = client.call("zoopla", "feature_listing", {"listing_id":"listing_8c41d2"}) const result = await cotlet.call('zoopla', 'feature_listing', {"listing_id":"listing_8c41d2"}); cotlet call zoopla feature_listing --data '{"listing_id":"listing_8c41d2"}' Example response
{
"listing_id": "67252011",
"featured_from": "2026-10-12",
"featured_until": "2026-10-19",
"credits_left": 1
}