Skip to content
AquaTracker logoAquaTracker

Automatic Data Ingestion (Sensor Webhook)

Sensors can submit measurements directly to AquaTracker over HTTPS, without manual entry. Each aquarium has its own ingest tokens, created in Aquarium → Settings → Automatic data ingestion.

Endpoint

POST /api/ingest
Authorization: Bearer awt_<your-token>
Content-Type: application/json

The token identifies the aquarium — no aquarium ID is needed in the payload. The plaintext token is shown once at creation; only its SHA-256 hash is stored. Tokens can be revoked at any time in aquarium settings.

Payload formats

Flat map (simplest)

{
  "ph": 7.2,
  "temperature": 25.4,
  "measuredAt": "2026-07-17T08:00:00Z",
  "notes": "optional note applied to all values"
}

Every key except measuredAt and notes is treated as a parameter name. measuredAt is optional (defaults to server time) and applies to all values in the payload.

Batch

{
  "measurements": [
    { "parameter": "ph", "value": 7.2, "measuredAt": "2026-07-17T08:00:00Z" },
    { "parameter": "temperature", "value": 25.4 },
    { "parameter": "nitrate", "value": 10, "notes": "after water change" }
  ]
}

Max 100 items per request.

Parameter names

Use the parameterName values, e.g.: temperature, ph, ammonia, nitrite, nitrate, gh, kh, co2, phosphate_freshwater, calcium, alkalinity, salinity, … (see the full list in aquarium settings / parameter definitions). Parameters not applicable to the aquarium's type (freshwater/saltwater) are rejected per item.

Response

{ "created": 2, "skipped": 0, "errors": [] }
  • created — measurements stored. Threshold alerts (and critical alert emails) fire automatically, exactly as with manual entry.
  • skipped — duplicates: an item with the same parameter and measuredAt already exists (safe to resend the same payload).
  • errors — per-item problems (unknown parameter, not applicable to this aquarium type, measuredAt more than 5 minutes in the future, …). One bad item never fails the whole batch.
StatusMeaning
201Processed (check created/skipped/errors)
400Invalid JSON, invalid payload, or no valid items
401Missing, invalid, or revoked token
429Rate limited (shared API limit: 100 req / 10 s per IP)

Examples

curl

curl -X POST "https://your-domain.com/api/ingest" \
  -H "Authorization: Bearer awt_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{"ph": 7.2, "temperature": 25.4}'

ESPHome (ESP32)

Sends pH and temperature on every sensor update:

# Requires ESPHome 2023.12+ for the http_request component.
http_request:
  id: aquatracker_ingest
  # verify_ssl: false  # only if you must skip certificate verification

sensor:
  - platform: ezo
    id: ph_ezo
    address: 99
    name: "pH"
    unit_of_measurement: "pH"
    update_interval: 60s
    on_value:
      then:
        - http_request.post:
            url: https://your-domain.com/api/ingest
            headers:
              Authorization: !secret aquatracker_token  # "Bearer awt_..."
              Content-Type: application/json
            json:
              ph: !lambda 'return x;'

  - platform: dallas_temp  # DS18B20
    name: "Temperature"
    update_interval: 60s
    on_value:
      then:
        - http_request.post:
            url: https://your-domain.com/api/ingest
            headers:
              Authorization: !secret aquatracker_token
              Content-Type: application/json
            json:
              temperature: !lambda 'return x;'

For fewer requests, buffer values and send one batch on a script/interval trigger instead.

Home Assistant

# configuration.yaml
rest_command:
  aquatracker_ingest:
    url: "https://your-domain.com/api/ingest"
    method: POST
    headers:
      Authorization: "Bearer awt_your_token_here"
      Content-Type: "application/json"
    payload: '{"temperature": {{ states("sensor.aquarium_temperature") }} }'
    content_type: "application/json"

automation:
  - alias: "Push aquarium temperature to AquaTracker"
    triggers:
      - trigger: state
        entity_id: sensor.aquarium_temperature
    actions:
      - action: rest_command.aquatracker_ingest

For multiple parameters in one call, use the batch payload format.