diff --git a/content/app/guides/multi-app-solution/_index.en.md b/content/app/guides/multi-app-solution/_index.en.md
index e69de29bb2d..79f4a07daee 100644
--- a/content/app/guides/multi-app-solution/_index.en.md
+++ b/content/app/guides/multi-app-solution/_index.en.md
@@ -0,0 +1,65 @@
+---
+title: General approach for making a multi-app solution in Altinn
+linktitle: Multi-app solution
+description: Considerations and explanations of how to go about when creating a multi-app solution
+weight: 250
+aliases:
+
+- /app/multi-app-solution/
+
+---
+
+Before continue reading these guidelines, please consider if
+a multi-app solution is what you need to fulfill the purpose
+of your form(s).
+
+## What is a multi-app solution?
+
+A multi-app solution is a solution consisting of two or more
+cooperating apps, where typically (as per now) the "
+original" application(s) will trigger a creation of a new
+instance of the receiving application. As a part of the
+instantiation of the receiving application it is possible
+prefill the instance with specific data from the running
+instance of the original application.
+
+## Do I need a multi-app solution?
+
+A multi-app solution is in most cases not a necessary
+architectural choice for an Altinn form.
+
+### Use cases where you can consider utilize a multi-app solution:
+
+Criteria that should be met if you could consider creating a
+multi-app solution:
+
+- My forms will be answered by users that does not have
+ Altinn
+- It is okay that my receiving forms must be deleted in
+ order to end the lifecycle of the form.
+- The receiving form will act as temporary dashboard in
+ order to view and/or process the incoming forms, since you
+ dont have any receiving platform that are processing the
+ forms.
+
+### Alternative solution using eFormidling
+
+It might be that the solution you are looking for is a form,
+or multiple forms, that is set up to interact with _
+eFormidling_, which is another service offered by
+Digitaliseringsdiriktoratet. Read more about
+eFormidling [here](../../development/configuration/eformidling/_index.en.md)
+. A solution that is integrated with eFormidling can
+implement custom code on process-changes by using the
+predefined methods i app-backend. Read more about
+that [here](../../development/configuration/process/_index.en.md)
+. This custom code can build up a
+message, with some form-specific content, that can be sent
+to some public institution, instead of using
+instantiating a second application being the receiving form.
+Be aware that Altinn and eFormidling integration has some
+limitations in terms of supported message types, which as
+per now is limited to DPO and DPF.
+Which means that you will not need to follow this guide.
+
+{{}}
\ No newline at end of file
diff --git a/content/app/guides/multi-app-solution/_index.nb.md b/content/app/guides/multi-app-solution/_index.nb.md
index e69de29bb2d..739a2db7471 100644
--- a/content/app/guides/multi-app-solution/_index.nb.md
+++ b/content/app/guides/multi-app-solution/_index.nb.md
@@ -0,0 +1,16 @@
+---
+title: Generell fremgangsmåte for å utvikle en multi-app løsning i Altinn
+linktitle: Multi-app løsning
+description: Vurderinger som burde gjøres og forklaringer på hvordan å gå frem når man utvikler en multi-app løsning
+weight: 250
+aliases:
+
+- /app/multi-app-solution/
+---
+
+Før du leser videre i denne guiden, vær så snill å gjør en vurdering om en multi-app løsning er det du trenger for å realisere skjemaet ditt.
+
+## Trenger jeg en multi-app løsning?
+...
+
+{{}}
\ No newline at end of file
diff --git a/content/app/guides/multi-app-solution/considerations/_index.en.md b/content/app/guides/multi-app-solution/considerations/_index.en.md
new file mode 100644
index 00000000000..3f62066ed4d
--- /dev/null
+++ b/content/app/guides/multi-app-solution/considerations/_index.en.md
@@ -0,0 +1,11 @@
+---
+title: Considerations you should do before developing a multi-app solution
+linktitle: Considerations involving multi-app solution
+description: Considerations that should have been made when creating a multi-app solution
+weight: 30
+aliases:
+
+- /app/multi-app-solution/considerations/
+
+---
+
diff --git a/content/app/guides/multi-app-solution/considerations/_index.nb.md b/content/app/guides/multi-app-solution/considerations/_index.nb.md
new file mode 100644
index 00000000000..ac1d5a460d5
--- /dev/null
+++ b/content/app/guides/multi-app-solution/considerations/_index.nb.md
@@ -0,0 +1,8 @@
+---
+title: Considerations you should do before developing a multi-app solution
+linktitle: Considerations involving multi-app solution
+description: Considerations that should have been made when creating a multi-app solution
+weight: 30
+aliases:
+- /app/multi-app-solution/considerations/
+---
\ No newline at end of file
diff --git a/content/app/guides/multi-app-solution/instructions/_index.en.md b/content/app/guides/multi-app-solution/instructions/_index.en.md
new file mode 100644
index 00000000000..3fc5413724f
--- /dev/null
+++ b/content/app/guides/multi-app-solution/instructions/_index.en.md
@@ -0,0 +1,23 @@
+---
+title: Instructions for making a multi-app solution in Altinn
+linktitle: Multi-app solution instructions
+description: Explanations of how to go about when creating a general multi-app solution
+weight: 20
+aliases:
+
+- /app/multi-app-solution/instructions/
+
+---
+
+{{}}
+
+## General Modifications
+
+In general, there are a few things that one must remember to
+do in the process of developing these applications.
+
+1. Remember adding custom services to
+ the `RegisterCustomAppServices` method in `program.cs`
+2. If adding any values as prefill for the new instance of
+ the receiving application, remember to add them to the
+ data model of the receiving application
diff --git a/content/app/guides/multi-app-solution/instructions/_index.nb.md b/content/app/guides/multi-app-solution/instructions/_index.nb.md
new file mode 100644
index 00000000000..2a2ac2fc81f
--- /dev/null
+++ b/content/app/guides/multi-app-solution/instructions/_index.nb.md
@@ -0,0 +1,12 @@
+---
+title: Instructions for making a multi-app solution in Altinn
+linktitle: Multi-app solution instructions
+description: Explanations of how to go about when creating a general multi-app solution
+weight: 20
+aliases:
+
+- /app/multi-app-solution/instructions/
+
+---
+
+{{}}
\ No newline at end of file
diff --git a/content/app/guides/multi-app-solution/instructions/receiver-app/_index.en.md b/content/app/guides/multi-app-solution/instructions/receiver-app/_index.en.md
new file mode 100644
index 00000000000..2b2847903bd
--- /dev/null
+++ b/content/app/guides/multi-app-solution/instructions/receiver-app/_index.en.md
@@ -0,0 +1,58 @@
+---
+title: Receiver Application
+linktitle: Multi-app solution instructions
+description: Instructions for setting up the receiver application
+weight: 20
+aliases:
+
+- /app/multi-app-solution/instructions/receiver-app
+
+---
+
+## Getting Data From the Trigger Application
+
+The receiving application needs much less configuration as a
+bare minimum receiver application, at least. The main task
+for the receiver application is to fetch the data received
+from the trigger application(s) and represent them in a way.
+This is done by utilising the `ProcessDataRead` method in
+the `DataProcessor` service along with the `UpdateData`
+method on the `dataClient`. See example code below:
+
+```csharp
+public async Task ProcessDataRead(Instance instance, Guid? dataId, object data)
+{
+ bool edited = false;
+
+ if (data.GetType() == typeof(DataModel))
+ {
+ DataModel model = (DataModel)data;
+
+ DataElement attachments = instance.Data.FirstOrDefault(de => de.DataType == "vedlegg");
+
+ if (attachments != null)
+ {
+ _logger.LogInformation("// App 2 // Received data");
+
+ var instanceGuid = Guid.Parse(instance.Id.Split("/")[1]);
+
+ await _dataClient.UpdateData(model, instanceGuid, typeof(DataModel), instance.Org, instance.AppId, int.Parse(instance.InstanceOwner.PartyId), Guid.Parse(instance.Data.Where(de => de.DataType == "datamodel").First().Id));
+ edited = true;
+ }
+ }
+ return await Task.FromResult(edited);
+}
+```
+
+## Stopping a Running Instance
+
+Since this receiving application, in most cases, will act as
+an on-demand dashboard for collecting data from trigger
+apps, the application has no natural way of ending its
+process, since it is not sent in as any other normal form.
+To bypass this obstacle, the incoming forms should either;
+
+1. be manually deleted after being read, or
+2. they must be implemented with a demand of some sort of
+ user interaction
+ that will trigger the process to end.
\ No newline at end of file
diff --git a/content/app/guides/multi-app-solution/instructions/receiver-app/_index.nb.md b/content/app/guides/multi-app-solution/instructions/receiver-app/_index.nb.md
new file mode 100644
index 00000000000..1ecbda1eb08
--- /dev/null
+++ b/content/app/guides/multi-app-solution/instructions/receiver-app/_index.nb.md
@@ -0,0 +1,10 @@
+---
+title: Mottaksapp
+linktitle: Multi-app solution instructions
+description: Instruksjoner for mottaksappen
+weight: 20
+aliases:
+
+- /app/multi-app-solution/instructions/receiver-app
+
+---
diff --git a/content/app/guides/multi-app-solution/instructions/trigger-app/_index.en.md b/content/app/guides/multi-app-solution/instructions/trigger-app/_index.en.md
new file mode 100644
index 00000000000..3f8167b3cae
--- /dev/null
+++ b/content/app/guides/multi-app-solution/instructions/trigger-app/_index.en.md
@@ -0,0 +1,290 @@
+---
+title: Trigger Application
+linktitle: Multi-app solution instructions
+description: Instructions for setting up the trigger application
+weight: 20
+toc: true
+aliases:
+
+- /app/multi-app-solution/instructions/trigger-app
+
+---
+
+## Setup app to use Maskinporten Integration
+
+In the process of setting up the application to use the
+integration there are three things that needs to be done;
+
+1. For the application to be able to read the secrets from
+ Azure keyvault the application need to be configured to
+ do so. See
+ the [secrets section](../../../../development/configuration/secrets)
+ to achieve this.
+2. Add the appsettings section example
+ from [Key Vault Usage](../../preparations/_index.en.md#key-vault-usage) into
+ the `appsettings.json` file in the application that
+ should perform the instantiation of the receiving
+ application. Remember to adapt the section
+ name `MaskinportenSettings` to the name you chose for the
+ secrets in Azure keyvault.
+
+```json
+{
+ "MaskinportenSettings": {
+ "Environment": "ver2",
+ "ClientId": "",
+ "Scope": "altinn:serviceowner/instances.read",
+ "EncodedJwk": "",
+ "ExhangeToAltinnToken": true,
+ "EnableDebugLog": true
+ }
+}
+```
+
+3. Modify the `program.cs` file for the same application to
+ connect to Azure keyvault. Continue reading for a
+ detailed explanation.
+
+### Modifying `program.cs` to use Key Vault
+
+First of all you need to add the MaskinportenHttpClient
+service in the function `RegisterCustomAppServices`:
+
+```csharp
+services.AddMaskinportenHttpClient(config.GetSection("MaskinportenSettings"));
+```
+
+Then you need to add the following
+function `ConnectToKeyVault` in the bottom of the file:
+
+```csharp
+static void ConnectToKeyVault(IConfigurationBuilder config)
+{
+ IConfiguration stageOneConfig = config.Build();
+ KeyVaultSettings keyVaultSettings = new KeyVaultSettings();
+ stageOneConfig.GetSection("kvSetting").Bind(keyVaultSettings);
+ if (!string.IsNullOrEmpty(keyVaultSettings.ClientId) &&
+ !string.IsNullOrEmpty(keyVaultSettings.TenantId) &&
+ !string.IsNullOrEmpty(keyVaultSettings.ClientSecret) &&
+ !string.IsNullOrEmpty(keyVaultSettings.SecretUri))
+ {
+ string connectionString = $"RunAs=App;AppId={keyVaultSettings.ClientId};" +
+ $"TenantId={keyVaultSettings.TenantId};" +
+ $"AppKey={keyVaultSettings.ClientSecret}";
+ AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(connectionString);
+ KeyVaultClient keyVaultClient = new KeyVaultClient(
+ new KeyVaultClient.AuthenticationCallback(
+ azureServiceTokenProvider.KeyVaultTokenCallback));
+ config.AddAzureKeyVault(
+ keyVaultSettings.SecretUri, keyVaultClient, new DefaultKeyVaultSecretManager());
+ }
+}
+```
+
+This function can then be used in the
+function `ConfigureWebHostBuilder`. The function already
+exist, so just change the content to the following:
+
+```csharp
+void ConfigureWebHostBuilder(IWebHostBuilder builder)
+{
+ builder.ConfigureAppConfiguration((_, configBuilder) =>
+ {
+ configBuilder.LoadAppConfig(args);
+ ConnectToKeyVault(configBuilder);
+ });
+}
+```
+
+## Add task to process
+
+In most cases it is necessary to pass the data the end user
+has added to the form, to the receiver application. The data
+entered by the end user is represented in the pdf which is
+added to the instance object as a part of the `dataTypes`
+field with the name `ref-data-as-pdf`. This data element can
+be retrieved from the `instance` object in the custom code
+that can be added on predefined functions in app-backend.
+Read more about how these custom code is
+added [here](../../../../development/configuration/process/pre-post-hooks)
+.
+
+However, if you wish the retrieve the pdf data element, your
+application must have multiple process tasks. This is due to
+the pdf generation is executed after a task has ended. So if
+you wish to collect the pdf(s) from the data tasks from the
+process, you will need to have at least two tasks, where the
+final task is _not_ a data task. The task can be a _confirm_
+or _feedback_ task.
+
+_NB: It might be that you need to get an updated version of
+the instance object from Altinn Storage by calling
+the `GetInstance` method on the `IInstanceClient`._
+
+### Confirm Task Type
+
+If using the _confirm_ task type, make sure the
+instantiation of the receiver application happens when the
+task is finished, i.e. use the `ProcessTaskEnd.End()`
+function. This is necessary since the user can go back
+to the data task and do changes.
+
+{{% panel theme="warning" %}}
+TODO: Ask Vemund if this require v8 or only recommended. And
+if not using v8 keep in mind that accumulated pdfs must be
+deleted and action buttons are not implemented so go-to-task
+must be used even though not recommended??
+{{% /panel %}}
+
+### Feedback Task Type
+
+If using the _feedback_ task type, the instantiation of the
+receiving application can be done on the task start
+function. Be aware that there has to be some external
+triggers that can make sure the application is moved to the
+end task event, or else it will stay on the feedback task
+forever. The external trigger cannot be the receiving
+application since this application will send the request to
+end the original request sent from the trigger application
+while the trigger application is waiting for the same
+request to complete, which will cause a conflict.
+
+TODO: Is it necessary with multiple steps if pdf of form is
+not sent to receiver app?
+
+### Update `process.bpmn` and `policy.xml` accordingly
+
+Remember to update the process.bpmn file to match the the
+process, and remember adding gateways if you have chosen
+the _confirm_ task type.
+
+Policy.xml also needs updates so read and write operations
+can be done on the new task.
+
+## Trigger the instantiation of the receiving app
+
+The instantiation of the receiving application is done with
+an api call to the running receiving application. The
+content of the call will
+be the new instance object, which will look something like
+this:
+
+```csharp
+var instanceTemplate = new InstansiationInstance
+{
+ InstanceOwner = new InstanceOwner
+ {
+ //OrganisationNumber = [receiverOrgNr], Or
+ //PersonNumber = [receiverSsnNr],
+ },
+ Prefill = new()
+ {
+ {"someDataInReceiverDataModel", someValueFromThisTriggerAppliaction},
+ {"moreDataInReceiverDataModel", someStaticValue},
+ ...
+ },
+};
+```
+
+The request to create the instance is added to the appClient
+which is a custom service that also must be configured.
+
+Call the method triggering the request in the appClient like
+this:
+
+```csharp
+Instance receivingInstance = await _appClient.CreateNewInstance([AppOwnerOrgName], [receivingApp], [instanceTemplate]);
+```
+
+In the AppClient add this code:
+
+```csharp
+public async Task CreateNewInstance(string org, string app, InstansiationInstance instanceTemplate)
+{
+ string apiUrl = $"{AppOwnerOrgName}/{receivingApp}/instances/create";
+
+ string envUrl = $"https://{AppOwnerOrgName}.apps.{_settings.HostName}";
+
+ _client.BaseAddress = new Uri(envUrl);
+
+ StringContent content = new StringContent(JsonConvert.SerializeObject(instanceTemplate), Encoding.UTF8, "application/json");
+
+ HttpResponseMessage response = await _client.PostAsync(apiUrl, content);
+
+ if (response.IsSuccessStatusCode)
+ {
+ Instance createdInstance = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
+
+ return createdInstance;
+ }
+ throw await PlatformHttpException.CreateAsync(response);
+}
+```
+
+## Delivering data to the receiver app
+
+In order to pass data to the the receiving application there
+are several ways of doing this.
+
+1. Add data as values on the datamodel of the receiving
+ application by adding the data model field name and the
+ corresponding value in the `prefill` field of the the
+ instance template that you created in the _Trigger the
+ instantiation of the receiving app_ section above.
+2. If the intention is to manipulate the texts in Altinn
+ Inbox for the instances of the receiving application,
+ use [_presentation
+ fields_](../../../../development/configuration/messagebox/presentationfields)
+ .
+3. Add data as binary data by doing a POST request to the
+ Altinn platform on the instance after it is instantiated.
+ Before some data types can be added, they must be
+ retrieved from Altinn Platform, such as the pdf for
+ example, since the application does not have direct
+ access to this by default. The already
+ defined `GetBinaryData` method on the dataClient should
+ be used to get the data and a custom code, called
+ e.g. `InsertBinaryData`, should be used to insert the
+ data.
+ See example code below of both below:
+
+```csharp
+DataElement pdf = updatedInstance.Data.FindLast(d => d.DataType == "ref-data-as-pdf");
+var stream = await _dataClient.GetBinaryData(instance.Org, instance.AppId,int.Parse(instance.InstanceOwner.PartyId), instanceGuid, Guid.Parse(pdf.Id));
+
+```
+
+```csharp
+public async Task InsertBinaryData(string org, string app, string instanceId, string dataType, string contentType, string filename, Stream stream)
+{
+ string apiUrl = $"{org}/{app}/instances/{instanceId}/data?dataType=vedlegg";
+
+ DataElement dataElement;
+
+ StreamContent content = new(stream);
+ content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
+ if (!string.IsNullOrEmpty(filename))
+ {
+ content.Headers.ContentDisposition = new ContentDispositionHeaderValue(DispositionTypeNames.Attachment)
+ {
+ FileName = filename,
+ FileNameStar = filename
+ };
+ }
+
+ HttpResponseMessage response = await _client.PostAsync(apiUrl, content);
+
+ if (response.IsSuccessStatusCode)
+ {
+ string instancedata = await response.Content.ReadAsStringAsync();
+ dataElement = JsonConvert.DeserializeObject(instancedata);
+
+ return dataElement;
+ }
+ throw await PlatformHttpException.CreateAsync(response);
+}
+```
+
+4. Data can also be added to the application
+ using [DataProcessors](../../../../development/logic/dataprocessing)
+ .
\ No newline at end of file
diff --git a/content/app/guides/multi-app-solution/instructions/trigger-app/_index.nb.md b/content/app/guides/multi-app-solution/instructions/trigger-app/_index.nb.md
new file mode 100644
index 00000000000..a905bedf68f
--- /dev/null
+++ b/content/app/guides/multi-app-solution/instructions/trigger-app/_index.nb.md
@@ -0,0 +1,11 @@
+---
+title:
+linktitle: Multi-app solution instructions
+description:
+weight: 20
+toc: true
+aliases:
+
+- /app/multi-app-solution/instructions/trigger-app
+
+---
diff --git a/content/app/guides/multi-app-solution/preparations/_index.en.md b/content/app/guides/multi-app-solution/preparations/_index.en.md
new file mode 100644
index 00000000000..981867249c2
--- /dev/null
+++ b/content/app/guides/multi-app-solution/preparations/_index.en.md
@@ -0,0 +1,92 @@
+---
+title: Preparations before making a multi-app solution in Altinn
+linktitle: Multi-app solution preparations
+description: What preparations that should be done before creating a multi-app solution
+weight: 10
+aliases:
+
+- /app/multi-app-solution/preparations/
+
+---
+
+A crucial part of the multi-app solution is to make sure the
+applications are able, and allowed, to communicate. This is
+essential due to the main concept of this solution - the
+instantiation of the receiving application. As a part of the
+process of the original form you will have logic that
+creates a request to the receiving application that starts a
+new instance. This request will go to Altinn Storage in
+order to create and persist the instance object, but the
+request will have credentials from the private user who
+logged in to the original form, thus is not allowed to start
+a new instance owned by the organisation that owns the
+receiving application. As a way to bypass this obstacle, we
+can use a Maskinporten integration to authenticate the
+request on behalf of the organisation owning the receiving
+application. In order to achieve this we need to;
+
+1. Create the integration
+ at [Samarbeidsportalen](https://samarbeid.digdir.no/)
+2. Store the keys from the integration in Azure Keyvault for
+ the organisation
+3. Set up the application to use Azure Keyvault and the
+ client to use Maskinporten
+
+// TODO: ASK RUNE WHAT NEEDED TO BE DONE IN THE AUTH PART
+
+## Maskinporten Integration
+
+Before going forward on this step, make sure you have access
+to Azure Key Vault for your organization, so the keys
+created in the following guide can be added directly into
+the secrets in Azure.
+
+If different people in the
+organization have access to different resources needed in
+this process, please cooperate and do the following steps on
+the same machine. This is recommended to avoid sending
+secrets between machines.
+
+When access to creating secrets in Azure Key vault is
+confirmed, please proceed to create the integration;
+navigate to
+the [Maskinporten Setup guide](../../../../../technology/solutions/cli/configuration/maskinporten-setup)
+.
+
+## Key Vault Usage
+
+When the integration is created two secrets have to be
+placed in Azure Key vault:
+
+1. The base64 encoded JWT public and private key pair
+2. The clientID for the integration
+
+It is important that the name of these secrets corresponds
+to the name of the section in the appsettings file in the
+application repository. E.g. if your appsettings section for
+the Maskinporten integration section looks like this:
+
+```json
+{
+ "MaskinportenSettings": {
+ "Environment": "ver2",
+ "ClientId": "",
+ "Scope": "altinn:serviceowner/instances.read",
+ "EncodedJwk": "",
+ "ExhangeToAltinnToken": true,
+ "EnableDebugLog": true
+ }
+}
+```
+
+The secrets in Azure keyvault should have names like this:
+
+```
+MaskinportenSettings--ClientId
+MaskinportenSettings--EncodedJwk
+```
+
+_NB: The secrets is read by the application on start up so
+if
+changing the secrets after the application is deployed, you
+will need to redeploy the application._
diff --git a/content/app/guides/multi-app-solution/preparations/_index.nb.md b/content/app/guides/multi-app-solution/preparations/_index.nb.md
new file mode 100644
index 00000000000..2ba11c91fba
--- /dev/null
+++ b/content/app/guides/multi-app-solution/preparations/_index.nb.md
@@ -0,0 +1,10 @@
+---
+title: Preparations before making a multi-app solution in Altinn
+linktitle: Multi-app solution preparations
+description: What preparations that should be done before creating a multi-app solution
+weight: 10
+aliases:
+
+- /app/multi-app-solution/preparations/
+
+---