InfluxDB line protocol
Tag Historian accepts InfluxDB line protocol on POST /api/v2/write — the endpoint every InfluxDB v2 client already knows. Point Home Assistant, Telegraf, or anything with an influxdb_v2 output at it and it writes without modification.
This is an ingest-compatible endpoint, not an InfluxDB. Read where this is not InfluxDB before assuming anything beyond “my writer works”.
Last updated
Why write here instead of running InfluxDB
One reason only: there is no server. No VM to patch, no disk to size, no retention policy to get wrong, no restore to rehearse. Hourly minimum, maximum, average and count for every series is kept 10 years on every plan, including the free one, and it costs nothing extra because it is a byproduct of how the data is stored.
If you are happy operating InfluxDB, keep operating InfluxDB. This endpoint is for people who want the writer they already have to point somewhere they do not have to run.
Get an API key
Create an account and an API key first. The free plan is €0 and takes an email address — no card — and gives you 5 tags and 50,000 readings a day. Then create the key on the Settings page in Tag Historian Explorer — and the scope you give it is not a detail.
The key is shown once. Copy it straight into your client’s token setting — if you lose it, generate a new one rather than hunting for the old one.
The request
POST /api/v2/write?org=anything&bucket=anything&precision=s
Authorization: Token <your-api-key>
Content-Type: text/plain
home.livingroom.temperature value=21.5 1765731600| Part | What Tag Historian does with it |
|---|---|
Authorization: Token <api-key> | Your normal Tag Historian API key. X-API-Key: <api-key> works too. |
org, bucket | Ignored. Accepted so clients that insist on them are happy; your API key alone decides where data lands. |
precision | ns, us, ms or s. Default ns, same as InfluxDB. |
| Body | Line protocol, one point per line. Content-Encoding: gzip is supported. |
Thirty seconds from a shell, if you want to watch one write succeed before committing:
curl -i -X POST \
"https://api.taghistorian.com/api/v2/write?precision=s" \
-H "Authorization: Token <your-api-key>" \
--data-binary "home.livingroom.temperature value=21.5 $(date +%s)"Responses
| Status | Meaning |
|---|---|
204 No Content | Everything was accepted. |
400 Bad Request | Unparsable body, empty body (Home Assistant's setup probe), invalid precision, or a derived tag name that cannot be stored. Parse errors carry line, 1-based, for the first bad line. |
402 Payment Required | Storage quota reached. Permanent until you upgrade or data ages out — there is no point retrying, which is also how Influx clients treat it. |
403 Forbidden | Email address not confirmed and the 7-day grace period has passed. The key is valid and reading still works; confirm the address and writing resumes immediately. |
413 Payload Too Large | More than 5 000 points in one request, or a body over 10 MB compressed or decompressed. Split the batch — Telegraf does this automatically. |
422 Unprocessable Entity | Some points were dropped because they would have created new tags beyond your tag quota. Points for tags that already exist were written. |
429 Too Many Requests | Daily readings quota reached. Retry-After says when to come back. |
503 Service Unavailable | Temporarily unavailable. Honour Retry-After and retry. |
How lines become tag names
Line protocol has measurements, tags and fields. Tag Historian has flat tag names. The mapping is deterministic, so the same series always lands in the same name and tag order on the wire never matters.
- Series name. If the point carries
domainandentity_idtags — which is what Home Assistant sends — the series is{domain}.{entity_id}. Any other tags are appended as.key-value, sorted by key, so two Home Assistant instances writing the same entity stay two distinct series. Otherwise the series is the measurement name, with every tag appended the same way:cpu,cpu=cpu0,host=srv01becomescpu.cpu-cpu0.host-srv01. - Sanitization. Names allow
[A-Za-z][A-Za-z0-9_.-]*, up to 200 characters. Anything else becomes_(Telegraf'sdisk,path=/becomesdisk.path-_), a name not starting with a letter is prefixed witht, and a name over 200 characters is truncated and suffixed with a short stable hash. Sanitized spellings can collide in contrived cases —a=banda-bsanitize alike — which is accepted; pick distinguishable tag values if you are near that edge. - Fields. A field called
valuewins: it becomes the reading and every sibling field on that line is ignored. Without one, every numeric field becomes its own tag named{series}.{field}. - Strings are never stored. Booleans become 1 and 0; string fields are skipped, and a line with only string fields stores nothing.
| Line | Stored as |
|---|---|
state,domain=sensor,entity_id=temp value=21.5 | sensor.temp = 21.5 |
cpu usage=0.93 | cpu.usage = 0.93 |
meter power=1500,voltage=230 | meter.power = 1500, meter.voltage = 230 |
meter value=7,power=1500 | meter = 7 — power ignored, value wins |
status text="ok" | nothing — string field |
Every tag created this way is an ordinary Tag Historian tag: it counts against your quota, has statistics, and can be queried, charted and exported like any other.
Where this is not InfluxDB
These are the things an InfluxDB user will expect that this endpoint does not do. They are deliberate. Do not design around behaviour that is not there.
- No deduplication or upsert. InfluxDB treats a point with the same series and timestamp as an overwrite. Tag Historian appends: rewriting a point makes a duplicate, or gets dropped by deadband compression if the value is close enough to the last one. Do not replay data you have already written.
- No query API. This is write-only compatibility. There is no Flux and no
/api/v2/query. Data comes back out through the Tag Historian API and exports (JSON, CSV, Parquet), not through InfluxDB tooling. organdbucketare decorative. They are parsed and discarded. Two writers with the same API key land in the same place no matter what bucket they claim to write to.
Ready-made configurations
- Home Assistant — the built-in
influxdbintegration, and the four settings that decide whether it works. - Telegraf —
outputs.influxdb_v2, and the tag quota trap in the default inputs.
Endpoint: https://api.taghistorian.com
Common questions
- Can I use an existing InfluxDB client library?
- Yes, for writing. Tag Historian accepts InfluxDB v2 line protocol on POST /api/v2/write with either an Authorization: Token header or X-API-Key. There is no query API — no Flux and no /api/v2/query — so a client that reads back will not work. For reading, use the official Python client — it wraps the Tag Historian read, aggregate and export endpoints, lists alerts and alert rules, and honours Retry-After. It is not on PyPI yet; install it from our git repository, github.com/softi-dev/tag-historian-clients.
- Do org and bucket need to be real?
- No. They are accepted so that clients which insist on them are satisfied, then discarded. Your API key alone decides where the data lands.
- What happens if I write more points than my tag quota allows?
- The request returns 422 and the points that would have created new tags are dropped. Points for tags that already exist are still written — a batch is not all-or-nothing on this endpoint, deliberately, because Home Assistant and Telegraf treat a whole-request failure as a reason to retry everything forever.
- Are string values stored?
- No. Tag Historian stores numbers; booleans are stored as 1 and 0. String fields are skipped, and a line with only string fields stores nothing.