Early adopter pricing — locked for life. Only 4 spots available. Claim yours now before spots run out →

Webhook Integration

DataKubo ingests device data via HTTP webhooks. Point your LoRaWAN network server (or any HTTP source) at our ingestion endpoint, and we handle normalization, storage, and indexing.

Endpoint

POST https://api.datakubo.com/api/v1/ingest/water-consumption

Headers

HeaderRequiredDescription
X-API-KeyYesYour organization's API key
Content-TypeYesapplication/json

Supported formats

DataKubo automatically detects and normalizes payloads from:

  • ChirpStack (v3 and v4)
  • The Things Network (TTN v3)
  • Custom HTTP (any JSON payload with the required fields)

ChirpStack payload

ChirpStack sends an up event when a device transmits data. DataKubo extracts the device EUI, tenant, and decoded payload automatically.

{
  "deviceInfo": {
    "tenantName": "your-tenant",
    "deviceName": "Water Meter #1",
    "devEui": "a1b2c3d4e5f60001"
  },
  "object": {
    "cumulativeFlowM3": 123.456,
    "battery": 3.6
  }
}
💡

Configure your ChirpStack application to send HTTP integration events to the DataKubo endpoint. The tenantName maps to your organization automatically.

TTN payload

The Things Network sends uplink messages with a decoded_payload field. DataKubo maps TTN fields to our normalized format.

{
  "end_device_ids": {
    "device_id": "water-meter-001",
    "dev_eui": "A1B2C3D4E5F60001"
  },
  "uplink_message": {
    "decoded_payload": {
      "cumulativeFlowM3": 123.456,
      "battery": 3.6
    },
    "rx_metadata": [{}],
    "settings": {
      "data_rate": {}
    }
  }
}

TTN field mapping

TTN FieldNormalized FieldNotes
cumulativeFlowM3consumption_m3Preferred — cubic meters
waterconsumption_m3B-Meters alternative
cumulativeFlowconsumption_m3Xinos — liters, auto-converted to m³
battery / bateriabattery_levelVoltage value
battery_statusbattery_level"OK" → 3.6V, "LOW" → 2.8V
application_idtenant_nameMaps to organization or community
ℹ️

TTN messages without a decoded_payload are acknowledged (HTTP 200) but skipped — no data is stored.

Custom HTTP payload

If you're not using ChirpStack or TTN, send a JSON payload with these fields:

{
  "dev_eui": "a1b2c3d4e5f60001",
  "consumption_m3": 123.456,
  "battery_level": 3.6,
  "timestamp": "2025-01-15T10:30:00Z"
}

Response codes

CodeMeaning
200Data ingested successfully
400Invalid payload format
401Invalid or missing API key
429Rate limit exceeded (100,000 req/month)
500Internal server error

Rate limits

Webhook ingestion is rate-limited to 100,000 requests per month per organization. This counter resets on the 1st of each month.

Rate limit headers are included in every response:

X-RateLimit-Limit: 100000
X-RateLimit-Remaining: 99847
X-RateLimit-Reset: 2025-02-01T00:00:00Z
⚠️

Dashboard API calls are not counted against your rate limit — only webhook ingestion requests count.

Next steps