Remote Platform

Analytics API v1

Saha Robotics Analytics API integration guide

Authentication

You must include your API key in the HTTP header for all requests:

x-api-key: <API_KEY>

Your API key only grants access to projects assigned to you. If you send a request with an unassigned projectId, you will receive 403.

Base URL

EnvironmentURL
Productionhttps://remote.saharobotik.com/api/client/analytics
Staginghttps://staging.saharobotik.com/api/client/analytics

Swagger Documentation

EnvironmentURL
Productionhttps://remote.saharobotik.com/api/swagger/client/analytics
Staginghttps://staging.saharobotik.com/api/swagger/client/analytics

Rate Limit

A maximum of 6 requests per minute is allowed for each endpoint.
When the limit is exceeded, a 429 Too Many Requests error is returned and the limit resets after 60 seconds.

Endpoint Overview

Analytics

MethodPathDescription
POST/nltx/summary/{projectId}Summary statistics for a project
POST/nltx/summary/{projectId}/robot/{robotId}Summary statistics for a specific robot
POST/nltx/positions/{projectId}/robot/{robotId}Robot position data
POST/nltx/analyzes/{projectId}/latestsLatest analysis results for a project (max 10)
GET/nltx/anomalies/{projectId}/anomaly/{anomalyId}Details of a specific anomaly
GET/nltx/deliveries/averageAverage delivery times across all projects
GET/nltx/data/{projectId}/most-delivered-locationsMost delivered-to locations (last 3 months)

Tablet Configuration

MethodPathDescription
GET/projects/{projectId}/tablet-config/activatedActive tablet configuration for a project

Note: In analytics endpoints (summary, analyzes, anomaly, etc.), project_id in the response is a string (e.g. "123"). In the tablet config endpoint, project_id is a number (e.g. 7). The {projectId} path parameter is always numeric. Use String(project_id) when comparing.

Project summary statistics

POST /nltx/summary/{projectId}

Returns summary statistics for a project.

Request body

{
  "interval": "week"
}

interval values (required):

  • week — last 1 week (-1w)
  • month — last 1 month (-1m)

Response

{
  "last_km": 1250.5,
  "last_wh": 340.2,
  "last_iah": 280.1,
  "data_km": [
    { "date": "2026-06-10T00:00:00Z", "value": 12.3 },
    { "date": "2026-06-11T00:00:00Z", "value": 15.7 }
  ],
  "data_km_avg": 14.0,
  "data_wh": [
    { "date": "2026-06-10T00:00:00Z", "value": 5.2 },
    { "date": "2026-06-11T00:00:00Z", "value": 6.1 }
  ],
  "data_wh_avg": 5.65,
  "data_iah": [
    { "date": "2026-06-10T00:00:00Z", "value": 4.1 },
    { "date": "2026-06-11T00:00:00Z", "value": 4.8 }
  ],
  "data_iah_avg": 4.45,
  "data_logs": [
    { "date": "2026-06-10T00:00:00Z", "code": "ROBOT_DELIVERY_TASK_SUCCESS", "value": 42 }
  ],
  "data_logs_avg": [
    { "code": "ROBOT_DELIVERY_TASK_SUCCESS", "value": 38 }
  ],
  "today": "2026-06-17T00:00:00Z",
  "interval": ["2026-06-10T00:00:00Z", "2026-06-11T00:00:00Z"],
  "most_delivered_locations": [
    { "key": "Table 5", "value": 120 }
  ]
}

Robot summary statistics

POST /nltx/summary/{projectId}/robot/{robotId}

Returns summary statistics for a specific robot.

Request body

{
  "interval": "week"
}

interval values (required):

  • week — last 1 week (-1w)
  • month — last 1 month (-1m)

Response

Returns summary statistics in the same structure as the summary endpoint.

Robot position data

POST /nltx/positions/{projectId}/robot/{robotId}

Returns robot position data.

Request body

{
  "interval": "week",
  "code": "ROBOT_FAILURE",
  "map": "map_name"
}

All of interval, code, and map are required.

interval values:

  • week — last 1 week (-1w)
  • month — last 1 month (-1m)

code values: ROBOT_FAILURE, ROBOT_NAV_STUCK, ROBOT_LOC_LOST, ROBOT_INTERNET_CONN_FAILED, etc.

Response

[
  { "x": 12.34, "y": 56.78, "yaw": 1.57 }
]

Latest analysis results

POST /nltx/analyzes/{projectId}/latests

Returns the latest analysis results for a project (max 10).

No request body is required. Only the projectId path parameter is sufficient.
POST requests respond with a 201 status code (NestJS default).

The anomaly_id value is obtained from this endpoint. If present, call GET /nltx/anomalies/{projectId}/anomaly/{anomalyId} for anomaly details.

Response

Returns an empty array if no analyses exist:

[]

Returns up to 10 records if analyses exist:

[
  {
    "id": "analysis-id-001",
    "project_id": "123",
    "robot_id": "robot-001",
    "calculator": "weekly",
    "score": {
      "value": 85,
      "based_on": 100
    },
    "metrics": [
      {
        "id": "metric-id-001",
        "key": "ODOM_KM",
        "point": 10,
        "weight": 1
      }
    ],
    "suggestions": [
      {
        "id": "suggestion-id-001",
        "key": "SUGGESTION_INCREASE_DISTANCE_TRAVELED",
        "code": "SUGGESTION_INCREASE_DISTANCE_TRAVELED",
        "severity": "medium"
      }
    ],
    "created_at": "2026-01-15T10:00:00Z",
    "start_date": "2026-01-08T00:00:00Z",
    "end_date": "2026-01-15T00:00:00Z",
    "anomaly_id": "anomaly-id-001",
    "previous_scores": [
      {
        "value": 80,
        "based_on": 100
      }
    ]
  }
]
FieldTypeDescription
idstringAnalysis record ID
project_idstringProject ID
robot_idstringRobot ID. Optional; may be absent for project-level analyses
anomaly_idstringAnomaly ID. If empty, no anomaly exists
scoreobjectAnalysis score
metricsarrayList of metrics
suggestionsarrayList of suggestions

Anomaly details

GET /nltx/anomalies/{projectId}/anomaly/{anomalyId}

Returns details of a specific anomaly.

The anomaly_id value is obtained from the analyzes/latests response.
If projectId and anomalyId do not match, 404 is returned.

Response

{
  "id": "anomaly-id-001",
  "project_id": "123",
  "robot_id": "robot-001",
  "detector": "threshold",
  "anomalies": [
    {
      "detector": "threshold",
      "key": "ODOM_KM",
      "code": "ANOMALY_ODOM_KM_IS_HIGHER_THAN_EXPECTED",
      "type": "too_high",
      "level": 2,
      "percentage": 35.5
    }
  ],
  "created_at": "2026-01-15T10:00:00Z"
}

Average delivery times

GET /nltx/deliveries/average

Returns average delivery times across all projects.

This endpoint does not take a projectId in the URL. It returns the average delivery times for all projects in the system (not filtered by the API key's assigned projects).

Response type: Record<string, string> — project ID → duration string.

Response

{
  "42": "8m45s",
  "56": "12m30s"
}

Most delivered locations

GET /nltx/data/{projectId}/most-delivered-locations

Returns the most delivered-to locations (last 3 months).

Returns data for the last 3 months (backend fixed -3m). Returns 403 for unauthorized projectId.

Response

[
  { "key": "Table 5", "value": 120 },
  { "key": "Lobby", "value": 85 }
]

Active tablet configuration

GET /projects/{projectId}/tablet-config/activated

Returns the active tablet configuration for a project.

If no active configuration exists, returns 404 with message: Active tablet config not found.

Response

{
  "id": 96,
  "project_id": 7,
  "name": "Configuration Name",
  "activated": true,
  "deleted": false,
  "checksum": "2a308a87",
  "created_at": "2023-03-29T20:29:57.539Z",
  "updated_at": "2026-04-29T06:27:25.566Z",
  "config": {
    "videos": {
      "home": {
        "enabled": true,
        "src": [
          "https://assets.saharobotik.com/video/.../video1.mp4",
          "https://assets.saharobotik.com/video/.../video2.mp4"
        ],
        "loop": true,
        "muted": true
      },
      "going": {
        "enabled": false
      },
      "sleeping": {
        "enabled": false
      },
      "pixelGoing": {
        "enabled": false
      },
      "pixelSleeping": {
        "enabled": false
      },
      "celebrating": {
        "enabled": false
      },
      "celebratingAtTheTarget": {
        "enabled": false
      }
    }
  }
}

Video Fields

FieldTypeDescription
config.videos.home.srcstring | string[]Default video URLs on the pixel screen (single URL or array)
config.videos.home.enabledbooleanOptional. If false, video is disabled; if absent or true, video is enabled

The videos field is optional; if no videos have been configured for the project, it will not be present inside config.

Error Codes

CodeDescription
400Invalid request / NLTX service error
401Invalid or missing API key
403You do not have access to this project
404Record not found
429Rate limit exceeded, wait 60 seconds
500Server error