Skip to main content

GraphQL API

The Apollon API provides a full GraphQL interface with query/mutation support via async-graphql.

Endpoints

EndpointMethodDescription
/v1/gqlPOSTGraphQL query/mutation endpoint
/v1/graphiqlGETGraphiQL IDE (disabled when docs.graphiql = false)
/v1/schemaGETGraphQL schema in SDL format (plain text)

Custom Scalars

ScalarFormatExample
DateTimeRFC 3339 string"2026-06-09T12:00:00Z"
UUIDStandard UUID string"550e8400-e29b-41d4-a716-446655440000"

Queries

gps

Current GPS position from the Peplink router. Returns null if the GPS provider is unreachable.

query {
gps {
id
timestamp
latitude
longitude
altitude
speedKmh
speedMps
speedMph
speedKnots
tripId
}
}

gpsSpeed

Current speed from the Peplink router. Returns null if unreachable.

query {
gpsSpeed {
speedKmh
}
}

gpsHistory

Historical GPS records in a time range. Both parameters are unix timestamps (seconds). Defaults to the last 24 hours.

query {
gpsHistory(start: 1717848000, end: 1717934400) {
start
end
count
records {
id
timestamp
latitude
longitude
altitude
speedKmh
tripId
}
}
}
ArgumentTypeRequiredDefaultDescription
startIntNo24h agoStart of time range (unix timestamp)
endIntNonowEnd of time range (unix timestamp)

trips

All trips, ordered by start time descending.

query {
trips {
id
startTime
endTime
cargo
weight
status
logGps
category {
id
name
}
sender {
id
name
}
receiver {
id
name
}
gpsLocations {
latitude
longitude
speedKmh
timestamp
}
}
}

trip

A single trip by ID.

query {
trip(id: "550e8400-e29b-41d4-a716-446655440000") {
id
cargo
status
startLatitude
startLongitude
endLatitude
endLongitude
category { name }
sender { name }
receiver { name }
gpsLocations { latitude longitude timestamp }
}
}

clients

All clients, ordered by name ascending.

query {
clients {
id
name
email
phone
city
country
contacts {
id
name
email
position
isPrimary
}
tripsAsSender { id cargo status }
tripsAsReceiver { id cargo status }
}
}

client

A single client by ID.

query {
client(id: "550e8400-e29b-41d4-a716-446655440000") {
id
name
email
street
houseNumber
postalCode
city
country
additionalInfo
contacts { id name isPrimary }
tripsAsSender { id cargo }
tripsAsReceiver { id cargo }
}
}

categories

All cargo categories, ordered by name ascending.

query {
categories {
id
name
description
createdAt
updatedAt
trips { id cargo status }
}
}

category

A single cargo category by ID.

query {
category(id: "550e8400-e29b-41d4-a716-446655440000") {
id
name
description
createdAt
updatedAt
trips { id cargo status weight }
}
}

health

System health check covering database, Peplink, forwarding, and WebSocket status.

query {
health {
status
uptime
database
peplink
forwarding
websocket
websocketClients
timestamp
}
}

Mutations

createTrip

Create a new trip.

mutation {
createTrip(input: {
startLatitude: 51.5074
startLongitude: -0.1278
cargo: "Electronics"
categoryId: "..."
weight: 250.5
senderId: "..."
receiverId: "..."
logGps: true
}) {
id
startTime
cargo
status
}
}

Input: CreateTripInput

FieldTypeRequiredDefault
startLatitudeFloat!Yes--
startLongitudeFloat!Yes--
cargoString!Yes--
categoryIdUUID!Yes--
weightFloat!Yes--
senderIdUUID!Yes--
receiverIdUUID!Yes--
logGpsBoolean!Nofalse

updateTrip

Update an existing trip. Only provided fields are changed.

mutation {
updateTrip(input: {
id: "550e8400-..."
cargo: "Updated Electronics"
weight: 300.0
status: CANCELLED
}) {
id
cargo
weight
status
}
}

Input: UpdateTripInput

FieldTypeRequired
idUUID!Yes
cargoStringNo
categoryIdUUIDNo
weightFloatNo
senderIdUUIDNo
receiverIdUUIDNo
statusGqlTripStatusNo
logGpsBooleanNo

deleteTrip

Delete a trip and its associated GPS locations. Returns true on success.

mutation {
deleteTrip(id: "550e8400-...")
}

completeTrip

Complete an active trip by setting end coordinates and status.

mutation {
completeTrip(input: {
id: "550e8400-..."
endLatitude: 52.5200
endLongitude: 13.4050
}) {
id
status
endTime
endLatitude
endLongitude
}
}

Input: CompleteTripInput

FieldTypeRequired
idUUID!Yes
endLatitudeFloat!Yes
endLongitudeFloat!Yes

createClient

Create a new client, optionally with contact persons.

mutation {
createClient(input: {
name: "ACME Logistics"
email: "info@acme.example.com"
phone: "+49 30 12345678"
street: "Hauptstrasse"
houseNumber: "42"
postalCode: "10115"
city: "Berlin"
country: "DE"
contacts: [{
name: "John Doe"
email: "john@acme.example.com"
phone: "+49 30 12345679"
position: "Logistics Manager"
isPrimary: true
}]
}) {
id
name
contacts { id name isPrimary }
}
}

Input: CreateClientInput

FieldTypeRequiredDefault
nameString!Yes--
emailString!Yes--
phoneString!Yes--
streetString!Yes--
houseNumberString!Yes--
postalCodeString!Yes--
cityString!Yes--
countryString!Yes--
additionalInfoStringNonull
contacts[CreateContactInput!]!No[]

updateClient

Update an existing client. Only provided fields are changed.

mutation {
updateClient(input: {
id: "550e8400-..."
name: "ACME Logistics GmbH"
city: "Hamburg"
}) {
id
name
city
}
}

Input: UpdateClientInput

FieldTypeRequired
idUUID!Yes
nameStringNo
emailStringNo
phoneStringNo
streetStringNo
houseNumberStringNo
postalCodeStringNo
cityStringNo
countryStringNo
additionalInfoStringNo

createContact

Add a contact person to an existing client.

mutation {
createContact(
clientId: "550e8400-..."
input: {
name: "Jane Smith"
email: "jane@acme.example.com"
phone: "+49 30 12345680"
position: "Fleet Manager"
isPrimary: false
}
) {
id
name
isPrimary
clientId
}
}

Input: CreateContactInput

FieldTypeRequiredDefault
nameString!Yes--
emailString!Yes--
phoneString!Yes--
positionString!Yes--
isPrimaryBoolean!Nofalse

updateContact

Update a contact person. Only provided fields are changed.

mutation {
updateContact(input: {
id: "660e8400-..."
clientId: "550e8400-..."
name: "Jane Doe"
isPrimary: true
}) {
id
name
isPrimary
}
}

Input: UpdateContactInput

FieldTypeRequired
idUUID!Yes
clientIdUUID!Yes
nameStringNo
emailStringNo
phoneStringNo
positionStringNo
isPrimaryBooleanNo

deleteContact

Delete a contact person. Returns true on success.

mutation {
deleteContact(contactId: "660e8400-...", clientId: "550e8400-...")
}

createCategory

Create a new cargo category.

mutation {
createCategory(input: {
name: "Fragile Goods"
description: "Items requiring careful handling"
}) {
id
name
description
createdAt
}
}

Input: CreateCategoryInput

FieldTypeRequired
nameString!Yes
descriptionStringNo

updateCategory

Update an existing cargo category. Only provided fields are changed.

mutation {
updateCategory(input: {
id: "550e8400-..."
name: "Fragile Items"
}) {
id
name
updatedAt
}
}

Input: UpdateCategoryInput

FieldTypeRequired
idUUID!Yes
nameStringNo
descriptionStringNo

deleteCategory

Delete a cargo category. Returns false if trips still reference it.

mutation {
deleteCategory(id: "550e8400-...")
}

Output Types

GqlGpsLocation

FieldTypeDescription
idUUID!Location record ID
timestampDateTime!When the location was recorded
latitudeFloat!Latitude in degrees
longitudeFloat!Longitude in degrees
altitudeFloatAltitude in meters (nullable)
speedKmhFloat!Speed in km/h
speedMpsFloat!Speed in m/s
speedMphFloat!Speed in mph
speedKnotsFloat!Speed in knots
tripIdUUIDAssociated trip ID (nullable)

GqlTrip

FieldTypeDescription
idUUID!Trip ID
startTimeDateTime!Trip start time
endTimeDateTimeTrip end time (null if active)
startLatitudeFloat!Start latitude
startLongitudeFloat!Start longitude
endLatitudeFloatEnd latitude (null if active)
endLongitudeFloatEnd longitude (null if active)
cargoString!Cargo description
weightFloat!Cargo weight
statusGqlTripStatus!ACTIVE, COMPLETED, or CANCELLED
logGpsBoolean!Whether GPS logging is enabled
categoryGqlCargoCategory!Resolved category relation
senderGqlClient!Resolved sender client relation
receiverGqlClient!Resolved receiver client relation
gpsLocations[GqlGpsLocation!]!GPS locations for this trip

GqlClient

FieldTypeDescription
idUUID!Client ID
nameString!Client name
emailString!Email address
phoneString!Phone number
streetString!Street name
houseNumberString!House number
postalCodeString!Postal code
cityString!City
countryString!Country
additionalInfoStringAdditional info (nullable)
contacts[GqlContactPerson!]!Contact persons
tripsAsSender[GqlTrip!]!Trips where client is sender
tripsAsReceiver[GqlTrip!]!Trips where client is receiver

GqlContactPerson

FieldTypeDescription
idUUID!Contact ID
nameString!Contact name
emailString!Email
phoneString!Phone number
positionString!Job position/title
isPrimaryBoolean!Whether this is the primary contact
clientIdUUID!Parent client ID

GqlCargoCategory

FieldTypeDescription
idUUID!Category ID
nameString!Category name
descriptionStringDescription (nullable)
createdAtDateTime!Creation timestamp
updatedAtDateTime!Last update timestamp
trips[GqlTrip!]!Trips in this category

GqlTripStatus (Enum)

ValueDescription
ACTIVETrip is in progress
COMPLETEDTrip has been completed
CANCELLEDTrip has been cancelled

HealthStatus

FieldTypeDescription
statusString!Overall status (ok or degraded)
uptimeInt!Server uptime in seconds
databaseString!Database status
peplinkString!Peplink provider status
forwardingString!Forwarding service status
websocketString!WebSocket status (running or closing)
websocketClientsInt!Number of connected WebSocket clients
timestampDateTime!Check timestamp