API Documentation
Access your property intelligence data programmatically. The RealiQ REST API is available on the Enterprise plan.
Authentication
All API requests require an API key passed via the Authorization header. API keys can be created and managed from Settings > API Keys in your dashboard.
curl -H "Authorization: Bearer nc_live_abc123..." \
https://www.realiq.uk/api/v1/propertiesAPI keys start with nc_ and are hashed with SHA-256 before storage. Keep your keys secret.
Rate Limiting
Each API key is limited to 1,000 requests per day. When exceeded, the API returns a 429 Too Many Requests response. Rate limit counters reset at midnight UTC.
Response Format
All responses use a standard JSON envelope.
Success (list)
{
"data": [ ... ],
"meta": {
"count": 50,
"has_more": true,
"cursor": "eyJpZCI6IjUwIn0"
}
}Success (single)
{
"data": { ... }
}Error
{
"error": {
"message": "Invalid API key",
"code": "UNAUTHORIZED"
}
}Pagination
List endpoints support cursor-based pagination. Pass cursor and optional limit (default 50, max 100).
GET /api/v1/properties?limit=25&cursor=eyJpZCI6IjI1In0Endpoints
GET/api/v1/properties
List properties with optional filters.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| sector | string | Filter by sector (e.g. Office, Industrial, Industrial Open Storage, Retail) |
| city | string | Filter by city name |
| postcode | string | Filter by postcode prefix |
| min_price | number | Minimum asking price |
| max_price | number | Maximum asking price |
curl -H "Authorization: Bearer nc_live_abc123..." \
"https://www.realiq.uk/api/v1/properties?sector=Industrial&limit=10"Example Response
{
"data": [
{
"id": "a1b2c3d4-...",
"name": "Apex Business Park",
"address": "Unit 5, Apex Park, Leeds LS11 5QA",
"sector": "Industrial",
"asking_price": 4250000,
"niy": 6.85,
"total_rent": 291125,
"number_of_tenants": 3,
"wault": 5.2,
"created_at": "2026-02-10T14:30:00Z"
}
],
"meta": { "count": 1, "has_more": false, "cursor": null }
}GET/api/v1/properties/:id
Get a single property with its tenancy schedule.
curl -H "Authorization: Bearer nc_live_abc123..." \
"https://www.realiq.uk/api/v1/properties/a1b2c3d4-..."PATCH/api/v1/properties/:id
Set sale status and sale evidence, edit Deal Tracker notes, or requote. Send only the fields you want to change; an explicit null clears a field. A status-only sale is allowed: sale_status of sold with no price records the sale and creates a comparable only once a real price and date exist. Legal moves are for_sale to under_offer, sold or withdrawn; under_offer to for_sale, sold or withdrawn; sold back to for_sale (undo); withdrawn back to for_sale. Requires write scope.
Fields
| Field | Type | Notes |
|---|---|---|
| sale_status | string | for_sale, under_offer, sold, withdrawn |
| sold_price | number | null | GBP. Optional even when sold |
| sale_date | YYYY-MM-DD | null | Optional even when sold |
| purchaser_investor_id | uuid | null | Must be an investor in your workspace |
| acquisition_type | string | investment or vacant_possession |
| guide_price | number | null | Requote. Matches are not recomputed; re-run matching afterwards |
| net_initial_yield | number | null | Requote, as a percentage |
| notes / notes_append | string | notes_append is atomic; notes replaces and needs expected_updated_at |
| strike_price, expected_updated_at | number, string | Internal target price; version token for optimistic concurrency (409 on conflict) |
# Status-only sale: the agent confirmed it sold but not for how much
curl -X PATCH -H "Authorization: Bearer nc_..." -H "Content-Type: application/json" \
-d '{"sale_status": "sold"}' \
https://www.realiq.uk/api/v1/properties/a1b2c3d4-...
# Requote after an audit
curl -X PATCH -H "Authorization: Bearer nc_..." -H "Content-Type: application/json" \
-d '{"guide_price": 2850000, "net_initial_yield": 6.75}' \
https://www.realiq.uk/api/v1/properties/a1b2c3d4-...GET/api/v1/matches
List investor-property matches with scores and AI commentary.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| status | string | Filter by status: new, reviewed, contacted, passed |
| min_score | number | Minimum match score (0-100) |
| investor_id | uuid | Filter matches for a specific investor |
curl -H "Authorization: Bearer nc_live_abc123..." \
"https://www.realiq.uk/api/v1/matches?min_score=90&status=new"GET/api/v1/comparables
List comparable transactions from your evidence database.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| sector | string | Filter by sector |
| city | string | Filter by city |
| start_date | date | Transaction date from (YYYY-MM-DD) |
| end_date | date | Transaction date to (YYYY-MM-DD) |
curl -H "Authorization: Bearer nc_live_abc123..." \
"https://www.realiq.uk/api/v1/comparables?sector=Office&city=Manchester"GET/api/v1/investors
List investors with their acquisition profiles.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| name | string | Search by investor name |
| type | string | Filter by investor type |
curl -H "Authorization: Bearer nc_live_abc123..." \
"https://www.realiq.uk/api/v1/investors?type=fund"GET/api/v1/investors/:id
Get a single investor with all their acquisition requirements.
curl -H "Authorization: Bearer nc_live_abc123..." \
"https://www.realiq.uk/api/v1/investors/e5f6g7h8-..."PATCH/api/v1/investors/:id
Update an investor: send any of name, type, notes or active. Types are Institution, Private, REIT, Fund, Family Office, Prop Co or Other. Requires a key with write scope.
curl -X PATCH \
-H "Authorization: Bearer nc_..." \
-H "Content-Type: application/json" \
-d '{"type": "Prop Co", "notes": "Trading co, off-market only"}' \
https://www.realiq.uk/api/v1/investors/e5f6g7h8-...GETPOST/api/v1/investors/:id/contacts
List an investor's contacts, or add one. POST takes name (required), email, phone, role and is_primary; setting is_primary demotes any existing primary. POST requires write scope.
curl -X POST \
-H "Authorization: Bearer nc_..." \
-H "Content-Type: application/json" \
-d '{"name": "Jane Doe", "email": "jane@fund.com", "role": "Head of Acquisitions", "is_primary": true}' \
https://www.realiq.uk/api/v1/investors/e5f6g7h8-.../contactsPATCHDELETE/api/v1/investors/:id/contacts/:contactId
Correct a contact or remove one when they leave the firm. PATCH takes any of name, email, phone, role, notes and is_primary; pass null to clear a field, and setting is_primary demotes any existing primary. DELETE reports whether the contact was the primary, so you know the investor is left without one. Both require write scope.
curl -X PATCH \
-H "Authorization: Bearer nc_..." \
-H "Content-Type: application/json" \
-d '{"role": "Partner", "phone": null}' \
https://www.realiq.uk/api/v1/investors/e5f6g7h8-.../contacts/c1d2e3f4-...
curl -X DELETE \
-H "Authorization: Bearer nc_..." \
https://www.realiq.uk/api/v1/investors/e5f6g7h8-.../contacts/c1d2e3f4-...GETPATCH/api/v1/requirements/:id
Read or update an acquisition mandate. PATCH accepts name, sectors, locations, min_lot_size, max_lot_size, min_yield, max_yield, min_wault_years, tenant_covenant_min (A/B/C), return_criteria_list, notes, is_hot and active. Re-run matching afterwards to rescore. Requires write scope.
curl -X PATCH \
-H "Authorization: Bearer nc_..." \
-H "Content-Type: application/json" \
-d '{"sectors": ["Multi-Let Industrial"], "min_yield": 6.5, "return_criteria_list": ["Core Plus", "Value-Add"]}' \
https://www.realiq.uk/api/v1/requirements/a1b2c3d4-...GET/api/v1/tenancies
List tenancies across all properties.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| property_id | uuid | Filter tenancies for a specific property |
| tenant_name | string | Search by tenant name |
curl -H "Authorization: Bearer nc_live_abc123..." \
"https://www.realiq.uk/api/v1/tenancies?tenant_name=Amazon"GET/api/v1/stats
Get portfolio overview statistics.
curl -H "Authorization: Bearer nc_live_abc123..." \
"https://www.realiq.uk/api/v1/stats"Example Response
{
"data": {
"properties_count": 188,
"total_value": 1510000000,
"total_rent": 104100000,
"investors_count": 109,
"matches_count": 12120,
"comparables_count": 923,
"sector_breakdown": {
"Industrial": 72,
"Office": 48,
"Retail": 35,
"Mixed Use": 18,
"Other": 15
}
}
}POST/api/v1/extract
Run AI extraction on a document (PDF, DOCX or XLSX). Requires a key with write scope. Results that pass validation are committed to the portfolio and matched automatically. Flagged results remain in pending review. Pass auto_commit=false or review_required=true to require review for every result.
Direct file upload
PDFs are accepted up to 20MB. DOCX and XLSX files are accepted up to 50MB and converted to text before extraction.
curl -X POST \
-H "Authorization: Bearer nc_..." \
-F "file=@brochure.pdf" \
https://www.realiq.uk/api/v1/extractUpload to storage, then extract
For batch workflows, upload each source straight to private storage and extract it by reference. The same 20MB PDF and 50MB DOCX/XLSX extraction limits apply. Three steps: get a signed URL, PUT the file to it, then call extract with the returned storage_path.
# 1. Get a signed upload URL
curl -X POST \
-H "Authorization: Bearer nc_..." \
-H "Content-Type: application/json" \
-d '{"filename": "big-brochure.pdf"}' \
https://www.realiq.uk/api/v1/uploads
# -> { "data": { "upload_url": "https://...", "storage_path": "<org>/api/..." } }
# 2. PUT the file straight to storage
curl -X PUT --data-binary @big-brochure.pdf \
-H "Content-Type: application/pdf" \
"<upload_url from step 1>"
# 3. Run extraction on the uploaded file
curl -X POST \
-H "Authorization: Bearer nc_..." \
-H "Content-Type: application/json" \
-d '{"storage_path": "<storage_path from step 1>"}' \
https://www.realiq.uk/api/v1/extractExtract supplied text
Send 50 to 200,000 characters when your own pipeline has already extracted the document body. RealiQ retains the submitted text as the source record.
curl -X POST \
-H "Authorization: Bearer nc_..." \
-H "Content-Type: application/json" \
-d '{"filename":"deal-email.eml","document_type":"brochure","text":"<full document text>"}' \
https://www.realiq.uk/api/v1/extractTo backfill a whole folder, see scripts/bulk-upload.py, which loops these three steps over every document.
Example Response
{
"data": {
"extraction_id": "f1a2b3c4-...",
"property": {
"name": "Phoenix House",
"address": "45 High Street, Birmingham B2 4LP",
"sector": "Office",
"asking_price": 3750000,
"niy": 7.2
},
"tenancies_count": 4,
"comparables_count": 2,
"validation": {
"score": 87,
"status": "passed"
},
"status": "completed",
"commit_outcome": {
"requested": true,
"performed": true,
"outcome": "saved",
"property_id": "a1b2c3d4-..."
}
}
}GET/api/v1/extractions
List your extractions. Defaults to status=pending_review (documents extracted but not yet committed to the portfolio). Cursor-paginated.
curl -H "Authorization: Bearer nc_..." \
"https://www.realiq.uk/api/v1/extractions?status=pending_review&limit=100"GET/api/v1/extractions/:id
Retrieve the complete structured result, validation record, commit state and source-file availability for one organisation-scoped extraction.
curl -H "Authorization: Bearer nc_..." \
"https://www.realiq.uk/api/v1/extractions/<extraction_id>"POST/api/v1/extractions/commit
Commit pending-review extractions to your portfolio (properties, tenancies and comparables) in bulk, for legacy or deliberately reviewed workflows. With no body it commits the next validation-passed batch of up to 50. Pass extraction_ids to commit specific reviewed results, including flagged ones. Runs without AI matching by default to keep it fast; pass match: true to score as you commit, or Run Matching in the app afterwards. Loop while meta.has_more is true. Requires write scope.
curl -X POST \
-H "Authorization: Bearer nc_..." \
-H "Content-Type: application/json" \
-d '{"match": false}' \
https://www.realiq.uk/api/v1/extractions/commit
# -> { "data": [ { "extraction_id": "...", "outcome": "saved", "property_id": "...", "comparables_inserted": 3 }, ... ],
# "meta": { "count": 50, "has_more": true } }