Developers

Build with the Hoshika API

OAuth2 for third-party apps (trackers, extensions, bots) and a JSON API for anime & manga lists.

1. Register your app

Any Hoshika account can create OAuth credentials from Settings → Applications.

  • Redirect URIs must be https (http://localhost is allowed for development).
  • The client secret is shown only once — store it safely.
  • Up to 5 apps per account.

2. OAuth 2.0 (authorization code + PKCE)

Standard flow: send the user to authorize, they approve on the consent screen, you exchange the code for tokens. PKCE is required.

# Discovery (OpenID Connect)
https://hoshika.app/api/auth/.well-known/openid-configuration

# 1) Authorization (PKCE required)
GET https://hoshika.app/api/auth/oauth2/authorize
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=https://yourapp.example/callback
  &response_type=code
  &scope=openid profile offline_access
  &code_challenge=BASE64URL(SHA256(verifier))
  &code_challenge_method=S256

# 2) Token exchange
POST https://hoshika.app/api/auth/oauth2/token
  grant_type=authorization_code
  code=...&code_verifier=...&client_id=...&client_secret=...
  redirect_uri=https://yourapp.example/callback

# → { access_token, refresh_token, expires_in: 86400 }

Access tokens last 24 hours; refresh tokens 90 days. Send the token as Authorization: Bearer on every API call.

3. The API

Base URL https://hoshika.app/api/v1 — JSON in and out. Every response includes ok, and errors carry a stable machine-readable code.

curl https://hoshika.app/api/v1/library?type=anime \
  -H "Authorization: Bearer ACCESS_TOKEN"
MethodEndpointDescription
GET/api/v1/search?q=Search anime & manga
GET/api/v1/anime/{shortId}Anime details
GET/api/v1/manga/{shortId}Manga details
GET/api/v1/library?type=anime|mangaThe user's list (cursor pagination)
POST/api/v1/library/entryAdd/update a list entry (partial upsert)
DELETE/api/v1/library/entryRemove an entry
POST/api/v1/ratingsRate an anime
# Upsert de progreso (campos parciales)
POST /api/v1/library/entry
{ "type": "anime", "mediaId": "<uuid>", "status": "watching",
  "progress": 7, "userScore": 8 }

# Contrato de error (siempre):
{ "ok": false, "code": "unauthorized" | "invalid" | "rate_limited" | ... }

4. Rules of the road

  • Rate limits apply per user and per IP; on 429 back off and retry later.
  • Adult content follows each user's own settings: minors and users with the filter enabled can neither see nor add explicit titles (adult_content_blocked).
  • Users can revoke your app's access at any time from Settings → Applications.
  • Catalog entries expose mal_id and anilist_id where known — map your IDs once and cache it.

Questions, higher limits, or want your tracker listed? Get in touch