Authentication
Overview
The Service API uses user account authentication with JWT tokens. Each user is assigned to a role with specific permissions.
For comprehensive information about roles, permissions, and access control, see Roles and Access Management.
Authentication Flow
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#73F9C1','primaryTextColor':'#143633','primaryBorderColor':'#143633','lineColor':'#143633','secondaryColor':'#C7FDE6','tertiaryColor':'#F6FAFA','actorBkg':'#73F9C1','actorBorder':'#143633','noteBorderColor':'#FF8862','noteBkgColor':'#FFCFC0','signalColor':'#143633'}}}%%
sequenceDiagram
note over Client,API: Login
Client->>API: LoginMutation($email, $password, $organizationName)
API-->>Client: accessToken, refreshToken
note over Client,API: RefreshToken
Client->>API: RefreshMutation($refreshToken)
API-->>Client: accessToken, refreshToken
note over Client,API: Logout
Client->>API: LogoutMutation()
API-->>Client: Session terminatedLogin
Authenticate with email, password, and organization name to receive access and refresh tokens.
Login Mutation
mutation Login($email: String!, $organizationName: String!, $password: String!) {
login(loginInput: {
email: $email,
organizationName: $organizationName,
password: $password
}) {
accessToken
expiresIn
refreshExpiresIn
refreshToken
organizationId
}
}
Example Variables
{
"email": "demo@haltian.com",
"organizationName": "demo",
"password": "your-password"
}
Response
{
"data": {
"login": {
"accessToken": "eyJhbGciO...",
"expiresIn": 900,
"refreshExpiresIn": 43200,
"refreshToken": "eyJhbGc...",
"organizationId": "2a749da0-5512-..."
}
}
}
Token Details
| Token | Validity | Purpose |
|---|---|---|
accessToken | 15 minutes | Authorization header for API requests |
refreshToken | 12 hours | Obtain new access token without re-login |
Using the Access Token
Include the access token in the Authorization header for all API requests:
Authorization: Bearer eyJhbGciO...
Example with cURL
curl -X POST https://haltian-iot-api.example.com/v1/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciO..." \
-d '{"query": "{ devices { id name } }"}'
Refresh Token
Before the access token expires, use the refresh token to obtain a new access token without requiring the user to log in again.
Refresh Token Mutation
mutation RefreshToken($organizationId: String!, $refreshToken: String!) {
refreshToken(refreshTokenInput: {
organizationId: $organizationId,
refreshToken: $refreshToken
}) {
accessToken
expiresIn
refreshExpiresIn
refreshToken
}
}
Token Refresh Strategy
- Track token expiration time client-side
- Refresh the token before it expires (e.g., at 80% of validity)
- Store new tokens securely
- If refresh fails, redirect to login
Logout
Terminate the session and invalidate tokens:
mutation Logout {
logout {
success
}
}
API Endpoint
The GraphQL endpoint URL depends on your Haltian IoT deployment:
https://haltian-iot-api.{haltian_iot_center_domain}/v1/graphql
Where {haltian_iot_center_domain} is the same domain used for Haltian IoT Studio login.
Introspection
The API schema is available via GraphQL introspection:
- Requires authentication
- Schema adapts to user’s role (Manager sees full API, Viewer sees limited queries)
- Use Postman, Apollo CLI, or other GraphQL clients to explore
The full GraphQL API specification is available only through introspection. The visible schema depends on your user role.
Security Best Practices
- Never expose tokens in client-side code or version control
- Use HTTPS for all API communications
- Implement token refresh to maintain sessions without storing passwords
- Handle token expiration gracefully with automatic refresh or re-authentication
- Logout explicitly when the user session ends