Show / Hide Table of Contents

API Samples & Common Scenarios

This page demonstrates common integration scenarios with the Platina Standard REST API. All examples use API version v8.0 and assume OAuth 2.0 authentication.

πŸ’‘ Tip: The API exposes interactive documentation at /swagger where you can try endpoints directly. See Swagger UI.


Authentication

All requests require a Bearer token in the Authorization header. See the Authorization Guide for setup.

Get a token (C#)

using Microsoft.Identity.Client;

var app = ConfidentialClientApplicationBuilder
    .Create("<client-id>")
    .WithClientSecret("<client-secret>")
    .WithAuthority("https://login.microsoftonline.com/<tenant-id>/")
    .Build();

var result = await app.AcquireTokenForClient(
    new[] { "api://<client-id>/.default" }
).ExecuteAsync();

string accessToken = result.AccessToken;

Using the token

All subsequent examples use this helper:

using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var client = new HttpClient
{
    BaseAddress = new Uri("https://your-server/api/v8.0/")
};
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);

cURL

TOKEN="<your-bearer-token>"
BASE_URL="https://your-server/api/v8.0"

curl -H "Authorization: Bearer $TOKEN" "$BASE_URL/diaries"

Scenario 1 β€” List Diaries and Reference Data

Before creating cases or deeds, you need to discover available diaries, case types, and other reference data.

List all diaries

GET /v8.0/diaries
var response = await client.GetAsync("diaries");
var diaries = await response.Content.ReadFromJsonAsync<JsonElement>();

// Each diary has an "id" (ApiId) and "name"
foreach (var diary in diaries.GetProperty("items").EnumerateArray())
{
    Console.WriteLine($"{diary.GetProperty("id")} β€” {diary.GetProperty("name")}");
}

List reference data

GET /v8.0/reference-data

This returns links to all available reference data collections:

var refData = await client.GetFromJsonAsync<JsonElement>("reference-data");
// Returns links to: countries, case-types, deed-types, business-codes,
// journalized-case-statuses, secrecy-levels, pul-levels, etc.

Useful reference data endpoints

Endpoint Returns
GET /reference-data/case-types All case types
GET /reference-data/deed-types All deed types
GET /reference-data/business-codes Business codes
GET /reference-data/journalized-case-statuses Case statuses
GET /reference-data/journalized-case-origins Case origins (Incoming, Outgoing, etc.)
GET /reference-data/confidential-paragraphs Confidentiality paragraphs
GET /diaries/{id}/handling-officers Handling officers for a diary
GET /diaries/{id}/postlists Post lists for a diary
GET /diaries/{id}/case-types Case types available in a specific diary

Scenario 2 β€” Create a Journalized Case

Register a new incoming case in a diary.

POST /v8.0/diaries/{diaryId}/journalized-cases
Content-Type: application/json

Request body

{
  "registrationDate": "2025-04-01T00:00:00+02:00",
  "inOutDate": "2025-04-01T00:00:00+02:00",
  "statusId": "<status-api-id>",
  "origin": "Incoming",
  "caseTypeId": "<case-type-api-id>",
  "pulLevel": 0,
  "secrecyLevel": 0,
  "title": "Building permit application β€” Storgatan 12",
  "description": "Application for building permit, residential extension.",
  "initiators": [
    {
      "name": "Anna Andersson",
      "city": "Stockholm",
      "zipCode": "114 32",
      "streetAddress": "Storgatan 12",
      "email": "anna.andersson@example.com",
      "personOrgNumber": "198501011234"
    }
  ],
  "handlingOfficers": [
    {
      "id": "<officer-api-id>",
      "message": "Please review and register",
      "isMain": true
    }
  ]
}

C# example

var diaryId = "Nk981MWbd04"; // from GET /diaries

var caseData = new
{
    registrationDate = "2025-04-01T00:00:00+02:00",
    inOutDate = "2025-04-01T00:00:00+02:00",
    statusId = "<status-api-id>",
    origin = "Incoming",
    caseTypeId = "<case-type-api-id>",
    pulLevel = 0,
    secrecyLevel = 0,
    title = "Building permit application β€” Storgatan 12",
    description = "Application for building permit, residential extension.",
    initiators = new[]
    {
        new
        {
            name = "Anna Andersson",
            city = "Stockholm",
            zipCode = "114 32",
            streetAddress = "Storgatan 12",
            email = "anna.andersson@example.com"
        }
    }
};

var json = JsonSerializer.Serialize(caseData);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await client.PostAsync($"diaries/{diaryId}/journalized-cases", content);

if (response.StatusCode == System.Net.HttpStatusCode.Created)
{
    // The Location header contains the URL to the new case
    var location = response.Headers.Location;
    // The X-Platina-DiaryNumber header contains the assigned diary number
    var diaryNumber = response.Headers.GetValues("X-Platina-DiaryNumber").First();

    Console.WriteLine($"Case created! Diary number: {diaryNumber}");
    Console.WriteLine($"Location: {location}");
}

Response

  • 201 Created β€” Case was created. Check Location header for the case URL and X-Platina-DiaryNumber for the assigned number.
  • 400 Bad Request β€” Validation error (missing required fields, invalid data).
  • 404 Not Found β€” Diary not found or no access.
  • 409 Conflict β€” Configuration conflict (e.g. business code required but not provided).

Scenario 3 β€” Create a Deed

Register a standalone deed (not linked to a journalized case).

POST /v8.0/deeds
Content-Type: application/json
{
  "diaryId": "<diary-api-id>",
  "postListId": "<postlist-api-id>",
  "registrationDate": "2025-04-01T00:00:00+02:00",
  "inOutDate": "2025-04-01T00:00:00+02:00",
  "origin": "DrawnUp",
  "deedTypeId": "<deed-type-api-id>",
  "pulLevel": 0,
  "secrecyLevel": 0,
  "title": "Internal memo β€” Budget 2025",
  "description": "Departmental budget proposal for fiscal year 2025.",
  "initiators": [
    {
      "name": "Erik Eriksson",
      "email": "erik.eriksson@example.com"
    }
  ]
}

Response

  • 201 Created β€” Deed created. Location header has the deed URL.

Scenario 4 β€” Create a Deed Under a Journalized Case

Add a deed to an existing case. This is the most common pattern: a case is created first, then deeds are added as the case progresses.

POST /v8.0/journalized-cases/{caseId}/deeds
Content-Type: application/json
{
  "postListId": "<postlist-api-id>",
  "registrationDate": "2025-04-01T00:00:00+02:00",
  "inOutDate": "2025-04-01T00:00:00+02:00",
  "origin": "Incoming",
  "deedTypeId": "<deed-type-api-id>",
  "pulLevel": 0,
  "secrecyLevel": 0,
  "title": "Architect drawings β€” revision 2",
  "description": "Updated floor plans received from architect."
}

Response

  • 201 Created β€” Location header has the deed URL, X-Platina-DiaryNumber has the assigned number.

Scenario 5 β€” Upload a Document to a Case

Attach a file (e.g. PDF, DOCX) to a journalized case.

POST /v8.0/journalized-cases/{caseId}/documents/from-file
Content-Type: multipart/form-data

C# example

var caseId = "ozA5b1LlEzx";
var filePath = @"C:\Documents\building-plans.pdf";

using var fileStream = File.OpenRead(filePath);
using var formContent = new MultipartFormDataContent();

var fileContent = new StreamContent(fileStream);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
    Name = "file",
    FileName = Path.GetFileName(filePath)
};

formContent.Add(fileContent);

var response = await client.PostAsync(
    $"journalized-cases/{caseId}/documents/from-file",
    formContent
);

if (response.StatusCode == System.Net.HttpStatusCode.Created)
{
    var documentUrl = response.Headers.Location;
    Console.WriteLine($"Document uploaded: {documentUrl}");
}

cURL example

curl -X POST "$BASE_URL/journalized-cases/$CASE_ID/documents/from-file" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@building-plans.pdf"

Scenario 6 β€” Search and Retrieve Cases

Look up a case by diary number

GET /v8.0/journalized-cases/with-diary-number/{diaryNumber}
var diaryNumber = "2025-0042";
var response = await client.GetAsync(
    $"journalized-cases/with-diary-number/{diaryNumber}"
);
var caseData = await response.Content.ReadFromJsonAsync<JsonElement>();

Search cases with filters

GET /v8.0/journalized-cases/with-metadata?diaryId={id}&initiatorName={name}

Get a case with its deeds

// Get the case
var caseResponse = await client.GetAsync($"journalized-cases/{caseId}");
var caseData = await caseResponse.Content.ReadFromJsonAsync<JsonElement>();

// Get its deeds
var deedsResponse = await client.GetAsync($"journalized-cases/{caseId}/deeds");
var deeds = await deedsResponse.Content.ReadFromJsonAsync<JsonElement>();

Scenario 7 β€” Work with Custom Data

Read and write custom fields on journalized cases, deeds, or documents.

Read custom data

GET /v8.0/journalized-cases/{id}/custom-data

Write custom data

PUT /v8.0/journalized-cases/{id}/custom-data
Content-Type: application/json
{
  "bkStr1": "Project Alpha",
  "bkStr2": "Phase 2",
  "bkInt8": 42,
  "bkFloat5": 99.95
}

For details on how custom fields map to Platina's tCustomData table, see Custom Data Support.


Scenario 8 β€” Update and Finish a Case

Update a journalized case

PATCH /v8.0/journalized-cases/{id}
Content-Type: application/json
{
  "title": "Building permit β€” Storgatan 12 (APPROVED)",
  "description": "Updated: permit granted 2025-04-15."
}

Finish (close) a journalized case

POST /v8.0/finished-journalized-cases
Content-Type: application/json
{
  "journalizedCaseId": "<case-api-id>"
}

Scenario 9 β€” Manage Handling Officers and Initiators

Add a handling officer to a case

POST /v8.0/journalized-cases/{id}/handling-officers
Content-Type: application/json
{
  "id": "<officer-api-id>",
  "message": "Forwarded for legal review",
  "isMain": false
}

Add an initiator to a case

POST /v8.0/journalized-cases/{id}/initiators
Content-Type: application/json
{
  "name": "Karin Karlsson",
  "email": "karin@example.com",
  "city": "GΓΆteborg"
}

Remove a handling officer

DELETE /v8.0/journalized-cases/{id}/handling-officers/{officerId}

Complete Workflow Example

A typical integration follows this pattern:

1. Authenticate          β†’  Get Bearer token
2. Discover              β†’  GET /diaries, GET /reference-data/*
3. Create case           β†’  POST /diaries/{id}/journalized-cases
4. Upload documents      β†’  POST /journalized-cases/{id}/documents/from-file
5. Add deeds             β†’  POST /journalized-cases/{id}/deeds
6. Set custom data       β†’  PUT /journalized-cases/{id}/custom-data
7. Finish case           β†’  POST /finished-journalized-cases

Error Handling

The API uses standard HTTP status codes:

Code Meaning Action
200 Success Process the response
201 Created Resource created β€” check Location header
400 Bad Request Fix validation errors in request body
401 Unauthorized Token expired or invalid β€” re-authenticate
404 Not Found Resource doesn't exist or user lacks access
409 Conflict Request contradicts Platina settings (e.g. missing business code)
500 Server Error Contact support; check server logs

Error responses include a JSON body with details:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "Bad Request",
  "status": 400,
  "errors": {
    "title": ["The title field is required."]
  }
}
Back to top Created by Formpipe