Developers
Marking a book as read is an API operation.
When you mark a work as “Read” in your library, the website sends the request below. Your code can send the same request, get the same result, and pass the same checks.
Writes
A write request, line by line
PUT /v1/works/{id}/reader-status
Authorization: Bearer …
Idempotency-Key: 7f3c2a9e-read
Content-Type: application/json
{
"actingSubject":
"https://rezics.com/id/…",
"expectedVersion": 3,
"status": "read",
"finishedOn": "2026-10-19"
}The path identifies a work
{id}Every item in REZICS has a permanent identifier beginning with https://rezics.com/id/. It stays the same across languages and sites.
State the identity
actingSubjectAn account can act for itself or an organization. Every write states whose identity is acting, and the server checks its permissions before it runs.
Make retries safe
Idempotency-KeyEvery write includes an idempotency key. After a timeout or disconnect, retry with the same key to avoid writing twice.
Prevent overwrites
expectedVersionIf you read version 3, state version 3 in your request. If someone else edits it first, your write will not overwrite their changes.
Errors use problem details
application/problem+jsonFailures return a fixed code. Your code can branch on it without comparing message text.
Retries
Retry the same request and get the same result.
Send the same content again with the same key, and the server returns the first result: version stays at 4 and replayed becomes true. Reuse the key with different content and it returns 409 reader_status_conflict. If the version is no longer 3, it returns 409 stale_reader_status. Read again before writing.
First request
200 { "status": "read", "version": 4, "replayed": false }Retry
200 { "status": "read", "version": 4, "replayed": true }Stale version
409 { "status": 409, "code": "stale_reader_status" }
Types
The API and its types share one definition
The REZICS website calls the API with TypeScript. Request and response types come directly from the server’s route declarations. If a field is renamed or an error code is added, callers know at compile time. The TypeScript SDK comes from the same definition, so its types match the website’s.
OpenAPI 3.1 documentation comes from the same route declarations. It specifies each operation’s authentication, request format, and response for every status code.
main().v1
.works({ id: uuid(work) })
['reader-status'].put({
actingSubject,
expectedVersion,
status: 'read',
...dates,
}, headers())generated/openapi/main/public.json
Reads
Reads have rules too
nextCursor · snapshotLong lists include a cursor for the next page so you can read to the end. Library exports also include a snapshot. If data changes midway, the response says so instead of giving you a file assembled from mixed versions.
count.precisionSearch results say whether the total is exact or “at least” the stated number.
title.language · basisTitles include a language tag and writing direction, and explain whether the language was requested, matches the same script, uses another script, or is a fallback.
404 resource_unavailableA resource you cannot access returns the same response as one that does not exist, so its existence stays private.
Developers
More pages
- MCP serverAI agents connect at /mcp and see tools allowed by their permissions
- Connected appsAuthorize with OAuth and revoke access at any time
- Wiki toolkitExtract on your computer and send only proposals
- Zone themesCreate a custom layout for a community site
- Open sourceAGPL-3.0 platform, Apache-2.0 standalone packages
Build your tools on one API.
Use your own code to read and write works, library entries, and community data. Every operation follows REZICS identity and authorization rules.