API
No account, no API key management, no rate limits. Create a project, get a token back, start writing. Everything below works with copy and paste.
Create a project
/api/v1/projectsUnauthenticated. Returns a project id and a write token. The project is deleted after 7 days unless claimed with an email.
curl -X POST https://v2.floatpt.com/api/v1/projects \
-H "Content-Type: application/json" \
-d '{"name": "my sensor"}'Response
{
"projectId": "3w5dkptw1mhfs9rg",
"nodeId": "apwpmtjgkyj5h8tm",
"token": "fp_9x2m4kdjw8fh3nzq7bvt5cyr",
"name": "my sensor",
"expiresAt": 1785355200000,
"expiresInDays": 7
}Write measurements
/api/v1/measurementsSend a flat JSON object, or an array of them. Values must be numbers, strings, booleans or null — no nesting. Keys are discovered automatically; there is no schema to declare.
curl -X POST https://v2.floatpt.com/api/v1/measurements \
-H "Authorization: Bearer fp_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"temperature": 23.5, "humidity": 55.7}'Batch up to 1 MB per request — cheaper and faster than one call per reading:
curl -X POST https://v2.floatpt.com/api/v1/measurements \
-H "Authorization: Bearer fp_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '[{"temperature": 23.5}, {"temperature": 23.6}]'Add ?wait=0 to return as soon as the write is buffered instead of waiting for it to land. Pass _ts (epoch milliseconds) in a reading to set its timestamp explicitly.
Read as CSV
/api/v1/projects/:id/measurementsDefaults to the last 7 days. Restrict columns with ?keys=a,b and the window with ?from= and ?to= (epoch milliseconds).
curl "https://v2.floatpt.com/api/v1/projects/PROJECT_ID/measurements?keys=temperature"Response
inserted_at,node,temperature
2026-07-24T19:52:35.235Z,sensor,23.5
2026-07-24T19:52:36.235Z,sensor,23.6Query
/api/v1/projects/:id/seriesEvery string field in a reading is a dimension: group by it, filter on it, aggregate over it. Nothing is declared in advance, so a device that starts sending a new field becomes queryable on the next request. This is what the chart polls.
curl "https://v2.floatpt.com/api/v1/projects/PROJECT_ID/series"Response
{
"calc": "raw", "groupBy": "node", "bucketMs": null,
"keys": ["humidity", "temperature"],
"groups": ["living-room", "outdoor"],
"dimensions": {
"room": [{ "value": "living", "count": 1435 }],
"firmware": [{ "value": "1.4.2", "count": 2868 }]
},
// dimensions come from a catalogue built during compaction: they describe
// the project rather than the window, and counts are approximate
"totalRows": 2870, "matchedRows": 2870,
"series": {
"temperature": {
"outdoor": { "t": [1785355200000], "v": [23.5] }
}
},
"summary": {
"temperature": {
"outdoor": { "min": 3.6, "max": 23.3, "avg": 16.8, "last": 21.2, "count": 2866 }
}
}
}Parameters
from, toEpoch milliseconds. Defaults to the last 5 minutes.keysComma-separated measurement names. Defaults to every numeric key.group_byAny string field, ornode(the default). One line per distinct value.wherefield:value, repeatable. Multiple filters combine with AND.calcraw(default) samples the signal.avg,min,max,p50,p95,p99,countaggregate into time buckets instead.heatmapreturns a time/value histogram inheatmapsrather than lines — colour is density, so groups are pooled.points, bucketsPayload caps.summaryalways describes every matching reading, never the reduced series.
Two sensors in one room disagreeing? Group by firmware to find out which build is wrong:
curl "https://v2.floatpt.com/api/v1/projects/PROJECT_ID/series?calc=avg&group_by=firmware&where=room:living&keys=temperature"Discover keys
/api/v1/projects/:id/keysThe set of measurement keys seen in this project, with types and counts. Built incrementally as data arrives.
curl "https://v2.floatpt.com/api/v1/projects/PROJECT_ID/keys"Claim a project
/api/v1/projects/:id/claimAttach an email to stop the project expiring.
curl -X POST https://v2.floatpt.com/api/v1/projects/PROJECT_ID/claim \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com"}'About tokens
Tokens are stored unencrypted and are readable by anyone who has the project id, including from GET /api/v1/projects/:id. That is a deliberate tradeoff so documentation and the UI can show a real, working key inline. A floatpt token grants write access to one project and nothing else — but treat every project as public, and do not store anything sensitive in one.