openapi: 3.1.0
info:
title: Connells Website JSON API (undocumented)
version: '2026-07-26'
summary: Read-only JSON endpoints served by the Connells estate agency website.
description: >-
This is NOT a published Connells Group product. Connells Group publishes no
developer portal, no documentation and no specification of any kind. This
document was DERIVED by API Evangelist purely from live, anonymous,
unauthenticated HTTP probes of https://www.connells.co.uk/api on 2026-07-26,
and every schema below is a faithful transcription of an observed response
body — nothing was invented, and no field appears here that was not returned
by the live service.
The endpoints are Next.js App Router route handlers backing the
www.connells.co.uk consumer site (branch finder, people directory,
testimonials wall and location autocomplete). Content is sourced from the
Homeflow estate-agency platform that powers the Connells consumer estate
(asset URLs resolve to *.homeflow-assets.co.uk). They are unversioned,
undocumented, carry no service-level commitment, are rate limited by
Cloudflare (HTTP 429 with Retry-After) and may change or disappear without
notice. Treat them as an observation of the estate, not as a contract.
The sibling Connells Group brand sites (Hamptons, Sequence, Bairstow Eves,
Fox & Sons, John D Wood, Blundells, Barnard Marcus, William H Brown) run the
Homeflow Rails application directly and 302-redirect /api/* to their
homepage; Countrywide 301-redirects; Gascoigne Halman 404s. Only
www.connells.co.uk exposes these handlers.
x-provenance: api-evangelist-derived-from-live-probes
x-published-by-provider: false
x-probe-date: '2026-07-26'
servers:
- url: https://www.connells.co.uk/api
description: Production (undocumented, unversioned, no SLA)
tags:
- name: Branches
description: Connells branch (office) directory.
- name: People
description: Connells staff directory.
- name: Testimonials
description: Published customer testimonials.
- name: Locations
description: Geographic locations and place-name lookup.
paths:
/branches:
get:
operationId: listBranches
summary: List Connells branches
description: >-
Returns the first page of the Connells branch directory. Observed
2026-07-26 as 162 branches across 14 pages of 12. No query parameter was
honoured — page, pageSize, per_page, limit, lat, lng, search, q, query,
slug, service, distance and isLettingsEnabled were each probed and all
returned page 1 unchanged. OPTIONS reports "Allow: GET, HEAD, OPTIONS".
tags: [Branches]
security: []
responses:
'200':
description: A page of branches.
content:
application/json:
schema:
$ref: '#/components/schemas/BranchListEnvelope'
'429':
$ref: '#/components/responses/RateLimited'
/branches/{branchId}:
get:
operationId: getBranch
summary: Get one branch by numeric id
description: >-
Returns a single branch by its numeric id (observed: 8020 = Abingdon).
The path segment must be the numeric id; passing the branch slug
("abingdon") returns HTTP 200 with a null result rather than a 404.
tags: [Branches]
security: []
parameters:
- name: branchId
in: path
required: true
description: Numeric branch identifier, as returned by listBranches.
schema:
type: integer
example: 8020
responses:
'200':
description: The branch, or a null result when no branch matches.
content:
application/json:
schema:
$ref: '#/components/schemas/BranchEnvelope'
'429':
$ref: '#/components/responses/RateLimited'
/staff:
get:
operationId: listStaff
summary: List Connells staff
description: >-
Returns the first page of the Connells people directory. Observed
2026-07-26 as 841 staff across 71 pages of 12. Same envelope and same
non-honoured pagination behaviour as listBranches.
tags: [People]
security: []
responses:
'200':
description: A page of staff members.
content:
application/json:
schema:
$ref: '#/components/schemas/StaffListEnvelope'
'429':
$ref: '#/components/responses/RateLimited'
/testimonials:
get:
operationId: listTestimonials
summary: List published customer testimonials
description: >-
Returns 12 published customer testimonials. Note the envelope differs
from the others: `pagination` is null and the error key is singular
(`error`, not `errors`).
tags: [Testimonials]
security: []
responses:
'200':
description: Testimonials.
content:
application/json:
schema:
$ref: '#/components/schemas/TestimonialListEnvelope'
'429':
$ref: '#/components/responses/RateLimited'
/locations:
get:
operationId: listLocations
summary: List locations
description: >-
Returns a bare JSON array (no envelope) of 12 location records. Ids are
24-character hexadecimal strings (MongoDB ObjectId form), consistent
with the Homeflow platform behind the site. Several records were
observed with empty `name` and `urlLabel` values.
tags: [Locations]
security: []
responses:
'200':
description: An array of locations.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Location'
'429':
$ref: '#/components/responses/RateLimited'
/places:
get:
operationId: searchPlaces
summary: Look up places by name
description: >-
Place-name autocomplete. Requires the `name` query parameter; without it
the service returns HTTP 200 with an empty result set and the error
"Name required for places search". Results are returned as positional
arrays of three strings — [display label, place id, place slug] — rather
than as objects.
tags: [Locations]
security: []
parameters:
- name: name
in: query
required: true
description: Free-text place name to search for.
schema:
type: string
example: bedford
responses:
'200':
description: Matching places, or an error entry when `name` is absent.
content:
application/json:
schema:
$ref: '#/components/schemas/PlaceSearchEnvelope'
'429':
$ref: '#/components/responses/RateLimited'
/properties:
get:
operationId: listProperties
summary: Property listings (route present, non-functional)
description: >-
This route handler exists but returned HTTP 500 with an empty body on
every probe on 2026-07-26 — bare, and with location, search, type and
page query parameters. It is documented here only to record that the
route is present and failing; no successful response has ever been
observed, so no 200 schema is asserted. Property listings on
www.connells.co.uk are server-rendered from the Homeflow platform, not
fetched from this endpoint by the browser.
tags: [Branches]
security: []
responses:
'500':
description: Observed on every probe. Empty body.
'429':
$ref: '#/components/responses/RateLimited'
components:
responses:
RateLimited:
description: >-
Rate limited at the Cloudflare edge. Body is the plain-text string "Too
many requests" and a Retry-After header is supplied (34 seconds
observed).
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
example: 34
content:
text/plain:
schema:
type: string
example: Too many requests
schemas:
Pagination:
type: object
description: Pagination envelope returned by the list endpoints.
properties:
totalCount:
type: integer
example: 162
currentPage:
type: integer
example: 1
pageSize:
type: integer
example: 12
pageCount:
type: integer
example: 14
hasPrevPage:
type: boolean
hasNextPage:
type: boolean
ApiError:
type: object
properties:
message:
type: string
example: Name required for places search
BranchListEnvelope:
type: object
properties:
results:
type: array
items:
$ref: '#/components/schemas/Branch'
pagination:
$ref: '#/components/schemas/Pagination'
errors:
type: [array, 'null']
items:
$ref: '#/components/schemas/ApiError'
BranchEnvelope:
type: object
properties:
result:
oneOf:
- $ref: '#/components/schemas/Branch'
- type: 'null'
errors:
type: [array, 'null']
items:
$ref: '#/components/schemas/ApiError'
StaffListEnvelope:
type: object
properties:
results:
type: array
items:
$ref: '#/components/schemas/StaffMember'
pagination:
$ref: '#/components/schemas/Pagination'
errors:
type: [array, 'null']
items:
$ref: '#/components/schemas/ApiError'
TestimonialListEnvelope:
type: object
description: >-
Note the singular `error` key and the null `pagination` — this envelope
is not consistent with the branch and staff envelopes.
properties:
results:
type: array
items:
$ref: '#/components/schemas/Testimonial'
pagination:
type: 'null'
error:
type: [object, 'null']
PlaceSearchEnvelope:
type: object
properties:
results:
type: array
description: Each match is a positional 3-string array.
items:
$ref: '#/components/schemas/PlaceMatch'
errors:
type: [array, 'null']
items:
$ref: '#/components/schemas/ApiError'
PlaceMatch:
type: array
description: '[display label, place id, place slug]'
minItems: 3
maxItems: 3
items:
type: string
example:
- Bedford, Bedfordshire
- 51e7c40773dadaf60feea517
- bedford
Branch:
type: object
description: A Connells branch (high-street office).
properties:
id:
type: integer
example: 8020
slug:
type: string
example: abingdon
name:
type: string
example: Abingdon
mainPhoto:
type: [string, 'null']
format: uri
description: Branch photograph, served from the Homeflow asset CDN.
email:
type: [string, 'null']
format: email
description:
type: [string, 'null']
description: Long-form marketing copy for the branch.
lat:
type: [number, 'null']
example: 51.6701702207
lng:
type: [number, 'null']
example: -1.2827574378
displayAddress:
type: [string, 'null']
description: Newline-delimited postal address.
contactTelephone:
type: [string, 'null']
urlLabel:
type: [string, 'null']
salesTelephone:
type: [string, 'null']
lettingsTelephone:
type: [string, 'null']
branchManager:
oneOf:
- $ref: '#/components/schemas/StaffMember'
- type: 'null'
services:
type: array
items:
$ref: '#/components/schemas/BranchService'
agencyId:
type: [integer, 'null']
example: 909
isSalesEnabled:
type: [boolean, 'null']
isLettingsEnabled:
type: [boolean, 'null']
departments:
type: array
description: Observed empty on every record sampled.
items:
type: object
distance:
type: [number, 'null']
description: Observed null; presumably populated by a proximity search.
branchUrl:
type: [string, 'null']
example: /estate-agents/abingdon
BranchService:
type: object
description: A service line offered at a branch.
properties:
service:
type: string
example: Lettings
phone_number:
type: [string, 'null']
fax_number:
type: [string, 'null']
email_address:
type: [string, 'null']
enabled:
type: [boolean, 'null']
StaffMember:
type: object
description: >-
A Connells colleague. The same shape is embedded as a branch's
`branchManager`.
properties:
id:
type: integer
example: 23232373
slug:
type: string
example: paul-barron
name:
type: string
example: Paul Barron
jobTitle:
type: [string, 'null']
example: Instructions Manager
avatar:
type: [string, 'null']
format: uri
mobileNumber:
type: [string, 'null']
description: Observed null on every record sampled.
email:
type: [string, 'null']
description: Observed null on every record sampled.
urlLabel:
type: [string, 'null']
team:
type: [string, 'null']
shortBio:
type: [string, 'null']
longBio:
type: [string, 'null']
branchId:
type: [integer, 'null']
description: Foreign key to Branch.id.
example: 8020
Testimonial:
type: object
properties:
id:
type: integer
example: 417891
name:
type: string
description: Partially redacted customer name as published on the site.
content:
type: string
displayDate:
type: string
description: Human-formatted date, DD/MM/YYYY.
example: 24/07/2026
contactCounty:
type: [string, 'null']
example: Cambridgeshire
createdAt:
type: string
format: date-time
example: '2026-07-24T13:29:00.000Z'
Location:
type: object
properties:
id:
type: string
description: 24-character hexadecimal identifier (MongoDB ObjectId form).
example: 590a049361034ea359e75f51
name:
type: string
description: Observed empty on several records.
countyName:
type: string
example: West Yorkshire
urlLabel:
type: string
description: Observed empty on several records.