Log inGet API key

API reference

Every table in your SQLite databases is a JSON endpoint. All responses are JSON; errors look like {"error":{"code","message"}}.

Base URL & authentication

Base URL: https://ndsql.top/api

Create a key under API keys and send it with every request, any of these ways:

X-API-Key: nd_xxxxxxxx
Authorization: Bearer nd_xxxxxxxx
https://ndsql.top/api/shop/products?api_key=nd_xxxxxxxx

Read-only keys can only use GET. Keys can be limited to one database. CORS is enabled, so browser apps (React, Vue) can call the API directly — keep write keys on your server.

Quick start

curl "https://ndsql.top/api/shop/products?limit=10&order=-id" \
  -H "X-API-Key: YOUR_KEY"
const res = await fetch("https://ndsql.top/api/shop/products?limit=10", {
  headers: { "X-API-Key": "YOUR_KEY" },
});
const { data, meta } = await res.json();
$ch = curl_init("https://ndsql.top/api/shop/products?limit=10");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["X-API-Key: YOUR_KEY"],
]);
$json = json_decode(curl_exec($ch), true);

Endpoints

MethodPathWhat it doesKey
GET/apiList your databasesread
POST/apiCreate a database: {"name":"shop"}write
GET/api/{db}List tables and columnsread
POST/api/{db}Create a table (see below)write
GET/api/{db}/{table}List rows (filters, order, paging)read
POST/api/{db}/{table}Insert a row, or an array of up to 100write
GET/api/{db}/{table}/{id}Get one rowread
PATCH/api/{db}/{table}/{id}Update fields (PUT works too)write
DELETE/api/{db}/{table}/{id}Delete a rowwrite

Create a table

Types: text, integer, real, boolean. id and created_at are added automatically.

curl -X POST "https://ndsql.top/api/shop" \
  -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"table":"products","columns":[
        {"name":"name","type":"text"},
        {"name":"price","type":"real"},
        {"name":"in_stock","type":"boolean"}]}'

Insert, update, delete

# insert
curl -X POST "https://ndsql.top/api/shop/products" -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Keyboard","price":49.5,"in_stock":true}'

# update
curl -X PATCH "https://ndsql.top/api/shop/products/1" -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"price":44}'

# delete
curl -X DELETE "https://ndsql.top/api/shop/products/1" -H "X-API-Key: YOUR_KEY"

Insert returns 201 with the saved row, including its id.

Filtering, ordering, paging

QueryMeaning
?name=KeyboardEquals
?price[gt]=10&price[lte]=100Operators: eq, ne, gt, gte, lt, lte, like
?name[like]=Key%25Pattern match (%25 is %)
?order=-priceSort by column; - for descending (default id)
?limit=20&p=2Page size (max 100, default 50) and page number
{
  "data": [ { "id": 7, "name": "Keyboard", "price": 49.5, "in_stock": true, "created_at": "2026-10-20 09:14:02" } ],
  "meta": { "total": 1, "page": 1, "limit": 50, "pages": 1 }
}

Errors & limits

StatusMeaning
400 / 422Bad body, unknown field, or invalid value for the column type
401Missing or invalid API key
403Read-only key used for a write, or key scoped to another database
404Database, table or row not found
409Already exists, or a plan limit was reached
413Database is full (25 MB) or too many rows in one request
429More than 120 requests per minute on one key. Check Retry-After

Limits: 5 databases per account, 20 tables per database, 30 columns per table, 25 MB per database. Need more? nahid@ndsql.top