API reference

The Orihon reader SDK speaks to one delivery endpoint in your region. A client pulls the catalog for a library, then downloads the volumes it lists. Every route documented here lives on this host.

Base URL

Every call goes to the region you're assigned; this endpoint is ap-northeast-1.

https://orihon.dev/v1

Authenticate with a publisher key, passed as a bearer token. A key is tied to one publisher and one channel. Reader keys can browse the catalog and pull pages and volumes; they can't package or publish.

Authorization: Bearer orh_live_5b1e9a04c7f3d268

Endpoints

Method Path Purpose
GET /v1/catalog List the series and issues a library should show for a publisher and channel.
GET /v1/volumes/:volume_id Download an immutable offline volume bundle. This is where the bytes are.
GET /v1/pages/:issue_id List an issue's pages with their dimensions and checksums.
POST /v1/entitlements/verify Confirm a reader may hold a title before the SDK caches it.
POST /v1/reads/ack Record a reader's position so it follows them to another device.

Read the catalog

The catalog decides what shows up in a reader's library. The SDK reads it at launch and whenever the app returns to the foreground — it's light, and it's the one response you want current.

GET /v1/catalog?series=srs_hoshikawa&channel=store
// 200 OK
{
  "catalog_id": "cat_2026_07_11_9b2e",
  "channel": "store",
  "series": [
    {
      "series_id": "srs_hoshikawa",
      "title": "Hoshikawa Lights",
      "volumes": [
        {
          "volume_id": "vol_hoshikawa_07_3af19c",
          "number": 7,
          "page_count": 196,
          "size_bytes": 348127232
        },
        {
          "volume_id": "vol_hoshikawa_08_5c07b1",
          "number": 8,
          "page_count": 204,
          "size_bytes": 361824256
        }
      ]
    }
  ]
}

Download a volume

Every volume is addressed by its content hash and never changes — the same volume_id gives back the same bytes forever. Clients hold onto them and only reach back when the catalog points to something newer. Because the endpoint honours range requests, a transfer cut off in a tunnel picks up from where it stopped instead of starting over.

GET /v1/volumes/vol_hoshikawa_07_3af19c
Range: bytes=0-
// 200 OK (or 206 Partial Content)
Content-Type: application/vnd.orihon.volume
Content-Length: 348127232
ETag: "3af19c"
Cache-Control: public, max-age=31536000, immutable

A single volume is 150–400 MB of packed full-resolution pages. A reader who loads a whole series before a trip pulls the entire run at once — several GB per device, paid once. Plan around libraries downloaded rather than page views: readers sync when they open the app, so a new release spreads across a day instead of arriving in a spike.

List an issue's pages

This returns an issue's pages with their dimensions and per-page checksums, so the SDK can confirm what it cached and re-pull a single bad page rather than the whole volume.

GET /v1/pages/iss_hoshikawa_c052
// 200 OK
{
  "issue_id": "iss_hoshikawa_c052",
  "volume_id": "vol_hoshikawa_07_3af19c",
  "reading_direction": "rtl",
  "pages": [
    { "index": 0, "w": 1536, "h": 2172, "sha256": "7d10…a4" },
    { "index": 1, "w": 1536, "h": 2172, "sha256": "c98b…19" }
  ]
}

Verify an entitlement

Called before the SDK caches a title, so a device only holds what the reader is allowed to keep. Bundles are signed as well, so a file lifted off a device is inert without a valid entitlement.

POST /v1/entitlements/verify
Content-Type: application/json

{
  "publisher": "pub_5b1e9a04",
  "reader_token": "rt_9f2c…",
  "volume_id": "vol_hoshikawa_07_3af19c"
}
// 200 OK
{
  "entitled": true,
  "scope": "owned",
  "expires": null
}

Acknowledge a read position

Not required, but worth wiring up: it's what lets a reader set a volume down on their phone and open it on a tablet at the same page. It's the only call that sends anything upstream, and it's kept deliberately tiny.

POST /v1/reads/ack
Content-Type: application/json

{
  "reader_token": "rt_9f2c…",
  "issue_id": "iss_hoshikawa_c052",
  "page": 41
}

SDK quickstart

Swift, for iOS. The Android SDK mirrors these calls.

import Orihon

let reader = try await Orihon.start(
    publisherId: "pub_5b1e9a04",
    endpoint:    "https://orihon.dev",
    channel:     "store"
)

// Pre-cache a volume the reader owns; resumes on its own if the network drops.
let volume = try await reader.library.download("vol_hoshikawa_07_3af19c")

if volume.isReadyOffline {
    print("Cached \(volume.pageCount) pages")
}

Errors

Code Meaning What to do
401 Key missing, malformed, or revoked. Confirm the key is current. Each key is scoped to one publisher and channel.
403 Reader is not entitled to this title. Re-check entitlement; don't cache. The catalog lists only what a channel may show.
404 No such volume or issue for this publisher. Usually a stale ID. Re-read the catalog; immutable IDs never change meaning.
429 Too many catalog resolves from one address. Respect Retry-After; the SDK already backs off with jitter.

Service health for this region is published at /status.