Skip to main content
Version: 4.1 (2026 H2)

CMI

primedocs integrates with CMI in several ways. Which variant fits depends on where the document creation process starts and which clients are in use:

VariantProcess starts inBuilding blocks
A — Connect (desktop to desktop)CMI DesktopConnect via console call
B — Web to webCMI WebConnect Session Template
C — CMI as data source and storage targetprimedocsHttpDataProvider (Select) and Output Management
note

The URLs in the examples (cmi.example.com) are placeholders — the effective hosts and paths (including the tenant) are installation-specific and provided by CMI. The examples show the key elements of the configuration; schemas, fields, and mappings need to be adapted to the concrete use case.

Prerequisites for variants B and C

The CMI REST APIs require OAuth 2.0 authentication. Both are prepared in the DataSource Admin:

  • Connected Service for CMI: Create a Connected Service under Settings → Connected Services (key CMI in the examples). All configurations reference it via ConnectedServiceKey and insert the access token via the placeholder {__ConnectedService.AccessToken__} (typically in the Authorization header).
  • URL allow-list for InvokeUrl: Allow the CMI target URLs used for upload and storage (variants B and C) under Settings → Connect Settings → InvokeUrl - Configuration. Without this entry, the InvokeUrl call is blocked.

Variant A — Connect (desktop to desktop)

In a pure desktop environment, CMI Desktop invokes the primedocs desktop client automatically in the background and passes a Connect file containing the data of the business case (e.g. recipients, subject, references). From the user's point of view this is a single action in CMI — with no manual intermediate step.

Technically, CMI issues the console call of the primedocs client (not run by hand):

.\primedocs.exe /connect "C:\Temp\Geschaeft-1234.pdcx"

primedocs creates the document from it; storing the result in CMI is handled by CMI itself. Details on the invocation mechanism (file extensions, protocol handler, fetching the Connect XML from a URL): Start document generation.

Variant B — Web to web (Connect Session Template)

CMI Web embeds primedocs web (iframe or new tab) and starts a pre-initialized document creation via the URL of a Connect Session Template:

https://{instance}/app/web/session/template/cmi?saveLocationCmiTenant={tenant}&saveLocationCmiToken={token}&document={document-guid}

The parameter names can be chosen freely — they only need to match what the session template consumes via $.parameter(…). In this example, CMI passes:

ParameterPurpose
saveLocationCmiTenantCMI tenant used for storing the result.
saveLocationCmiTokenToken of the CMI document under which the result is stored.
documentGUID of the CMI document — used by the initializer to load the business case data.

The flow:

  1. When the session starts, the initializers load data from CMI (HttpDataProvider → CMI ContentProvider API) and pick up the storage parameters (CodeDataProvider).
  2. The user selects the template, fills in the form, and generates the document.
  3. The OnSuccess commands upload the document to CMI (InvokeUrl), confirm the storage (ShowDialog), and report completion to the embedding CMI (BrowserParentPostMessage) so CMI can continue its process.

Connect Session Template

<ConnectSessionTemplatesConfiguration>
<ConnectSessionTemplate Name="cmi">
<Initializers>
<!-- Loads data of the CMI document via the ContentProvider API -->
<HttpDataProvider ConnectedServiceKey="CMI">
<Configuration>
<Step>
<Request Method="POST">
<Url><![CDATA[https://cmi.example.com/{tenant}/v2/ContentProvider]]></Url>
<Header Name="Authorization" Value="Bearer {__ConnectedService.AccessToken__}" />
<Header Name="Content-Type" Value="application/json" />
<BodyBuilder><![CDATA[
function main() {
return JSON.stringify({
dokumentGuid: $.parameter("document"),
contentProviderKeys: [ "Kontakte" ]
});
}
]]></BodyBuilder>
</Request>
<Response>
<Data JsonPath="$.Kontakte[*]">
<Code>
function main() {
return {
Forms: {
Kontakte: {
"Key": source("name"),
"Name": source("displayName")
}
}
};
}
</Code>
</Data>
</Response>
</Step>
</Configuration>
</HttpDataProvider>
<!-- Picks up the CMI storage location from the URL parameters -->
<CodeDataProvider>
<Code><![CDATA[
function main() {
return {
Data: {
"CmiTenant": $.parameter("saveLocationCmiTenant"),
"CmiToken": $.parameter("saveLocationCmiToken")
}
};
}
]]></Code>
</CodeDataProvider>
</Initializers>
<Commands>
<OnSuccess>
<!-- Uploads the generated document to CMI -->
<InvokeUrl ConnectedServiceKey="CMI">
<Step>
<MultipartFormDataRequest>
<Url field-Content="Fields.UploadUrl" />
<Header Name="Authorization" Value="Bearer {__ConnectedService.AccessToken__}" />
<Header Name="Accept" Value="application/json" />
<File Name="file" field-FileName="Fields.FileName">
<Document />
</File>
</MultipartFormDataRequest>
</Step>
</InvokeUrl>
<ShowDialog Title="CMI" Message="The document has been stored in CMI." />
<!-- Notifies the embedding CMI about completion -->
<BrowserParentPostMessage TargetOrigin="https://cmi.example.com">
<Code><![CDATA[
function main() {
return {
type: "template-chooser-document-uploaded",
name: $("Fields.FileName")
};
}
]]></Code>
</BrowserParentPostMessage>
</OnSuccess>
</Commands>
</ConnectSessionTemplate>
</ConnectSessionTemplatesConfiguration>

The available contentProviderKeys and the field structure of the response are defined by CMI; the transformation into the Forms structure happens in the Code element via source(…).

Data receives the storage parameters, Fields builds the upload URL from them, Forms defines the target structure for the loaded CMI data:

<DataConfiguration>
<Schema>
<Text Id="CmiTenant" />
<Text Id="CmiToken" />
</Schema>
</DataConfiguration>
<FieldsConfiguration>
<Fields>
<Text Name="UploadUrl">
<Code><![CDATA[
function main() {
return "https://cmi.example.com/" + $("Data.CmiTenant") + "/v1/Template/" + $("Data.CmiToken");
}
]]></Code>
</Text>
<Text Name="FileName" Value="Document.docx" />
</Fields>
</FieldsConfiguration>
<FormsConfiguration>
<Elements>
<ObjectCollection Id="Kontakte" Label="Kontakt" SelectedObjectId="Kontakt">
<Schema>
<Text Id="Key" Label="Key" />
<Text Id="Name" Label="Name" />
</Schema>
</ObjectCollection>
</Elements>
</FormsConfiguration>

Thanks to SelectedObjectId, the user's selection is available to fields and placeholders as Forms.Kontakt (e.g. $("Forms.Kontakt").Name), see Forms.

CMI placeholders in the document

Word content controls following the naming scheme CMI_[FIELDNAME] as well as bookmarks are filled automatically by CMI when it processes the document further. This allows CMI metadata to be added without primedocs having to supply the data.

Replaces the previous integration

Up to primedocs 4.0, the CMI web integration was configured via the <cmi> element in primedocs.config and the fixed URL /app/web/cmi. The Connect Session Template approach supersedes that configuration: data retrieval, upload endpoint, authentication (Connected Service instead of a client secret in the configuration file), and the behaviour after generation are freely configurable.

Variant C — CMI as data source and storage target

This variant is interesting when the document is not created from within CMI — for example directly in primedocs web or in Office — but data of a CMI business case should still flow in and/or the result should be written back to CMI. The two building blocks can be used independently of each other.

Loading a business case from CMI (Select)

An Object in the Forms configuration gets an HttpDataProvider that calls the CMI search API. The user searches for the business case in the form; its values are then available to the template as Forms.Geschaeft.*.

<FormsConfiguration>
<Elements>
<Text Id="FileName" Label="Document name" Value="primedocs document" />
<Object Id="Geschaeft" Label="CMI business case">
<Schema>
<Text Id="Id" Label="Id" />
<Text Id="Titel" Label="Title" />
<Text Id="Typ" Label="Type" />
<Text Id="Status" Label="Status" />
<Text Id="Nummer" Label="Number" />
<Text Id="Beginn" Label="Start" />
</Schema>
<Summary>
<Field Id="Nummer" />
<Field Id="Titel" />
</Summary>
<DataProviders>
<HttpDataProvider DisplayName="CMI" ConnectedServiceKey="CMI">
<SearchParameters>
<Text Id="Term" Label="Search term" Required="true" />
</SearchParameters>
<Configuration>
<Step>
<Request Method="GET">
<UrlBuilder><![CDATA[
function main() {
const baseUrl = "https://cmi.example.com/api";
return baseUrl + "/AbstraktesGeschaeft/Search/FULLTEXT[" + $("Term") + "]";
}
]]></UrlBuilder>
<Header Name="Authorization" Value="Bearer {__ConnectedService.AccessToken__}" />
</Request>
<Response>
<Data JsonPath="$[*]">
<Mapping>
<Map Source="guid" Target="Id" />
<Map Source="typeName" Target="Typ" />
<Map Source="titel" Target="Titel" />
<Map Source="lifecycleStatus" Target="Status" />
<Map Source="laufnummer" Target="Nummer" />
<Map Source="beginn" Target="Beginn" />
</Mapping>
</Data>
</Response>
</Step>
</Configuration>
</HttpDataProvider>
</DataProviders>
</Object>
</Elements>
</FormsConfiguration>

Writing the document to CMI (Output Management)

A DesktopOutput in Output Management stores the document via the CMI API — in two steps: first the document object is created in the business case, then the generated file is checked in as a PDF.

The Fields configuration provides the file name and the request body:

<FieldsConfiguration>
<Fields>
<Text Name="FileName">
<Code><![CDATA[
function main() {
let fileName = $("Forms.FileName");
if (fileName == null) {
fileName = "Document";
}
if (!fileName.toLowerCase().endsWith(".pdf")) {
fileName += ".pdf";
}
return fileName;
}
]]></Code>
</Text>
<Text Name="CreateDocumentBody">
<Code><![CDATA[
function main() {
if ($("Forms.Geschaeft") == null) {
return "";
}
return JSON.stringify({
titel: $("Forms.FileName"),
version: 0,
bemerkung: "Generated via primedocs",
geschaeft: {
guid: $("Forms.Geschaeft").Id
}
});
}
]]></Code>
</Text>
</Fields>
</FieldsConfiguration>

The output executes both steps via an InvokeUrl command:

<OutputConfiguration>
<DesktopOutput Name="Store in CMI">
<Commands>
<InvokeUrl ConnectedServiceKey="CMI">
<!-- Step 1: create the document object in the CMI business case -->
<Step>
<Request Method="POST">
<Url>https://cmi.example.com/api/Dokument</Url>
<Header Name="Authorization" Value="Bearer {__ConnectedService.AccessToken__}" />
<Header Name="Content-Type" Value="application/json" />
<Body field-Content="Fields.CreateDocumentBody" />
</Request>
<Response>
<Property Name="DokumentGuid" JsonPath="$" />
</Response>
</Step>
<!-- Step 2: check in the generated file as PDF -->
<Step>
<MultipartFormDataRequest>
<Url>https://cmi.example.com/api/Dokument/CheckIn/{DokumentGuid}</Url>
<Header Name="Authorization" Value="Bearer {__ConnectedService.AccessToken__}" />
<Header Name="Accept" Value="application/json" />
<File Name="file" field-FileName="Fields.FileName" ContentType="application/pdf">
<Document Conversion="Pdf" />
</File>
</MultipartFormDataRequest>
</Step>
</InvokeUrl>
</Commands>
</DesktopOutput>
</OutputConfiguration>
note

For primedocs web and the Office web add-ins, the same storage can be configured as a WebOutputInvokeUrl is one of the web-capable commands (see Output Management).