## Setting up the HTTP client

The S2S (System-to-System) platform has undergone a modernization, transitioning from SOAP web services to a HTTP XML API server architecture. This upgrade requires all integrating parties to migrate their existing SOAP connectors to properly configured HTTP clients.

This guide provides a complete overview of:

- HTTP XML API architecture details

- Required configuration changes for client integration

- Authentication and security requirements (mTLS with OCES certificates)

- API endpoint structure

- Digital signature implementation for XML payloads

Throughout this documentation, you’ll find Java code examples extracted from the reference client. These examples demonstrate code snippets that could be used for reference when making your own implementation.

### Endpoints

The endpoints paths are structured in a way to maintain the naming of the SOAP endpoints. Each SOAP action have their own unique URL mapping.

All the endpoints follow the pattern:

    xml-api.tinglysning.dk/<SOAP_WEB_SERVICE_NAME>/<SOAP_ACTION>

Example endpoints are presented below:

SOAP Web Service | SOAP Action | Endpoint URL
--- | --- | ---
ElektroniskAkt | BilSummariskHent | xml-api.tinglysning.dk/ElektroniskAkt/BilSummariskHent
TingbogAnmeld | EjendomOpret | xml-api.tinglysning.dk/TingbogAnmeld/EjendomOpret
Abonnement | AbonnementOpret | xml-api.tinglysning.dk/Abonnement/AbonnementOpret

### OCES certifikat

All endpoints require mTLS, where the client uses a valid OCES certificate.

If a valid OCES certificate is not used for mTLS, the endpoints will respond with an HTTP status `400 Bad Request`, and an error message in XML that follows the schema defined in Fejl.xsd.

In the event of a lack of OCES certification, the error message in XML will look like:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Fejl xmlns="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">
        <faultcode>Client</faultcode>
        <faultstring>Der var intet SSL certifikat i requestet</faultstring>
    </Fejl>

### Reference implementation

The Java reference client demonstrates how to create an `SSLContext` with an OCES client certificate and an OCES truststore.

This can subsequently be used to set up an HTTP client.

As shown in the Java reference client, an `SSLContext` can be created by:

    1
    Unresolved directive in klient.adoc - include::{javaDir}/SslContextCreate.java[]

An HTTP client can then be created and configured with mTLS:

    1
    Unresolved directive in klient.adoc - include::{javaDir}/HttpClientCreate.java[]

### Verification

Java reference client comes with connection tests. They are used to verify that successful connection to e-Tinglysning is possible. To verify that OCES certificates are correct, update the application.properties file in Integration test package. Then run one of the integration tests (for example ElektroniskAktSpec). Alternatively, you can run `gradle integrationTest` to run all connection tests.

Example configuration of keystores is shown below:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    ssl.keystore.system.certificate.path=test.pfx
    ssl.keystore.system.certificate.password=Test1234
    ssl.keystore.system.certificate.key.alias=testSystem
    ssl.keystore.system.certificate.type=PKCS12

    ssl.truststore.path=test.p12
    ssl.truststore.password=Test1234
    ssl.truststore.type=PKCS12

    ssl.keystore.company.certificate.path=test.pfx
    ssl.keystore.company.certificate.password=Test1234
    ssl.keystore.company.certificate.key.alias=testCompany
    ssl.keystore.company.certificate.type=PKCS12

## Headers

The S2S server is configured to require a set of custom headers in each HTTP call. To make a successful request, you are responsible for configuring your HTTP client to provide these headers in your calls. This chapter provides an overview of the expected values and possible issues that you may encounter.

Header | Required | Format
--- | --- | ---
Tinglysning-Message-ID | Yes | uuid:[uuid-v4]
Tinglysning-Relates-To | No | String

### Tinglysning-Message-ID

The land registry message ID is a random UUIDv4 generated by the client before sending a new request to the S2S endpoint. This header is used to uniquely identify the full request-response process, and therefore it is required in every request. It also helps both parties debug problems more easily.

#### Header structure

The header consists of the prefix "uuid:" followed by a randomly generated UUIDv4. The header must not contain uppercase letters.

Header name | Header value
--- | ---
Tinglysning-Message-ID | uuid:44b147ff-b221-43f7-be45-cdb55f085413

#### Expected errors

If the header is not provided, you can expect HTTP status `400 Bad Request` with this XML response:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Fejl xmlns="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">
        <ns2:faultcode xmlns="" xmlns:ns2="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">Client</ns2:faultcode>
        <faultstring>Følgende krævede header var ikke tilstede: Tinglysning-Message-ID</faultstring>
    </Fejl>

If the header has an invalid structure, expect HTTP status `400 Bad Request` with this XML response:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Fejl xmlns="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">
        <ns2:faultcode xmlns="" xmlns:ns2="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">Client</ns2:faultcode>
        <faultstring>Det modtagne MessageID er i invalidt format: uuid:ce01bb6d-3479-4975-8ab5-. Et MessageID skal være på formen uuid:[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}</faultstring>
    </Fejl>

### Tinglysning-Relates-To

Sometimes your application needs to provide additional reference information in the call. You can use the "relates to" header for this purpose. This header is not required and expects a string value.

Header name | Header value
--- | ---
Tinglysning-Relates-To | CASE-2024-001

### Content-Type

All endpoints expect users to provide their request body in XML format. API is configured to receive XML and will also respond with XML. If left out, this header will be filled out automatically but you can also set it up manually.

Header name | Header value
--- | ---
Content-Type | application/xml

#### Expected errors

Providing a different value will result in request rejection with HTTP status `415 Unsupported Media` Type and this message:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Fejl xmlns="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">
        <ns2:faultcode xmlns="" xmlns:ns2="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">Client</ns2:faultcode>
        <faultstring>Ikke understøttet Content-Type: 'test/test'. Indstil venligst 'Content-Type'-headeren til 'application/xml'.</faultstring>
    </Fejl>

#### Reference implementation

Given the correct SSL context and HTTP client setup (look at the Reference OCES implementation), you can create a successful call using the provided example from the Java reference client:

    1
    Unresolved directive in headers.adoc - include::{javaDir}/ExampleRequest.java[]

## Signing of payload

This chapter describes how to digitally sign XML documents using OCES (Offentlige Certifikater til Elektronisk Service) certificates. The implementation supports multiple signature types for different use cases in Danish digital infrastructure. Signing the document remains the same between SOAP and HTTP.

### Signature types

1. System Certificate Signing

   Used for standard document operations such as data retrieval and searching. This must be used as the default unless stated otherwise.

2. Non-Repudiation Certificate Signing

   Used for legally binding documents that modify existing data.

3. Disponent Role Signing

   Used for legally binding documents where a person acts on behalf of another individual or company.

Most endpoints still require you to sign the document. If you are unsure about which signature type to use, check the request message XSD in the controller documentation. In most cases, system certificate signing will be the correct option.

Usage and implementation of signature types can be found in the reference client by examining these methods:

    1
    Unresolved directive in signing.adoc - include::{javaDir}/SigningMethodsOverview.java[]

### Signature body

The signature takes the form of an encrypted string appended to the XML sent in the request body

Currently, the S2S server supports RSA_SHA1, RSA_SHA256, and RSA_SHA512 algorithms for signature methods and RSA_SHA1, RSA_SHA256 for digest. Creating signatures with other algorithms will result in document rejection. Due to security reasons, it is recommended to use at least RSA_SHA256, as RSA_SHA1 is not considered secure anymore.

All signatures follow the XML Digital Signature specification and include:

- SignedInfo: Contains canonicalization method, signature algorithm, and references

- KeyInfo: Embeds the X.509 certificate used for signing

- Signature Value: The actual cryptographic signature

Differences between signing methods:

Disponent signatures | Basic signatures
--- | ---
Use XPath filtering to sign only specific parts of the document while excluding metadata and administrative elements | The full document is signed in a designated element at the end of the XML
Use CanonicalizationMethod.INCLUSIVE | Use CanonicalizationMethod.EXCLUSIVE

For disponent signatures, HTTP XML API will check for the correct XPath expression. Either one of following expressions could be used to exclude parts of the document from signing.

XPATH_SUBSET_V1

    Unresolved directive in signing.adoc - include::{javaDir}/XpathSubsetv1.java[]

XPATH_SUBSET_V2

    Unresolved directive in signing.adoc - include::{javaDir}/XpathSubsetv2.java[]

Here is example from reference client on how you can include XPath into your project:

    1
    Unresolved directive in signing.adoc - include::{javaDir}/XpathInclude.java[]

### Example usages

Since the S2S reference client expects the XML to be passed as String, current examples will parse to the Document using helper methods.

For data retrieval, a simple signature will suffice:

    1
    Unresolved directive in signing.adoc - include::{javaDir}/SignBasic.java[]

When you need to change or add new data, signing with repudiation must be used. The example below shows a case when a disponent is involved in document creation. This requires two types of signatures at the same time:

    1
    Unresolved directive in signing.adoc - include::{javaDir}/SignDisponentRepudiation.java[]

## General error response

General failure response consists of HTML response with body that follows XML Fejl.xsd. Here is a result of example request with invalid UUID.

    HTTP/1.1 400 Bad Request
    Date: Thu, 31 Jul 2025 13:43:48 GMT
    Server: Apache/2.4.59 (Win64) OpenSSL/3.1.5
    Access-Control-Allow-Credentials: true
    Referrer-Policy: same-origin
    X-Frame-Options: DENY
    Content-Type: application/xml;charset=UTF-8
    X-Content-Type-Options: nosniff
    X-XSS-Protection: 1; mode=block
    Access-Control-Allow-Origin: http://localhost:4200
    Access-Control-Allow-Headers: origin, x-requested-with, content-type
    Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS
    X-Apache-Request-Id: (null)
    X-Apache-Stats: Received: t=1753969428028952 Elapsed time: D=125634
    X-Apache-Node: localhost
    Connection: close
    Transfer-Encoding: chunked
    Content-Length: 432

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?><Fejl xmlns="http://rep.oio.dk/tinglysning.dk/schema/fault/1/"><ns2:faultcode xmlns="" xmlns:ns2="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">Client</ns2:faultcode><faultstring>Det modtagne MessageID er i invalidt format: uuid:44b147ff-b221-43f7-be45-. Et MessageID skal være på formen uuid:[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}</faultstring></Fejl>