Get your first IoT device sending data to Datum in under 10 minutes.
- Docker and Docker Compose installed
- A device (ESP32, Raspberry Pi, or any HTTP-capable device)
- Basic understanding of REST APIs
# Clone the repository
git clone https://github.com/yourusername/datum-server.git
cd datum-server
# Start with Docker Compose
docker-compose up -dThe server starts at http://localhost:8000.
On first run, you'll need to create an admin user:
curl -X POST http://localhost:8000/sys/setup \
-H "Content-Type: application/json" \
-d '{
"admin_email": "admin@example.com",
"admin_password": "your-secure-password"
}'Response:
{
"message": "System initialized successfully",
"admin_id": "usr_abc123"
}curl -X POST http://localhost:8000/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "admin@example.com",
"password": "your-secure-password"
}'Response:
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user_id": "usr_abc123"
}Save this token - you'll need it for authenticated requests.
export TOKEN="eyJhbGciOiJIUzI1NiIs..."
curl -X POST http://localhost:8000/dev \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "My First Sensor",
"description": "Temperature sensor in the living room"
}'Response:
{
"device_id": "dev_xyz789",
"name": "My First Sensor",
"api_key": "dk_a1b2c3d4e5f6...",
"created_at": "2024-01-15T10:30:00Z"
}Important: Save the api_key - you'll use it on your device.
export API_KEY="dk_a1b2c3d4e5f6..."
export DEVICE_ID="dev_xyz789"
curl -X POST "http://localhost:8000/dev/$DEVICE_ID/data" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"temperature": 22.5,
"humidity": 45,
"battery": 3.7
}'Response:
{
"status": "ok",
"timestamp": "2024-01-15T10:35:00Z",
"commands_pending": 0
}#include <WiFi.h>
#include <HTTPClient.h>
const char* WIFI_SSID = "YourWiFi";
const char* WIFI_PASS = "YourPassword";
const char* API_KEY = "dk_a1b2c3d4e5f6...";
const char* DEVICE_ID = "dev_xyz789";
const char* SERVER = "http://your-server:8000";
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println("WiFi connected");
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = String(SERVER) + "/dev/" + DEVICE_ID + "/data";
http.begin(url);
http.addHeader("Authorization", String("Bearer ") + API_KEY);
http.addHeader("Content-Type", "application/json");
String payload = "{\"temperature\": 22.5, \"humidity\": 45}";
int code = http.POST(payload);
if (code > 0) {
Serial.printf("Response: %d\n", code);
}
http.end();
}
delay(60000); // Send every minute
}import urequests # MicroPython
# import requests as urequests # Standard Python
API_KEY = "dk_a1b2c3d4e5f6..."
DEVICE_ID = "dev_xyz789"
SERVER = "http://your-server:8000"
def send_data(temperature, humidity):
response = urequests.post(
f"{SERVER}/dev/{DEVICE_ID}/data",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"temperature": temperature,
"humidity": humidity
}
)
return response.status_code == 200curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:8000/dev/$DEVICE_ID/data"Response:
{
"device_id": "dev_xyz789",
"timestamp": "2024-01-15T10:35:00Z",
"payload": {
"temperature": 22.5,
"humidity": 45,
"battery": 3.7
}
}# Last 24 hours, hourly intervals
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:8000/dev/$DEVICE_ID/data/history?period=24h&interval=1h"Response:
{
"device_id": "dev_xyz789",
"start": "2024-01-14T10:35:00Z",
"end": "2024-01-15T10:35:00Z",
"interval": "1h",
"data": [
{
"timestamp": "2024-01-14T11:00:00Z",
"payload": {"temperature": 21.8, "humidity": 48}
},
{
"timestamp": "2024-01-14T12:00:00Z",
"payload": {"temperature": 22.1, "humidity": 46}
}
]
}curl -X POST "http://localhost:8000/dev/$DEVICE_ID/cmd" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action": "set_interval",
"payload": {"seconds": 30}
}'# Device polls for commands
curl -H "Authorization: Bearer $API_KEY" \
"http://localhost:8000/dev/$DEVICE_ID/cmd/pending"export CMD_ID="cmd_abc123"
curl -X POST "http://localhost:8000/dev/$DEVICE_ID/cmd/$CMD_ID/ack" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "success"}'Open your browser and navigate to:
http://localhost:8050
Login with your admin credentials to see:
- Device overview
- Real-time data visualization
- Command management
- System configuration
- 📖 API Reference - Complete endpoint documentation
- 🔧 Use Cases - Real-world application examples
- 🚀 Deployment Guide - Production deployment
- 🔒 Security Guide - Security best practices
- Check firewall allows port 8000
- Verify API key is correct
- Ensure device ID matches
- Check server logs:
docker-compose logs backend
- Verify data was sent (check HTTP response code)
- Check device ownership (user must own device)
- Verify token hasn't expired
- Use
/dataendpoint (device-initiated) - Reduce payload size
- Check network connection
- Consider using SSE for real-time needs
graph LR
DEVICE[IoT Device] -->|POST /data| API[Datum API]
API -->|Store| DB[(Storage)]
USER[User/Dashboard] -->|GET /data| API
API -->|Query| DB
USER -->|POST /cmd| API
DEVICE -->|GET /cmd| API
Your IoT platform is now ready! Start collecting data from your devices.