Skip to content

Telemetry API

The Botbit Telemetry API allows your robot fleet’s primary controllers to push operational metrics directly to Botbit. Each telemetry report updates the robot’s cumulative counters and automatically evaluates usage-based maintenance rules — generating tasks when robots approach service thresholds.

What the API accepts:

  • Operating hours (lifetime cumulative)
  • Miles driven (lifetime cumulative)
  • Battery charge cycles (lifetime cumulative)
  • Software versions (firmware, OS, app)

What happens when data arrives:

  1. Telemetry is stored (one row per robot per day)
  2. Robot aggregate counters are updated
  3. Usage-based maintenance rules are evaluated
  4. Tasks are auto-created when a robot is within 10% of a service interval

Your robot’s primary controller sends data to Botbit. Botbit does not poll your robots.

┌──────────────────────┐ ┌─────────────────────────┐
│ Primary Controller │ │ Botbit OpsCenter │
│ (on the robot) │────────▶│ POST /api/telemetry/ │
│ │ HTTPS │ ingest │
└──────────────────────┘ └─────────────────────────┘
├─ Store telemetry
├─ Update robot counters
└─ Evaluate maintenance rules
└─ Create tasks if within 10%

Why push?

  • Lower latency: Maintenance rules evaluate the moment new data arrives, not on a polling schedule
  • Simpler networking: Robots need outbound HTTPS only — no inbound ports to open
  • Idempotent: Sending the same report twice is harmless (upsert by robot + date)
  • Scales naturally: Each robot reports independently; no central poller to bottleneck

One API key covers your entire organization

Section titled “One API key covers your entire organization”

An API key is scoped to your organization, not to an individual robot. Any robot in the org can be identified by its serial_number in the request body.

You can create multiple keys for different purposes (one per factory, one per site, etc.), but each key works for all robots in the org.

The API accepts robot-level cumulative totals — the values that the primary controller tracks for the whole robot:

MetricFieldExample
Operating hoursoperating_hours1250.5
Miles drivenmiles_driven843.2
Battery charge cyclesbattery_charge_cycles312

It does not accept per-component health scores or status. Telemetry is about the robot as a whole, not individual components like a LIDAR or motor. Component health tracking is a separate planned feature.

All metrics are lifetime cumulative totals — “this robot has driven 843 miles total”, not “it drove 5 miles since last report.” This makes the endpoint idempotent: re-sending the same report doesn’t double-count anything.

  1. Go to Settings → API & Integrations in the Botbit dashboard
  2. Click Create API Key
  3. Enter a name (e.g., “Factory Floor Controller”)
  4. Copy the key immediately — it is shown once and cannot be retrieved later
  5. The key starts with bb_live_ followed by a random string

Only organization admins can create and revoke API keys.

Include the key in the Authorization header:

POST /api/telemetry/ingest
Authorization: Bearer bb_live_a1b2c3d4e5f6...
Content-Type: application/json
  • Only the SHA-256 hash is stored — Botbit cannot recover your key
  • Keys can be revoked instantly in Settings (the key stops working immediately)
  • If a key is compromised, revoke it and create a new one
  • Keys have no expiration by default

Send telemetry data for a single robot.

{
"serial_number": "BOT-2025-00001",
"timestamp": "2026-01-29T14:30:00Z",
"operating_hours": 1250.5,
"miles_driven": 843.2,
"battery_charge_cycles": 312,
"firmware_version": "3.2.1",
"os_version": "1.0.4",
"app_version": "2.1.0"
}
FieldTypeDescription
serial_numberstringThe robot’s serial number or display ID (e.g., ROB-2024-00142 or BOT-2026-00028)
timestampstringISO 8601 datetime of the telemetry reading

Plus at least one of:

FieldTypeDescription
operating_hoursnumberLifetime cumulative operating hours
miles_drivennumberLifetime cumulative miles driven
battery_charge_cyclesnumberLifetime cumulative charge cycles
FieldTypeDescription
firmware_versionstringCurrent firmware version
os_versionstringCurrent OS version
app_versionstringCurrent application version
{
"success": true,
"robot_id": "uuid-of-the-robot",
"telemetry_date": "2026-01-29",
"tasks_generated": 1
}

tasks_generated indicates how many maintenance tasks were automatically created based on the new telemetry data.

StatusBodyMeaning
400{"error": "serial_number is required"}Missing or invalid request body
400{"error": "At least one metric ... is required"}No metrics provided
400{"error": "timestamp must be a valid ISO 8601 date"}Unparseable timestamp
401{"error": "API key invalid"}Missing, malformed, or revoked key
401{"error": "API key expired"}Key has passed its expiration date
404{"error": "Robot '...' not found in this organization"}Serial number / display ID doesn’t match any robot in this org
429{"error": "Rate limit exceeded"}Too many requests (see Rate Limiting)
500{"error": "Internal server error"}Server-side failure
HeaderDescription
X-RateLimit-RemainingRequests remaining in the current window
Retry-AfterSeconds to wait (only on 429 responses)

Each API key is limited to 60 requests per minute. This is a sliding window — the counter resets 60 seconds after the first request in a window.

If you exceed the limit, you’ll receive a 429 response with a Retry-After header indicating how many seconds to wait.

For most deployments, sending telemetry once per hour or once per day per robot is sufficient.

When telemetry arrives, Botbit evaluates all usage-based maintenance rules for that robot’s build configuration. Here’s the logic:

A maintenance task is created when a robot is within 10% of the next service interval.

Example: A rule says “service every 100 miles.”

Robot’s Current MilesNext ThresholdRemaining10% of IntervalTask Created?
501005010No (50 > 10)
851001510No (15 > 10)
91100910Yes (9 ≤ 10)
1432005710No (57 > 10)
192200810Yes (8 ≤ 10)

Botbit will not create duplicate tasks for the same threshold. If a task already exists for robot + rule + threshold value (regardless of task status — To Do, Done, Skip, etc.), it is skipped.

This means:

  • Sending telemetry multiple times at 91 miles → only one task for the 100-mile threshold
  • Completing the task at 98 miles, then sending telemetry at 99 miles → no new task (the 100-mile threshold is already covered)
  • After crossing 100 miles, the next threshold becomes 200 miles

Auto-generated tasks include:

  • Title: The maintenance action name from the rule
  • Due date: 7 days from when the threshold was crossed
  • Priority: Inherited from the maintenance rule
  • Criteria: Human-readable explanation, e.g., “Within 10% of 100 miles threshold (91/100)“
  1. A robot activated in Botbit with a known serial number
  2. A maintenance rule with interval_miles or interval_hours on that robot’s build configuration
  3. An API key (created in Settings → API & Integrations)
Terminal window
curl -X POST https://your-app.com/api/telemetry/ingest \
-H "Authorization: Bearer bb_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"serial_number": "BOT-2025-00001",
"timestamp": "2026-01-29T14:30:00Z",
"operating_hours": 1250.5,
"miles_driven": 843.2,
"battery_charge_cycles": 312
}'

For local development, replace https://your-app.com with http://localhost:9002.

A successful response looks like:

{
"success": true,
"robot_id": "abc-123-def",
"telemetry_date": "2026-01-29",
"tasks_generated": 0
}

tasks_generated: 0 means no thresholds were crossed. To trigger a task, set miles_driven or operating_hours to within 10% of a rule’s interval.

  • Assets page: The robot’s miles/hours should reflect the new values
  • Maintenance page: If a task was generated, it appears in the “To Do” column
Terminal window
# Missing API key → 401
curl -X POST https://your-app.com/api/telemetry/ingest \
-H "Content-Type: application/json" \
-d '{"serial_number": "BOT-2025-00001", "timestamp": "2026-01-29T14:30:00Z", "miles_driven": 100}'
# Wrong serial number → 404
curl -X POST https://your-app.com/api/telemetry/ingest \
-H "Authorization: Bearer bb_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"serial_number": "NONEXISTENT", "timestamp": "2026-01-29T14:30:00Z", "miles_driven": 100}'
# No metrics → 400
curl -X POST https://your-app.com/api/telemetry/ingest \
-H "Authorization: Bearer bb_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"serial_number": "BOT-2025-00001", "timestamp": "2026-01-29T14:30:00Z"}'

If you have a rule “service every 100 miles”:

Terminal window
# Robot at 91 miles → should generate a task (within 10%)
curl -X POST http://localhost:9002/api/telemetry/ingest \
-H "Authorization: Bearer bb_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"serial_number": "BOT-2025-00001",
"timestamp": "2026-01-29T15:00:00Z",
"miles_driven": 91
}'
# Expected: tasks_generated: 1
# Send again at 92 miles → should NOT create duplicate
curl -X POST http://localhost:9002/api/telemetry/ingest \
-H "Authorization: Bearer bb_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"serial_number": "BOT-2025-00001",
"timestamp": "2026-01-29T16:00:00Z",
"miles_driven": 92
}'
# Expected: tasks_generated: 0

The most common pattern. Each robot’s primary controller sends its own telemetry on a schedule (e.g., every hour):

Robot A ──POST──▶ /api/telemetry/ingest (serial_number: "BOT-001")
Robot B ──POST──▶ /api/telemetry/ingest (serial_number: "BOT-002")
Robot C ──POST──▶ /api/telemetry/ingest (serial_number: "BOT-003")

All three use the same API key.

A central service collects telemetry from all robots and forwards it to Botbit:

Robot A ──▶ ┌──────────┐
Robot B ──▶ │ Gateway │──POST──▶ /api/telemetry/ingest (one call per robot)
Robot C ──▶ └──────────┘

The gateway makes one API call per robot. There is no batch endpoint — each robot is a separate POST.

Use CaseFrequencyRate Limit Impact
Standard fleetEvery 1 hour~0.02 req/min per robot
High-utilizationEvery 15 minutes~0.07 req/min per robot
Daily summaryOnce per dayNegligible

With the 60 req/min limit, a single API key can support hundreds of robots reporting hourly.

Can I send telemetry for a robot that doesn’t exist yet? No. The robot must be activated in Botbit first. The serial_number field accepts either the robot’s hardware serial number (e.g., ROB-2024-00142) or its Botbit display ID (e.g., BOT-2026-00028). You’ll get a 404 error if neither matches.

What happens if I send the same data twice? Nothing bad. Telemetry is upserted by robot + date, so duplicate reports overwrite the previous values. Maintenance rules re-evaluate but won’t create duplicate tasks.

Do maintenance counters reset when a task is completed? No. Counters are lifetime cumulative. The algorithm uses floor(current / interval) to determine which cycle the robot is in. After completing a task at 98 miles (interval = 100), the next threshold is automatically 200 miles.

Can I send data about individual components? Not currently. The API accepts robot-level metrics only. Per-component telemetry (health scores, individual sensor data) is a planned future feature.

Can I use this API to pull data from Botbit? No. This is an ingest-only endpoint. There is no read API for telemetry data at this time.

What if my robot skips past a threshold? The algorithm handles this. If a robot jumps from 80 miles to 150 miles in one report, it calculates the correct cycle and targets the next threshold (200 miles). The skipped threshold (100) does not generate a retroactive task.