GraphQL API Guide
GraphQL is a query language for APIs that offers an efficient and versatile alternative to REST APIs.
Benefits of Using GraphQL Over REST
Single Endpoint: GraphQL employs a single endpoint for all queries and mutations, contrasting with REST which necessitates multiple endpoints.
Streamlined Data Retrieval: With GraphQL, there's no need for intermediary datastores or additional layers when collating related data.
Precise Data Retrieval: Clients dictate the exact data they need, ensuring swift and succinct responses.
HTTP-Based: GraphQL, despite its unique query language, operates via standard HTTP, meaning any client capable of HTTP requests can interface with a GraphQL server. No GraphQL specific libraries are needed.
Authentication
Use the Authorization
HTTP header with your personal access token.
Header:
Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN
Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN
Obtaining a Personal Access Token
See: How do I create a personal access token?
Queries, Mutations, and Subscriptions
Queries
Queries allow for fetching data in a read-only manner. You can think of them as the equivalent of a GET request in REST.
Example: Get a device by ID.
query {
device(id: "1234567890") {
id
label
}
}
query {
device(id: "1234567890") {
id
label
}
}
Mutations
Mutations make modifications to the data and can be equated to POST, PUT, or DELETE requests in REST.
Example: Create and enable a new device.
mutation {
createDevice(device: { label: "Drone01", enabled: true }) {
id
label
}
}
mutation {
createDevice(device: { label: "Drone01", enabled: true }) {
id
label
}
}
Subscriptions
Subscriptions are a unique feature of GraphQL, allowing for real-time updates through WebSockets. They're valuable for keeping the client-side data in sync with the server.
Example: Receive real-time position updates for all of the current user's devices.
subscription {
devices {
id
lastPosition {
timestamp
position { llaDec { lat lon alt } }
}
}
}
subscription {
devices {
id
lastPosition {
timestamp
position { llaDec { lat lon alt } }
}
}
}
Filters
Filters allow you to fine-tune your GraphQL queries, allowing you to retrieve data based on specific conditions.
StringConditional
StringConditional
is an input type that provides a mechanism to filter strings based on certain conditions:
input StringConditional {
"""
Equals operator
"""
eq: String
"""
Not Equals operator
"""
ne: String
}
input StringConditional {
"""
Equals operator
"""
eq: String
"""
Not Equals operator
"""
ne: String
}
This input type provides two fields:
eq
: This field expects a string value. When provided, it represents an "equals" condition, meaning that the field being filtered should match (be equal to) the provided string.ne
: This field also expects a string value. When provided, it represents a "not equals" condition, meaning that the field being filtered should not match (be different from) the provided string.
For example, if you were to use this input type in a query to filter devices by a specific label, it could look something like this:
query {
myDevices(filter: { label: { eq: "My Special Device" } }) {
content {
id
label
}
}
}
query {
myDevices(filter: { label: { eq: "My Special Device" } }) {
content {
id
label
}
}
}
DeviceFilter
The DeviceFilter
allows for querying devices based on specific attributes such as label, status, and tags.
Filtering by Connection Status
To filter devices by their connection status, use the status
attribute of DeviceFilter
and choose a value from the ConnectionStatus
enum.
query {
myDevices(filter: { status: "GOOD" }) {
content {
id
label
}
}
}
query {
myDevices(filter: { status: "GOOD" }) {
content {
id
label
}
}
}
This query retrieves devices with a connection status of "GOOD".
Filtering by Label
To query devices based on string values, use the StringConditional
.
query {
myDevices(filter: { label: { eq: "MyVehicle" } }) {
content {
id
label
}
}
}
query {
myDevices(filter: { label: { eq: "MyVehicle" } }) {
content {
id
label
}
}
}
In this example, devices labeled "MyVehicle" are fetched.
TagFilter
Filtering by Tag Value
To fetch devices with a specific tag value, utilize the tag
field within DeviceFilter
. The tag
field expects a TagFilter
.
query {
myDevices(filter: { tag: { key: "Group", value: { eq: "Warehouse A" } } }) {
content {
id
label
}
}
}
query {
myDevices(filter: { tag: { key: "Group", value: { eq: "Warehouse A" } } }) {
content {
id
label
}
}
}
This query targets devices with a tag that has a key named "Group" and a value of "Warehouse A".
Logical Operators in Filters
Logical operators, namely and
, or
, and not
, allow you to combine or exclude multiple filter conditions, granting you the ability to construct more advanced queries.
AND Operator
The and
operator helps you combine multiple filter conditions, returning results that match all the given conditions.
query {
myDevices(filter: { and: [{ status: "GOOD" }, { label: { eq: "MyVehicle" } }] }) {
content {
id
label
}
}
}
query {
myDevices(filter: { and: [{ status: "GOOD" }, { label: { eq: "MyVehicle" } }] }) {
content {
id
label
}
}
}
This fetches devices that are both in a "GOOD" connection status and have a label of "MyVehicle".
OR Operator
The or
operator retrieves results that fulfill any of the conditions provided.
query {
myDevices(filter: { or: [{ status: "NO_CONNECTION" }, { label: { eq: "MyDrone" } }] }) {
content {
id
label
}
}
}
query {
myDevices(filter: { or: [{ status: "NO_CONNECTION" }, { label: { eq: "MyDrone" } }] }) {
content {
id
label
}
}
}
This query looks for devices that either have a connection status of "NO_CONNECTION" or are labeled "MyDrone".
NOT Operator
The not
operator returns results that don't match the provided conditions.
query {
myDevices(filter: { not: [{ status: "BAD_POSITION" }] }) {
content {
id
label
}
}
}
query {
myDevices(filter: { not: [{ status: "BAD_POSITION" }] }) {
content {
id
label
}
}
}
Here, we're fetching devices that do not have a connection status of "BAD_POSITION".
Queries
myDevices
The myDevices
retrieves all devices associated with your account. It also supports filtering based on various criteria:
type Query {
"""
Get all devices that belong to the current User's account
"""
myDevices(filter: DeviceFilter, offset: Int, limit: Int): DevicePage!
}
type Query {
"""
Get all devices that belong to the current User's account
"""
myDevices(filter: DeviceFilter, offset: Int, limit: Int): DevicePage!
}
You can filter devices based on a DeviceFilter
input type, specify an offset
to determine where to start the results from, and set a limit
to determine how many results to retrieve.
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "query { myDevices(filter: { label: { eq: \"MyDevice\" } }) { content { id label } } }"
}'
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "query { myDevices(filter: { label: { eq: \"MyDevice\" } }) { content { id label } } }"
}'
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "query { myDevices(filter: { label: { eq: \"MyDevice\" } }) { content { id label } } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "query { myDevices(filter: { label: { eq: \"MyDevice\" } }) { content { id label } } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `query { myDevices(filter: { label: { eq: "MyDevice" } }) { content { id label } } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `query { myDevices(filter: { label: { eq: "MyDevice" } }) { content { id label } } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type Device struct {
ID string `json:"id"`
Label string `json:"label"`
}
type DevicePage struct {
Content []Device `json:"content"`
}
type GraphQLResponse struct {
Data struct {
MyDevices DevicePage `json:"myDevices"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `query { myDevices(filter: { label: { eq: "MyDevice" } }) { content { id label } } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
for _, device := range result.Data.MyDevices.Content {
fmt.Printf("ID: %s, Label: %s\n", device.ID, device.Label)
}
}
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type Device struct {
ID string `json:"id"`
Label string `json:"label"`
}
type DevicePage struct {
Content []Device `json:"content"`
}
type GraphQLResponse struct {
Data struct {
MyDevices DevicePage `json:"myDevices"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `query { myDevices(filter: { label: { eq: "MyDevice" } }) { content { id label } } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
for _, device := range result.Data.MyDevices.Content {
fmt.Printf("ID: %s, Label: %s\n", device.ID, device.Label)
}
}
device
The device
query allows a user to retrieve a specific device by its Device ID:
type Query {
"""
Get a Device by its Device ID
"""
device(id: ID!): Device!
}
type Query {
"""
Get a Device by its Device ID
"""
device(id: ID!): Device!
}
The id
parameter is required.
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "query { device(id: \"YOUR_DEVICE_ID\") { id label } }"
}'
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "query { device(id: \"YOUR_DEVICE_ID\") { id label } }"
}'
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "query { device(id: \"YOUR_DEVICE_ID\") { id label } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "query { device(id: \"YOUR_DEVICE_ID\") { id label } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `query { device(id: "YOUR_DEVICE_ID") { id label } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `query { device(id: "YOUR_DEVICE_ID") { id label } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type Device struct {
ID string `json:"id"`
Label string `json:"label"`
}
type GraphQLResponse struct {
Data struct {
Device Device `json:"device"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `query { device(id: "YOUR_DEVICE_ID") { id label } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("ID: %s, Label: %s\n", result.Data.Device.ID, result.Data.Device.Label)
}
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type Device struct {
ID string `json:"id"`
Label string `json:"label"`
}
type GraphQLResponse struct {
Data struct {
Device Device `json:"device"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `query { device(id: "YOUR_DEVICE_ID") { id label } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("ID: %s, Label: %s\n", result.Data.Device.ID, result.Data.Device.Label)
}
viewPersonalAccessTokens
The viewPersonalAccessTokens query allows a user to retrieve all personal access tokens associated with the current user's account:
type Query {
"""
View all personal access tokens for current user
"""
viewPersonalAccessTokens: [PersonalAccessToken!]
}
The viewPersonalAccessTokens query allows a user to retrieve all personal access tokens associated with the current user's account:
type Query {
"""
View all personal access tokens for current user
"""
viewPersonalAccessTokens: [PersonalAccessToken!]
}
No parameters are required for this query.
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "query { viewPersonalAccessTokens { name description createdAt } }"
}'
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "query { viewPersonalAccessTokens { name description createdAt } }"
}'
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "query { viewPersonalAccessTokens { name description createdAt } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "query { viewPersonalAccessTokens { name description createdAt } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `query { viewPersonalAccessTokens { name description createdAt } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `query { viewPersonalAccessTokens { name description createdAt } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type PersonalAccessToken struct {
Name string `json:"name"`
Description string `json:"description"`
CreatedAt string `json:"createdAt"`
}
type GraphQLResponse struct {
Data struct {
PersonalAccessTokens []PersonalAccessToken `json:"viewPersonalAccessTokens"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `query { viewPersonalAccessTokens { name description createdAt } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
for _, token := range result.Data.PersonalAccessTokens {
fmt.Printf("Name: %s, Description: %s, Created At: %s\n", token.Name, token.Description, token.CreatedAt)
}
}
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type PersonalAccessToken struct {
Name string `json:"name"`
Description string `json:"description"`
CreatedAt string `json:"createdAt"`
}
type GraphQLResponse struct {
Data struct {
PersonalAccessTokens []PersonalAccessToken `json:"viewPersonalAccessTokens"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `query { viewPersonalAccessTokens { name description createdAt } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
for _, token := range result.Data.PersonalAccessTokens {
fmt.Printf("Name: %s, Description: %s, Created At: %s\n", token.Name, token.Description, token.CreatedAt)
}
}
Mutations
createDevice
The createDevice
mutation allows a user to create a new device
type Mutation {
"""
Create a new device
"""
createDevice(input: CreateDeviceInput!): Device!
}
type Mutation {
"""
Create a new device
"""
createDevice(input: CreateDeviceInput!): Device!
}
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { createDevice(device: {label: \"YOUR_DEVICE_LABEL\"}) { id label } }"
}'
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { createDevice(device: {label: \"YOUR_DEVICE_LABEL\"}) { id label } }"
}'
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { createDevice(device: {label: \"YOUR_DEVICE_LABEL\"}) { id label type } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { createDevice(device: {label: \"YOUR_DEVICE_LABEL\"}) { id label type } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { createDevice(device: {label: "YOUR_DEVICE_LABEL" }) { id label } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { createDevice(device: {label: "YOUR_DEVICE_LABEL" }) { id label } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type Device struct {
ID string `json:"id"`
Label string `json:"label"`
Type string `json:"type"`
}
type GraphQLResponse struct {
Data struct {
CreateDevice Device `json:"createDevice"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `mutation { createDevice(device: {label: "YOUR_DEVICE_LABEL"}) { id label } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("ID: %s, Label: %s\n", result.Data.CreateDevice.ID, result.Data.CreateDevice.Label)
}
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type Device struct {
ID string `json:"id"`
Label string `json:"label"`
Type string `json:"type"`
}
type GraphQLResponse struct {
Data struct {
CreateDevice Device `json:"createDevice"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `mutation { createDevice(device: {label: "YOUR_DEVICE_LABEL"}) { id label } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("ID: %s, Label: %s\n", result.Data.CreateDevice.ID, result.Data.CreateDevice.Label)
}
createDevices
The createDevices
mutation allows a user to create multiple devices at once.
type Mutation {
"""
Create multiple Devices
"""
createDevices(quantity: Int!, enabled: Boolean): [Device!]!
}
type Mutation {
"""
Create multiple Devices
"""
createDevices(quantity: Int!, enabled: Boolean): [Device!]!
}
The quantity
parameter is required and specifies the number of devices to be created. The enabled
parameter is optional and sets the state of the devices.
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { createDevices(quantity: 2, enabled: true) { id label } }"
}'
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { createDevices(quantity: 2, enabled: true) { id label } }"
}'
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { createDevices(quantity: 2, enabled: true) { id label } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { createDevices(quantity: 2, enabled: true) { id label } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { createDevices(quantity: 2, enabled: true) { id label } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { createDevices(quantity: 2, enabled: true) { id label } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type Device struct {
ID string `json:"id"`
Label string `json:"label"`
}
type GraphQLResponse struct {
Data struct {
Devices []Device `json:"createDevices"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `mutation { createDevices(quantity: 2, enabled: true) { id label } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
for _, device := range result.Data.Devices {
fmt.Printf("ID: %s, Label: %s\n", device.ID, device.Label)
}
}
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type Device struct {
ID string `json:"id"`
Label string `json:"label"`
}
type GraphQLResponse struct {
Data struct {
Devices []Device `json:"createDevices"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `mutation { createDevices(quantity: 2, enabled: true) { id label } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
for _, device := range result.Data.Devices {
fmt.Printf("ID: %s, Label: %s\n", device.ID, device.Label)
}
}
updateDevice
The updateDevice
mutation allows a user to update the details of a specific device.
type Mutation {
"""
Update a specific Device
"""
updateDevice(device: DeviceInput!): Device!
}
type Mutation {
"""
Update a specific Device
"""
updateDevice(device: DeviceInput!): Device!
}
The device
parameter is required and should be of type DeviceInput
.
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { updateDevice(device: {id: \"YOUR_DEVICE_ID\", label: \"New Label\"}) { id label } }"
}'
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { updateDevice(device: {id: \"YOUR_DEVICE_ID\", label: \"New Label\"}) { id label } }"
}'
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { updateDevice(device: {id: \"YOUR_DEVICE_ID\", label: \"New Label\"}) { id label } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { updateDevice(device: {id: \"YOUR_DEVICE_ID\", label: \"New Label\"}) { id label } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { updateDevice(device: {id: "YOUR_DEVICE_ID", label: "New Label"}) { id label } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { updateDevice(device: {id: "YOUR_DEVICE_ID", label: "New Label"}) { id label } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type Device struct {
ID string `json:"id"`
Label string `json:"label"`
}
type GraphQLResponse struct {
Data struct {
Device Device `json:"updateDevice"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `mutation { updateDevice(device: {id: "YOUR_DEVICE_ID", label: "New Label"}) { id label } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("ID: %s, Label: %s\n", result.Data.Device.ID, result.Data.Device.Label)
}
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type Device struct {
ID string `json:"id"`
Label string `json:"label"`
}
type GraphQLResponse struct {
Data struct {
Device Device `json:"updateDevice"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `mutation { updateDevice(device: {id: "YOUR_DEVICE_ID", label: "New Label"}) { id label } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("ID: %s, Label: %s\n", result.Data.Device.ID, result.Data.Device.Label)
}
createPersonalAccessToken
The createPersonalAccessToken
mutation allows a user to create a new personal access token.
type Mutation {
"""
Create a new personal access token
"""
createPersonalAccessToken(name: String!, description: String, role: TokenRole, expiryInDays: Int! = 365): String!
}
type Mutation {
"""
Create a new personal access token
"""
createPersonalAccessToken(name: String!, description: String, role: TokenRole, expiryInDays: Int! = 365): String!
}
The name
parameter is required, and you can optionally provide a description
, role
, and expiryInDays
parameter. The role
can be either ROLE_READ
for read-only permission or ROLE_READ_WRITE
for read-write permission. The expiryInDays
defaults to 365 days if not specified.
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { createPersonalAccessToken(name: \"Token Name\", description: \"Description for the token\", role: ROLE_READ, expiryInDays: 365) }"
}'
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { createPersonalAccessToken(name: \"Token Name\", description: \"Description for the token\", role: ROLE_READ, expiryInDays: 365) }"
}'
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { createPersonalAccessToken(name: \"Token Name\", description: \"Description for the token\", role: ROLE_READ, expiryInDays: 365) }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { createPersonalAccessToken(name: \"Token Name\", description: \"Description for the token\", role: ROLE_READ, expiryInDays: 365) }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { createPersonalAccessToken(name: "Token Name", description: "Description for the token", role: ROLE_READ, expiryInDays: 365) }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { createPersonalAccessToken(name: "Token Name", description: "Description for the token", role: ROLE_READ, expiryInDays: 365) }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type GraphQLResponse struct {
Data struct {
Token string `json:"createPersonalAccessToken"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `mutation { createPersonalAccessToken(name: "Token Name", description: "Description for the token", role: ROLE_READ, expiryInDays: 365) }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Created Token: %s\n", result.Data.Token)
}
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type GraphQLResponse struct {
Data struct {
Token string `json:"createPersonalAccessToken"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `mutation { createPersonalAccessToken(name: "Token Name", description: "Description for the token", role: ROLE_READ, expiryInDays: 365) }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Created Token: %s\n", result.Data.Token)
}
revokePersonalAccessToken
The revokePersonalAccessToken
mutation allows a user to revoke a personal access token using its name.
type Mutation {
"""
Revoke a personal access token by name
"""
revokePersonalAccessToken(name: String!): Boolean!
}
type Mutation {
"""
Revoke a personal access token by name
"""
revokePersonalAccessToken(name: String!): Boolean!
}
The name
parameter is required and should match the name of the personal access token you wish to revoke.
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { revokePersonalAccessToken(name: \"Token Name\") }"
}'
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { revokePersonalAccessToken(name: \"Token Name\") }"
}'
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { revokePersonalAccessToken(name: \"Token Name\") }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { revokePersonalAccessToken(name: \"Token Name\") }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { revokePersonalAccessToken(name: "Token Name") }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { revokePersonalAccessToken(name: "Token Name") }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type GraphQLResponse struct {
Data struct {
Success bool `json:"revokePersonalAccessToken"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `mutation { revokePersonalAccessToken(name: "Token Name") }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Revoke Success: %v\n", result.Data.Success)
}
// Using the net/http package:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type GraphQLRequest struct {
Query string `json:"query"`
}
type GraphQLResponse struct {
Data struct {
Success bool `json:"revokePersonalAccessToken"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
query := `mutation { revokePersonalAccessToken(name: "Token Name") }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Revoke Success: %v\n", result.Data.Success)
}
setDeviceTag
The setDeviceTag
mutation allows a user to assign a tag to a specific device.
type Mutation {
"""
Assign a tag to a device
"""
setDeviceTag(input: TagInput!): Tag!
}
type Mutation {
"""
Assign a tag to a device
"""
setDeviceTag(input: TagInput!): Tag!
}
The input
parameter is required and should be of type TagInput
, which typically includes fields such as id
and key
.
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { setDeviceTag(input: { ids: [\"YOUR_DEVICE_ID\"], key: \"YourTagName\", value: \"YourTagValue\" }) { key, value } }"
}'
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { setDeviceTag(input: { ids: [\"YOUR_DEVICE_ID\"], key: \"YourTagName\", value: \"YourTagValue\" }) { key, value } }"
}'
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { setDeviceTag(input: { ids: [\"YOUR_DEVICE_ID\"], key: \"YourTagName\", value: \"YourTagValue\" }) { key, value } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { setDeviceTag(input: { ids: [\"YOUR_DEVICE_ID\"], key: \"YourTagName\", value: \"YourTagValue\" }) { key, value } }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { setDeviceTag(input: { ids: ["YOUR_DEVICE_ID"], key: "YourTagName", value: "yourTagValue" }) { key, value } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { setDeviceTag(input: { ids: ["YOUR_DEVICE_ID"], key: "YourTagName", value: "yourTagValue" }) { key, value } }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type TagInput struct {
IDs []string `json:"ids"`
Key string `json:"key"`
Value string `json:"value"`
}
type GraphQLRequest struct {
Query string `json:"query"`
Variables map[string]TagInput `json:"variables"`
}
type Tag struct {
Key string `json:"key"`
Value string `json:"value"`
}
type GraphQLResponse struct {
Data struct {
Tag Tag `json:"setDeviceTag"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
tagInput := TagInput{
IDs: []string{"YOUR_DEVICE_ID"},
Key: "YourTagName",
Value: "yourTagValue",
}
query := `mutation ($input: TagInput!) { setDeviceTag(input: $input) { key, value } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query, Variables: map[string]TagInput{"input": tagInput}})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Tag: %s = %s\n", result.Data.Tag.Key, result.Data.Tag.Value)
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type TagInput struct {
IDs []string `json:"ids"`
Key string `json:"key"`
Value string `json:"value"`
}
type GraphQLRequest struct {
Query string `json:"query"`
Variables map[string]TagInput `json:"variables"`
}
type Tag struct {
Key string `json:"key"`
Value string `json:"value"`
}
type GraphQLResponse struct {
Data struct {
Tag Tag `json:"setDeviceTag"`
} `json:"data"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
tagInput := TagInput{
IDs: []string{"YOUR_DEVICE_ID"},
Key: "YourTagName",
Value: "yourTagValue",
}
query := `mutation ($input: TagInput!) { setDeviceTag(input: $input) { key, value } }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query, Variables: map[string]TagInput{"input": tagInput}})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Tag: %s = %s\n", result.Data.Tag.Key, result.Data.Tag.Value)
}
unsetDeviceTag
The unsetDeviceTag
mutation allows a user to remove a tag from a specific device.
type Mutation {
"""
Remove a tag from a device
"""
unsetDeviceTag(input: TagInput!): Boolean!
}
type Mutation {
"""
Remove a tag from a device
"""
unsetDeviceTag(input: TagInput!): Boolean!
}
The input
parameter is required and should be of type TagInput
, which typically includes fields such as ids
and key
.
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { unsetDeviceTag(input: { ids: [\"YOUR_DEVICE_ID\"], key: \"YourTagName\" }) }"
}'
curl -X POST "https://graphql.pointonenav.com/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-d '{
"query": "mutation { unsetDeviceTag(input: { ids: [\"YOUR_DEVICE_ID\"], key: \"YourTagName\" }) }"
}'
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { unsetDeviceTag(input: { ids: [\"YOUR_DEVICE_ID\"], key: \"YourTagName\" }) }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
# Using the requests library:
import requests
url = "https://graphql.pointonenav.com/graphql"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
data = {
"query": "mutation { unsetDeviceTag(input: { ids: [\"YOUR_DEVICE_ID\"], key: \"YourTagName\" }) }"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { unsetDeviceTag(input: { ids: ["YOUR_DEVICE_ID"], key: "YourTagName" }) }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// Using the fetch API:
const url = "https://graphql.pointonenav.com/graphql";
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
};
const body = {
query: `mutation { unsetDeviceTag(input: { ids: ["YOUR_DEVICE_ID"], key: "YourTagName" }) }`
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type TagInput struct {
IDs []string `json:"ids"`
Key string `json:"key"`
}
type GraphQLRequest struct {
Query string `json:"query"`
Variables map[string]TagInput `json:"variables"`
}
type GraphQLResponse struct {
Data struct {
UnsetDeviceTag interface{} `json:"unsetDeviceTag"`
} `json:"data"`
Error []struct {
Message string `json:"message"`
} `json:"errors"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
tagInput := TagInput{
IDs: []string{"YOUR_DEVICE_ID"},
Key: "YourTagName",
}
query := `mutation ($input: TagInput!) { unsetDeviceTag(input: $input) }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query, Variables: map[string]TagInput{"input": tagInput}})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
panic(err)
}
// Check if there are any errors in the response
if len(result.Error) > 0 {
for _, err := range result.Error {
fmt.Println("Error:", err.Message)
}
return
}
fmt.Printf("Success: unsetDeviceTag = %v\n", result.Data.UnsetDeviceTag)
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type TagInput struct {
IDs []string `json:"ids"`
Key string `json:"key"`
}
type GraphQLRequest struct {
Query string `json:"query"`
Variables map[string]TagInput `json:"variables"`
}
type GraphQLResponse struct {
Data struct {
UnsetDeviceTag interface{} `json:"unsetDeviceTag"`
} `json:"data"`
Error []struct {
Message string `json:"message"`
} `json:"errors"`
}
func main() {
url := "https://graphql.pointonenav.com/graphql"
tagInput := TagInput{
IDs: []string{"YOUR_DEVICE_ID"},
Key: "YourTagName",
}
query := `mutation ($input: TagInput!) { unsetDeviceTag(input: $input) }`
requestBody, _ := json.Marshal(GraphQLRequest{Query: query, Variables: map[string]TagInput{"input": tagInput}})
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_PERSONAL_ACCESS_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GraphQLResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
panic(err)
}
// Check if there are any errors in the response
if len(result.Error) > 0 {
for _, err := range result.Error {
fmt.Println("Error:", err.Message)
}
return
}
fmt.Printf("Success: unsetDeviceTag = %v\n", result.Data.UnsetDeviceTag)
}
Subscriptions
device
The device
subscription allows a user to receive state changes for a given device by its Device ID through a WebSocket connection.
The id
parameter is required.
import asyncio
import uuid
import websockets
import json
async def query_device(device_id):
query = {
"id": str(uuid.uuid4()), # Unique ID for the subscription
"type": "subscribe",
"payload": {
"query": """
subscription {
device(id: "%s") {
id
lastPosition {
position {
llaDec {
lat
lon
alt
}
}
timestamp
}
connectionStatus
}
}
""" % device_id
}
}
init_message = {
"type": "connection_init",
"payload": {
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
}
uri = "wss://graphql.pointonenav.com/subscriptions"
async with websockets.connect(uri) as websocket: # Connect using the graphql-transport-ws protocol
await websocket.send(json.dumps(init_message))
while True:
response_str = await websocket.recv()
connect_response = json.loads(response_str)
# Handle different message types here (connection_ack, data, error, etc.)
if connect_response["type"] == 'connection_ack':
# Connection acknowledged, now send subscription request
subscribe_msg = json.dumps(query)
print("Subscribe: ", subscribe_msg)
await websocket.send(subscribe_msg)
device_msg_str = await websocket.recv()
device_response = json.loads(device_msg_str)
else:
print("Connection Error", json.dumps(connect_response))
break
while True:
if device_response["type"] == 'next':
# Handle incoming data
device_update = device_response['payload']['data']['device']
device_msg = json.dumps(device_update)
print("Next: ", device_msg)
# Process the device update here....
elif device_response["type"] == 'error':
# Handle err data
err_msg = connect_response['payload']
print("Message Error: ", json.dumps(err_msg))
elif device_response["type"] == "complete":
break
device_id = 'YOUR_DEVICE_ID'
asyncio.get_event_loop().run_until_complete(query_device(device_id))
import asyncio
import uuid
import websockets
import json
async def query_device(device_id):
query = {
"id": str(uuid.uuid4()), # Unique ID for the subscription
"type": "subscribe",
"payload": {
"query": """
subscription {
device(id: "%s") {
id
lastPosition {
position {
llaDec {
lat
lon
alt
}
}
timestamp
}
connectionStatus
}
}
""" % device_id
}
}
init_message = {
"type": "connection_init",
"payload": {
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
}
uri = "wss://graphql.pointonenav.com/subscriptions"
async with websockets.connect(uri) as websocket: # Connect using the graphql-transport-ws protocol
await websocket.send(json.dumps(init_message))
while True:
response_str = await websocket.recv()
connect_response = json.loads(response_str)
# Handle different message types here (connection_ack, data, error, etc.)
if connect_response["type"] == 'connection_ack':
# Connection acknowledged, now send subscription request
subscribe_msg = json.dumps(query)
print("Subscribe: ", subscribe_msg)
await websocket.send(subscribe_msg)
device_msg_str = await websocket.recv()
device_response = json.loads(device_msg_str)
else:
print("Connection Error", json.dumps(connect_response))
break
while True:
if device_response["type"] == 'next':
# Handle incoming data
device_update = device_response['payload']['data']['device']
device_msg = json.dumps(device_update)
print("Next: ", device_msg)
# Process the device update here....
elif device_response["type"] == 'error':
# Handle err data
err_msg = connect_response['payload']
print("Message Error: ", json.dumps(err_msg))
elif device_response["type"] == "complete":
break
device_id = 'YOUR_DEVICE_ID'
asyncio.get_event_loop().run_until_complete(query_device(device_id))
import WebSocket from 'ws';
import {v4 as uuidv4} from "uuid";
const queryDevices = async (deviceId: string) => {
const query = {
id: uuidv4(), // Unique Connection Identifier
type: "subscribe",
payload: {
query: `
subscription {
device(id: "${deviceId}") {
id
label
lastPosition {
position {
llaDec {
lat
lon
alt
}
}
timestamp
}
connectionStatus
}
}
`
}
};
const initMessage = {
type: "connection_init",
payload: {
Authorization: "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
};
const uri = "wss://graphql.pointonenav.com/subscriptions";
const websocket = new WebSocket(uri);
websocket.on('open', async () => {
websocket.send(JSON.stringify(initMessage));
});
websocket.on('message', (message: string) => {
const {type, payload} = JSON.parse(message);
if (type === 'connection_ack') {
console.log('Connected!')
websocket.send(JSON.stringify(query));
} else if (type === 'next') {
console.log('Next: ' + JSON.stringify(payload))
} else if (type === 'error') {
console.log('Error: ' + JSON.stringify(payload))
}
});
};
const deviceId = 'YOUR_DEVICE_ID';
queryDevices(deviceId);
import WebSocket from 'ws';
import {v4 as uuidv4} from "uuid";
const queryDevices = async (deviceId: string) => {
const query = {
id: uuidv4(), // Unique Connection Identifier
type: "subscribe",
payload: {
query: `
subscription {
device(id: "${deviceId}") {
id
label
lastPosition {
position {
llaDec {
lat
lon
alt
}
}
timestamp
}
connectionStatus
}
}
`
}
};
const initMessage = {
type: "connection_init",
payload: {
Authorization: "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
};
const uri = "wss://graphql.pointonenav.com/subscriptions";
const websocket = new WebSocket(uri);
websocket.on('open', async () => {
websocket.send(JSON.stringify(initMessage));
});
websocket.on('message', (message: string) => {
const {type, payload} = JSON.parse(message);
if (type === 'connection_ack') {
console.log('Connected!')
websocket.send(JSON.stringify(query));
} else if (type === 'next') {
console.log('Next: ' + JSON.stringify(payload))
} else if (type === 'error') {
console.log('Error: ' + JSON.stringify(payload))
}
});
};
const deviceId = 'YOUR_DEVICE_ID';
queryDevices(deviceId);
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"github.com/google/uuid"
"github.com/gorilla/websocket"
)
// Connection Init message structure
type InitMessage struct {
Type string `json:"type"`
Payload map[string]string `json:"payload"`
}
// GraphQLSubscriptionMessage represents the structure of a GraphQL WebSocket message
type GraphQLSubscriptionMessage struct {
Type string `json:"type"`
ID string `json:"id,omitempty"`
Payload map[string]string `json:"payload,omitempty"`
}
func main() {
serverURL := url.URL{Scheme: "wss", Host: "graphql.pointonenav.com", Path: "/subscriptions"}
// Prepare the WebSocket handshake request headers
headers := http.Header{}
headers.Add("Sec-WebSocket-Protocol", "graphql-transport-ws")
// Connect to the GraphQL WebSocket endpoint
conn, _, err := websocket.DefaultDialer.Dial(serverURL.String(), headers)
if err != nil {
log.Fatal("Error connecting to WebSocket:", err)
}
defer conn.Close()
TOKEN := "YOUR_PERSONAL_ACCESS_TOKEN"
auth := map[string]string{
"Authorization": "Bearer " + TOKEN,
}
var init = InitMessage{
Type: "connection_init",
Payload: auth,
}
// Initialize the websocket connection
if err := conn.WriteJSON(init); err != nil {
log.Fatal("Error sending connection_init message:", err)
}
// Read and print messages from the server
for {
_, message, err := conn.ReadMessage()
if err != nil {
log.Fatal("Error reading message from server:", err)
break
}
fmt.Println("Received message from server:", string(message))
var msg GraphQLSubscriptionMessage
json.Unmarshal(message, &msg)
switch msg.Type {
case "connection_ack":
query := `subscription {
device(id: "YOUR_DEVICE_ID_HERE"){
id
label
connectionStatus
}
}`
fmt.Println("Connection acknowledged.")
var qMap = map[string]string{
"query": query,
}
// Send the subscribe message with query
var subscribe = GraphQLSubscriptionMessage{
ID: uuid.NewString(),
Type: "subscribe",
Payload: qMap,
}
err := conn.WriteJSON(subscribe)
if err != nil {
log.Fatal("Error sending subscribe message:", err)
}
case "next":
data, err := json.Marshal(msg.Payload)
if err != nil {
log.Fatal("Error converting response", err)
}
fmt.Println("Data received:", data)
// process the message
case "complete":
fmt.Println("Subscription complete.")
return
case "error":
fmt.Println("Error:", msg.Payload)
default:
fmt.Println("Unknown message type:", msg.Type)
}
}
}
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"github.com/google/uuid"
"github.com/gorilla/websocket"
)
// Connection Init message structure
type InitMessage struct {
Type string `json:"type"`
Payload map[string]string `json:"payload"`
}
// GraphQLSubscriptionMessage represents the structure of a GraphQL WebSocket message
type GraphQLSubscriptionMessage struct {
Type string `json:"type"`
ID string `json:"id,omitempty"`
Payload map[string]string `json:"payload,omitempty"`
}
func main() {
serverURL := url.URL{Scheme: "wss", Host: "graphql.pointonenav.com", Path: "/subscriptions"}
// Prepare the WebSocket handshake request headers
headers := http.Header{}
headers.Add("Sec-WebSocket-Protocol", "graphql-transport-ws")
// Connect to the GraphQL WebSocket endpoint
conn, _, err := websocket.DefaultDialer.Dial(serverURL.String(), headers)
if err != nil {
log.Fatal("Error connecting to WebSocket:", err)
}
defer conn.Close()
TOKEN := "YOUR_PERSONAL_ACCESS_TOKEN"
auth := map[string]string{
"Authorization": "Bearer " + TOKEN,
}
var init = InitMessage{
Type: "connection_init",
Payload: auth,
}
// Initialize the websocket connection
if err := conn.WriteJSON(init); err != nil {
log.Fatal("Error sending connection_init message:", err)
}
// Read and print messages from the server
for {
_, message, err := conn.ReadMessage()
if err != nil {
log.Fatal("Error reading message from server:", err)
break
}
fmt.Println("Received message from server:", string(message))
var msg GraphQLSubscriptionMessage
json.Unmarshal(message, &msg)
switch msg.Type {
case "connection_ack":
query := `subscription {
device(id: "YOUR_DEVICE_ID_HERE"){
id
label
connectionStatus
}
}`
fmt.Println("Connection acknowledged.")
var qMap = map[string]string{
"query": query,
}
// Send the subscribe message with query
var subscribe = GraphQLSubscriptionMessage{
ID: uuid.NewString(),
Type: "subscribe",
Payload: qMap,
}
err := conn.WriteJSON(subscribe)
if err != nil {
log.Fatal("Error sending subscribe message:", err)
}
case "next":
data, err := json.Marshal(msg.Payload)
if err != nil {
log.Fatal("Error converting response", err)
}
fmt.Println("Data received:", data)
// process the message
case "complete":
fmt.Println("Subscription complete.")
return
case "error":
fmt.Println("Error:", msg.Payload)
default:
fmt.Println("Unknown message type:", msg.Type)
}
}
}
devices
The devices
subscription establishes a WebSocket connection to receive state changes for all the current user's devices.
type Subscription {
"""
WebSocket connection to receive state changes for all current user's devices
"""
devices: [Device!]
}
type Subscription {
"""
WebSocket connection to receive state changes for all current user's devices
"""
devices: [Device!]
}
This subscription does not require any parameters.
async def query_devices():
query = {
"id": str(uuid.uuid4()), # Unique ID for the subscription
"type": "subscribe",
"payload": {
"query": """
subscription {
devices {
id
lastPosition {
position {
llaDec {
lat
lon
alt
}
}
timestamp
}
connectionStatus
}
}
"""
}
}
init_message = {
"type": "connection_init",
"payload": {
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
}
uri = "wss://graphql.pointonenav.com/subscriptions"
async with websockets.connect(uri) as websocket: # Connect using the graphql-transport-ws protocol
await websocket.send(json.dumps(init_message))
while True:
response_str = await websocket.recv()
connect_response = json.loads(response_str)
# Handle different message types here (connection_ack, data, error, etc.)
if connect_response["type"] == 'connection_ack':
# Connection acknowledged, now send subscription request
subscribe_msg = json.dumps(query)
print("Subscribe: ", subscribe_msg)
await websocket.send(subscribe_msg)
device_msg_str = await websocket.recv()
device_response = json.loads(device_msg_str)
else:
print("Connection Error", json.dumps(connect_response))
break
while True:
if device_response["type"] == 'next':
# Handle incoming data
device_update = device_response['payload']['data']['devices']
device_msg = json.dumps(device_update)
print("Next: ", device_msg)
# Process the device update here....
elif device_response["type"] == 'error':
# Handle err data
err_msg = connect_response['payload']
print("Message Error: ", json.dumps(err_msg))
elif device_response["type"] == "complete":
break
asyncio.get_event_loop().run_until_complete(query_devices())
async def query_devices():
query = {
"id": str(uuid.uuid4()), # Unique ID for the subscription
"type": "subscribe",
"payload": {
"query": """
subscription {
devices {
id
lastPosition {
position {
llaDec {
lat
lon
alt
}
}
timestamp
}
connectionStatus
}
}
"""
}
}
init_message = {
"type": "connection_init",
"payload": {
"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
}
uri = "wss://graphql.pointonenav.com/subscriptions"
async with websockets.connect(uri) as websocket: # Connect using the graphql-transport-ws protocol
await websocket.send(json.dumps(init_message))
while True:
response_str = await websocket.recv()
connect_response = json.loads(response_str)
# Handle different message types here (connection_ack, data, error, etc.)
if connect_response["type"] == 'connection_ack':
# Connection acknowledged, now send subscription request
subscribe_msg = json.dumps(query)
print("Subscribe: ", subscribe_msg)
await websocket.send(subscribe_msg)
device_msg_str = await websocket.recv()
device_response = json.loads(device_msg_str)
else:
print("Connection Error", json.dumps(connect_response))
break
while True:
if device_response["type"] == 'next':
# Handle incoming data
device_update = device_response['payload']['data']['devices']
device_msg = json.dumps(device_update)
print("Next: ", device_msg)
# Process the device update here....
elif device_response["type"] == 'error':
# Handle err data
err_msg = connect_response['payload']
print("Message Error: ", json.dumps(err_msg))
elif device_response["type"] == "complete":
break
asyncio.get_event_loop().run_until_complete(query_devices())
import WebSocket from 'ws';
import {v4 as uuidv4} from "uuid";
const queryDevices = async () => {
const query = {
id: uuidv4(), // Unique Connection Identifier
type: "subscribe",
payload: {
query: `
subscription {
devices {
id
lastPosition {
position {
llaDec {
lat
lon
alt
}
}
timestamp
}
connectionStatus
}
}
`
}
};
const initMessage = {
type: "connection_init",
payload: {
Authorization: "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
};
const uri = "wss://graphql.pointonenav.com/subscriptions";
const websocket = new WebSocket(uri);
websocket.on('open', async () => {
websocket.send(JSON.stringify(initMessage));
});
websocket.on('message', (message: string) => {
websocket.on('message', (message: string) => {
const {type, payload} = JSON.parse(message);
if (type === 'connection_ack') {
console.log('Connected!')
websocket.send(JSON.stringify(query));
} else if (type === 'next') {
console.log('Next: ' + JSON.stringify(payload))
} else if (type === 'error') {
console.log('Error: ' + JSON.stringify(payload))
}
});
});
};
queryDevices();
import WebSocket from 'ws';
import {v4 as uuidv4} from "uuid";
const queryDevices = async () => {
const query = {
id: uuidv4(), // Unique Connection Identifier
type: "subscribe",
payload: {
query: `
subscription {
devices {
id
lastPosition {
position {
llaDec {
lat
lon
alt
}
}
timestamp
}
connectionStatus
}
}
`
}
};
const initMessage = {
type: "connection_init",
payload: {
Authorization: "Bearer YOUR_PERSONAL_ACCESS_TOKEN"
}
};
const uri = "wss://graphql.pointonenav.com/subscriptions";
const websocket = new WebSocket(uri);
websocket.on('open', async () => {
websocket.send(JSON.stringify(initMessage));
});
websocket.on('message', (message: string) => {
websocket.on('message', (message: string) => {
const {type, payload} = JSON.parse(message);
if (type === 'connection_ack') {
console.log('Connected!')
websocket.send(JSON.stringify(query));
} else if (type === 'next') {
console.log('Next: ' + JSON.stringify(payload))
} else if (type === 'error') {
console.log('Error: ' + JSON.stringify(payload))
}
});
});
};
queryDevices();
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"github.com/google/uuid"
"github.com/gorilla/websocket"
)
const query = `subscription {
devices {
id
label
connectionStatus
}
}`
// Connection Init message structure
type InitMessage struct {
Type string `json:"type"`
Payload map[string]string `json:"payload"`
}
// GraphQLSubscriptionMessage represents the structure of a GraphQL WebSocket message
type GraphQLSubscriptionMessage struct {
Type string `json:"type"`
ID string `json:"id,omitempty"`
Payload map[string]string `json:"payload,omitempty"`
}
func main() {
serverURL := url.URL{Scheme: "wss", Host: "graphql.pointonenav.com", Path: "/subscriptions"}
// Prepare the WebSocket handshake request headers
headers := http.Header{}
headers.Add("Sec-WebSocket-Protocol", "graphql-transport-ws")
// Connect to the GraphQL WebSocket endpoint
conn, _, err := websocket.DefaultDialer.Dial(serverURL.String(), headers)
if err != nil {
log.Fatal("Error connecting to WebSocket:", err)
}
defer conn.Close()
TOKEN := "YOUR_PERSONAL_ACCESS_TOKEN"
auth := map[string]string{
"Authorization": "Bearer " + TOKEN,
}
var init = InitMessage{
Type: "connection_init",
Payload: auth,
}
// Initialize the websocket connection
if err := conn.WriteJSON(init); err != nil {
log.Fatal("Error sending connection_init message:", err)
}
// Read and print messages from the server
for {
_, message, err := conn.ReadMessage()
if err != nil {
log.Fatal("Error reading message from server:", err)
break
}
fmt.Println("Received message from server:", string(message))
var msg GraphQLSubscriptionMessage
json.Unmarshal(message, &msg)
switch msg.Type {
case "connection_ack":
fmt.Println("Connection acknowledged.")
var qMap = map[string]string{
"query": query,
}
// Send the subscribe message with query
var subscribe = GraphQLSubscriptionMessage{
ID: uuid.NewString(),
Type: "subscribe",
Payload: qMap,
}
err := conn.WriteJSON(subscribe)
if err != nil {
log.Fatal("Error sending subscribe message:", err)
}
case "next":
data, err := json.Marshal(msg.Payload)
if err != nil {
log.Fatal("Error converting response", err)
}
fmt.Println("Data received:", data)
// process the message
case "complete":
fmt.Println("Subscription complete.")
return
case "error":
fmt.Println("Error:", msg.Payload)
default:
fmt.Println("Unknown message type:", msg.Type)
}
}
}
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"github.com/google/uuid"
"github.com/gorilla/websocket"
)
const query = `subscription {
devices {
id
label
connectionStatus
}
}`
// Connection Init message structure
type InitMessage struct {
Type string `json:"type"`
Payload map[string]string `json:"payload"`
}
// GraphQLSubscriptionMessage represents the structure of a GraphQL WebSocket message
type GraphQLSubscriptionMessage struct {
Type string `json:"type"`
ID string `json:"id,omitempty"`
Payload map[string]string `json:"payload,omitempty"`
}
func main() {
serverURL := url.URL{Scheme: "wss", Host: "graphql.pointonenav.com", Path: "/subscriptions"}
// Prepare the WebSocket handshake request headers
headers := http.Header{}
headers.Add("Sec-WebSocket-Protocol", "graphql-transport-ws")
// Connect to the GraphQL WebSocket endpoint
conn, _, err := websocket.DefaultDialer.Dial(serverURL.String(), headers)
if err != nil {
log.Fatal("Error connecting to WebSocket:", err)
}
defer conn.Close()
TOKEN := "YOUR_PERSONAL_ACCESS_TOKEN"
auth := map[string]string{
"Authorization": "Bearer " + TOKEN,
}
var init = InitMessage{
Type: "connection_init",
Payload: auth,
}
// Initialize the websocket connection
if err := conn.WriteJSON(init); err != nil {
log.Fatal("Error sending connection_init message:", err)
}
// Read and print messages from the server
for {
_, message, err := conn.ReadMessage()
if err != nil {
log.Fatal("Error reading message from server:", err)
break
}
fmt.Println("Received message from server:", string(message))
var msg GraphQLSubscriptionMessage
json.Unmarshal(message, &msg)
switch msg.Type {
case "connection_ack":
fmt.Println("Connection acknowledged.")
var qMap = map[string]string{
"query": query,
}
// Send the subscribe message with query
var subscribe = GraphQLSubscriptionMessage{
ID: uuid.NewString(),
Type: "subscribe",
Payload: qMap,
}
err := conn.WriteJSON(subscribe)
if err != nil {
log.Fatal("Error sending subscribe message:", err)
}
case "next":
data, err := json.Marshal(msg.Payload)
if err != nil {
log.Fatal("Error converting response", err)
}
fmt.Println("Data received:", data)
// process the message
case "complete":
fmt.Println("Subscription complete.")
return
case "error":
fmt.Println("Error:", msg.Payload)
default:
fmt.Println("Unknown message type:", msg.Type)
}
}
}
Type Reference
Enums
ConnectionStatus
enum ConnectionStatus {
UNKNOWN,
GOOD,
NO_CONNECTION,
BAD_POSITION,
NO_POSITION
}
enum ConnectionStatus {
UNKNOWN,
GOOD,
NO_CONNECTION,
BAD_POSITION,
NO_POSITION
}
TokenRole
enum TokenRole {
ROLE_READ,
ROLE_READ_WRITE
}
enum TokenRole {
ROLE_READ,
ROLE_READ_WRITE
}
TokenStatus
enum TokenStatus {
ACTIVE,
EXPIRED,
REVOKED
}
enum TokenStatus {
ACTIVE,
EXPIRED,
REVOKED
}
Scalars
scalar DateTime
scalar LocalDateTime
scalar DateTime
scalar LocalDateTime
Objects
Device
type Device {
id: ID!
account: Account!
label: String!
lastPosition: PositionHistory!
type: String
services: DeviceServices!
tags: [Tag!]
createdAt: DateTime!
updatedAt: DateTime
}
type Device {
id: ID!
account: Account!
label: String!
lastPosition: PositionHistory!
type: String
services: DeviceServices!
tags: [Tag!]
createdAt: DateTime!
updatedAt: DateTime
}
DevicePage
A page of results from a device query
type DevicePage implements PageResult {
content: [Device!]
pageNumber: Int!
pageSize: Int!
offset: Int!
totalElements: Int!
totalPages: Int!
first: Boolean!
last: Boolean!
}
type DevicePage implements PageResult {
content: [Device!]
pageNumber: Int!
pageSize: Int!
offset: Int!
totalElements: Int!
totalPages: Int!
first: Boolean!
last: Boolean!
}
PersonalAccessToken
type PersonalAccessToken {
name: String!
description: String
status: TokenStatus!
role: TokenRole!
createdAt: DateTime!
expiresAt: DateTime
revokedAt: DateTime
}
type PersonalAccessToken {
name: String!
description: String
status: TokenStatus!
role: TokenRole!
createdAt: DateTime!
expiresAt: DateTime
revokedAt: DateTime
}
DeviceServices
Information about individual services attached to a device
type DeviceServices {
rtk: RtkService
}
type DeviceServices {
rtk: RtkService
}
NTRIP
Information specifically related to using NTRIP protocol
type NTRIP {
login: String!
password: String!
casterUrl: String
mountPoint: String
solutionType: String
numSats: Int
}
type NTRIP {
login: String!
password: String!
casterUrl: String
mountPoint: String
solutionType: String
numSats: Int
}
Position
Geo-Positional data in a variety of formats
type Position {
llaDMS: PositionLLADMS
llaDec: PositionLLADD
ecef: PositionECEF
}
type Position {
llaDMS: PositionLLADMS
llaDec: PositionLLADD
ecef: PositionECEF
}
PositionLLADMS
Geo-Position as converted from Degrees, Minutes, Seconds
type PositionLLADMS {
lat: String
lon: String
alt: String
}
type PositionLLADMS {
lat: String
lon: String
alt: String
}
PositionLLADD
Geo-Position as Latitude, Longitude, Altitude
type PositionLLADD {
lat: String
lon: String
alt: String
}
type PositionLLADD {
lat: String
lon: String
alt: String
}
PositionECEF
Geo-Position as Earth-Fixed, Earth Centric
type PositionECEF {
x: Float
y: Float
z: Float
}
type PositionECEF {
x: Float
y: Float
z: Float
}
PositionHistory
Historical positional data for a specific Device (if applicable)
type PositionHistory {
timestamp: LocalDateTime
position: Position
}
type PositionHistory {
timestamp: LocalDateTime
position: Position
}
RTKService
Provides information regarding RTK related service
type RtkService {
enabled: Boolean!
polarisKey: String!
ntrip: NTRIP!
connectionStatus: ConnectionStatus!
}
type RtkService {
enabled: Boolean!
polarisKey: String!
ntrip: NTRIP!
connectionStatus: ConnectionStatus!
}
Tag
Key-Value Pair metadata to aid in classification of Devices
type Tag {
key: String!
value: String
createdAt: DateTime!
updatedAt: DateTime
}
type Tag {
key: String!
value: String
createdAt: DateTime!
updatedAt: DateTime
}
Input Types
DeviceInput
Device Input for create/update requests
input DeviceInput {
id: ID
label: String
type: String
enabled: Boolean
}
input DeviceInput {
id: ID
label: String
type: String
enabled: Boolean
}
TagInput
Tag input for create/update requests
input TagInput {
key: String
value: String
ids: [ID!]
}
input TagInput {
key: String
value: String
ids: [ID!]
}
DeviceFilter
The search input to be submitted to filterable device queries
input DeviceFilter {
type: String
label: StringConditional
status: String
tag: TagFilter
and: [DeviceFilter]
or: [DeviceFilter]
not: [DeviceFilter]
}
input DeviceFilter {
type: String
label: StringConditional
status: String
tag: TagFilter
and: [DeviceFilter]
or: [DeviceFilter]
not: [DeviceFilter]
}
StringConditional
Defines String based operations for conditionals in filters
input StringConditional {
eq: String
ne: String
}
input StringConditional {
eq: String
ne: String
}
TagFilter
Tag Filter used in queries
input TagFilter {
key: String
value: StringConditional
}
input TagFilter {
key: String
value: StringConditional
}
Interfaces
PageResult
Any page-able list
interface PageResult {
pageNumber: Int!
pageSize: Int!
offset: Int!
totalElements: Int!
totalPages: Int!
first: Boolean!
last: Boolean!
}
interface PageResult {
pageNumber: Int!
pageSize: Int!
offset: Int!
totalElements: Int!
totalPages: Int!
first: Boolean!
last: Boolean!
}