Roboda Cloud API
Telemetry ingest and live AGV dashboard documentation
Use Roboda Cloud to accept authenticated robot telemetry, validate subscription access, update device online state, and plot AGVs on the dashboard and maps.
https://ingest.roboda.tech/v1/state
https://api.roboda.tech/v1/state
Both endpoints route to the same strict Roboda Cloud ingest handler.
What the API does
The State API stores the latest JSON state for one registered robot device, updates the last-seen time, marks the device online, and feeds the subscribed user dashboard.
- Accepts telemetry only from a valid device API key or token.
- Checks that the owner has an active Roboda Cloud subscription or trial.
- Checks token expiry and plan device limit before saving telemetry.
- Supports indoor x/y AGV plotting and outdoor latitude/longitude maps.
Device model
Each registered AGV or robot should have its own device token. A plan with a 25 device limit should use up to 25 registered devices, each sending telemetry with its own token.
Request flow
Security
Authentication headers
Send one valid Roboda device token in a request header. Keep tokens out of browser code, public repositories, screenshots, and query strings.
| Header | Example | Use |
|---|---|---|
x-api-key | YOUR_DEVICE_TOKEN | Recommended for telemetry clients. |
x-roboda-api-key | YOUR_DEVICE_TOKEN | Roboda-specific API key header. |
x-roboda-token | YOUR_DEVICE_TOKEN | Compatible with the original State API. |
Authorization | Bearer YOUR_DEVICE_TOKEN | Standard bearer-token style. |
Quick start
Send a first telemetry packet
Replace the token with a real device token from the Roboda Cloud dashboard. This example sends indoor position, battery, speed, current, temperature, and heading.
curl -X POST https://ingest.roboda.tech/v1/state \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_DEVICE_TOKEN" \
-d '{
"device": "agv-01",
"timestamp": "2026-05-17T12:00:00+05:30",
"state": {
"mode": "auto",
"x": 42,
"y": 68,
"battery_v": 7.4,
"battery_percent": 72,
"speed_mps": 0.45,
"current_a": 1.2,
"temperature_c": 34,
"heading_deg": 90,
"distance_cm": 38
}
}'
Successful response
{
"ok": true,
"saved_at": "2026-05-17 12:00:01",
"device_id": 31540,
"device": "agv-01",
"workspace_id": "rb-ws-...",
"plan_device_limit": 25,
"expires": "2027-05-16 17:39:00"
}
Dashboard result
- Device status changes to online.
- Battery gauge and numeric chart update.
- Indoor map moves the AGV to x/y position.
- Latest JSON viewer stores the payload for inspection.
Reference
Endpoint reference
Use ingest.roboda.tech for robot telemetry. api.roboda.tech is an equivalent alias for integrations.
| Method | URL | Purpose | Auth |
|---|---|---|---|
GET | https://ingest.roboda.tech/health | Public service health check. | No |
POST | https://ingest.roboda.tech/v1/state | Store latest robot state and update online status. | Yes |
POST | https://ingest.roboda.tech/v1/ingest | Alias for strict telemetry ingest. | Yes |
POST | https://ingest.roboda.tech/v1/devices/state | Alias for device state ingest. | Yes |
POST | https://www.roboda.tech/wp-json/roboda-cloud/v1/state | WordPress REST fallback for state ingest. | Yes |
Payload
Recommended telemetry fields
The API stores JSON flexibly, but the dashboard reads common field names for charts, dials, and maps. Put robot readings inside state where possible.
Identity
device, device_id, timestamp, state.mode, state.signal
Indoor map
state.x, state.y, state.indoor_x, state.indoor_y. Use a 0-100 coordinate scale for the floor map.
Outdoor map
state.lat, state.lng, state.latitude, state.longitude for OpenStreetMap/Leaflet position plotting.
Power
state.battery_v, state.battery_percent, state.current_a, state.voltage.
Motion
state.speed_mps, state.speed, state.motor_pwm, state.heading_deg, state.rpm.
Sensors
state.distance_cm, state.temperature_c, state.obstacle, state.line_left, state.line_right.
{
"source": "robot-firmware",
"device": "agv-07",
"timestamp": "2026-05-17T12:00:00+05:30",
"state": {
"mode": "warehouse-run",
"signal": "online",
"x": 61,
"y": 44,
"lat": 13.0827,
"lng": 80.2707,
"battery_v": 7.6,
"battery_percent": 78,
"speed_mps": 0.52,
"motor_pwm": 164,
"current_a": 1.35,
"temperature_c": 36.2,
"heading_deg": 135,
"distance_cm": 42
}
}
Live maps
Plot AGVs on indoor and outdoor maps
The Roboda dashboard merges multiple devices into one fleet view and lets the user focus a selected device. Send x/y for indoor maps or lat/lng for outdoor GPS maps.
Coordinate rules
x: 0is the left edge,x: 100is the right edge.y: 0is the top edge,y: 100is the bottom edge.- AGVs without x/y still appear in the staging lane until live position arrives.
- Outdoor map requires real latitude and longitude values.
Code examples
Client examples
Use these as templates. Keep production tokens in environment variables or server-side configuration.
import os
import requests
from datetime import datetime, timezone
endpoint = "https://ingest.roboda.tech/v1/state"
token = os.environ["ROBODA_DEVICE_TOKEN"]
payload = {
"device": "agv-01",
"timestamp": datetime.now(timezone.utc).isoformat(),
"state": {
"x": 42,
"y": 68,
"battery_v": 7.4,
"speed_mps": 0.45,
"current_a": 1.2,
"temperature_c": 34
}
}
response = requests.post(
endpoint,
json=payload,
headers={"x-api-key": token},
timeout=10
)
response.raise_for_status()
print(response.json())
const endpoint = "https://ingest.roboda.tech/v1/state";
async function sendState(deviceToken, state) {
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": deviceToken
},
body: JSON.stringify({
device: "agv-01",
timestamp: new Date().toISOString(),
state
})
});
if (!response.ok) {
throw new Error(await response.text());
}
return response.json();
}
#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
const char* ssid = "YOUR_WIFI";
const char* pass = "YOUR_PASSWORD";
const char* token = "YOUR_DEVICE_TOKEN";
const char* endpoint = "https://ingest.roboda.tech/v1/state";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) delay(500);
}
void loop() {
WiFiClientSecure client;
client.setInsecure(); // For classroom tests. Use CA certificate in production.
HTTPClient http;
http.begin(client, endpoint);
http.addHeader("Content-Type", "application/json");
http.addHeader("x-api-key", token);
String body = "{\"device\":\"agv-01\",\"state\":{\"x\":42,\"y\":68,\"battery_v\":7.4,\"speed_mps\":0.45}}";
int code = http.POST(body);
Serial.printf("Roboda response: %d\n", code);
http.end();
delay(3000);
}
// Arduino Nano does not have native Wi-Fi or HTTPS.
// Send sensor readings over Serial to a PC, phone, ESP32, or Raspberry Pi gateway.
void setup() {
Serial.begin(9600);
}
void loop() {
int batteryRaw = analogRead(A0);
int x = 42;
int y = 68;
Serial.print("{\"device\":\"nano-agv-01\",\"state\":{");
Serial.print("\"x\":"); Serial.print(x);
Serial.print(",\"y\":"); Serial.print(y);
Serial.print(",\"battery_raw\":"); Serial.print(batteryRaw);
Serial.println("}}");
delay(1000);
}
// Gateway responsibility:
// 1. Read each JSON line from Serial.
// 2. Add x-api-key header server-side.
// 3. POST it to https://ingest.roboda.tech/v1/state.
Errors
Common API responses
Handle these responses in the sender software so robots can retry safely or ask the user to refresh subscription/device settings.
| Status | Code | Meaning | Action |
|---|---|---|---|
401 | roboda_missing_token | No token was sent. | Add one accepted auth header. |
403 | roboda_invalid_token | Token does not match a registered device. | Regenerate or copy the correct device token. |
402 | roboda_subscription_required | Owner has no active trial/subscription. | Renew or activate Roboda Cloud. |
402 | roboda_subscription_expired | Access expiry has passed. | Renew subscription or license. |
403 | roboda_device_limit_exceeded | Device is outside the active plan limit. | Disable extra devices or upgrade plan. |
413 | roboda_payload_too_large | JSON payload is too large for the plan. | Send compact telemetry or reduce frequency/fields. |
Testing
AGV telemetry simulator
For lab testing, Roboda has a local simulator that can send random telemetry for up to 25 AGVs. It keeps real device tokens server-side and sends battery, location, speed, current, temperature, heading, and distance values.
Use it for
- Testing dashboard charts before hardware is ready.
- Checking plan device-limit behavior.
- Populating indoor maps with multiple AGVs.
- Verifying token expiry and invalid-token rejection.
Production rule
Only subscribed/trial users with valid device tokens can ingest telemetry. Invalid API keys, expired tokens, and devices beyond plan limit are discarded.
Use https://ingest.roboda.tech/v1/state for the simulator endpoint.
Operational guidance
Best practices
Do
- Use one token per robot device.
- Send compact JSON every 1-5 seconds for live maps.
- Include timestamp, battery, position, and signal/mode.
- Regenerate a token if it is exposed.
Do not
- Do not hard-code real tokens in public web pages.
- Do not share one token across many AGVs.
- Do not send huge camera images through the state endpoint.
- Do not rely on Arduino Nano alone for HTTPS; use a gateway.