GraphQL API
The Apollon API provides a full GraphQL interface with query/mutation support via async-graphql.
Endpoints
| Endpoint | Method | Description |
|---|---|---|
/v1/gql | POST | GraphQL query/mutation endpoint |
/v1/graphiql | GET | GraphiQL IDE (disabled when docs.graphiql = false) |
/v1/schema | GET | GraphQL schema in SDL format (plain text) |
Custom Scalars
| Scalar | Format | Example |
|---|---|---|
DateTime | RFC 3339 string | "2026-06-09T12:00:00Z" |
UUID | Standard 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
}
}
}
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
start | Int | No | 24h ago | Start of time range (unix timestamp) |
end | Int | No | now | End 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
| Field | Type | Required | Default |
|---|---|---|---|
startLatitude | Float! | Yes | -- |
startLongitude | Float! | Yes | -- |
cargo | String! | Yes | -- |
categoryId | UUID! | Yes | -- |
weight | Float! | Yes | -- |
senderId | UUID! | Yes | -- |
receiverId | UUID! | Yes | -- |
logGps | Boolean! | No | false |
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
| Field | Type | Required |
|---|---|---|
id | UUID! | Yes |
cargo | String | No |
categoryId | UUID | No |
weight | Float | No |
senderId | UUID | No |
receiverId | UUID | No |
status | GqlTripStatus | No |
logGps | Boolean | No |
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
| Field | Type | Required |
|---|---|---|
id | UUID! | Yes |
endLatitude | Float! | Yes |
endLongitude | Float! | 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
| Field | Type | Required | Default |
|---|---|---|---|
name | String! | Yes | -- |
email | String! | Yes | -- |
phone | String! | Yes | -- |
street | String! | Yes | -- |
houseNumber | String! | Yes | -- |
postalCode | String! | Yes | -- |
city | String! | Yes | -- |
country | String! | Yes | -- |
additionalInfo | String | No | null |
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
| Field | Type | Required |
|---|---|---|
id | UUID! | Yes |
name | String | No |
email | String | No |
phone | String | No |
street | String | No |
houseNumber | String | No |
postalCode | String | No |
city | String | No |
country | String | No |
additionalInfo | String | No |
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
| Field | Type | Required | Default |
|---|---|---|---|
name | String! | Yes | -- |
email | String! | Yes | -- |
phone | String! | Yes | -- |
position | String! | Yes | -- |
isPrimary | Boolean! | No | false |
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
| Field | Type | Required |
|---|---|---|
id | UUID! | Yes |
clientId | UUID! | Yes |
name | String | No |
email | String | No |
phone | String | No |
position | String | No |
isPrimary | Boolean | No |
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
| Field | Type | Required |
|---|---|---|
name | String! | Yes |
description | String | No |
updateCategory
Update an existing cargo category. Only provided fields are changed.
mutation {
updateCategory(input: {
id: "550e8400-..."
name: "Fragile Items"
}) {
id
name
updatedAt
}
}
Input: UpdateCategoryInput
| Field | Type | Required |
|---|---|---|
id | UUID! | Yes |
name | String | No |
description | String | No |
deleteCategory
Delete a cargo category. Returns false if trips still reference it.
mutation {
deleteCategory(id: "550e8400-...")
}
Output Types
GqlGpsLocation
| Field | Type | Description |
|---|---|---|
id | UUID! | Location record ID |
timestamp | DateTime! | When the location was recorded |
latitude | Float! | Latitude in degrees |
longitude | Float! | Longitude in degrees |
altitude | Float | Altitude in meters (nullable) |
speedKmh | Float! | Speed in km/h |
speedMps | Float! | Speed in m/s |
speedMph | Float! | Speed in mph |
speedKnots | Float! | Speed in knots |
tripId | UUID | Associated trip ID (nullable) |
GqlTrip
| Field | Type | Description |
|---|---|---|
id | UUID! | Trip ID |
startTime | DateTime! | Trip start time |
endTime | DateTime | Trip end time (null if active) |
startLatitude | Float! | Start latitude |
startLongitude | Float! | Start longitude |
endLatitude | Float | End latitude (null if active) |
endLongitude | Float | End longitude (null if active) |
cargo | String! | Cargo description |
weight | Float! | Cargo weight |
status | GqlTripStatus! | ACTIVE, COMPLETED, or CANCELLED |
logGps | Boolean! | Whether GPS logging is enabled |
category | GqlCargoCategory! | Resolved category relation |
sender | GqlClient! | Resolved sender client relation |
receiver | GqlClient! | Resolved receiver client relation |
gpsLocations | [GqlGpsLocation!]! | GPS locations for this trip |
GqlClient
| Field | Type | Description |
|---|---|---|
id | UUID! | Client ID |
name | String! | Client name |
email | String! | Email address |
phone | String! | Phone number |
street | String! | Street name |
houseNumber | String! | House number |
postalCode | String! | Postal code |
city | String! | City |
country | String! | Country |
additionalInfo | String | Additional info (nullable) |
contacts | [GqlContactPerson!]! | Contact persons |
tripsAsSender | [GqlTrip!]! | Trips where client is sender |
tripsAsReceiver | [GqlTrip!]! | Trips where client is receiver |
GqlContactPerson
| Field | Type | Description |
|---|---|---|
id | UUID! | Contact ID |
name | String! | Contact name |
email | String! | |
phone | String! | Phone number |
position | String! | Job position/title |
isPrimary | Boolean! | Whether this is the primary contact |
clientId | UUID! | Parent client ID |
GqlCargoCategory
| Field | Type | Description |
|---|---|---|
id | UUID! | Category ID |
name | String! | Category name |
description | String | Description (nullable) |
createdAt | DateTime! | Creation timestamp |
updatedAt | DateTime! | Last update timestamp |
trips | [GqlTrip!]! | Trips in this category |
GqlTripStatus (Enum)
| Value | Description |
|---|---|
ACTIVE | Trip is in progress |
COMPLETED | Trip has been completed |
CANCELLED | Trip has been cancelled |
HealthStatus
| Field | Type | Description |
|---|---|---|
status | String! | Overall status (ok or degraded) |
uptime | Int! | Server uptime in seconds |
database | String! | Database status |
peplink | String! | Peplink provider status |
forwarding | String! | Forwarding service status |
websocket | String! | WebSocket status (running or closing) |
websocketClients | Int! | Number of connected WebSocket clients |
timestamp | DateTime! | Check timestamp |