Skip to content

Code examples

Fredrik Dettner edited this page Oct 5, 2026 · 3 revisions

Code examples (curl / Python / C#)

curl for every endpoint, plus Python and C# starter snippets. All examples hit https://api.sedis.se/v2 and send the key in X-Api-Key. Set SEDIS_API_KEY in your environment first.

curl — Bolagsanalys

# Companies (paged)
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/bolagsanalys/companies?pageSize=5"

# Companies filtered
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/bolagsanalys/companies?companyId=SE12345"

# Parameters (English default; add &lang=sv for Swedish)
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/bolagsanalys/parameters?nameContains=return"

# Data — figures for a company + parameter over a quarter range
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/bolagsanalys/data?companyId=SE12345&parameterCode=NX71&fromDate=2024Q1&toDate=2026Q4"

# Data — a single quarter (accepts 20251 or 2025Q1)
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/bolagsanalys/data?companyId=SE12345&quarterId=20251"

curl — Fastighetsbenchmark

# Your property units (tenant-scoped) — page + filter
# (propertyType is the property-type id (int); the response carries propertyType: { id, name })
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/fastighetsbenchmark/property-units?propertyType=1&pageSize=100"

# Opt into GeoJSON geometry
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/fastighetsbenchmark/property-units?sedisId=PU-1&fields=sedisId,name,geometry"

# Bounding-box filter (auto-densified)
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/fastighetsbenchmark/property-units?bbox=17.8,59.2,18.2,59.4"

# Point + radius
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/fastighetsbenchmark/property-units?nearLon=18.07&nearLat=59.33&radiusM=2000"

# Your collections + comparison zones + curated reference data
curl -H "X-Api-Key: $SEDIS_API_KEY" "https://api.sedis.se/v2/fastighetsbenchmark/samlingar"
curl -H "X-Api-Key: $SEDIS_API_KEY" "https://api.sedis.se/v2/fastighetsbenchmark/jamforelseobjekt?nameContains=Stockholm"
curl -H "X-Api-Key: $SEDIS_API_KEY" "https://api.sedis.se/v2/fastighetsbenchmark/reference-zones"
curl -H "X-Api-Key: $SEDIS_API_KEY" "https://api.sedis.se/v2/fastighetsbenchmark/parameters?nameContains=return"

# Bidirectional clone lineage (opt-in, tenant-filtered)
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/fastighetsbenchmark/property-units/PU-1?fields=sedisId,name,belongsToJamforelseobjekt"
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/fastighetsbenchmark/jamforelseobjekt/JO-A?fields=sedisId,name,containsPropertyUnits"

# Time-series (two-call pattern; multi-value ?sedisIdIn=; bulk-sync count opt-out)
curl -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/fastighetsbenchmark/comp-data?sedisIdIn=PU-1,PU-2&parameterCode=NX71&fromDate=2016-01-01&toDate=2026-12-31&count=false"

# POST search (large geometry)
curl -X POST -H "X-Api-Key: $SEDIS_API_KEY" -H "Content-Type: application/json" \
  "https://api.sedis.se/v2/fastighetsbenchmark/property-units/search" \
  -d '{ "geometry": {"type":"Polygon","coordinates":[[[17.8,59.2],[18.2,59.2],[18.2,59.4],[17.8,59.4],[17.8,59.2]]]}, "propertyType":1 }'

# Create a Samling (Idempotency-Key required)
curl -X POST -H "X-Api-Key: $SEDIS_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  "https://api.sedis.se/v2/fastighetsbenchmark/samlingar" \
  -d '{ "name": "My Stockholm offices", "containingCompSedisIds": ["PU-1","PU-2"] }'

# Update a Samling — full replace of name + members (re-triggers the recalc cascade).
# PUT is idempotent; no Idempotency-Key header required.
curl -X PUT -H "X-Api-Key: $SEDIS_API_KEY" -H "Content-Type: application/json" \
  "https://api.sedis.se/v2/fastighetsbenchmark/samlingar/SAM-abc123" \
  -d '{ "name": "My Stockholm offices (2026)", "containingCompSedisIds": ["PU-1","PU-3"] }'

# Delete a Samling — cascades its data cleanup. → 204 No Content. Not yours → 404.
curl -X DELETE -H "X-Api-Key: $SEDIS_API_KEY" \
  "https://api.sedis.se/v2/fastighetsbenchmark/samlingar/SAM-abc123"

# Create a property unit (once) — keep the sedisId from the 201
curl -X POST -H "X-Api-Key: $SEDIS_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  "https://api.sedis.se/v2/fastighetsbenchmark/property-units" \
  -d '{ "name": "Kontoret Gladan 4", "geometry": { "type": "Point", "coordinates": [18.0645, 59.3326] } }'

# Upload its values for a value date and submit them to Sedis — see Writing data
curl -X POST -H "X-Api-Key: $SEDIS_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  "https://api.sedis.se/v2/fastighetsbenchmark/comp-uploads" \
  -d '{ "valueDate": "2025-12-31", "submit": true,
        "rows": [ { "name": "Kontoret Gladan 4", "values": { "FN0": 98000000, "EA0": 1, "EB0": 2 } } ] }'

Python

import os, uuid, requests

BASE = "https://api.sedis.se/v2"
session = requests.Session()
session.headers["X-Api-Key"] = os.environ["SEDIS_API_KEY"]

def get(path, **params):
    r = session.get(f"{BASE}{path}", params=params)
    r.raise_for_status()
    return r.json()

# Page through every company
def all_companies(page_size=200):
    page = 1
    while True:
        body = get("/bolagsanalys/companies", pageSize=page_size, page=page)
        yield from body["data"]
        if page >= (body["totalPages"] or 0):
            break
        page += 1

# The worked example: office units in a zone, with a time-series
zone = get("/fastighetsbenchmark/jamforelseobjekt", nameContains="Stockholm")["data"][0]
# propertyType is the property-type id (int); the response carries propertyType: { id, name }
units = get("/fastighetsbenchmark/property-units",
            belongsToJamforelseobjektSedisId=zone["sedisId"], propertyType=1)["data"]
code = get("/fastighetsbenchmark/parameters", nameContains="Total return")["data"][0]["code"]
ids = ",".join(u["sedisId"] for u in units)
series = get("/fastighetsbenchmark/comp-data",
             sedisIdIn=ids, parameterCode=code,
             fromDate="2016-01-01", toDate="2026-12-31", count="false")["data"]

# Create a Samling (idempotent retry-safe)
def create_samling(name, comp_ids, idem_key=None):
    r = session.post(f"{BASE}/fastighetsbenchmark/samlingar",
                     headers={"Idempotency-Key": idem_key or str(uuid.uuid4())},
                     json={"name": name, "containingCompSedisIds": comp_ids})
    r.raise_for_status()
    return r.json()

# Update a Samling — full replace of name + members; re-triggers the recalc cascade.
# PUT/DELETE are idempotent — no Idempotency-Key header needed.
def update_samling(sedis_id, name, comp_ids):
    r = session.put(f"{BASE}/fastighetsbenchmark/samlingar/{sedis_id}",
                    json={"name": name, "containingCompSedisIds": comp_ids})
    r.raise_for_status()  # 404 if the Samling is not yours
    return r.json()

# Delete a Samling — cascades its data cleanup (the member units are not deleted).
def delete_samling(sedis_id):
    r = session.delete(f"{BASE}/fastighetsbenchmark/samlingar/{sedis_id}")
    r.raise_for_status()  # 204 on success; 404 if not yours

C#

using System.Net;
using System.Net.Http.Json;

// AutomaticDecompression makes HttpClient ask for compressed responses (see Query conventions).
var http = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.All })
{
    BaseAddress = new Uri("https://api.sedis.se/v2/")
};
http.DefaultRequestHeaders.Add("X-Api-Key", Environment.GetEnvironmentVariable("SEDIS_API_KEY"));

// A response envelope is generic over the item type
record Envelope<T>(T[] Data, int Page, int PageSize, int? TotalCount, int? TotalPages);
record Company(string CompanyId, string Name, string CountryCode);

// GET a page of companies
var companies = await http.GetFromJsonAsync<Envelope<Company>>(
    "bolagsanalys/companies?pageSize=5&companyId=SE12345");
foreach (var c in companies!.Data)
    Console.WriteLine($"{c.CompanyId}  {c.Name}");

// Time-series for the worked example. Each row is self-describing via DataType
// ("decimal" | "boolean" | "enum" | "date"); read the member that matches.
record CompEnumValue(int Value, string Name, string EnumType);
record CompDatum(string SedisId, string ParameterCode, string ValueDate,
                 string DataType, decimal? Figure, bool? Boolean, CompEnumValue? Enum, string? Date);
var series = await http.GetFromJsonAsync<Envelope<CompDatum>>(
    "fastighetsbenchmark/comp-data?sedisIdIn=PU-1,PU-2&parameterCode=NX71" +
    "&fromDate=2016-01-01&toDate=2026-12-31&count=false");
foreach (var d in series!.Data)
    Console.WriteLine(d.DataType switch
    {
        "boolean" => $"{d.ValueDate}: {d.Boolean}",
        "enum"    => $"{d.ValueDate}: {d.Enum!.Name} ({d.Enum.EnumType})",
        "date"    => $"{d.ValueDate}: {d.Date}",
        _         => $"{d.ValueDate}: {d.Figure}"
    });

// Create a Samling with a mandatory, retry-safe Idempotency-Key
using var req = new HttpRequestMessage(HttpMethod.Post, "fastighetsbenchmark/samlingar")
{
    Content = JsonContent.Create(new { name = "My Stockholm offices", containingCompSedisIds = new[] { "PU-1", "PU-2" } })
};
req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
var created = await http.SendAsync(req);
created.EnsureSuccessStatusCode();

// Update a Samling — full replace of name + members; re-triggers the recalc cascade.
// PUT/DELETE are idempotent, so no Idempotency-Key header is required.
var updated = await http.PutAsJsonAsync(
    "fastighetsbenchmark/samlingar/SAM-abc123",
    new { name = "My Stockholm offices (2026)", containingCompSedisIds = new[] { "PU-1", "PU-3" } });
updated.EnsureSuccessStatusCode(); // 404 if the Samling is not yours

// Delete a Samling — cascades its data cleanup. 204 on success; 404 if not yours.
var deleted = await http.DeleteAsync("fastighetsbenchmark/samlingar/SAM-abc123");
deleted.EnsureSuccessStatusCode();

Note: The C# JSON casing maps automatically: v2 sends camelCase (companyId), System.Text.Json with the web defaults binds it to PascalCase records.

Clone this wiki locally