Skip to main content

GraphQL API Quickstart

This guide will help you make your first GraphQL query to the SensorUp API and understand the basics of working with the federated graph.

Prerequisites

Before you begin, you’ll need:
  • Access to a SensorUp environment (demo, staging, or production)
  • Valid authentication credentials (see Authentication)
  • A GraphQL client or HTTP tool (curl, Postman, or a programming language client)

Your First Query

Using curl

curl -X POST https://customer-demo.sensorup.com/api/graphql \
  -H "Content-Type: application/json" \
  -H "x-sensorup-sessionid: YOUR_SESSION_ID" \
  -d '{
    "query": "query { session { username authenticated } }"
  }'

Response

{
  "data": {
    "session": {
      "username": "your-username",
      "authenticated": true
    }
  }
}

Understanding the Query Structure

GraphQL queries have three main components:
query {           # Operation type (query, mutation, or subscription)
  session {       # Root field - what you're querying
    username      # Selection - fields you want returned
    authenticated
  }
}

Common Query Patterns

Querying Asset Profiles

query GetAssetProfiles {
  assetProfiles {
    all(first: 10) {
      edges {
        node {
          profile
          title
          displayNameProperty
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}

Getting Specific Asset by ID

query GetAsset($profileId: ID!, $assetId: ID!) {
  assetProfiles {
    byId(profile: $profileId) {
      profile
      title
      assetById(id: $assetId) {
        id
        displayName
        properties
        geometry
      }
    }
  }
}
Variables:
{
  "profileId": "your-profile-id",
  "assetId": "your-asset-id"
}

Querying Issues

query GetIssues {
  issues {
    all(first: 10) {
      edges {
        node {
          id
          displayName
          status
          createdAt
          audit {
            createdBy {
              userId
            }
          }
        }
      }
    }
  }
}

Making Mutations

Mutations modify data on the server. All mutations follow a consistent pattern with result types that include correlationId and errors.

Creating an Asset Filter

mutation CreateAssetFilter($input: CreateAssetFilterInput!) {
  createAssetFilter(input: $input) {
    assetFilter {
      id
      displayName
      profile
    }
    correlationId
    errors {
      message
      type
    }
  }
}
Variables:
{
  "input": {
    "id": "my-filter-id",
    "displayName": "My Asset Filter",
    "profile": "asset-profile-id",
    "subProfiles": []
  }
}

Pagination

The API uses Relay-style cursor-based pagination:
query PaginatedAssets($first: Int!, $after: String) {
  assetProfiles {
    byId(profile: "your-profile") {
      assets(first: $first, after: $after) {
        edges {
          node {
            id
            displayName
          }
        }
        pageInfo {
          hasNextPage
          hasPreviousPage
          startCursor
          endCursor
        }
      }
    }
  }
}
First page:
{ "first": 10 }
Next page:
{ "first": 10, "after": "cursor-from-previous-page" }

Error Handling

Query Errors

GraphQL returns errors in the errors array:
{
  "errors": [
    {
      "message": "Cannot query field 'invalidField' on type 'Asset'",
      "locations": [{ "line": 3, "column": 5 }]
    }
  ]
}

Mutation Errors

Mutations return errors in the result type:
{
  "data": {
    "createAssetFilter": {
      "assetFilter": null,
      "correlationId": "abc-123",
      "errors": [
        {
          "message": "Asset filter with this ID already exists",
          "type": "DUPLICATE_ID"
        }
      ]
    }
  }
}

Using GraphQL Clients

JavaScript/TypeScript

// Using graphql-request
import { request, gql } from 'graphql-request'

const query = gql`
  query {
    session {
      username
      authenticated
    }
  }
`

const data = await request(
  'https://customer-demo.sensorup.com/api/graphql',
  query,
  {},
  { 'x-sensorup-sessionid': sessionId }
)

Python

# Using gql
from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport

transport = RequestsHTTPTransport(
    url='https://customer-demo.sensorup.com/api/graphql',
    headers={'x-sensorup-sessionid': session_id}
)

client = Client(transport=transport, fetch_schema_from_transport=True)

query = gql("""
    query {
        session {
            username
            authenticated
        }
    }
""")

result = client.execute(query)

Next Steps

Now that you’ve made your first queries:
  1. Authentication - Learn about auth methods and credential management
  2. Common Patterns - Deep dive into pagination, filtering, and GeoJSON
  3. Domain Guides - Explore specific use cases:
  4. Subgraph Reference - Complete schema documentation:
    • Assets - Asset profiles for field service
    • CAM Assets - Connected asset management
    • Issues - Issue tracking
    • Forms - XForms data collection
    • Auth - Authentication and sessions
    • Workflow - Workflow definitions
    • And more in the subgraphs directory

Interactive Exploration

SensorUp includes Apollo Explorer as a built-in plugin for interactive query building and schema exploration: Demo Environment:
https://customer-demo.sensorup.com/plugins/sr/apolloGraphql
Features:
  • Interactive query builder with autocomplete
  • Full schema documentation browser
  • Query history and saved queries
  • Authentication handled automatically (no need to manually set headers)
  • Real-time query validation
For other environments:
  • Replace customer-demo.sensorup.com with your environment’s hostname
  • The plugin path remains /plugins/sr/apolloGraphql

Additional Resources

For further exploration tools, contact your SensorUp account team about:
  • Apollo Studio access for advanced query planning and performance monitoring
  • Postman collections with example queries