Using the API
Every endpoint is listed and tryable in the Swagger UI. This page is a walkthrough; for the exhaustive reference see the Swagger UI and docs/API.md.
Authentication
API keys (for programs)
Write operations (creating and updating resources, etc.) and reads of private data require an API key. Keys belong to an account and carry read / write scopes.
Authorization: Bearer <public_id>.<secret>How to issue one:
- Dashboard /dashboard/keys (Google login) → "Issue a new key"
POST /api/me/keys(Firebase ID token)
The secret is shown once
A key's secret (.secret) is shown only once at issue time (the server stores only a sha256 hash). Save it somewhere safe (e.g. 1Password). If it leaks, revoke and reissue.
Reading public data needs no key
Listing, searching and fetching public (is_public) resources works without authentication.
# Search within a site (returns public items only)
curl 'https://archivebase.ldas.jp/api/{account}/dl/{db}/search?q=term'Quickstart (curl)
KEY="ak_xxxxxxxx.yyyyyyyyyyyy" # issued in the dashboard
BASE="https://archivebase.ldas.jp"
ACC="your-account"Create a database (library)
curl -s -X POST "$BASE/api/$ACC/databases" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"slug":"nishikie","title":"Nishikie Collection"}'Create a resource (item)
curl -s -X POST "$BASE/api/$ACC/dl/nishikie/resources" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{
"slug":"0380-17-1",
"type":"item",
"title":"Doke musha zukushi",
"metadata":{"dcterms:creator":"Utagawa Kuniyoshi","year":"1858"}
}'Search (no key)
curl -s "$BASE/api/$ACC/dl/nishikie/search?q=Kuniyoshi&facet=placeName"Common endpoints
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /api/{account}/dl/{db}/resources | read | List (type / parent / page[...]) |
| POST | /api/{account}/dl/{db}/resources | write | Create |
| GET | /api/{account}/dl/{db}/resources/{id} | read | Fetch (by slug or uuid) |
| PATCH | /api/{account}/dl/{db}/resources/{id} | write | Partial update |
| DELETE | /api/{account}/dl/{db}/resources/{id} | write | Delete |
| GET | /api/{account}/dl/{db}/search | (public) | Search & facets |
| POST | /api/{account}/dl/{db}/import | write | CSV bulk import (Omeka CSVImport-compatible) |
| POST | /api/{account}/dl/{db}/uploads | write | Issue a presigned S3 PUT URL for a binary |
| GET | /api/{account}/usage | read | Usage |
Search query (JSON:API style)
/search accepts:
q— search terms (websearch syntax)facet=<key>— metadata key(s) to aggregate (repeatable)filter[<key>]=<value>— filter by metadata (repeat the same key for OR)page[number]+page[size](orpage[limit]+page[offset]) — pagingsort=<key>— ordering; prefix with-for descending (sort=-year)
curl 'https://archivebase.ldas.jp/api/{account}/dl/{db}/search?q=Hokusai&filter[persName]=Katsushika+Hokusai&page[size]=20&sort=-year'Legacy params are deprecated
limit / offset / dir and bare metadata params are deprecated (marked as such in Swagger). New code should use page[...] / filter[...] / sort=-<key>.
Access control and errors
- Private databases and items return 404 to unauthorised requests (their existence is not revealed)
- Writes to another account's resources return 403 (insufficient scope)
- Anonymous access to authenticated endpoints returns 401
- Duplicate slug is 409, quota exceeded is 402, single-upload size overflow is 413
Errors are returned as JSON { "error": "..." }.
Custom domains
A public site can be served under a custom host name like xxxx.ldas.jp (Vercel-style — rewritten to the tenant internally, the address bar keeps the host). Manage it with the Firebase-session GET/POST/DELETE /api/me/domains (or the dashboard → site detail → "Custom domain"). For now, single-label *.ldas.jp subdomains only, public DBs only. See the Swagger UI and the user guide.
Bulk import
- CSV (Omeka CSVImport-compatible) — from the dashboard's site detail, or
POST /dl/{db}/import - dcb format — an importer for
collection.csv/item.csv/media.csv/annotation.csv(npm run import:dcb)
Work in progress
Details of API-key scope design, rate limits, and whether webhooks / harvesting (OAI-PMH, etc.) are supported are yet to be documented.