> For the complete documentation index, see [llms.txt](https://docs.fortifiedid.se/access/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fortifiedid.se/access/key-components/authenticators/credential-validators/freja-e-id/with-qr-or-app-switch.md).

# With QR or "app-switch"

Configuration reference for Freja e-ID authentication with QR code or app-switch.

Use this authenticator when users should authenticate by scanning a Freja e-ID QR code or by opening the Freja app on the same device.

## Configuration

Based on the Freja e-ID documentation found here:

[Freja eID Relying Party Developers' Documentation](https://frejaeid.atlassian.net/wiki/spaces/DOC/pages/2162826/REST+API+Documentation)

{% hint style="info" %}
**Authenticator type:** `FrejaWithQRCode`
{% endhint %}

Common Authenticator configuration can be found [here](/access/key-components/authenticators/common-configuration.md).

{% tabs %}
{% tab title="Properties" %}

<table data-full-width="true"><thead><tr><th>Name</th><th>Description</th><th>Default value</th><th data-type="checkbox">Mandatory</th></tr></thead><tbody><tr><td><code>internal_http_destination</code></td><td>ID of the internal HTTP client used to communicate with the backend.</td><td>N/A</td><td>true</td></tr><tr><td><code>mode</code></td><td>Four modes are available: <code>"prod_personal"</code>, <code>"test_personal"</code>, <code>"prod_org"</code>, and <code>"test_org"</code>. The selected mode determines the Freja endpoint.</td><td><code>"prod_personal"</code></td><td>true</td></tr><tr><td><code>attributesToReturn</code></td><td>Array of attributes returned after completed authentication. See the allowed values in the Freja documentation.</td><td>N/A</td><td>true</td></tr><tr><td><code>minRegistrationLevel</code></td><td>Required registration level. Allowed values are <code>"BASIC"</code>, <code>"EXTENDED"</code>, or <code>"PLUS"</code>.</td><td><code>"PLUS"</code></td><td>false</td></tr><tr><td><code>relyingPartyId</code></td><td>Relying party ID used for the request.</td><td>N/A</td><td>false</td></tr><tr><td><code>custom_identifier</code></td><td>Tag added to logged events.</td><td>N/A</td><td>false</td></tr><tr><td><code>poll_frequency</code></td><td>Number of seconds between browser status requests.</td><td><code>2</code></td><td>false</td></tr><tr><td><code>allowed_polling_for_minutes</code></td><td>Total number of minutes that the QR/app-switch flow remains active. Access automatically rotates Freja transactions during this time.</td><td><code>2</code></td><td>false</td></tr><tr><td><code>webroot_dir</code></td><td>See common authenticator configuration.</td><td><code>web/authenticator/freja/freja_qr_or_appswitch</code></td><td>false</td></tr><tr><td><code>use_dynamic_qr_code</code></td><td>Use dynamic QR codes.</td><td><code>true</code></td><td>false</td></tr></tbody></table>
{% endtab %}

{% tab title="Example" %}

```json
{
	"id": "frejaqrcode",
	"type": "FrejaWithQRCode",
	"config": {
		"base_path": "/test/authn",
		"internal_http_destination": "freja",
		"webroot_dir": "web/authenticator/freja/freja_qr_or_appswitch",
		"attributesToReturn": [
			"BASIC_USER_INFO", "EMAIL_ADDRESS"
		],
		"minRegistrationLevel": "EXTENDED",
		"mode": "prod_personal",
		"poll_frequency": 2,
		"allowed_polling_for_minutes": 5
	}
}
```

{% endtab %}
{% endtabs %}

## Total flow timeout

Freja authentication requests have a fixed validity of two minutes. The `allowed_polling_for_minutes` property controls the total Access flow rather than changing that Freja limit. For example, set the property to `5` to keep the browser flow active for five minutes.

While a request remains in `STARTED`, Access replaces it with a new Freja transaction after one minute and updates the QR code or app-switch link. Access does not rotate a request after it has been delivered to the Freja app. If a delivered request expires while time remains, Access creates a new transaction; the user may then need to scan the new QR code or open the app again.

The browser countdown uses the same total deadline as the backend. When the configured time has elapsed, the current transaction is cancelled and the user can start a new flow.

{% hint style="warning" %}
Property *base\_path* should not contain the full path when used in conjunction with the [Selector](/access/key-components/authenticators/flow-control/selector.md), instead, the full URI will be handled by the selector. The full path will be *base\_path + / + id*.
{% endhint %}

## App-switch return URL

The `return_url` value is used as Freja `originAppScheme` for app-switch flows. If `return_url` is not configured, Access does not add an empty `originAppScheme` parameter to the Freja start URL.

Access also avoids adding `originAppScheme` more than once. If the generated Freja URL already contains the parameter, the browser app-switch flow uses that value as-is.

## Logging

Apart from system logging, event logging is done when starting, completing, and failing a transaction.

Event ids are:

* WEB\_100005("Freja authentication started")
  * IDENTIFIER (user trace id)
  * SOURCE\_ADDRESS (ip address of device starting transaction)
  * CUSTOMER\_IDENTIFIER (if configured)
  * AUTHENTICATOR\_IDENTIFIER (id and display name)
* WEB\_100006("Freja authentication completed")
  * IDENTIFIER (user trace id)
  * SOURCE\_USER\_NAME (identifier used)
  * SOURCE\_ADDRESS (ip address of the device used)
  * REQUESTEDATTRIBUTES (BASIC\_USER\_INFO, EMAIL\_ADDRESS, ALL\_EMAIL\_ADDRESSES etc)
  * CUSTOMER\_IDENTIFIER (if configured)
  * AUTHENTICATOR\_IDENTIFIER (id and display name)
* WEB\_100008("Freja authentication canceled or expired")
  * IDENTIFIER (user trace id)
  * SOURCE\_ADDRESS (ip address of the device used)
  * CUSTOMER\_IDENTIFIER (if configured)
  * AUTHENTICATOR\_IDENTIFIER (id and display name)

## Data exposed to global state

After a user completes a transaction, the authenticator is marked as done. Data from the authentication response is then put into the global state, replacing existing values:

* details
* givenName
* surName
* ssn
* co
* mail
* organisationIdIdentifier
* integratorSpecificUserId
* relyingPartyUserId
* registrationLevel
* loaLevel
* uniquePersonalIdentifier

Note that it is not guaranteed that all parameters hold value. The result varies depending on the configuration

## API

When communicating with the backend this describes the

### General requirements

Backend communications are made using AJAX and the HTTP PUT method. Every request need a Content-Type with the value of `application/json`*.*

### Getting state

Body must conform to the example below.

```json
{
    "type": "state"
}
```

### Starting an authentication

To start authentication send AJAX request containing the user's identifier, 12 digits.

```json
{
    "type": "start",
    "data": {
        "identifier": "<user_data>"
    }
}
```

### Cancel a request

A request can be canceled at any time. This is done by sending a cancel request.

```json
{
    "type": "cancel"
}
```

### Response from server

In general, you should expect a server response with http status code 200. Anything else is to be considered an error.

Response body will be in the form of a JSON object. Typically the response looks like:

```json
{
    "status": "ABOUT_TO_START",
    "frejaStatus": "",
    "authRef": "",
    "pollFrequency": 2,
    "countdownSeconds": 300,
    "remainingSeconds": 300
}
```

The property `"status"` will contain status.

### Possible status messages

One of the following status codes is returned based on the current state.

* ABOUT\_TO\_START
* PENDING
* COMPLETED
* FREJA\_ERROR
* ERROR

### Possible frejaStatus messages

One of the following frejaStatus codes is returned based on the current state.

* STARTED
* DELIVERED\_TO\_MOBILE
* CANCELED
* RP\_CANCELED
* EXPIRED
* APPROVED
* REJECTED
* UNKNOWN

## Data in authRef

Once the authentication process has started the identifier generated by the Freja-backed server is sent back to the client in parameter *authRef*.

## Translation keys

```json
{
  "freja.qr_or_app_switch.personal_identity_number": "Personal identity number",
  "freja.qr_or_app_switch.start_authentication": "Start authentication",
  "freja.qr_or_app_switch.open_app": "Open Freja app",
  "freja.qr_or_app_switch.open_freja_app_on_this_device": "Log in using Freja on this device",
  "freja.qr_or_app_switch.show_qr_code": "Show QR code for login",
  "freja.qr_or_app_switch.start_freja_app": "Open Freja app",
  "freja.qr_or_app_switch.scan_qr_code": "Open Freja app and scan QR code",
  "freja.qr_or_app_switch.qr_code_scanned": "QR code scanned",
  "freja.qr_or_app_switch.app_opened": "Freja app opened",
  "freja.qr_or_app_switch.verify_authentication": "Verifify identification in the Freja app",
  "freja.qr_or_app_switch.authentication_verified": "Identification verified",
  "freja.qr_or_app_switch.redirecting": "Redirecting...",
  "freja.qr_or_app_switch.start_app": "Start your Freja app.",
  "freja.qr_or_app_switch.cancel": "Cancel",
  "freja.qr_or_app_switch.canceling": "Canceling...",
  "freja.qr_or_app_switch.ERROR": "Unknown error. Please try again.",
  "freja.qr_or_app_switch.UNKNOWN": "Unknown error. Please try again.",
  "freja.qr_or_app_switch.CANCELED": "Action cancelled. Please try again.",
  "freja.qr_or_app_switch.EXPIRED": "The Freja eID app is not responding. Please check that the program is started and that you have internet access.",
  "freja.qr_or_app_switch.REJECTED": "Authentication denied",
  "freja.qr_or_app_switch.RP_CANCELED": "Action cancelled. Please try again.",
  "freja.qr_or_app_switch.INTERRUPTED": "Action cancelled. Please try again.",
  "freja.qr_or_app_switch.API_ERROR": "Unknown error. Please try again.",
  "allow-cookies-body": "To save your language settings on this device you need to approve a language cookie.",
  "allow-cookies-button": "Approve language cookie",
  "authentication.help_text": "",
  "change_language": ""
}
```

```json
{
  "freja.qr_or_app_switch.personal_identity_number": "Personnummer",
  "freja.qr_or_app_switch.start_authentication": "Starta verifiering",
  "freja.qr_or_app_switch.open_app": "Öppna Freja eID-appen",
  "freja.qr_or_app_switch.open_freja_app_on_this_device": "Logga in med Freja på den här enheten",
  "freja.qr_or_app_switch.show_qr_code": "Visa QR-kod för inloggning",
  "freja.qr_or_app_switch.start_freja_app": "Öppna Freja eID-appen",
  "freja.qr_or_app_switch.scan_qr_code": "Öppna Freja eID-appen och skanna QR-koden",
  "freja.qr_or_app_switch.qr_code_scanned": "QR-koden har skannats",
  "freja.qr_or_app_switch.app_opened": "Freja eID-appen öppnad",
  "freja.qr_or_app_switch.verify_authentication": "Bekräfta i Freja eID-appen",
  "freja.qr_or_app_switch.authentication_verified": "Bekfräftat identitet",
  "freja.qr_or_app_switch.redirecting": "Omdirigerar...",
  "freja.qr_or_app_switch.start_app": "Starta Freja eID-appen",
  "freja.qr_or_app_switch.cancel": "Avbryt",
  "freja.qr_or_app_switch.canceling": "Avbryter...",
  "freja.qr_or_app_switch.ERROR": "Okänt fel. Försök igen.",
  "freja.qr_or_app_switch.UNKNOWN": "Okänt fel. Försök igen.",
  "freja.qr_or_app_switch.CANCELED": "Åtgärden avbruten. Försök igen",
  "freja.qr_or_app_switch.EXPIRED": "Freja eID-appen svarar inte. Kontrollera att den är startad och att  du har internetanslutning.",
  "freja.qr_or_app_switch.REJECTED": "Legitimeringen nekad",
  "freja.qr_or_app_switch.RP_CANCELED": "Åtgärden avbruten. Försök igen",
  "freja.qr_or_app_switch.INTERRUPTED": "Åtgärden avbruten. Försök igen",
  "freja.qr_or_app_switch.API_ERROR": "Okänt fel. Försök igen.",
  "allow-cookies-body": "Vill du spara dina språkinställningar på denna enhet behövs ett godkännande av  språk-cookie.",
  "allow-cookies-button": "Godkänn språk-cookie",
  "authentication.help_text": "",
  "change_language": ""
}

```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.fortifiedid.se/access/key-components/authenticators/credential-validators/freja-e-id/with-qr-or-app-switch.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
