Hitta Bolån API – Dokumentation
Detta API används för att beräkna och presentera bolåneerbjudanden, samt exponera marknadsräntor (list- och snitträntor) per bindningstid.
Dokumentet beskriver autentisering, endpoints, request/response-format samt centrala affärsregler (inklusive rule_deviation).
Översikt
Alla API-svar returneras som JSON. API:t är skyddat med API-nyckel via HTTP-header. Rekommenderad användning är att klienten hämtar marknadsräntor (rates-endpoints) separat från individuella beräkningar (calculate).
/api kräver giltig x-api-key.
Autentisering
Ange API-nyckeln i headern x-api-key. Om nyckeln saknas eller är felaktig returneras 401 Unauthorized.
/data/*.Exempel (curl)
curl -X GET "/data/rates/list" \ -H "x-api-key: DIN_API_KEY"
Vanliga statuskoder
| 200 | OK |
|---|---|
| 400 | Felaktig input (t.ex. calculate) |
| 401 | Unauthorized (saknad/fel API-key) |
| 500 | Internt fel |
Felhantering
API:t returnerar fel som JSON med error-fält (och ibland extra detaljer).
Klienten bör hantera 4xx som användar-/inputfel och 5xx som tillfälliga serverfel.
Felrespons (exempel)
{
"error": "Unauthorized"
}
Rekommenderad klientlogik
| 401 | Verifiera att x-api-key skickas korrekt. |
|---|---|
| 400 | Visa valideringsfel. (Ex: saknade fält eller ogiltiga värden.) |
| 500 | Visa generellt fel och tillåt “försök igen”. Logga request-id om tillgängligt. |
GET /data/form/questions...
Returnerar konfigurerade formulärfrågor (t.ex. rabatter) som används för att
bygga ett dynamiskt UI. Användarens val skickas vidare till
/data/calculate via fältet selected_discounts
(och i vissa fall som top-level fält som energy_class).
Endpointen returnerar endast aktiva frågor och filtrerar automatiskt bort frågor som är kopplade till banker du inte erbjuder. Du behöver inte själv filtrera baserat på bank.
Query-parametrar
| group | string (valfri) |
Filtrera på en specifik grupp, t.ex. discounts. |
|---|
Exempel (curl)
curl -X GET "/data/form/questions?group=discounts" \ -H "x-api-key: DIN_API_KEY"
Response
{
"questions": [
{
"id": 2,
"key": "IKEA_Family",
"label": "IKEA Family medlem?",
"tooltip": "Som IKEA Family medlem får du extra bolånerabatt hos Ikano Bank.",
"type": "checkbox",
"group": "discounts",
"options": null,
"dependsOn": null,
"bankIds": [],
"active": true,
"sortOrder": 2
},
{
"id": 3,
"key": "ICA_Stammis",
"label": "ICA Stammis medlem?",
"tooltip": "Som ICA Stammis kan du få extra bolånerabatt hos ICA Banken.",
"type": "checkbox",
"group": "discounts",
"options": null,
"dependsOn": null,
"bankIds": [],
"active": true,
"sortOrder": 3
},
{
"id": 4,
"key": "monthly_spend",
"label": "Hur mycket handlar du för på ICA varje månad?",
"tooltip": "Rabatten hos ICA Banken baseras på hur mycket du spenderar per månad som ICA Stammis.",
"type": "select",
"group": "discounts",
"options": [
{ "value": 0, "label": "0 kr" },
{ "value": 500, "label": "1 – 999 kr" },
{ "value": 1500, "label": "1 000 – 1 999 kr" },
{ "value": 3000, "label": "2 000 – 3 999 kr" },
{ "value": 5000, "label": "4 000 – 5 999 kr" },
{ "value": 7000, "label": "6 000 – 7 999 kr" },
{ "value": 8500, "label": "Mer än 8 000 kr" }
],
"dependsOn": { "key": "ICA_Stammis", "value": true },
"bankIds": [],
"active": true,
"sortOrder": 4
},
{
"id": 12,
"key": "TCO_Saco_HSB_SPP",
"label": "Välj ett alternativ (Saco/TCO, HSB Bospar, SPP)",
"tooltip": "Vissa organisationer och samarbeten kan ge dig extra bolånerabatt.",
"type": "select",
"group": "discounts",
"options": [
{ "value": "", "label": "Inget av alternativen gäller" },
{ "value": "TCO", "label": "Mitt fackförbund är anslutet till TCO" },
{ "value": "Saco", "label": "Mitt fackförbund är anslutet till Saco" },
{ "value": "HSB", "label": "Jag bosparar hos HSB" },
{ "value": "SPP", "label": "Jag är kund/anställd hos SPP" }
],
"dependsOn": null,
"bankIds": [],
"active": true,
"sortOrder": 12
},
{
"id": 13,
"key": "energy_class",
"label": "Bostadens energiklass",
"tooltip": "Du kan hitta energiklassinformation på Boverkets energideklaration söksida.",
"type": "select",
"group": "discounts",
"options": [
{ "value": "Vet ej", "label": "Vet ej" },
{ "value": "A", "label": "A" },
{ "value": "B", "label": "B" },
{ "value": "C", "label": "C" },
{ "value": "D", "label": "D" },
{ "value": "E", "label": "E" },
{ "value": "F", "label": "F" },
{ "value": "G", "label": "G" }
],
"dependsOn": null,
"bankIds": [],
"active": true,
"sortOrder": 13
}
]
}
| questions | array |
Lista med frågeobjekt, sorterade på sortOrder. |
|---|---|---|
| questions[].id | number |
Unikt id i databasen. |
| questions[].key | string |
Unik nyckel som identifierar rabatten. Används som key i payload till /data/calculate. |
| questions[].label | string |
Text som visas i UI. |
| questions[].tooltip | string | null |
Förklarande tooltip-text (valfri). |
| questions[].type | string |
checkbox, select, text eller number. |
| questions[].group | string |
UI-gruppering, t.ex. discounts. |
| questions[].options | array | null |
Alternativ för select. Varje alternativ är ett objekt
{ value, label }. value kan vara
string eller number.
|
| questions[].dependsOn | object | null |
Om satt: frågan ska bara renderas när villkoret är uppfyllt.
Format: { key, value } där key refererar till en annan frågas
key, och value är det svar som krävs för att frågan ska visas.
|
| questions[].bankIds | number[] |
Informativt. Lista över bank-id:n som frågan är relevant för. Tom array betyder att frågan är generell. Filtrering mot ditt konto sker redan server-side — du behöver inte agera på detta fält. |
| questions[].active | boolean |
Endpointen returnerar endast aktiva frågor, så detta är alltid true. |
| questions[].sortOrder | number |
Sorteringsordning. Frågorna kommer redan sorterade. |
| Rendering (rekommenderat) |
|
|---|---|
| Mappning till /data/calculate |
Användarens svar samlas i två format:
Inom selected_discounts finns tre mönster:
|
| Payload-exempel till /data/calculate |
{
"loan_amount": 3000000,
"property_value": 5000000,
"term": "ThreeMonth",
"property_type": "Villa",
"energy_class": "B",
"selected_discounts": [
{ "key": "IKEA_Family" },
{ "key": "ICA_Stammis", "value": 3000 },
{ "key": "Avanza_PB", "value": 15000000 },
{ "key": "TCO" }
]
}
|
| Viktigt |
Backend normaliserar payloaden internt. Du kan skicka strängar
eller {key, value}-objekt i selected_discounts;
rabatter som kräver ett belopp (t.ex. ICA spend, Avanza PB-kapital)
måste skickas som objekt med value.
|
Discount reference (selected_discounts)
selected_discounts används i POST /data/calculate för att
aktivera rabatter. Varje rabatt identifieras av ett stabilt key.
key-värden är stabila och kan användas
direkt mot /data/calculate även om klienten inte använder
/data/form/questions.
Format
{
"selected_discounts": [
{ "key": "IKEA_Family" },
{ "key": "TCO" },
{ "key": "ICA_Stammis", "value": 5000 }
]
}
Tillgängliga discounts
| key | Kräver value | Typ | Beskrivning |
|---|---|---|---|
IKEA_Family |
Nej | boolean | IKEA Family-medlemskap (Ikano Bank). |
TCO |
Nej | boolean | Fackförbund anslutet till TCO. |
Saco |
Nej | boolean | Fackförbund anslutet till Saco. |
HSB |
Nej | boolean | Bosparande eller medlemskap i HSB. |
SPP |
Nej | boolean | Kund eller anställd hos SPP. |
ICA_Stammis |
Ja | number | Månatlig handel hos ICA (kr/mån). |
Regler
- Skicka endast rabatter som användaren uppfyller.
- Boolean-rabatter skickas utan
value. - Rabatter med nivåer kräver
value. - Okända
key-värden ignoreras av backend.
Koppling till /data/form/questions
/data/form/questions returnerar samma key-värden
tillsammans med UI-metadata (label, tooltip, sortOrder).
Backend matchar alltid rabatter baserat på key – inte label.
POST /data/calculate
Beräknar fram räntan man kan få för en specifik förfrågan baserat på lånebeloppets storlek, belåningsgrad, bindningstid, övriga rabatter och bankregler. Responsen sorterar alltid lägsta ränta överst och banker med rule_deviation längst ner.
rule_deviation.Request
{
"loan_amount": 2700000,
"property_value": 4500000,
"property_type": "Bostadsratt",
"term": "ThreeMonth",
"current_rate": 0,
"selected_discounts": ["IKEA_Family"],
"energy_class": "Vet ej"
}
| loan_amount | number |
Ja | Lånebelopp i kronor. |
|---|---|---|---|
| property_value | number |
Ja | Bostadens uppskattade marknadsvärde. |
| property_type | string |
Ja | Bostadstyp. |
| term | string |
Ja | Bindningstid. |
| current_rate | number |
Villkor | Nuvarande bolåneränta" |
| selected_discounts | string[] |
Nej | Valda rabatter |
| energy_class | string |
Nej | Bostadens energiklass |
Exempel (curl)
curl -X POST "/data/calculate" \
-H "Content-Type: application/json" \
-H "x-api-key: DIN_API_KEY" \
-d '{
"loan_amount": 2700000,
"property_value": 4500000,
"property_type": "Bostadsratt",
"term": "ThreeMonth",
"current_rate": 0,
"selected_discounts": "selected_discounts": [
{ "key": "IKEA_Family" },
{ "key": "TCO" },
{ "key": "ICA_Stammis", "value": 5000 }
],
"energy_class": "Vet ej"
}'
Response (exempel)
{
"results": [
{
"bankId": 1,
"bankName": "Exempelbank",
"logo": "...",
"utm_link_move": "https://...",
"fixed_rate": 3.95,
"average_rate": 3.80,
"personal_rate": 3.65,
"total_discount": -0.30,
"effective_rate": 3.72,
"monthly_interest_cost": 8200,
"monthly_amortization": 4500,
"amortization_percentage": 1,
"total_monthly_cost_before_tax": 12700,
"monthly_tax_deduction": 2050,
"total_monthly_cost_after_tax_deduction": 10650,
"loan_amount": 2700000,
"property_value": 4500000,
"ltv": 60,
"down_payment": 1800000,
"current_rate": null,
"monthly_savings_before_tax": null,
"monthly_savings_after_tax": null,
"green_mortgage": false,
"rule_deviation": null,
"open_price_model": true,
"agreement": "..."
}
]
}
Fält (urval)
| personal_rate | Personlig ränta efter tillämpliga rabatter (om möjligt). number|null |
|---|---|
| average_rate | Bankens snittränta (kan vara fallback). number|null |
| fixed_rate | Bankens listränta / grundränta. number|null |
| rule_deviation | Meddelande-lista om banken inte kan ge korrekt erbjudande (visas utan räntedata). string[]|null |
| total_monthly_cost_before_tax | Total månadskostnad före skatteavdrag. number|null |
GET /data/rates/list
Returnerar listräntor (Fixed) per bank, grupperat per bindningstid (term). Banker sorteras med lägsta listränta först inom varje term.
Exempel (curl)
curl -X GET "/data/rates/list" \ -H "x-api-key: DIN_API_KEY"
Response
{
"terms": {
"ThreeMonth": [
{ "bankId": 2, "bankName": "Bank A", "logo": "https://api.hittabolan.se/public/logos/2.webp", "bank_link": "https://trk.hittabolan.se/XXXXX", "fixed_rate": 3.95 },
{ "bankId": 7, "bankName": "Bank B", "logo": "https://api.hittabolan.se/public/logos/7.webp", "bank_link": "https://trk.hittabolan.se/YYYYY", "fixed_rate": 4.05 }
],
"OneYear": [
{ "bankId": 7, "bankName": "Bank B", "logo": "https://api.hittabolan.se/public/logos/7.webp", "bank_link": "https://trk.hittabolan.se/YYYYY", "fixed_rate": 3.85 }
]
}
}
| terms | object |
Nyckel per term (bindningstid). |
|---|---|---|
| terms[].bankId | number |
Unikt bank-ID. |
| terms[].bankName | string |
Bankens namn. |
| terms[].logo | string |
URL till bankens logotyp. |
| terms[].bank_link | string |
Spårbar länk (affiliate) till bankens erbjudande. |
| terms[].fixed_rate | number |
Listränta (Fixed) i procent. Sorterad lägst först per term. |
GET /data/rates/average
Returnerar snittränta per term (aggregerat över banker som har giltig Average-ränta för termen). Detta är en marknadsindikator – ingen banklista i denna endpoint.
Average-rader.Exempel (curl)
curl -X GET "/data/rates/average" \ -H "x-api-key: DIN_API_KEY"
Response
{
"terms": {
"ThreeMonth": { "average_rate": 2.65, "banks": 13 },
"OneYear": { "average_rate": 2.80, "banks": 13 },
"FiveYear": { "average_rate": 2.20, "banks": 13 }
}
}
| terms | object |
Nyckel per term. |
|---|---|---|
| terms[].average_rate | number |
Snittränta (Average) i procent, avrundad till två decimaler. |
| terms[].banks | number |
Antal banker som ingår i snittet för termen. |
GET /data/rates/average
Returnerar snittränta (Average) per bank och term, grupperat per bindningstid. Banker sorteras med lägsta snittränta först inom varje term.
Exempel (curl)
curl -X GET "/data/rates/average" \ -H "x-api-key: DIN_API_KEY"
Response
{
"terms": {
"ThreeMonth": [
{ "bankId": 2, "bankName": "Bank A", "logo": "https://api.hittabolan.se/public/logos/2.webp", "bank_link": "https://trk.hittabolan.se/XXXXX", "average_rate": 2.35 },
{ "bankId": 8, "bankName": "Skandia", "logo": "https://api.hittabolan.se/public/logos/8.webp", "bank_link": "https://trk.hittabolan.se/XXXXX", "average_rate": 2.81 }
],
"OneYear": [
{ "bankId": 7, "bankName": "Bank B", "logo": "https://api.hittabolan.se/public/logos/7.webp", "bank_link": "https://trk.hittabolan.se/YYYYY", "average_rate": 2.75 }
]
}
}
| terms | object |
Nyckel per term (bindningstid). |
|---|---|---|
| terms[].bankId | number |
Unikt bank-ID. |
| terms[].bankName | string |
Bankens namn. |
| terms[].logo | string |
URL till bankens logotyp. |
| terms[].bank_link | string |
Spårbar länk (affiliate) till bankens erbjudande. |
| terms[].average_rate | number |
Bankens snittränta (Average) i procent. |
rule_deviation
rule_deviation används när en bank inte kan ge ett korrekt prissatt erbjudande för indata (t.ex. otillåten bostadstyp, belåningsgrad utanför regelverk, eller bank kräver manuell kontakt).
När rule_deviation finns ska klienten visa meddelandet och inte visa räntedata för banken.
rule_deviation är en array med minst ett element, visa endast första meddelandet som och dölja räntor/kostnader.
Sortering
Calculate-resultat sorteras av API:t:
banker utan rule_deviation först, sedan lägsta ränta (personal → average → fixed).
Banker med rule_deviation returneras sist.
Rates-endpoints: inom varje term sorteras banklistor stigande på respektive ränta (lägst först).
Affärsregler (urval)
Nedan regler påverkar datat:
| Fritidshus | Vissa banker kan exkludera Fritidshus via regler och då sätts rule_deviation i calculate. |
|---|---|
| Rabatter | Rabatter drivs via selected_discounts, energy_class (green mortgage). |
| Amortering | Baseras på belåningsgrad (LTV): >70% = 2%, >50% = 1%, annars 0% (i beräkningslogik). |