Persondata — Search by ID and name+address
Look up a person via SPAR by personnummer or by name and address.
Persondata wraps SPAR (Statens personadressregister), the Swedish state population register. Two lookup modes are exposed, each in XML and JSON variants.
Production uses your own SPAR certificate
Persondata is live in sandbox and production. In sandbox the lookups run against Skatteverket's SPAR test environment with a test certificate you add by clicking Aktivera SPAR i sandbox in the dashboard (Tjänster → Personadress). In production every organisation uses its own SPAR agreement with Skatteverket: upload the certificate together with Skatteverket's three numbers (kundnummer leveransmottagare, kundnummer slutkund and uppdragsnummer) in the dashboard under Certifikat → SPAR. No agreement yet? You can buy Cerrtify's help applying for one when you choose your plan. Until the certificate is uploaded, production requests answer 403 spar_not_configured. A production request must also carry slutAnvandarId, your identifier for the end user the lookup is made for.
Search by personnummer
curl -X POST https://sandbox-api.cerrtify.com/service/persondata/search/id.json \
-H "X-API-Key: cert_..." \
-H "Content-Type: application/json" \
-d '{
"idNummer": "195704133106",
"slutAnvandarId": "agent-42"
}'idNummer is a 12-digit personnummer or samordningsnummer (YYYYMMDDNNNN; a hyphen before the last four digits is accepted). The format is checked before the search is sent to SPAR: anything but 12 digits is answered with 400 and the error code invalid_idnummer. The number in the example is a test person in SPAR's test environment. slutAnvandarId is your internal end-user identifier — SPAR requires it for audit trails.
Search by name + address
When you don't have a personnummer:
curl -X POST https://sandbox-api.cerrtify.com/service/persondata/search/name-address.json \
-H "X-API-Key: cert_..." \
-H "Content-Type: application/json" \
-d '{
"fornamn": "Anna",
"mellanEfternamn": "Andersson",
"utdelningsadress": "Storgatan 1",
"postort": "Stockholm",
"postnr": "11122",
"slutAnvandarId": "agent-42"
}'Choose parts of the answer
The JSON variants take the field delar: a list of numbers that says which parts of each person post you want back. Ask only for what you need.
curl -X POST https://sandbox-api.cerrtify.com/service/persondata/search/id.json \
-H "X-API-Key: cert_..." \
-H "Content-Type: application/json" \
-d '{
"idNummer": "195704133106",
"slutAnvandarId": "agent-42",
"delar": [1, 4]
}'| No. | Part | Contents |
|---|---|---|
0 | All | Everything SPAR sends |
1 | Namn | First names, the name in use, middle name, last name, mailing name |
2 | Persondetaljer, Utvandrad | Date of birth, sex, county and parish of birth, citizenship, deregistration and date of death, references to other numbers, samordningsnummer details, emigration |
3 | Folkbokforing | County, municipality, district, residence status, registration date |
4 | Folkbokforingsadress | c/o, address lines 1 and 2, postcode, town |
5 | SarskildPostadress | Special postal address, Swedish or international |
6 | Utlandsadress | Address abroad |
7 | Kontaktadress | Contact address, Swedish or international |
8 | Relation | Guardians and spouse or registered partner |
9 | Fastighet | Property designation, share and tax value |
10 | SummeradInkomst, InkomstAr | Summed income and income year |
- Without
delarthe answer holds parts 1–4. PersonId,Sekretessmarkering,SkyddadFolkbokforingandSenasteAndringSPARare always included.- What SPAR releases at all depends on what Skatteverket has approved for your organisation. A part you are not entitled to is missing from the answer even if you ask for it.
- An unknown number is answered with
400and the error codeinvalid_delar. The XML variants always pass on SPAR's whole answer and do not takedelar.
The answer to the example above:
{
"Posts": [
{
"PersonId": { "IdNummer": "195704133106", "Typ": "PERSONNUMMER" },
"Sekretessmarkering": "NEJ",
"SkyddadFolkbokforing": "NEJ",
"SenasteAndringSPAR": "2021-09-25",
"Namn": [
{
"DatumFrom": "2021-09-25",
"DatumTill": "9999-12-31",
"Aviseringsnamn": "Efternamn3542, Christina Birgitta",
"Fornamn": "Christina Birgitta Ulrika",
"Tilltalsnamn": "20",
"Mellannamn": "Thomeaus",
"Efternamn": "Efternamn3542"
}
],
"Folkbokforingsadress": [
{
"SvenskAdress": {
"DatumFrom": "2021-09-25",
"DatumTill": "9999-12-31",
"Utdelningsadress2": "Gatan142 8",
"PostNr": "11146",
"Postort": "STOCKHOLM"
}
}
]
}
],
"UUID": "27462246-5b1a-4379-8faf-09aba4cba964"
}A part that SPAR repeats is a list. The entry valid now comes first and has DatumTill 9999-12-31; older entries follow. Empty fields are left out. If SPAR refuses the question, the answer holds Undantag with Kod and Beskrivning instead of posts, and if a name search has too many hits it holds OverstigerMaxAntalSvarsposter.
Test persons in sandbox
In sandbox the searches go to Skatteverket's test environment for SPAR. It holds made-up test persons, and Skatteverket publishes the list in the document Testfall för personsökning i kundtestmiljön (version 9.1, 2025-09-09) on SPAR's page about Personsök. The table shows what each test person is for and which part (delar) the data comes in. A dash means the data is always included.
idNummer | Shows | Part |
|---|---|---|
195704133106 | First names, middle name, last name, mailing name, name in use | 1 |
198007199295 | Registered address with history | 4 |
198001139297 | Apartment number in the address | 4 |
197901249297 | Special postal address in Sweden | 5 |
194812161596 | Special postal address abroad | 5 |
198307259294 | Emigrated person whose address abroad is in Sweden | 6 |
195309112489 | Emigrated person with an address abroad | 6 |
199903672385 | Samordningsnummer with confirmed identity, contact address in Sweden, references to other numbers | 2, 7 |
199201782399 | Samordningsnummer with probable identity, contact address abroad | 2, 7 |
199012652385 | Samordningsnummer where the identity level does not apply | 2 |
197605832380 | Samordningsnummer declared dormant because its validity ran out | 2 |
200301702395 | Samordningsnummer declared dormant for another reason, with a reference | 2 |
198112752384 | Samordningsnummer, deceased | 2 |
196305782390 | Samordningsnummer with sekretessmarkering | – |
197110021834 | Reference from an old number | 2 |
197807202390 | Several references | 2 |
199101112390 | Deregistered after a change of identity, with a reference to the new one | 2 |
198604069883 | Deregistered, deceased | 2 |
197712272389 | Deregistered, emigrated; extended retention | 2 |
197908032399 | Deregistered, emigrated, removed and read in again | 2 |
198203249274 | Sekretessmarkering | – |
198103269299 | Sekretessmarkering, deceased | 2 |
198106039228 | Skyddad folkbokföring | – |
198308299299 | Immunitetsnummer | – |
198404112388 | Immunitetsnummer, deceased | 2 |
198207052385 | Immunitetsnummer, deregistered as wrongly registered | 2 |
198501182391 | Immunitetsnummer, replaced, with a reference to the new identity | 2 |
201607052394 | Two guardians | 8 |
198003119255 | Registered partner | 8 |
199401272381 | Former registered partner | 8 |
- According to Skatteverket's test cases, relations are only released when the search is made with permission for relations.
- The test cases hold no person with property or income, so expect parts 9 and 10 to be empty in sandbox.
- The list also has test cases for the name search (chapter 4) and persons with unusual names and addresses (chapter 5).
This shows which parts come back for one test person. The examples use the tool jq to print the field names in the answer:
KEY="cert_..." # your sandbox key
for d in "[0]" "[1]" "[2]" "[3]" "[4]" "[5]" "[6]" "[7]" "[8]" "[9]" "[10]" "[1,4]" "[2,8]"; do
printf '%-8s -> ' "$d"
curl -s -X POST https://sandbox-api.cerrtify.com/service/persondata/search/id.json \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d "{\"idNummer\":\"195704133106\",\"delar\":$d}" \
| jq -r '.error // ((.Posts[0] // {}) | keys_unsorted | join(", "))'
doneAnd this tries several test persons with all parts:
for id in 198007199295 197901249297 195309112489 199903672385 198604069883 201607052394; do
printf '%s -> ' "$id"
curl -s -X POST https://sandbox-api.cerrtify.com/service/persondata/search/id.json \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d "{\"idNummer\":\"$id\",\"delar\":[0]}" \
| jq -r '.error // ((.Posts[0] // {}) | keys_unsorted | join(", "))'
doneXML vs JSON
The .json variants parse the SPAR XML response into a stable JSON shape. The non-.json variants pass the raw SPAR XML through unmodified — useful if you need exact field fidelity for compliance.
When SPAR isn't configured
- Production, no certificate uploaded:
403 spar_not_configured. Upload your SPAR certificate and Skatteverket's numbers in the dashboard (see above). - Sandbox: calls with a sandbox key go to Skatteverket's test environment with the platform's test certificate; you need none of your own. Clicking Aktivera SPAR i sandbox in the dashboard also adds the test certificate to your organisation and unlocks the test form there.
503 service_unavailablemeans the SPAR client could not be started on our side (for example an unreadable certificate). Check the uploaded certificate and passphrase, and contact support if it persists.