Skip to main content

Ingest Data

Send a single time-series data point to a bucket.

Endpoint

POST /api/data

Authentication

Key TypeAllowed
Admin (dakkio_a_)✅ Yes
Write (dakkio_w_)✅ Yes
Read (dakkio_r_)❌ No

Recommended: Use a Write key (dakkio_w_) for data ingestion. Write keys are scoped to a specific bucket and have only the permissions needed for sending data.

Why use a Write key?
  • Security: Write keys can only access one bucket, limiting exposure if compromised
  • Principle of least privilege: Only grant the permissions needed
  • Device-specific keys: Create a unique Write key for each device/sensor

Request

Headers

HeaderTypeRequiredDescription
X-API-Keystring✅ YesYour Write or Admin API key
Content-Typestring✅ YesMust be application/json

Body Parameters

ParameterTypeRequiredDescription
bucketIdstring✅ YesThe bucket ID (24-character hex string)
dataSourceIdstring✅ YesThe data source ID (24-character hex string)
timestampstring❌ NoISO 8601 timestamp (default: current time)
valuesobject✅ YesKey-value pairs of measurements
metadataobject❌ NoAdditional context about the data point

Example Request

curl -X POST https://api.dakkio.io/api/data \
-H "X-API-Key: dakkio_w_abc123def456..." \
-H "Content-Type: application/json" \
-d '{
"bucketId": "507f1f77bcf86cd799439011",
"dataSourceId": "507f1f77bcf86cd799439012",
"timestamp": "2024-01-15T10:30:00Z",
"values": {
"temperature": 22.5,
"humidity": 65,
"pressure": 1013.25
},
"metadata": {
"deviceId": "ESP32-001",
"location": "Living Room",
"batteryLevel": 85
}
}'

Response

Success Response (201 Created)

{
"message": "Data point ingested successfully",
"dataPoint": {
"_id": "507f1f77bcf86cd799439016",
"bucketId": "507f1f77bcf86cd799439011",
"dataSourceId": "507f1f77bcf86cd799439012",
"timestamp": "2024-01-15T10:30:00Z",
"values": {
"temperature": 22.5,
"humidity": 65,
"pressure": 1013.25
},
"metadata": {
"deviceId": "ESP32-001",
"location": "Living Room",
"batteryLevel": 85
},
"createdAt": "2024-01-15T10:30:05Z"
}
}

Error Responses

400 Bad Request - Validation Error

{
"error": "Validation Error",
"message": "Invalid request parameters",
"details": [
{
"path": ["body", "bucketId"],
"message": "Expected string, received undefined"
}
]
}

401 Unauthorized - Invalid API Key

{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}

403 Forbidden - Insufficient Permissions

{
"error": "Forbidden",
"message": "Read keys cannot ingest data. Use a Write or Admin key."
}

404 Not Found - Bucket Not Found

{
"error": "Not Found",
"message": "Bucket not found"
}

Code Examples

JavaScript/Node.js

const axios = require('axios');

async function ingestData() {
const response = await axios.post(
'https://api.dakkio.io/api/data',
{
bucketId: '507f1f77bcf86cd799439011',
dataSourceId: '507f1f77bcf86cd799439012',
timestamp: new Date().toISOString(),
values: {
temperature: 22.5,
humidity: 65
},
metadata: {
deviceId: 'ESP32-001'
}
},
{
headers: {
'X-API-Key': process.env.DAKKIO_WRITE_KEY,
'Content-Type': 'application/json'
}
}
);

console.log('Success:', response.data);
}

Python

import requests
import os
from datetime import datetime

def ingest_data():
response = requests.post(
'https://api.dakkio.io/api/data',
headers={
'X-API-Key': os.environ['DAKKIO_WRITE_KEY'],
'Content-Type': 'application/json'
},
json={
'bucketId': '507f1f77bcf86cd799439011',
'dataSourceId': '507f1f77bcf86cd799439012',
'timestamp': datetime.utcnow().isoformat() + 'Z',
'values': {
'temperature': 22.5,
'humidity': 65
},
'metadata': {
'deviceId': 'ESP32-001'
}
}
)

if response.status_code == 201:
print('Success:', response.json())
else:
print('Error:', response.json())

Go

package main

import (
"bytes"
"encoding/json"
"net/http"
"os"
"time"
)

func ingestData() error {
data := map[string]interface{}{
"bucketId": "507f1f77bcf86cd799439011",
"dataSourceId": "507f1f77bcf86cd799439012",
"timestamp": time.Now().UTC().Format(time.RFC3339),
"values": map[string]interface{}{
"temperature": 22.5,
"humidity": 65,
},
"metadata": map[string]interface{}{
"deviceId": "ESP32-001",
},
}

jsonData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api.dakkio.io/api/data", bytes.NewBuffer(jsonData))
req.Header.Set("X-API-Key", os.Getenv("DAKKIO_WRITE_KEY"))
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()

return nil
}

Best Practices

1. Use Batch Ingestion for Multiple Points

If you have multiple data points, use the batch endpoint for better efficiency.

2. Always Use UTC Timestamps

// ✅ Correct
timestamp: new Date().toISOString() // "2024-01-15T10:30:00.123Z"

// ❌ Wrong
timestamp: Date.now() // Unix milliseconds - not accepted
timestamp: "15/01/2024" // Wrong format - not accepted

3. Include Device Metadata

Adding metadata helps with debugging and monitoring:

{
"values": { "temperature": 22.5 },
"metadata": {
"deviceId": "ESP32-001",
"firmwareVersion": "1.2.3",
"batteryLevel": 85
}
}

4. Create Separate Write Keys Per Device

Instead of sharing one Write key across all devices:

  • Create a unique Write key for each device
  • Name keys descriptively (e.g., "Living Room Sensor")
  • Revoke individual keys if a device is compromised