Connect API
Via the Connect API, third-party systems can use primedocs document generation on the server side via the primedocs Connect interface.
Endpoints
All Connect API endpoints live under …/api/v3/{datasourceId}/Connect. The request body is the primedocs Connect XML. The Connect API runs without a user context (client credentials); for scenarios with a user context and connected services, use the Connect Session API.
| Method | Endpoint | Purpose |
|---|---|---|
POST | /Document | Generates a document and returns the file. With the query parameter conversion=Pdf the result is returned as a PDF (default: None). |
POST | /Result | Runs the generation and returns a ConnectResultReport (JSON). The document itself is handled by a command (e.g. InvokeUrl). |
POST | /Update | Updates an existing primedocs document and returns the updated file. Supports conversion=Pdf and behavior=Merge|Replace. See Update a document. |
GET | /Templates | Lists the available templates (paged). |
POST | /Session | Creates a Connect Session and returns a ConnectSessionResult with a sessionId and a webAppLink to the web app. |
POST | /File | Deprecated — use /Document instead. |
A Connect is validated internally when a session is created (POST /Session); there is no standalone /Validate endpoint in this API version.
/File is deprecatedThe former /File endpoint remains for compatibility but redirects to /Document. New integrations should use /Document.
PDF output
POST …/Connect/Document?conversion=Pdf returns the generated document as a PDF. Without the parameter (or conversion=None), the native Office format is returned.
For server-side PDF generation:
- Images are embedded correctly — images from the profile and organization unit (e.g. logos or signatures) are included in the PDF.
- Date format follows the document language — data-bound date fields are formatted according to the document's language, not the server language (so, for example, no German month name in a French document).
Querying templates (/Templates)
GET …/Connect/Templates returns a paged list (query parameters page, pageSize; default 10, max 100). Optional filters:
userQuery— e.g.title:*Letter* field[FIELD.ID]:*value*templateQuery— e.g.templateId:GUID active:true tags:TAG1;TAG2 localizedName:*Letter*uiLcid,userId— optional.
The meta template IDs usable in templateQuery are provided by the common endpoint GET .../Common/MetaTemplates. It can be called with the same Connect token (pd_ConnectWebApi) — no additional client for the Admin API is needed.
The response contains only templates for which the target user holds the Use permission level — either directly or through one of their directory groups (see Template permissions). The permission filter is applied before paging: the total number of matches therefore also counts permitted templates only. Organization-unit permissions are additionally checked per profile, so the profiles returned for a template likewise contain approved entries only.
Update a document (/Update)
POST …/api/v3/{datasourceId}/Connect/Update updates an existing document created with primedocs and returns the updated file (conversion=Pdf is supported as with /Document). The functional details (merge/replace, language override, enabled remote sources) are described under Updating documents.
The document to update is supplied in one of three ways:
- Multipart (
multipart/form-data) with the partsdocument(the existing Office file) andconnect(the connect XML). If thedocumentpart is missing, a400with a corresponding hint is returned. - Inline as Base64 in the connect XML (body = plain connect XML):
<DocumentLocation Format="DocxBase64">…base64…</DocumentLocation>. - Server-side fetch via
<DocumentLocation Source="https://…"/>— only for remote sources enabled in the datasource settings.
| Query parameter | Description |
|---|---|
behavior (optional) | Replace (default) or Merge — controls how incoming Forms/Data values are applied. Alternatively as the UpdateBehavior attribute on the DocumentLocation. Contradicting values (query vs. attribute) result in a 400. |
conversion (optional) | None (default) or Pdf. |
proposedFileName (optional) | Proposed file name. |
/Document and /Result/Document and /Result reject update connects (with a DocumentLocation) and point to /Update with a 400; conversely, /Update rejects plain generation connects.
Result
The result depends on the template type. In all cases, a file is created.
For Word, Excel and PowerPoint templates, it is a corresponding file.
Outlook
For all Outlook templates, HTML is returned by default, along with a list of linked images in json format:
{
"Body":"<html><head></head><body><p>Hello World</p>\r\n<p><b>My Firstname</b> My LastName</p>\r\n<img src=\"cid:profile-org-logo-1312016b.png\"></body></html>",
"AttachmentImages":[
{
"Name":"profile-org-logo-1312016b.png",
"Base64Data":"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAA1JREFUGFdj+P//PwMACPwC/ohfBuAAAAAASUVORK5CYII="
}
]
}
Body: Contains the HTML content of the signature or email template. If image data from the profile is accessed in the template (e.g. via<img src="{{Profile.Org.Logo}}" />), the image is replaced via acid-link and stored inAttachmentImages.
Note: If external images are linked or images are stored directly via base64 in the template/signature, nocid-link is added. This only happens via primedocs images.AttachmentImages: Contains allcid-images.
<primedocsConnect>
<Template Id="e76712a7-d7ab-4112-9240-e688522e5f75" />
<Author>
<Profile Id="dfc92748-fbf2-4861-bfac-683fec6139fe" />
</Author>
<!-- This can be omitted, because this is the default: -->
<Outlook ContentType="Html" />
</primedocsConnect>
PlainText
PlainText signatures and email templates can also be defined via the Connect API. To do this, Connect must be configured with the Outlook-element:
<primedocsConnect>
<Template Id="e76712a7-d7ab-4112-9240-e688522e5f75" />
<Author>
<Profile Id="dfc92748-fbf2-4861-bfac-683fec6139fe" />
</Author>
<Outlook ContentType="PlainText" />
</primedocsConnect>
In this case, the following json is returned:
{
"PlainTextContent":"My Firstname My Lastname"
}
ConnectResultReport
The POST /Result endpoint returns a ConnectResultReport as JSON. It describes the outcome of the generation and the processing of the commands:
{
"Status": "OK",
"Message": null,
"Messages": [
{ "Type": "Info", "Message": "…", "InternalMessage": null }
],
"CreatedOnUtc": "2026-01-01T12:00:00Z",
"Dialogs": [
{ "Title": "…", "Message": "…", "ButtonLabel": "…", "ButtonUri": "…" }
],
"HasDownload": false
}
| Field | Description |
|---|---|
Status | Outcome of the generation: OK, Error, Cancelled, Running, or Unknown. |
Message | Summary error message if Status is not OK (otherwise null). |
Messages | List of all log messages, each with Type, Message, and an optional InternalMessage. |
CreatedOnUtc | Completion time (UTC). |
Dialogs | Dialogs produced from ShowDialog commands (Title, Message, ButtonLabel, ButtonUri) for display in the client. |
HasDownload | true if a download (e.g. from a series output) is available. |
Authentication and call
To call the Connect APIs, a corresponding client must be registered in the primedocs.config, see primedocs.config.
After registration, an AccessToken can be requested from the IdS. The actual call can then be made against the Connect/Document endpoint of the WebApi using the AccessToken.
This PowerShell example shows how to obtain the AccessToken and call the endpoint:
# Configuration
$datasourceId = "b78c3707-d7c7-4fc7-b97f-87d70f63c1ac"
$tokenUrl = "https://{instanz}/ids/connect/token"
$baseApiUrl = "https://{instanz}/webapi/api"
$clientID = "CustomApiClient"
$clientSecret = "CustomClient_Secret_123"
$scope = "pd_ConnectWebApi"
$tokenRequestHeaders = @{
"Content-Type" = "application/x-www-form-urlencoded"
}
$tokenRequestBody = @{
client_id = $clientID
client_secret = $clientSecret
grant_type = "client_credentials"
scope = $scope
}
try {
$tokenResponse = Invoke-RestMethod -Uri $tokenUrl -Method POST -Headers $tokenRequestHeaders -Body $tokenRequestBody
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
if (-not $tokenResponse.access_token) {
Write-Error "Failed to obtain an access token!"
exit 1
}
Write-Host "Access Token: $($tokenResponse.access_token)"
$accessToken = $tokenResponse.access_token
$apiRequestHeaders = @{
"Authorization" = "Bearer $accessToken"
}
$putBodyRequestHeaders = @{
"Content-Type" = "application/json"
"Authorization" = "Bearer $accessToken"
}
$xmlBodyRequestHeaders = @{
"Content-Type" = "application/xml"
"Authorization" = "Bearer $accessToken"
}
function Show-Menu {
Write-Host "================ Main Menu ================"
Write-Host "1: Generate Document"
Write-Host "2: Validate Connect Form"
Write-Host "3: Create Connect Session"
Write-Host "4: Get Templates"
Write-Host "Q: Exit"
}
function GenerateDocument {
$connectFilePath = Read-Host "Enter connect file path"
$proposedFileName = Read-Host "Enter proposed file name (without extension, optional)"
$outputFilePath = Read-Host "Enter output file path (e.g., C:\\Temp\\Generated.docx)"
$pdfConversion = Read-Host "Convert result to pdf (y/n, default n)"
if (-not (Test-Path $connectFilePath)) {
Write-Error "Connect file not found: $connectFilePath"
return
}
$connectFileContent = Get-Content -Path $connectFilePath -Raw
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Connect/Document"
if (![string]::IsNullOrWhiteSpace($proposedFileName)) {
$apiUrl += "?proposedFileName=$proposedFileName"
}
if ($pdfConversion -eq "y" -or $pdfConversion -eq "Y") {
if ($apiUrl -like "*?*") {
$apiUrl += "&conversion=Pdf"
}
else {
$apiUrl += "?conversion=Pdf"
}
}
try {
Invoke-WebRequest -Uri $apiUrl -Method POST -Headers $xmlBodyRequestHeaders -Body $connectFileContent -OutFile $outputFilePath
Write-Host "File saved to: $outputFilePath"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function ValidateConnectForm {
$templateId = Read-Host "Enter Template ID"
$fieldKey = Read-Host "Enter field key"
$fieldValue = Read-Host "Enter field value"
$body = @{
templateId = $templateId
formValues = @{
$fieldKey = $fieldValue
}
}
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Connect/Validate"
try {
$utf8body = ([System.Text.Encoding]::UTF8.GetBytes(($body | ConvertTo-Json)))
$response = Invoke-RestMethod -Uri $apiUrl -Method POST -Headers $putBodyRequestHeaders -Body $utf8body
$response | ConvertTo-Json -Depth 6
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function CreateConnectSession {
$connectFilePath = Read-Host "Enter connect file path"
if (-not (Test-Path $connectFilePath)) {
Write-Error "Connect file not found: $connectFilePath"
return
}
$connectFileContent = Get-Content -Path $connectFilePath -Raw
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Connect/Session"
try {
$response = Invoke-RestMethod -Uri $apiUrl -Method POST -Headers $xmlBodyRequestHeaders -Body $connectFileContent
Write-Output "SessionId: $($response.sessionId)"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetTemplates {
$pageSize = Read-Host "Enter pagesize"
$page = Read-Host "Enter page"
$userId = Read-Host "Enter userId (or empty)"
$userQuery = Read-Host "Enter userQuery (or empty)"
$templateQuery = Read-Host "Enter templateQuery (or empty)"
$uiLcid = Read-Host "Enter uiLcid (or empty)"
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Connect/Templates?pageSize=$($pageSize)&page=$($page)"
if (![string]::IsNullOrWhiteSpace($userId)) { $apiUrl += "&userId=$userId" }
if (![string]::IsNullOrWhiteSpace($userQuery)) { $apiUrl += "&userQuery=$userQuery" }
if (![string]::IsNullOrWhiteSpace($templateQuery)) { $apiUrl += "&templateQuery=$templateQuery" }
if (![string]::IsNullOrWhiteSpace($uiLcid)) { $apiUrl += "&uiLcid=$uiLcid" }
try {
$response = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
foreach ($template in $response.data) {
Write-Output "$($template.id): $($template.localizedName)'"
}
Write-Output "Page: $($response.pagingDetails.page) / $($response.pagingDetails.totalPages)"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
do {
Show-Menu
$selection = Read-Host "Please select an option"
switch ($selection) {
'1' { GenerateDocument }
'2' { ValidateConnectForm }
'3' { CreateConnectSession }
'4' { GetTemplates }
'Q' { break; }
Default {
Write-Host "Invalid option selected"
}
}
} while ($selection -ne 'Q')
Error handling
The HTTP status codes and the error response format are described uniformly for all API areas under API → Error handling. In addition, the POST /Result endpoint returns a ConnectResultReport with Status: "Error" and a Message in case of an error.
Swagger / Open API
The full, always up-to-date OpenAPI description can be obtained directly from a running instance, e.g. from the PrimeSoft reference instance:
https://primesoft.primedocs.io/webapi/swagger/index.html
You can also visualise the description using the Swagger Editor. Below is the excerpt for the Connect/Document endpoint as an example:
{
"openapi": "3.0.1",
"info": {
"title": "primedocs WebApi",
"version": "v3"
},
"paths": {
"/api/v3/{datasourceId}/Connect/Document": {
"post": {
"tags": ["Connect"],
"parameters": [
{
"name": "proposedFileName",
"in": "query",
"schema": { "type": "string" }
},
{
"name": "conversion",
"in": "query",
"schema": { "type": "string", "enum": ["None", "Pdf"] }
},
{
"name": "datasourceId",
"in": "path",
"required": true,
"schema": { "type": "string", "format": "uuid" }
}
],
"responses": {
"200": { "description": "Success" }
}
}
}
}
}