Anessa was previously called Insurely. You may still see the Insurely name in parts of our documentation while we complete the transition.

API quick start

Start a collection for a demo user, follow its status and fetch the data. Everything runs against se-demo, a demo company that completes a collection without a real BankID login, using the Swedish wealth API 2026-04-01.

Before you start

  • An API key, sent in the Authorization-token header. See Authentication for how to get one.
  • Your server's IP address registered with us. Calls from other addresses get 401 Authentication failed.
  • se-demo enabled for your client. Check that step 1 lists it.

Every request sends Insurely-Version: 2026-04-01. Without it, the API answers with your client's minimum version, which has different endpoints. Set two variables first:

export INSURELY_API_URL=https://api.insurely.com   # test: https://api.test.insurely.com
export INSURELY_API_KEY=<your API key>

Check that the company is available

GET /companies/availability lists the companies your client can collect from, with their login methods and current status.

curl "$INSURELY_API_URL/companies/availability" \
  -H "Authorization-token: $INSURELY_API_KEY" \
  -H "Insurely-Version: 2026-04-01"

Look for the entry with "company": "se-demo" and "status": "OK".

Start a collection

POST /collections starts a collection. The personal number 196603233724 makes se-demo return an ISK, a custody account and an endowment insurance (KF). The demo companies page lists numbers for other outcomes.

curl -X POST "$INSURELY_API_URL/collections" \
  -H "Authorization-token: $INSURELY_API_KEY" \
  -H "Insurely-Version: 2026-04-01" \
  -H "Content-Type: application/json" \
  -d '{
    "company": "se-demo",
    "loginMethod": "SWEDISH_MOBILE_BANKID_OTHER_DEVICE",
    "parameters": [
      { "type": "SWEDISH_BANKID", "personalNumber": "196603233724" }
    ]
  }'
Response 201
{
  "id": "22e633bc-427d-4f4a-87cf-cfaca04ef351",
  "company": "se-demo",
  "status": "RUNNING",
  "pollingTimeout": "2026-10-21T12:59:10.545Z",
  "extraInformation": null
}

Keep the id. You use it in the next two steps.

Follow the status

Poll GET /collections/{collectionId}/status every pollingInterval milliseconds, and always before pollingTimeout, or the collection is stopped.

curl "$INSURELY_API_URL/collections/$COLLECTION_ID/status" \
  -H "Authorization-token: $INSURELY_API_KEY" \
  -H "Insurely-Version: 2026-04-01"
Response 200
{
  "id": "22e633bc-427d-4f4a-87cf-cfaca04ef351",
  "company": "se-demo",
  "status": "COMPLETED",
  "pollingInterval": 1000,
  "pollingTimeout": "2026-10-21T12:59:40.545Z",
  "extraInformation": {}
}

Stop polling when the status is COMPLETED, COMPLETED_PARTIAL or COMPLETED_EMPTY, or when it fails. With a real company the user signs in first: during WAITING_FOR_USER_ACTION, show the BankID QR code from extraInformation.SWEDISH_MOBILE_BANKID_ANIMATED_QR_DATA. The status table says what to do for each status.

Fetch the data

GET /collections/{collectionId}/wealth/data returns the collected products as a list. Each item has a type (ISK, CUSTODY_ACCOUNT, KF, OCCUPATIONAL_PENSION and so on) that tells you which fields it carries.

curl "$INSURELY_API_URL/collections/$COLLECTION_ID/wealth/data" \
  -H "Authorization-token: $INSURELY_API_KEY" \
  -H "Insurely-Version: 2026-04-01"
Example response 200 (one item shown)
[
  {
    "id": "df2e7a28-d871-45c1-a01e-515b7aeaf7da",
    "type": "ISK",
    "company": "se-demo",
    "productName": "Min ISK",
    "financialInformation": {
      "currentValue": { "amount": 26982.66, "currency": "SEK" },
      "performanceSinceStart": 0.1605
    },
    "holdings": [
      {
        "type": "FUND",
        "name": "Avanza Zero",
        "isin": "SE0001718388",
        "value": { "amount": 22468.39, "currency": "SEK" }
      }
    ]
  }
]

All steps in one script

Node 18 or later, no dependencies.

quick-start.mjs
const BASE = process.env.INSURELY_API_URL ?? 'https://api.insurely.com';
const headers = {
  'Authorization-token': process.env.INSURELY_API_KEY,
  'Insurely-Version': '2026-04-01',
  'Content-Type': 'application/json',
};
const DONE = ['COMPLETED', 'COMPLETED_PARTIAL', 'COMPLETED_EMPTY'];
const IN_PROGRESS = ['RUNNING', 'LOGIN', 'CUSTOMER_ENROLLMENT_CHECK', 'COLLECTING', 'WAITING_FOR_USER_ACTION'];

async function call(path, init = {}) {
  const res = await fetch(BASE + path, { headers, ...init });
  if (!res.ok) throw new Error(`${init.method ?? 'GET'} ${path}: ${res.status} ${await res.text()}`);
  return res.json();
}

const collection = await call('/collections', {
  method: 'POST',
  body: JSON.stringify({
    company: 'se-demo',
    loginMethod: 'SWEDISH_MOBILE_BANKID_OTHER_DEVICE',
    parameters: [{ type: 'SWEDISH_BANKID', personalNumber: '196603233724' }],
  }),
});

let status = collection;
while (IN_PROGRESS.includes(status.status)) {
  await new Promise((r) => setTimeout(r, status.pollingInterval ?? 1000));
  status = await call(`/collections/${collection.id}/status`);
  console.log(status.status);
}

if (!DONE.includes(status.status)) throw new Error(`Collection ended as ${status.status}`);
const products = await call(`/collections/${collection.id}/wealth/data`);
console.log(products.map((p) => `${p.type}: ${p.productName}`));

Python 3.9 or later with requests.

quick_start.py
import os, time, requests

BASE = os.environ.get("INSURELY_API_URL", "https://api.insurely.com")
HEADERS = {
    "Authorization-token": os.environ["INSURELY_API_KEY"],
    "Insurely-Version": "2026-04-01",
}
DONE = {"COMPLETED", "COMPLETED_PARTIAL", "COMPLETED_EMPTY"}
IN_PROGRESS = {"RUNNING", "LOGIN", "CUSTOMER_ENROLLMENT_CHECK", "COLLECTING", "WAITING_FOR_USER_ACTION"}

def call(method, path, **kwargs):
    res = requests.request(method, BASE + path, headers=HEADERS, timeout=30, **kwargs)
    res.raise_for_status()
    return res.json()

collection = call("POST", "/collections", json={
    "company": "se-demo",
    "loginMethod": "SWEDISH_MOBILE_BANKID_OTHER_DEVICE",
    "parameters": [{"type": "SWEDISH_BANKID", "personalNumber": "196603233724"}],
})

status = collection
while status["status"] in IN_PROGRESS:
    time.sleep(status.get("pollingInterval", 1000) / 1000)
    status = call("GET", f"/collections/{collection['id']}/status")
    print(status["status"])

if status["status"] not in DONE:
    raise SystemExit(f"Collection ended as {status['status']}")
products = call("GET", f"/collections/{collection['id']}/wealth/data")
print([f"{p['type']}: {p.get('productName')}" for p in products])

Next steps

Last updated on