Recipes
Copy-paste solutions to the tasks people actually do with the Data API — counting, filtering, paging and exporting real data.
Last updated on
Short, working answers to common questions, all against the live example table
mirusiuju_toksikologinis_rezultatas in namespace 111958286. Swap in your own
namespace and table and they keep working.
Count how many rows match — without downloading them
Ask for one row and read total; it reflects the filtered set, so it's the
cheapest way to size a query.
curl -s -X POST 'https://api.dataportal.gov.lt/namespaces/111958286/tables/mirusiuju_toksikologinis_rezultatas/query' \
-H 'Content-Type: application/json' \
-d '{"filter":"lytis=Moteris","limit":1}' | jq '.total'import requests
URL = "https://api.dataportal.gov.lt/namespaces/111958286/tables/mirusiuju_toksikologinis_rezultatas/query"
total = requests.post(URL, json={"filter": "lytis=Moteris", "limit": 1}).json()["total"]
print(total, "rows match")const URL = "https://api.dataportal.gov.lt/namespaces/111958286/tables/mirusiuju_toksikologinis_rezultatas/query";
const { total } = await fetch(URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ filter: "lytis=Moteris", limit: 1 }),
}).then((r) => r.json());
console.log(total, "rows match");Get only the columns you need
curl -X POST '…/query' -H 'Content-Type: application/json' \
-d '{"select":"lytis,mirties_metai,pavadinimas","limit":20}'Filter three ways
# Exact match
-d '{"filter":"lytis=Moteris"}'
# Range — deaths in 2018 or later
-d '{"filter":"mirties_metai._ge=2018"}'
# Contains — substance name includes "Etan"
-d '{"filter":"pavadinimas._co=Etan"}'Combine conditions (AND / OR)
Join conditions inside the filter string with &; each extra one is _and by
default, or prefix _or. for a disjunction.
# 2018+ AND female
-d '{"filter":"mirties_metai._ge=2018&_and.lytis=Moteris"}'
# female OR male
-d '{"filter":"lytis=Moteris&_or.lytis=Vyras"}'Newest first
curl -X POST '…/query' -H 'Content-Type: application/json' \
-d '{"sort":"-mirties_metai","limit":10}'Page through the whole table
Always add a stable sort (e.g. _id) so offset paging doesn't skip or repeat
rows. Stop when a page returns fewer than limit rows.
import requests
URL = "https://api.dataportal.gov.lt/namespaces/111958286/tables/mirusiuju_toksikologinis_rezultatas/query"
limit, offset = 1000, 0
rows = []
while True:
page = requests.post(URL, json={"limit": limit, "offset": offset, "sort": "_id"}).json()["data"]
rows += page
if len(page) < limit:
break
offset += limit
print(len(rows), "rows total")const URL = "https://api.dataportal.gov.lt/namespaces/111958286/tables/mirusiuju_toksikologinis_rezultatas/query";
const limit = 1000;
let offset = 0, rows = [];
while (true) {
const page = await fetch(URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ limit, offset, sort: "_id" }),
}).then((r) => r.json());
rows.push(...page.data);
if (page.data.length < limit) break;
offset += limit;
}
console.log(rows.length, "rows total");Pulling everything? Export instead.
For a full dump, don't page at all — the export endpoint streams the entire result set in one request.
Export the whole table to Excel
xlsx is capped at 1,000,000 rows; filter or limit larger tables.
curl -L -o toksikologija.xlsx \
-X POST 'https://api.dataportal.gov.lt/namespaces/111958286/tables/mirusiuju_toksikologinis_rezultatas/export?format=xlsx' \
-H 'Content-Type: application/json' -d '{}'Export just a filtered slice
Export shares the query body, so any filter you can query, you can export:
curl -L -o moterys.csv \
-X POST '…/export?format=csv' -H 'Content-Type: application/json' \
-d '{"select":"lytis,mirties_metai,pavadinimas","filter":"lytis=Moteris"}'Download a stored file
curl -L -O 'https://api.dataportal.gov.lt/namespaces/{namespace}/files/report.pdf'Querying tables
The full grammar behind these recipes.
Errors
What each status code means and how to handle it.
See also
How is this guide?