Recently, we’ve seen an uptick in questions about our LightDB REST API Stream endpoints. And to be honest, it’s not surprising. As someone with a background in embedded systems, I’ll be the first to admit that Cloud and REST APIs weren’t exactly in my comfort zone when I started digging into this. When I first looked at querying data from the cloud where I had sent my data…I was confused too. Add to that the inherently multidisciplinary nature of IoT, where you’re expected to juggle hardware, firmware, and cloud software, and it makes total sense why there’s a lot of confusion around how to properly use these endpoints.
Some engineers are wizards with firmware but have barely touched a cloud dashboard. Others can deploy a Kubernetes cluster blindfolded, but would rather avoid debugging an I²C bus. The diversity in background and skills is part of what makes IoT so exciting—and so complex.
We’ve been hearing your questions, and in the spirit of building a better platform (and explaining it along the way), let’s discuss the LightDB Stream endpoints and when to use POST
and when to use GET
requests…and whether there is a Right™ way.
LightDB Stream Endpoints Overview
If you poke around our OpenAPI docs, you’ll see a few endpoints under LightDB Stream:
GET
/POST /v1/projects/{projectId}/devices/{deviceId}/stream
- This lets you query stream data for a specific device. You can filter by time, path, and other parameters
GET
/POST /v1/projects/{projectId}/stream
- This lets you query stream data across all devices in a project—helpful for dashboards or fleet-wide analytics
At first glance, they look pretty straightforward. And most people can guess what they’re supposed to do. But then you notice that both support both GET
and POST
. That’s when things get murky. If the device is posting data to Golioth, why would the client also post to read it? Shouldn’t GET
be enough?
That’s exactly what I thought—and where the deeper story begins.
Why Can I Use Both POST and GET?
The biggest head-scratcher tends to be: Why do both endpoints accept both GET
and POST
?
GET
makes sense—it’s how we typically request data from REST APIs. Like going to a deli and ordering the number 4 sandwich one the menu. But why would I POST
to an endpoint just to fetch something? Isn’t that what my device does when sending data?
One of our forum posts recommends using POST
when querying LightDB Stream, which feels backward until you understand what’s going on under the hood.
Breaking It Down
Let’s compare the two in the context of:
GET
/POST /v1/projects/{projectId}/devices/{deviceId}/stream
GET
/POST /v1/projects/{projectId}/stream
Yes, both can be used to query data—but we recommend POST
for a subtle (yet important) reason: POST
allows complex queries in the request body.
LightDB Stream supports advanced queries—things like filtering by specific fields, defining time ranges, and setting limits. To represent all of that, you need a structured way to pass the query. That’s where POST
shines. To go back to the deli analogy, this is like ordering a complex sandwich just to your standards, instead of only asking for sandwich #4.
With POST
, you can include your query as a clean JSON payload in the request body. Here’s what that might look like:
{ "start": "2025-05-01T09:00:00+00:00", "end": "2025-04-29T12:00:00+00:00", "query": { "fields": [ { "path": "time", "type": "" }, { "path": "deviceId", "type": "" }, { "path": "temperature", "type": "" }, ], "filters": [] }, "page": 0, "perPage": 10 }
Trying to squeeze that into a GET
request would quickly turn into a mess. The URL would be long, fragile, and hard to read or debug. It might even break in certain browsers or proxy layers. And while some clients technically support request bodies with GET
, it’s against HTTP spec and not something we recommend.
Using POST
gives you a more expressive and flexible way to query data. You’re not bound by URL encoding or the limitations of query strings, and the result is cleaner, more maintainable, and more predictable across different tools and environments.
The equivalent GET
request would look like this:
curl -X GET \ "https://api.golioth.io/v1/projects/{projectId}/stream?start=2025-05-01T09:00:00%2B00:00&end=2025-04-29T12:00:00%2B00:00&fields=time,deviceId,temperature&page=0&perPage=10" \ -H 'accept: application/json' \ -H 'x-api-key: YOUR_API_TOKEN'
GET
request is useful for quick tests in a browser or a command-line tool. But as soon as your query gets more complex, with time-based filters or multiple fields, switch to POST
. It’s more robust, scales better, and won’t break when your query grows.
Conclusion
To wrap things up: while both GET
and POST
can be used to query LightDB Stream, they serve different use cases depending on the complexity of your request. GET
is great for quick, simple lookups—think of it as your go-to for ad-hoc testing, browser-based exploration, or lightweight queries with just a few parameters. It’s familiar, fast, and easy to drop into tools like curl
or Postman when you’re just poking around.
But when your query starts to grow, maybe you need to filter by time ranges, select specific fields, paginate through large datasets, or apply more advanced logic, POST
becomes a better tool. It allows you to express your intent through a structured JSON payload, which is not only more readable and maintainable but also avoids the pitfalls of overly long or fragile URLs. More importantly, POST
ensures your queries remain compatible across different clients and environments, especially when working at scale or integrating with dashboards and analytics pipelines.
In short, use GET
when you want simplicity. Use POST
when you want power, flexibility, and clarity.
If you’re building with LightDB Stream and run into questions—or just want to bounce ideas off other developers—you’re always welcome to reach out on the forum. Our team and community are there to help, and we love hearing how you’re using these tools in the real world. Let us know what you’re building!
No comments yet! Start the discussion at forum.golioth.io