Data
JSON records grouped by resource, structured queries, search and file storage, all scoped to one app. Use it for an app's own data when you don't want to design and migrate tables yet.
Records
A record is a JSON document under a resource name you choose.
curl -X POST https://api.dianthan.com/v1/records \
-H "X-API-Key: dn_live_…" -H "X-App-Id: app_…" \
-H "Content-Type: application/json" \
-d '{"resource":"contacts","data":{"name":"Acme Ltd","status":"active","owner":"usr_x81…"}}'{ "id": "rec_3kd…", "resource": "contacts", "data": { "name": "Acme Ltd", "status": "active", "owner": "usr_x81…" }, "created_at": "…" }Read with GET /v1/records/:id, change fields with PATCH /v1/records/:id (fields you send are merged), and delete with DELETE /v1/records/:id.
Queries
Queries are JSON. You never build SQL strings, so nothing can be injected.
curl -X POST https://api.dianthan.com/v1/query \
-H "X-API-Key: dn_live_…" -H "X-App-Id: app_…" \
-H "Content-Type: application/json" \
-d '{
"resource": "contacts",
"filter": { "status": "active" },
"sort": "-created_at",
"limit": 50
}'filtermatches fields by equality. Every field in it must match.sortnames a field, with a leading-for descending.limitandoffsetpage through results.
Search
curl -X POST https://api.dianthan.com/v1/search \
-H "X-API-Key: dn_live_…" -H "X-App-Id: app_…" \
-H "Content-Type: application/json" \
-d '{"query":"acme","resources":["contacts"],"limit":20}'Leave out resources to search every searchable resource in the app.
Declaring a resource
Once you know a resource's shape, register it to say which fields are allowed and whether it appears in search:
curl -X POST https://api.dianthan.com/v1/resources \
-H "X-API-Key: dn_live_…" -H "X-App-Id: app_…" \
-H "Content-Type: application/json" \
-d '{"resource":"contacts","description":"People and companies we work with","allowed_fields":["name","status","owner"],"searchable":true}'Files
Browsers upload files straight to Dianthan, so the bytes never pass through your server. Your server only starts the upload:
# 1. Your server asks for an upload URL
curl -X POST https://api.dianthan.com/v1/files/upload-url \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"filename":"report.pdf","mime_type":"application/pdf"}'
# → { "file_id": "fil_…", "upload_url": "/v1/files/fil_…/content", "method": "PUT" }
# 2. The browser PUTs the bytes to upload_url
# 3. Mark it complete
curl -X POST https://api.dianthan.com/v1/files/fil_…/complete -H "Authorization: Bearer $TOKEN"Get a short-lived download link with GET /v1/files/:id/download-url. Files belong to the user who uploaded them unless you're using an app key.
Isolation
Every record, query, search and file is filtered by app. A key for one app gets 403 from every other app. Within an app, people using their own access token can only reach routes meant for them. Listing records requires an app key or an admin.
In preview: exporting all of an app's records and files as one archive.