Create properties
POST /external/properties/ adds a property to a portfolio from your own systems, for example when a new asset is registered in your property register. You send the matrikkelnummer, and Telescope finds the plot, starts the analyses and fetches the buildings and energy certificates.
Before you start
- Creating must be enabled for your organization. Ask your Telescope contact to turn it on. Until then, requests return
403with the codeexternal_api_create_not_allowed. Reading works either way. - Norway only. Properties are found by their Norwegian matrikkelnummer.
- Portfolios come from the app. The API can't create portfolios. Create them in Telescope, then find their IDs with
GET /external/portfolios/.
Quick example
curl -X POST https://api.telescope.eco/external/properties/ \
-H "X-API-Key: $TELESCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"internal_reference_id": "P-1001",
"portfolio_id": "b2a4c7e0-1d2f-4f39-8e2a-5c6d7e8f9a01",
"name": "Storgata 1",
"address": "Storgata 1",
"postal_code": "0155",
"postal_area": "Oslo",
"country": "Norway",
"matrikkelnummer": "0301-208/101",
"value_estimate": 85000000
}'import requests
response = requests.post(
"https://api.telescope.eco/external/properties/",
headers={"X-API-Key": "your-secret"},
json={
"internal_reference_id": "P-1001",
"portfolio_id": "b2a4c7e0-1d2f-4f39-8e2a-5c6d7e8f9a01",
"name": "Storgata 1",
"address": "Storgata 1",
"postal_code": "0155",
"postal_area": "Oslo",
"country": "Norway",
"matrikkelnummer": "0301-208/101",
"value_estimate": 85_000_000,
},
timeout=60,
)
response.raise_for_status()
prop = response.json()
print(response.status_code, prop["id"]) # 201 when created, 200 when updated$body = @{
internal_reference_id = "P-1001"
portfolio_id = "b2a4c7e0-1d2f-4f39-8e2a-5c6d7e8f9a01"
name = "Storgata 1"
address = "Storgata 1"
postal_code = "0155"
postal_area = "Oslo"
country = "Norway"
matrikkelnummer = "0301-208/101"
value_estimate = 85000000
} | ConvertTo-Json
Invoke-RestMethod -Method Post `
-Uri "https://api.telescope.eco/external/properties/" `
-Headers @{ "X-API-Key" = $env:TELESCOPE_API_KEY } `
-ContentType "application/json" `
-Body $bodyThe response is the full property, in the same format as GET /external/properties/{id}/, with status 201 Created for a new property or 200 OK for an updated one.
Request fields
| Field | Required | Type | Description |
|---|---|---|---|
portfolio_id | Yes | UUID | The portfolio to add the property to. Must belong to your organization. Ignored when the property already exists, see below. |
country | Yes | text | Must be Norway. |
matrikkelnummer | Yes | text | The plot's Norwegian cadastral identifier, like 0301-208/101/0/0. Used to find the plot. See Matrikkelnummer. |
internal_reference_id | No, but recommended | text, max 255 | Your own ID for the property. If a property with this reference already exists, it is updated instead of creating a new one. |
name | No | text, max 255 | Display name in Telescope. Defaults to the address, or the matrikkelnummer without one. |
address | No | text, max 255 | Street address, like Storgata 1. Stored for display only; it is never used to find the plot. |
postal_code | No | text, max 255 | Postal code of the address. |
postal_area | No | text, max 255 | Postal area or city of the address. |
value_estimate | No | integer or null | Estimated value in NOK, from 0 to 999,999,999,999. |
Send JSON with Content-Type: application/json. Unknown fields are ignored.
Matrikkelnummer
The matrikkelnummer is how Telescope finds the property's plot, and with it the geometry that every analysis runs on. Write it as municipality-gnr/bnr/fnr/snr:
| Input | Stored as |
|---|---|
0301-208/101/0/0 | 0301-208/101/0/0 |
0301-208/101 | 0301-208/101/0/0 |
Shorter forms are accepted and always stored in full. If the value isn't a matrikkelnummer at all, such as an address, the request fails with invalid_matrikkelnummer. If it is valid but no plot is found, it fails with property_geometry_not_found.
Long numbers
Plots with a gårdsnummer or bruksnummer longer than four digits, or a festenummer longer than three, can't be looked up yet and return property_geometry_not_found.
What happens after you create a property
- Telescope validates the request and looks up the plot from the matrikkelnummer. This happens before anything is saved, so a failed lookup creates nothing.
- The property is saved and returned right away.
hazardsandbiodiversityare still empty, andbuildingsandenergy_certificatesusually are too. - In the background, Telescope runs the property's analyses and fetches its buildings and energy certificates.
- Fetch the property again later with
GET /external/properties/{id}/to read the results as they arrive.
Create or update
internal_reference_id makes the endpoint safe to call repeatedly:
| Situation | Result |
|---|---|
No internal_reference_id sent | A new property is always created. Retrying a failed request can create duplicates. |
| No property has this reference yet | A new property is created in portfolio_id. 201 Created. |
| One property has this reference | That property is updated in place. 200 OK. |
| Several properties share this reference | 400 with code ambiguous_internal_reference_id. Fix the duplicates in the app first. |
When a property is updated:
- It stays in its current portfolio.
portfolio_idis still required and validated, but the property isn't moved. Move it in the app. - Fields you leave out keep their current values. Fields you send replace them.
- Analyses rerun only if the plot changed, that is when the new matrikkelnummer leads to a different geometry.
- Buildings and energy certificates are fetched again only if the matrikkelnummer changed. The ones fetched for the old plot are removed, and ones added by hand in the app are kept. The new plot's buildings are only fetched if no buildings are left, and its energy certificates only if no certificates are left. So a building or certificate added by hand means the new ones of that kind aren't fetched.
Requests with the same reference are handled one at a time, so two systems sending the same property at once can't create two copies.
TIP
Always send internal_reference_id, using the ID from your source system. Then your integration can resend everything on every run without creating duplicates.
Bulk import from a CSV file
The endpoint creates one property per request. To import many, loop over your rows. Thanks to internal_reference_id, you can rerun the script after fixing failed rows.
import csv
import requests
session = requests.Session()
session.headers["X-API-Key"] = "your-secret"
PORTFOLIO_ID = "b2a4c7e0-1d2f-4f39-8e2a-5c6d7e8f9a01"
with open("properties.csv", newline="", encoding="utf-8") as file:
for row in csv.DictReader(file):
response = session.post(
"https://api.telescope.eco/external/properties/",
json={
"internal_reference_id": row["reference"],
"portfolio_id": PORTFOLIO_ID,
"address": row["address"],
"postal_code": row["postal_code"],
"postal_area": row["postal_area"],
"country": "Norway",
"matrikkelnummer": row["matrikkelnummer"],
},
timeout=60,
)
if response.ok:
print(f"{row['reference']}: {response.status_code}")
else:
print(f"{row['reference']}: failed, {response.json()}")Errors
Validation errors return 400 with an entry per field. For example, a matrikkelnummer without a plot:
{
"matrikkelnummer": {
"detail": "Couldn't find a plot for this matrikkelnummer.",
"code": "property_geometry_not_found"
}
}| Status | Field | Code | Meaning |
|---|---|---|---|
| 400 | matrikkelnummer | required, blank | The matrikkelnummer is missing or empty. |
| 400 | matrikkelnummer | invalid_matrikkelnummer | The value isn't a Norwegian matrikkelnummer. |
| 400 | matrikkelnummer | property_geometry_not_found | No plot was found for it. |
| 400 | country | invalid_choice | The country isn't Norway. |
| 400 | portfolio_id | does_not_exist | No portfolio with this ID in your organization. |
| 400 | internal_reference_id | ambiguous_internal_reference_id | Several properties share this reference. |
| 400 | value_estimate | min_value, max_value, invalid | The value is negative, too large or not a whole number. |
| 401 | authentication_failed | The API key is missing or invalid. | |
| 403 | external_api_create_not_allowed | Creating isn't enabled for your organization. |
See Errors for the general error format.

