> For the complete documentation index, see [llms.txt](https://docs.solutioo.de/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.solutioo.de/gls-connector/gls-connector_en_us/support/developer-reference.md).

# Developer Reference

Technical reference for AL developers: dependency, data context, the six extension events and a subscriber example.

This page is for AL developers who extend the GLS Connector with their own extension. You do not need this page for normal use.

## 1. Extension model and supported scope

You extend the GLS Connector exclusively through **six integration events** (see section 4). Only these events are intended as extension points.

The following are not committed as a stable interface:

* public procedures of the codeunits, even if they can technically be called,
* internal table structures and field meanings beyond the events,
* the structure of the GLS request beyond what is passed in the event.

A web service or API interface for external systems is not part of this reference.

## 2. Development environment, dependencies, versions

| Property         | Value                                |
| ---------------- | ------------------------------------ |
| App ID           | 3e6e4d00-ce16-4a21-9b22-bed6e333afaa |
| Name             | GLS Connector                        |
| Publisher        | solutioo                             |
| Version          | 26.13.40.0                           |
| application      | 25.0.0.0                             |
| runtime          | 14.0                                 |
| Own dependencies | none                                 |

Entry in your extension's app.json:

```json
"dependencies": [
  {
    "id": "3e6e4d00-ce16-4a21-9b22-bed6e333afaa",
    "name": "GLS Connector",
    "publisher": "solutioo",
    "version": "26.13.40.0"
  }
]
```

Download the symbols in a sandbox where the GLS Connector is installed. Set application and runtime of your extension to at least 25.0.0.0 and 14.0, respectively.

## 3. Authentication, permissions, data context

* To compile your subscriber, you need the app's symbols, not GLS credentials or access to a customer environment. For a later integration test, use your own sandbox and its GLS test access.
* The GLS credentials are stored per company in the app's isolated storage. Your extension has no access to them and does not need it.
* Subscribers run in the session of the user who triggers them, with that user's permissions, in the current company. Users still need the GLS permission sets, such as **GLS Integration User**.
* If your subscriber reads or writes additional tables, ship your own permission sets for them.
* The package and order records contain address and contact data. Do not write this data to telemetry or logs.

## 4. Event reference

### OnBeforeSendShipmentRequest

Publisher: codeunit 72243043 "SOUGLS API Management", \[IntegrationEvent(false, false)]

```al
local procedure OnBeforeSendShipmentRequest(var RequestJson: JsonObject; SOUGLSPackageHeaderRecord: Record "SOUGLS Package Header"; SalesHeader: Record "Sales Header")
```

**Timing:** after the request has been built with the Shipment and PrintingOptions nodes, immediately before it is sent to GLS. The first package of the shipment and the available sales header are passed. In flows without a sales order, you must not assume a populated SalesHeader. RequestJson can be modified; the package and sales header are passed here without var.

**Purpose:** add specific data to the request. Changes to RequestJson go directly to GLS. Do not remove or overwrite existing values without clarifying the consequences with GLS.

### OnAfterShipmentUploaded

Publisher: codeunit 72243043 "SOUGLS API Management", \[IntegrationEvent(false, false)]

```al
local procedure OnAfterShipmentUploaded(var SOUGLSPackageHeaderRecord: Record "SOUGLS Package Header")
```

**Timing:** after a successful upload, **per package** in the processing loop, after the attempt to reduce box inventory. For a shipment with three packages, the event is raised three times.

**Purpose:** follow-up actions after the upload, such as telemetry. The package record is passed with var. That alone does not guarantee that your changes are saved; plan any required write operations and permissions explicitly. Do not change keys or filters of the passed record that affect the running multi-package loop.

### OnBeforeSetPackageSubpageVisible

Publisher: codeunit 72243049 "SOUGLS Sales UI", \[IntegrationEvent(false, false)]

```al
local procedure OnBeforeSetPackageSubpageVisible(SalesHeader: Record "Sales Header"; var IsVisible: Boolean)
```

**Timing:** when determining whether the package section is shown on the sales document. IsVisible is initialized to true.

### OnBeforeSetListActionsVisible

Publisher: codeunit 72243049 "SOUGLS Sales UI", \[IntegrationEvent(false, false)]

```al
local procedure OnBeforeSetListActionsVisible(var IsVisible: Boolean)
```

**Timing:** when determining whether GLS actions are shown in lists. Initialized to true.

### OnBeforeSetCustomerCardFieldsVisible

Publisher: codeunit 72243049 "SOUGLS Sales UI", \[IntegrationEvent(false, false)]

```al
local procedure OnBeforeSetCustomerCardFieldsVisible(var IsVisible: Boolean)
```

**Timing:** when determining whether GLS fields are shown on the customer card. Initialized to true.

### OnBeforeDistributeSmartPacking

Publisher: codeunit 72243053 "SOUGLS Smart Packing", \[IntegrationEvent(false, false)]

```al
local procedure OnBeforeDistributeSmartPacking(var SalesHeader: Record "Sales Header"; BoxCode: Code[20]; var IsHandled: Boolean)
```

**Timing:** after the user has confirmed the Smart Packing recommendation, before the packages are created. If you set IsHandled to true, the standard package creation is skipped; your extension is then responsible for the packages.

## 5. Minimal subscriber example

The example writes a telemetry message without personal data after each uploaded package. Adjust the object ID and telemetry ID to your number range.

{% hint style="warning" %}
This example was created for the documentation and has not yet been compiled or tested. Verify it in your sandbox.
{% endhint %}

```al
codeunit 50100 "My GLS Upload Telemetry"
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"SOUGLS API Management", 'OnAfterShipmentUploaded', '', false, false)]
    local procedure LogGlsPackageUploaded(var SOUGLSPackageHeaderRecord: Record "SOUGLS Package Header")
    var
        CustomDimensions: Dictionary of [Text, Text];
    begin
        CustomDimensions.Add('EventName', 'OnAfterShipmentUploaded');
        Session.LogMessage('MYGLS0001', 'GLS package uploaded', Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions);
    end;
}
```

The example does not use parcel numbers, addresses or company names. It does not modify the passed record and does not send any further request to GLS.

## 6. Transactions, retries, errors

* Subscribers run in the caller's transaction. An error in a subscriber aborts the running process.
* **Especially critical for OnAfterShipmentUploaded:** at this point, the shipment already exists at GLS. If your subscriber raises an error, local changes can be rolled back while the GLS shipment remains. Catch errors and do not call Error there.
* Do not call Commit, and avoid long-running calls, such as HTTP requests, in these events.
* Expect multiple calls: OnAfterShipmentUploaded runs per package, and users can upload again after an error. Make follow-up actions idempotent.
* In OnBeforeSendShipmentRequest, invalid JSON causes GLS to reject the request.

## 7. Testing and debugging

* Test in a Business Central sandbox with GLS sandbox access.
* Set breakpoints in your subscriber and trigger **Smart Packing** or **Upload Packages to GLS** on the sales order.
* Check the request to GLS in the **API Call Log**.
* For version 26.13.40.0, we currently do not have our own up-to-date runtime test of the events. Therefore, verify their timing and frequency in your environment before going live.

## 8. Compatibility and changes

* This reference applies to version 26.13.40.0. After GLS Connector updates, check whether your extension still compiles and behaves as expected.
* Set the minimum version in your dependency to the version you tested.
* Rely only on the six events. Public procedures and internal processes can change without notice.

## 9. Technical FAQ and support

**Can I replace package creation completely?**

Only for Smart Packing, via OnBeforeDistributeSmartPacking with IsHandled.

**Can I read the GLS credentials?**

No. They are stored in the app's isolated storage.

**Can I hide the GLS fields on the customer card?**

Yes, with OnBeforeSetCustomerCardFieldsVisible.

**Do I get access to customer environments or an API key?**

That is not necessary. You develop against the symbols of the installed app.

Send technical questions to <support@solutioo.de>. Include the app version, the affected event and a minimal code excerpt without personal data.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.solutioo.de/gls-connector/gls-connector_en_us/support/developer-reference.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
