> ## Documentation Index
> Fetch the complete documentation index at: https://docu.truemetrics.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Metadata

> Logging Metadata allows you to map truemetrics data to your existing data.

# Introduction

The truemetrics SDK supports logging of not only sensor data but also metadata from your mobile application. This allows you to enrich truemetrics data with specific courier events and data to get most of truemetrics data.

# When to send metadata and what to use as trigger

When is the right time to send metadata? The truemetrics algorithm matches the metadata closest in time to the stop event. Most customers choose an interaction that occurs close to the actual service, such as scanning the parcel or the courier swiping to confirm arrival at the delivery location.

Try to avoid triggers that the driver might often forget, such as marking the delivery as closed or starting navigation to the next stop, as this can lead to mismatches between the metadata and the stop data in truemetrics.

If you're unsure, either discuss this with truemetrics or use multiple triggers to send metadata. Just make sure to include the type of trigger so that the data is not interpreted as multiple deliveries.

| Example Key   | Example Value                    |
| ------------- | -------------------------------- |
| type\_trigger | job\_finalized / scan\_performed |
| ...           | ...                              |

# How to send metadata

Use the `StandardMetadata` class to log structured event metadata:

```kotlin theme={null}
import io.truemetrics.truemetricssdk.metadata.StandardMetadata

val sdk = TruemetricsSdk.getInstance()
sdk.logMetadata(StandardMetadata(
    eventTime = "2025-01-15T14:30:00Z",
    eventType = "delivery_successful",
    deliveryId = "parcel_123",
    tourId = "tour_456",
    waypointLatitude = "52.5200",
    waypointLongitude = "13.4050",
    referenceLatitude = "52.5201",
    referenceLongitude = "13.4051",
    address = "Pflanzstrasse 5, 10762 Berlin",
    extra = mapOf(
        "type_vehicle" to "car",
        "type_consignee" to "B2C"
    )
))
```

<Note>
  The map-based `logMetadata(Map<String, String>)` overload is deprecated. Use `logMetadata(StandardMetadata)` instead.
</Note>

# Required Metadata Fields

The `StandardMetadata` class contains the following fields. All fields are strings.

| Field                | Serialized Key           | Description                                                                                |
| -------------------- | ------------------------ | ------------------------------------------------------------------------------------------ |
| `eventTime`          | `t_event`                | Timestamp when the event happened                                                          |
| `eventType`          | `type_event`             | Name of the event, e.g. `pickup_successful`, `delivery_successful`, `delivery_to_neighbor` |
| `deliveryId`         | `id_delivery_external`   | External identifier of the delivery, e.g. parcel ID                                        |
| `tourId`             | `id_tour`                | Identifier of the tour                                                                     |
| `waypointLatitude`   | `lat_waypoint_external`  | Latitude where the courier is routed to (normally a coordinate on the street)              |
| `waypointLongitude`  | `lon_waypoint_external`  | Longitude where the courier is routed to (normally a coordinate on the street)             |
| `referenceLatitude`  | `lat_reference_external` | Latitude where the courier is sent (building/destination)                                  |
| `referenceLongitude` | `lon_reference_external` | Longitude where the courier is sent (building/destination)                                 |
| `address`            | `address_raw`            | Raw address string, if already normalised available                                        |
| `extra`              | —                        | Additional key-value pairs (merged into the payload, standard fields take precedence)      |

# Additional Best Practices

## Service Type

Stop times can vary significantly depending on the type of service performed. Was it a fast B2B drop-off with a single parcel, or a more complex B2C pickup requiring a signature? You know best what is important for your business, and truemetrics allows you to enrich the data with your specific categories, enabling you to later analyze the data based on those categories.

Typical examples:

| Example Key     | Example Value        |
| --------------- | -------------------- |
| type\_consignee | B2C                  |
| type\_stop      | pickup (or drop-off) |
| type\_service   | E42c (internal code) |

## Vehicle types

Some of our customers have multiple vehicle types e.g. Trucks, cars and two-wheelers.

Especially for parking places,  it's quite interesting to be able to seperate this data by the type of the vehicle. To do that, just introduce a new  key-value pair and log the vehicle type.

| Example Key   | Example Value |
| ------------- | ------------- |
| type\_vehicle | car           |

# Advanced Metadata Features

## Metadata Templates

Create reusable templates for consistent metadata structures:

```kotlin theme={null}
val sdk = TruemetricsSdk.getInstance()

// Create a template
sdk.createMetadataTemplate("delivery", mapOf(
    "type" to "delivery",
    "version" to "1.0"
))

// Retrieve a template
val template = sdk.getMetadataTemplate("delivery")

// List all templates
val templateNames = sdk.getMetadataTemplateNames()

// Remove a template
sdk.removeMetadataTemplate("old_template")
```

## Tagged Metadata

Build metadata incrementally using tags:

```kotlin theme={null}
val sdk = TruemetricsSdk.getInstance()

// Create tagged metadata from a template
sdk.createMetadataFromTemplate("current_delivery", "delivery")

// Add data incrementally
sdk.appendToMetadataTag("current_delivery", "orderId", "123")
sdk.appendToMetadataTag("current_delivery", mapOf(
    "lat" to "52.5",
    "lon" to "13.4"
))

// Log when ready
sdk.logMetadataByTag("current_delivery")

// Clean up
sdk.removeMetadataTag("current_delivery")
```

### Tagged Metadata API Reference

| Method                                      | Return Type            | Description                    |
| ------------------------------------------- | ---------------------- | ------------------------------ |
| `createMetadataTemplate(name, data)`        | `Unit`                 | Create reusable template       |
| `getMetadataTemplate(name)`                 | `Map<String, String>?` | Get template by name           |
| `getMetadataTemplateNames()`                | `Set<String>`          | List all templates             |
| `removeMetadataTemplate(name)`              | `Boolean`              | Remove template                |
| `createMetadataFromTemplate(tag, template)` | `Boolean`              | Create tag from template       |
| `appendToMetadataTag(tag, data)`            | `Unit`                 | Append map to tagged metadata  |
| `appendToMetadataTag(tag, key, value)`      | `Unit`                 | Append single key-value to tag |
| `getMetadataByTag(tag)`                     | `Map<String, String>?` | Get tagged metadata            |
| `getMetadataTags()`                         | `Set<String>`          | Get all active tags            |
| `logMetadataByTag(tag)`                     | `Boolean`              | Log tagged metadata            |
| `removeMetadataTag(tag)`                    | `Boolean`              | Remove tag                     |
| `removeFromMetadataTag(tag, key)`           | `Boolean`              | Remove key from tag            |
| `clearAllMetadata()`                        | `Unit`                 | Clear all templates and tags   |
