Hoppa till huvudinnehåll

Försäkringskassan

List, read and update a company's Fritidskortet data. The /fk endpoints expose the whole company register (minimal data), plus a single company's enrollment status (fk_status), its basic organization data (name, address, contact info), and every grant that is activated on the company.

There are three endpoints:

MethodPathPurpose
GET/api/v3/company/fkList the entire register — minimal data (name, org_number, parent) for every company
GET/api/v3/company/{company_id}/fkFetch name, address, contact info, fk_status and activated grants for one company
PUT/api/v3/company/{company_id}/fkUpdate fk_status — and only fk_status

Related endpoints (not covered in detail here):

  • GET /api/v3/company/fk/status/{company_id} — check the company's utförarstatus against the external Fritidskortet system.
  • GET/POST/DELETE /api/v3/grant/... — manage grant types and grant activations (what populates company_grants below).

OpenAPI specification

A machine-readable OpenAPI 3.0 spec for these endpoints is available at company-fk.yaml. Import it into Swagger UI, Postman or a client generator.


Authentication

Both endpoints require an OAuth 2.0 access token. Obtain one with your client_id and client_secret using HTTP Basic auth:

curl -X POST https://<instance>.memlist.se/api/v3/access/user/basic \
-H "Authorization: Basic $(echo -n 'your-client-id:your-client-secret' | base64)"

The response contains an access_token. Send it on every request:

Authorization: Bearer <access_token>

See Authentication for the full flow, including token refresh, rate limits and error handling.

Permissions

The access token carries the permissions of its credentials' access group:

  • GET requires an access group that includes the company module.
  • PUT additionally requires the COMPANY.U (company update) permission. Without it the call returns 403.

GET /api/v3/company/fk

Lists every company in the register as a minimal record. This returns the whole register in a single response — there is no pagination and no filtering.

Use it to enumerate all organizations (for example to sync the register to an external system). When you need the full Fritidskortet detail for one company — fk_status, contact info, activated grants — use the single-company endpoint below.

Parameters

None. The endpoint takes no path or query parameters.

Response — 200 OK

An array with one entry per non-deleted company. Each entry carries only the company's name and organization number, plus its parent company (null for a top-level organization):

[
{
"name": "IFK Exempelstad",
"org_number": "802481-1234",
"parent": {
"org_number": "802000-0001",
"name": "Exempelförbundet"
}
},
{
"name": "Exempelförbundet",
"org_number": "802000-0001",
"parent": null
}
]

Field notes:

  • parent — the company's parent organization in the hierarchy, or null for a top-level company.
  • Deleted companies are excluded.
  • The response is intentionally minimal: it carries no company_id, fk_status, contact details or grants. Fetch a single company's /fk view for that data.

Example

curl -s "https://<instance>.memlist.se/api/v3/company/fk" \
-H "Authorization: Bearer $TOKEN" | jq

Errors

StatusBodyWhen
401Missing or expired token
500Unexpected server error

GET /api/v3/company/{company_id}/fk

Returns the Fritidskortet-relevant view of a single company.

Parameters

ParameterInTypeRequiredDescription
company_idpathstringYesThe company's id (a 36-char string id, not the numeric uuid-less legacy id)

Response — 200 OK

{
"company_id": "5cf693b1-8a20-4bd4-b3b0-5d2f45f2b6a1",
"uuid": "9c1b2f4e-77aa-4f0c-9a41-2f8d0c3e5b21",
"name": "IFK Exempelstad",
"shortname": "IFK EX",
"org_number": "802481-1234",
"fk_status": "ACTIVE",
"street": "Föreningsgatan 12",
"co": null,
"zipcode": "41255",
"post": "Göteborg",
"country": "Sverige",
"email": "kansli@ifkexempelstad.se",
"phone": "031-123456",
"landline": null,
"web": "https://ifkexempelstad.se",
"c_name": "Anna Andersson",
"c_email": "anna@ifkexempelstad.se",
"c_phone": "0701-234567",
"company_grants": [
{
"id": 3,
"created_at": "2026-08-14T13:02:11",
"grant": {
"id": 1,
"uuid": "d5a8e9c2-1b3f-4a6d-8e2c-9f1b0a7c4d3e",
"name": "Projektbidrag",
"descr": "Bidrag för tidsbegränsade projekt"
}
},
{
"id": 8,
"created_at": "2026-08-14T13:05:40",
"grant": {
"id": 2,
"uuid": "f2c1d0b9-8a7e-4c5d-b3a2-1e0f9d8c7b6a",
"name": "Verksamhetsbidrag",
"descr": "Löpande bidrag för ordinarie verksamhet"
}
}
]
}

Field notes:

  • c_name / c_email / c_phone — the company's contact person; email / phone are the organization's general contact details.
  • company_grants — one entry per grant activated on the company. An empty array means no grants are activated.
  • Fields that are unset in the database are returned as null (see co and landline above).

Errors

StatusBodyWhen
400{ "reason": "company_id: ...", "code": "validation_error", ... }Malformed path parameter
401Missing or expired token
404{ "reason": "company not found" }No company with that id, or the company is deleted
500Unexpected server error

PUT /api/v3/company/{company_id}/fk

Updates the company's Fritidskortet enrollment status. This endpoint updates only fk_status. Any other field present in the request body is ignored — it is not possible to change the company's name, address or anything else here.

Parameters

ParameterInTypeRequiredDescription
company_idpathstringYesThe company's id
fk_statusbodystringYesOne of the values below

fk_status values

The enum describes how far along the company is in the Fritidskortet enrollment flow:

ValueMeaning
NONENot enrolled (the default for every company)
ML_ADDEDAdded as an utförare on the Memlist side
FK_ADDEDRegistered in the external Fritidskortet system
ACTIVEEnrollment complete — the company is an active utförare
REJECTEDThe enrollment was rejected

Request

PUT /api/v3/company/5cf693b1-8a20-4bd4-b3b0-5d2f45f2b6a1/fk
Content-Type: application/json
Authorization: Bearer <token>

{ "fk_status": "ACTIVE" }

Response — 200 OK

{
"company_id": "5cf693b1-8a20-4bd4-b3b0-5d2f45f2b6a1",
"fk_status": "ACTIVE"
}

Errors

StatusBodyWhen
400see belowfk_status missing or not a valid enum value
401Missing or expired token
403The user's access group lacks the COMPANY.U permission
404{ "reason": "company not found" }No company with that id, or the company is deleted
500Unexpected server error

Validation failures (400) return a structured payload — errors maps each failing field to its messages so clients can render inline errors:

{
"reason": "fk_status: Invalid enum value. Expected 'NONE' | 'ML_ADDED' | 'FK_ADDED' | 'ACTIVE' | 'REJECTED', received 'ACTIV'",
"code": "validation_error",
"errors": {
"fk_status": [
"Invalid enum value. Expected 'NONE' | 'ML_ADDED' | 'FK_ADDED' | 'ACTIVE' | 'REJECTED', received 'ACTIV'"
]
},
"form_errors": []
}

Quick reference: curl

HOST="https://<instance>.memlist.se"

# Authenticate (client_id:client_secret via HTTP Basic)
TOKEN=$(curl -s -X POST "$HOST/api/v3/access/user/basic" \
-H "Authorization: Basic $(echo -n 'your-client-id:your-client-secret' | base64)" \
| jq -r '.access_token')

# Get FK data for a company
curl -s "$HOST/api/v3/company/5cf693b1-8a20-4bd4-b3b0-5d2f45f2b6a1/fk" \
-H "Authorization: Bearer $TOKEN" | jq

# Set fk_status
curl -s -X PUT "$HOST/api/v3/company/5cf693b1-8a20-4bd4-b3b0-5d2f45f2b6a1/fk" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"fk_status":"ACTIVE"}' | jq

Working examples

Node 18+, no dependencies.

const HOST = 'https://<instance>.memlist.se';
const CLIENT_ID = process.env.MEMLIST_CLIENT_ID;
const CLIENT_SECRET = process.env.MEMLIST_CLIENT_SECRET;

async function login() {
const credentials = Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64');
const res = await fetch(`${HOST}/api/v3/access/user/basic`, {
method: 'POST',
headers: { Authorization: `Basic ${credentials}` }
});

if (!res.ok) {
throw new Error(`login failed: ${res.status}`);
}

const data = await res.json();
return data.access_token;
}

async function get_company_fk(token, company_id) {
const res = await fetch(`${HOST}/api/v3/company/${company_id}/fk`, {
headers: { Authorization: `Bearer ${token}` }
});

if (res.status === 404) {
return null; // company not found (or deleted)
}

if (!res.ok) {
throw new Error(`get fk failed: ${res.status} ${await res.text()}`);
}

return res.json();
}

async function set_fk_status(token, company_id, fk_status) {
const res = await fetch(`${HOST}/api/v3/company/${company_id}/fk`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ fk_status })
});

if (res.status === 400) {
const err = await res.json();
throw new Error(`invalid fk_status: ${err.reason}`);
}

if (!res.ok) {
throw new Error(`put fk failed: ${res.status} ${await res.text()}`);
}

return res.json(); // { company_id, fk_status }
}

async function main() {
const company_id = '5cf693b1-8a20-4bd4-b3b0-5d2f45f2b6a1';
const token = await login();

const company = await get_company_fk(token, company_id);

if (!company) {
console.log('company not found');
return;
}

console.log(`${company.name} (${company.org_number})`);
console.log(`fk_status: ${company.fk_status}`);
console.log(`contact: ${company.c_name} <${company.c_email}>`);
console.log('activated grants:');
for (const row of company.company_grants) {
console.log(` - ${row.grant.name} (since ${row.created_at})`);
}

// Promote the company to ACTIVE
const updated = await set_fk_status(token, company_id, 'ACTIVE');
console.log(`updated fk_status -> ${updated.fk_status}`);
}

main().catch(err => {
console.error(err);
process.exit(1);
});

Run with:

MEMLIST_CLIENT_ID=your-client-id MEMLIST_CLIENT_SECRET=your-client-secret node fk_example.js