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:
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"
)
))
The map-based logMetadata(Map<String, String>) overload is deprecated. Use logMetadata(StandardMetadata) instead.
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
Create reusable templates for consistent metadata structures:
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")
Build metadata incrementally using tags:
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")
| 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 |