Skip to main content

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:

ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger10Items 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:

ParameterTypeDescription
idUUIDGPS 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:

ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger20Items 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:

ParameterTypeDescription
idstringUser 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:

ParameterTypeDescription
idstringUser ID
account_idstringPlatform 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"
}
}

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

Restrictions
  • 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)

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"
}
Password Requirements

The password must be at least 8 characters long.

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"
}

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 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"
}
Email Account Authentication

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.

Internal Use Only

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

  1. Login: User authenticates via credentials or OAuth
  2. Create: NextAuth calls POST /v1/sessions to create database session
  3. Use: Session token stored in session.accessToken for WebSocket auth
  4. Logout: NextAuth calls DELETE /v1/sessions/{token} on sign out
  5. Cleanup: Sessions are also deleted when user account is deleted

All responses include hypermedia links for API navigation:

  • self: Link to the current resource
  • first: 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:

CodeDescription
200OK - Request succeeded
201Created - Resource created
400Bad Request - Invalid input
401Unauthorized - Authentication required
403Forbidden - Insufficient permissions
404Not Found - Resource doesn't exist
429Too Many Requests - Rate limit exceeded
500Internal Server Error - Server error
503Service Unavailable - Service is down

Next Steps