One key per company
The company admin generates the key in Settings. It is shown once — we store only its fingerprint, so not even we can read it back.
API
A REST API over the very same warehouse you see in the app. Connect an e-shop, an ERP, Make.com or your own script to it. It is in every plan, Free included — a warehouse you cannot try connecting before you start paying is a pig in a poke.
The company admin generates the key in Settings. It is shown once — we store only its fingerprint, so not even we can read it back.
A history with the IP address, status, duration and response. When an integration falls apart you do not have to guess why.
One call tells you what the scanned code is and where it lies. You can wire up your own reader in an afternoon.
Authentication
No OAuth, no expiring tokens. The key belongs on a server — not in a browser or a mobile app, where anyone can read it.
curl -H "Authorization: Bearer cstrg_ab12cd34_…" \
https://www.cloudstrg.sk/api/v1/info
If you cannot set the Authorization header (some low-code tools), send the key in X-Api-Key.
{ "ok": true, "data": … }
{ "ok": false, "chyba": { "kod": "nenajdene", "sprava": "…" } }
That way an integration does not have to look at the HTTP status to know whether it succeeded — ok is enough. Lists also carry strankovanie with limit, offset and celkom.
200 / 201 — all good401 — missing or invalid key402 — the plan is full, a new position will not fit404 — the thing does not exist or does not belong to your company422 — missing or nonsensical parameter429 — call ceiling exceeded; try again in a minuteEndpoints
The base is https://www.cloudstrg.sk/api/v1. There are deliberately only two writes — create a container and say where it went. Changing the warehouse structure over the API is not possible: that is a decision for a person standing at the rack.
| Method | Path | What it does |
|---|---|---|
| GET |
/info
|
Who am I, which plan I have and how many calls I have left. |
| GET |
/sklady
|
List of warehouses. |
| GET |
/sklady/{id}
|
One warehouse. |
| GET |
/regaly?sklad_id=
|
Racks in a warehouse. |
| GET |
/police?regal_id=
|
Shelves in a rack. |
| GET |
/kontajnery
|
Boxes and binders. Filters: sklad_id, polica_id, typ, stav, q, nezaradene, limit, offset. |
| GET |
/kontajnery/{id}
|
One container, with the list of things inside. |
| POST |
/kontajnery
|
Creates a container and assigns it a code. Body: nazov, typ, popis, polica_id. |
| POST |
/kontajnery/{id}/presun
|
Moves a container onto a shelf. Body: polica_id (null = take it off the shelf). |
| GET |
/kod/{kod}
|
What this code off a label is and where it lies. |
| GET |
/hladat?q=
|
Search across boxes and the things inside them. |
| GET |
/grafana/metriky
|
The warehouse state right now as a flat array — for Stat panels. |
| GET |
/grafana/rad?metrika=
|
A daily time series with no gaps: hladania, otvorenia, pohyby, api. |
| GET |
/grafana/tabulka?co=
|
Ready-made rows for a Table panel: najhladanejsie, bez-vysledku, najziadanejsie, police, sklady. |
| GET |
/grafana/prometheus
|
The same numbers in the Prometheus text format. |
Examples
curl -H "Authorization: Bearer $KLUC" \
https://www.cloudstrg.sk/api/v1/kod/K-9WZ2QK
{
"ok": true,
"data": {
"typ": "kontajner",
"kod": "K-9WZ2QK",
"id": 412,
"nazov": "Účtovníctvo 2023",
"popis": "Košice · R1 · R1-2"
}
}
curl -H "Authorization: Bearer $KLUC" \
"https://www.cloudstrg.sk/api/v1/hladat?q=vŕtačka"
curl -X POST -H "Authorization: Bearer $KLUC" \
-H "Content-Type: application/json" \
-d '{"nazov":"Faktúry 2026","typ":"sanon","polica_id":12}' \
https://www.cloudstrg.sk/api/v1/kontajnery
The code is assigned automatically and comes back in the response — you then print the label for it in the app. The app decides about codes on purpose, so that two identical ones cannot come about.
Grafana
Grafana cannot reach our database and does not need to — it gets finished numbers over HTTPS. All it needs is an API key and one datasource.
In Grafana add an Infinity datasource, type JSON → URL, and put Authorization: Bearer cstrg_… in the headers. The responses are bare arrays of objects, so there is no root selector to set.
# Stat panels — the warehouse state right now
https://www.cloudstrg.sk/api/v1/grafana/metriky
# Time series — searches by day (also otvorenia, pohyby, api)
https://www.cloudstrg.sk/api/v1/grafana/rad?metrika=hladania&dni=30
# Table — what gets reached for most
https://www.cloudstrg.sk/api/v1/grafana/tabulka?co=najziadanejsie&dni=30
The series always has one row per day — including days when nothing happened. Without that, Grafana would join day three and day seven with a straight line, as if work had been going on in between.
scrape_configs:
- job_name: cloudstrg
scrape_interval: 60s
metrics_path: /api/v1/grafana/prometheus
scheme: https
authorization:
credentials: cstrg_ab12cd34_…
static_configs:
- targets: ['www.cloudstrg.sk']
Both routes return the same numbers, so they can be combined.
Calls for Grafana count against the same ceiling as the rest. A 10-second refresh is 360 calls an hour per panel — with ten panels you would burn through even the Free plan in eight minutes. Set the interval to one minute; warehouse numbers do not change faster than that.
Limits
Only the hourly call ceiling differs. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining, so the integration knows where it stands without having to guess.
500 calls per hour — free of charge
2,000 calls per hour
10,000 calls per hour
50,000 calls per hour
The ceiling is per company, not per key — so you create more keys for clarity, not for headroom. On exceeding it you get a 429 and a Retry-After header; nothing is deleted and in a minute everything carries on.
Start with a single rack
The Free plan costs nothing and has no time limit — 30 positions are enough for one rack and for finding out whether this suits you. You pick a paid plan only once you run out of room.