API Overview
Terragnos Core provides both REST and GraphQL APIs for programmatic access. All APIs are versioned, require authentication, and follow consistent patterns for error handling and data access.
API Base URL
The API is available at:
https://core.example.com/v1
For local development:
http://localhost:3000/v1
Authentication
All API requests require a JWT token in the Authorization header:
curl -H "Authorization: Bearer <your-jwt-token>" \
https://core.example.com/v1/objects
See the Security guide for details on JWT structure and token generation.
API Versioning
Terragnos Core uses URL-based versioning. The current version is v1:
- REST:
/v1/... - GraphQL:
/v1/graphql
Future versions will use /v2/..., /v3/..., etc. Breaking changes will only occur in new major versions.
REST API
Endpoint Structure
REST endpoints follow a consistent pattern:
- Collections:
GET /v1/{resource}– List resources - Single resource:
GET /v1/{resource}/{id}– Get specific resource - Create:
POST /v1/{resource}– Create new resource - Update:
PATCH /v1/{resource}/{id}– Update resource - Delete:
DELETE /v1/{resource}/{id}– Delete resource
Request Format
Headers:
Authorization: Bearer <jwt-token>
Content-Type: application/json
Body (for POST/PATCH):
{
"field1": "value1",
"field2": "value2"
}
Response Format
Success (200 OK):
{
"id": "resource-id",
"field1": "value1",
"field2": "value2",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
Error (4xx/5xx):
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input",
"details": {
"field": "name",
"reason": "Required field is missing"
}
}
}
Common HTTP Status Codes
200 OK– Request succeeded201 Created– Resource created400 Bad Request– Invalid request data401 Unauthorized– Missing or invalid authentication403 Forbidden– Insufficient permissions404 Not Found– Resource doesn't exist409 Conflict– Optimistic locking conflict429 Too Many Requests– Rate limit exceeded500 Internal Server Error– Server error
GraphQL API
Endpoint
POST /v1/graphql
Query Example
query {
objects(limit: 10) {
id
typeId
attributes
geometry
workflowState
}
}
Mutation Example
mutation {
createObject(input: {
typeId: "traffic-signal"
attributes: {
signalType: "standard"
}
geometry: {
type: "Point"
coordinates: [12.34, 56.78]
}
}) {
id
publicId
}
}
See the GraphQL documentation for the complete schema.
OpenAPI Specification
The complete REST API specification is available at:
GET /openapi/v1.json
This OpenAPI 3.0 document can be used to:
- Generate client SDKs
- Import into API testing tools (Postman, Insomnia)
- Generate API documentation
Rate Limiting
API requests are rate-limited to prevent abuse. Default limits:
- Time window: 60 seconds
- Maximum requests: 120 per window
When the limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header.
Configure limits via environment variables:
RATE_LIMIT_TTL– Time window in secondsRATE_LIMIT_LIMIT– Maximum requests per window
Pagination
List endpoints support pagination:
GET /v1/objects?limit=25&offset=0
Response includes pagination metadata:
{
"items": [...],
"pagination": {
"limit": 25,
"offset": 0,
"total": 150,
"hasMore": true
}
}
Filtering and Sorting
Many endpoints support filtering and sorting:
GET /v1/objects?typeId=traffic-signal&sortBy=createdAt&sortOrder=desc
See the API Reference for endpoint-specific filtering options.
Time-Travel Queries
Read endpoints support time-travel queries using the asOf parameter:
GET /v1/objects/{id}?asOf=2024-01-15T10:30:00Z
This returns the object's state at the specified point in time.
Health Checks
Monitor API health:
# Liveness check
GET /v1/health/live
# Readiness check
GET /v1/health/ready
Both return 200 OK when healthy. Use these endpoints for load balancer health checks.
Error Handling
Always check the response status code and handle errors appropriately:
try {
const response = await fetch('https://core.example.com/v1/objects', {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
const error = await response.json();
console.error('API Error:', error);
// Handle error
}
const data = await response.json();
// Use data
} catch (error) {
// Handle network error
}
SDKs
For easier integration, use the official SDKs:
SDKs handle authentication, error handling, and provide type-safe interfaces.