REST API Reference
Complete reference for all REST API endpoints.
Interactive Documentation
For an interactive experience, visit our Swagger UI where you can test endpoints directly.
Base URL
https://api.elcto.com
Health & Info
Get Health Status
Check the health status of the API and all services.
GET /health
GET /v1/health
Authentication: None required
Both endpoints return the same response. /health is available at the root level for load balancers and monitoring tools, while /v1/health is available under the versioned API for consistency.
Response:
{
"status": "healthy",
"version": "1.0.0",
"timestamp": "2025-11-24T10:30:00Z",
"uptime": {
"days": 5,
"hours": 12,
"minutes": 30,
"seconds": 45,
"total": 475845.0
},
"services": {
"database": {
"status": "up",
"responseTime": 15
},
"redis": {
"status": "up",
"responseTime": 3
},
"websocket": {
"status": "up",
"connections": 42,
"subscriptions": 128
}
},
"_links": {
"self": "https://api.elcto.com/health"
}
}
Get API Info
Get information about the API version and client details.
GET /v1
Authentication: None required
Response:
{
"version": "1.0.0",
"server": {
"uptime": 475845000
},
"client": {
"ip": "192.168.1.100",
"userAgent": "Mozilla/5.0...",
"browser": "Chrome",
"os": "Windows"
},
"timestamp": "2025-11-24T10:30:00Z",
"_links": {
"self": "https://api.elcto.com/v1"
}
}
GPS Data
List GPS Data
Retrieve a paginated list of GPS data points.
GET /v1/gps?page=1&limit=10
Authentication: Required (Viewer or Admin)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 10 | Items per page (max: 100) |
Response:
{
"data": [
{
"id": "abc-123",
"latitude": 51.5074,
"longitude": -0.1278,
"altitude": 11.0,
"timestamp": 1700000000,
"speed": 5.5,
"createdAt": "2025-11-24T10:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 100,
"total_pages": 10
},
"_links": {
"self": "https://api.elcto.com/v1/gps?page=1&limit=10",
"first": "https://api.elcto.com/v1/gps?page=1&limit=10",
"next": "https://api.elcto.com/v1/gps?page=2&limit=10",
"last": "https://api.elcto.com/v1/gps?page=10&limit=10"
}
}
Get Current GPS
Get the most recent GPS data point.
GET /v1/gps/current
Authentication: Required (Viewer or Admin)
Response:
{
"data": {
"id": "abc-123",
"latitude": 51.5074,
"longitude": -0.1278,
"altitude": 11.0,
"timestamp": 1700000000,
"speed": 5.5,
"createdAt": "2025-11-24T10:00:00Z"
},
"_links": {
"self": "https://api.elcto.com/v1/gps/abc-123"
}
}
Get GPS by ID
Retrieve a specific GPS data point by ID.
GET /v1/gps/{id}
Authentication: Required (Viewer or Admin)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | UUID | GPS data ID |
Response:
{
"data": {
"id": "abc-123",
"latitude": 51.5074,
"longitude": -0.1278,
"altitude": 11.0,
"timestamp": 1700000000,
"speed": 5.5,
"createdAt": "2025-11-24T10:00:00Z"
},
"_links": {
"self": "https://api.elcto.com/v1/gps/abc-123"
}
}
Create GPS Data
Create a new GPS data point.
POST /v1/gps
Content-Type: application/json
Authentication: Required (Admin only)
Rate Limit: 30 requests per 60 seconds
Request Body:
{
"latitude": 51.5074,
"longitude": -0.1278,
"altitude": 11.0,
"timestamp": 1700000000,
"speed": 5.5
}
Response (201 Created):
{
"data": {
"id": "abc-123",
"latitude": 51.5074,
"longitude": -0.1278,
"altitude": 11.0,
"timestamp": 1700000000,
"speed": 5.5,
"createdAt": "2025-11-24T10:00:00Z"
},
"_links": {
"self": "https://api.elcto.com/v1/gps/abc-123"
}
}
System Settings
Get All Settings
Retrieve all system settings.
GET /v1/settings
Authentication: Required (Admin only)
Get Public Settings
Retrieve public-facing settings.
GET /v1/settings/public
Authentication: None required
Get Setting by Key
Retrieve a specific setting by key.
GET /v1/settings/{key}
Authentication: Required (Admin only)
Create Setting
Create a new system setting.
POST /v1/settings
Content-Type: application/json
Authentication: Required (Admin only)
Update Setting
Update an existing setting.
PUT /v1/settings/{key}
Content-Type: application/json
Authentication: Required (Admin only)
Delete Setting
Delete a system setting.
DELETE /v1/settings/{key}
Authentication: Required (Admin only)
Statistics
Get Public Statistics
Retrieve public platform statistics.
GET /v1/stats/public
Authentication: None required
Users
List Users
Retrieve a paginated list of all users.
GET /v1/users?page=1&limit=20
Authentication: Required
Permission: users:read
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Items per page (max: 100) |
Response:
{
"data": [
{
"id": "user-123",
"username": "johndoe",
"primary_platform_account_id": "pa-456",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-20T15:30:00Z",
"last_login_at": "2025-01-25T09:00:00Z",
"deleted_at": null,
"privacy_mode": false
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"total_pages": 8
},
"_links": {
"self": "https://api.elcto.com/v1/users?page=1&limit=20",
"first": "https://api.elcto.com/v1/users?page=1&limit=20",
"next": "https://api.elcto.com/v1/users?page=2&limit=20",
"last": "https://api.elcto.com/v1/users?page=8&limit=20"
}
}
Get User by ID
Retrieve a specific user by their ID.
GET /v1/users/{id}
Authentication: Required
Permission: users:read (or self)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | User ID |
Response:
{
"data": {
"id": "user-123",
"username": "johndoe",
"primary_platform_account_id": "pa-456",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-20T15:30:00Z",
"last_login_at": "2025-01-25T09:00:00Z",
"deleted_at": null,
"privacy_mode": false
},
"_links": {
"self": "https://api.elcto.com/v1/users/user-123"
}
}
Get User Profile
Retrieve a user's profile with platform account details.
GET /v1/users/{id}/profile
Authentication: Required
Permission: users:read (or self)
Response:
{
"name": "John Doe",
"display_name": "johndoe",
"picture": "https://cdn.example.com/avatar.png",
"provider": "twitch",
"primary_provider": "twitch",
"last_login_at": "2025-01-25T09:00:00Z",
"created_at": "2025-01-15T10:00:00Z",
"privacy_mode": false
}
Get Current User
Retrieve the currently authenticated user.
GET /v1/users/me
Authentication: Required
Response: Same as Get User by ID
Update User
Update a user's information.
PATCH /v1/users/{id}
Content-Type: application/json
Authentication: Required
Permission: users:write (or self)
Request Body:
{
"username": "newusername",
"email": "[email protected]",
"avatar_url": "https://cdn.example.com/new-avatar.png",
"privacy_mode": true
}
All fields are optional. Only provided fields will be updated.
Response:
{
"data": {
"id": "user-123",
"username": "newusername",
"primary_platform_account_id": "pa-456",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-26T12:00:00Z",
"last_login_at": "2025-01-25T09:00:00Z",
"deleted_at": null,
"privacy_mode": true
},
"_links": {
"self": "https://api.elcto.com/v1/users/user-123"
}
}
Delete User
Soft delete a user (sets deleted_at timestamp and revokes all sessions/API keys).
DELETE /v1/users/{id}
Authentication: Required
Permission: users:delete
Response (204 No Content): Empty response on success
Get User Permissions
Retrieve a user's effective permissions (including role-based permissions).
GET /v1/users/{id}/permissions
Authentication: Required
Permission: users:read (or self)
Response:
{
"permissions": [
"users:read",
"users:write",
"gps:read",
"*:*"
]
}
Get User Roles
Retrieve a user's assigned roles.
GET /v1/users/{id}/roles
Authentication: Required
Permission: users:read (or self)
Response:
{
"roles": [
{
"id": "role-123",
"name": "admin",
"description": "Administrator role"
}
]
}
Assign Role to User
Assign a role to a user.
POST /v1/users/{id}/roles
Content-Type: application/json
Authentication: Required
Permission: users:write
Request Body:
{
"role_id": "role-123"
}
Remove Role from User
Remove a role from a user.
DELETE /v1/users/{id}/roles/{role_id}
Authentication: Required
Permission: users:write
Platform Accounts
List User Accounts
Retrieve all platform accounts linked to a user.
GET /v1/users/{id}/accounts
Authentication: Required
Permission: users:read (or self)
Response:
{
"data": [
{
"id": "pa-456",
"platform_id": "platform-twitch",
"platform_name": "Twitch",
"platform_slug": "twitch",
"platform_user_id": "12345678",
"is_oauth": true,
"is_primary": true,
"username": "johndoe",
"email": "[email protected]",
"avatar_url": "https://cdn.example.com/avatar.png",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-20T15:30:00Z"
}
],
"_links": {
"self": "https://api.elcto.com/v1/users/user-123/accounts"
}
}
Set Primary Platform Account
Change which platform account is used as the primary account for profile information.
PUT /v1/users/{id}/accounts/{account_id}/primary
Authentication: Required
Permission: users:write (or self)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | User ID |
account_id | string | Platform account ID to set as primary |
Response:
{
"data": {
"id": "pa-456",
"platform_id": "platform-discord",
"platform_name": "Discord",
"platform_slug": "discord",
"platform_user_id": "98765432",
"is_oauth": true,
"is_primary": true,
"username": "johndoe#1234",
"email": "[email protected]",
"avatar_url": "https://cdn.example.com/avatar.png",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-25T14:30:00Z"
},
"_links": {
"self": "https://api.elcto.com/v1/users/user-123/accounts/pa-456"
}
}
Unlink Platform Account
Remove a platform account link from a user.
DELETE /v1/users/{id}/accounts/{account_id}
Authentication: Required
Permission: users:write (or self)
Response (204 No Content): Empty response on success
- Cannot unlink the email platform account (use account deletion instead)
- Cannot unlink the last platform account (user must have at least one login method)
- Cannot unlink the primary account (change primary first)
Request Link Email Account
Start the process of linking an email account to a user. Sends a verification email.
POST /v1/users/{id}/email-link/request
Authorization: Bearer {token}
Content-Type: application/json
Authentication: Required
Permission: users:write (or self)
Request Body:
{
"email": "[email protected]",
"password": "securepassword123"
}
Response (200 OK):
{
"message": "Verification email sent. Please check your inbox.",
"expires_at": "2025-01-25T15:30:00Z"
}
The password must be at least 8 characters long.
Verify Link Email Account
Complete the email account linking by verifying the token from the email.
POST /v1/users/email-link/verify
Authorization: Bearer {token}
Content-Type: application/json
Authentication: Required
Request Body:
{
"token": "abc123def456..."
}
Response (200 OK):
{
"message": "Email account linked successfully",
"platform_account_id": "pa-789"
}
Get Pending Email Link
Check if there's a pending email link verification for a user.
GET /v1/users/{id}/email-link/pending
Authorization: Bearer {token}
Authentication: Required
Permission: users:read (or self)
Response (200 OK) - With pending link:
{
"pending": true,
"email": "[email protected]",
"expires_at": "2025-01-25T15:30:00Z"
}
Response (200 OK) - No pending link:
{
"pending": false,
"email": null,
"expires_at": null
}
Cancel Pending Email Link
Cancel a pending email link request.
DELETE /v1/users/{id}/email-link/pending
Authorization: Bearer {token}
Authentication: Required
Permission: users:write (or self)
Response (200 OK):
{
"message": "Pending email link cancelled"
}
Once an email account is linked, users can authenticate using email/password on platforms that support it. This provides an alternative to OAuth authentication.
Sessions
Session management endpoints for NextAuth integration. These endpoints require a system API key for authentication.
These endpoints are used internally by NextAuth for session management. They are not intended for direct client use.
Create Session
Create a new database session for a user.
POST /v1/sessions
Authorization: Bearer {SYSTEM_API_KEY}
Content-Type: application/json
Request Body:
{
"userId": "user-123",
"expires": "2025-02-25T10:00:00Z"
}
Response (201 Created):
{
"id": "sess-uuid",
"sessionToken": "sess_abc123...",
"userId": "user-123",
"expires": "2025-02-25T10:00:00Z",
"created_at": "2025-01-25T10:00:00Z"
}
Get Session
Retrieve a session by token.
GET /v1/sessions/{token}
Authorization: Bearer {SYSTEM_API_KEY}
Response:
{
"id": "sess-uuid",
"sessionToken": "sess_abc123...",
"userId": "user-123",
"expires": "2025-02-25T10:00:00Z",
"created_at": "2025-01-25T10:00:00Z"
}
Delete Session
Delete a session (sign out).
DELETE /v1/sessions/{token}
Authorization: Bearer {SYSTEM_API_KEY}
Response (204 No Content): Empty response on success
Session Flow with NextAuth
- Login: User authenticates via credentials or OAuth
- Create: NextAuth calls
POST /v1/sessionsto create database session - Use: Session token stored in
session.accessTokenfor WebSocket auth - Logout: NextAuth calls
DELETE /v1/sessions/{token}on sign out - Cleanup: Sessions are also deleted when user account is deleted
HATEOAS Links
All responses include hypermedia links for API navigation:
self: Link to the current resourcefirst: First page (pagination)prev: Previous page (pagination)next: Next page (pagination)last: Last page (pagination)
Error Responses
All errors follow a consistent format:
{
"error": "NotFound",
"message": "GPS data not found"
}
Common HTTP status codes:
| Code | Description |
|---|---|
| 200 | OK - Request succeeded |
| 201 | Created - Resource created |
| 400 | Bad Request - Invalid input |
| 401 | Unauthorized - Authentication required |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Resource doesn't exist |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error - Server error |
| 503 | Service Unavailable - Service is down |