Skip to main content

API v2

API v2 is the backend for the Publica.la mobile reading apps (Fenice). It powers authentication, library browsing, content download, reader settings, search, and tenant discovery.

Key characteristics:

  • JWT-based authentication via magic link or social login
  • Multi-tenant and single-tenant modes depending on the endpoint
  • Session management with mobile-specific validation and concurrency control
  • Cursor and offset pagination depending on the resource
Export all API v2 documentation (11 sections) as a single Markdown file.

Base URL

https://app.publica.la/api/v2/

For custom apps with their own domain:

https://{store_final_domain}/api/v2/

Authentication

All authenticated endpoints require a JWT token obtained through the login flow.

Authorization: Bearer {access_token}

The JWT contains email and jti (JWT ID) claims. The jti is used for mobile session tracking.

Middleware Stack

Every authenticated request passes through two middleware layers:

LayerPurpose
AuthSessionMiddlewareValidates JWT, manages mobile sessions, updates last_activity
MultiTenantAuthMiddleware or SingleTenantAuthMiddlewareSets user and tenant context

Tenant Modes

API v2 endpoints operate in one of two modes depending on the resource:

Multi-Tenant Mode

Used by endpoints that operate across all tenants the user belongs to (user profile, continue reading, search global, tenant discovery, settings, help).

  • Must NOT send X-Farfalla-Tenant-Id header (returns 412 if present)
  • May send X-CustomFenice-Tenant-Id to scope to a specific app

Single-Tenant Mode

Used by endpoints scoped to a specific tenant (library, reader, content download, store search, favorites).

  • Must send X-Farfalla-Tenant-Id header with the tenant ID (returns 412 if missing)

Headers Reference

HeaderDescriptionRequired
AuthorizationBearer {jwt_token}All authenticated endpoints
X-Farfalla-Tenant-IdTenant ID for single-tenant endpointsSingle-tenant endpoints only
X-CustomFenice-Tenant-IdCustom app tenant ID (defaults to Publica.la)Optional, multi-tenant endpoints
X-Fenice-LangLanguage preference (en, es, pt, it)Optional, login init
X-Fenice-App-VersionMobile app version stringOptional, help/feedback
X-FeniceBase-VersionFenice base framework versionOptional, help/feedback
Acceptapplication/jsonAll endpoints
Content-Typeapplication/jsonPOST/PUT endpoints

Pagination

Used by library and search endpoints:

{
"meta": {
"current_page": 1,
"from": 1,
"to": 10,
"last_page": 5,
"per_page": 10,
"total": 48
}
}

Cursor Pagination (Tenants & My Content)

Used by /tenants and /user/my-content. The cursor is exposed as an opaque token under meta:

{
"data": [],
"meta": {
"per_page": 20,
"next_cursor": "eyJ1c2Vyc19jb3VudCI6MTIzNCwiX3BvaW50c1RvTmV4dEl0ZW1zIjp0cnVlfQ",
"prev_cursor": null
}
}

Pass meta.next_cursor back as ?cursor= on the next request, along with any filters that were sent in the original request. When meta.next_cursor is null, there are no more pages.

The cursor is opaque. Treat it as a token: do not parse, modify, or store individual fields from it.


Error Handling

HTTP Status Codes

CodeMeaning
200Success
201Created (login init, help request)
204No Content (feature disabled, unsubscribe)
401Unauthenticated (invalid/expired JWT)
404Not Found
412Precondition Failed (wrong tenant header mode)
422Validation Error
500Server Error

Validation Error Response (422)

{
"message": "The given data was invalid.",
"errors": {
"email": ["The email field is required."],
"code": ["The code must be 8 characters."]
}
}

Endpoint Summary

Authentication

MethodEndpointDescription
POST/login/token/initSend magic link email
POST/login/token/validateValidate code and get JWT (returns access_token + refresh_token)
POST/login/social/{provider}Social login (Google, Facebook, Apple)
POST/auth/refreshRotate access token using a refresh token (no JWT required, 10/min)
GET/auth/session/validateValidate current session
GET/logoutInvalidate session on all devices

User

MethodEndpointTenant ModeDescription
GET/userMultiUser profile and tenant list
GET/user/continue-readingMultiContinue reading across tenants
GET/user/my-contentMultiAll accessible content across tenants (paginated)
POST/user/push-notificationsMultiRegister FCM token
DELETE/user/push-notificationsMultiUnregister FCM token

Tenants

MethodEndpointTenant ModeDescription
GET/tenantsMultiList tenants the user could sign up for (filter by country, name, cursor)

Library

MethodEndpointTenant ModeDescription
GET/librarySingleLibrary shelves and sections (supports scope=all for storefront mode)
GET/library/filterSingleFiltered library section (supports scope=all for storefront mode)
GET/library/{issue}/favorite-issuesSingleCheck if issue is favorited
POST/library/{issue}/favorite-issuesSingleToggle favorite status
MethodEndpointTenant ModeDescription
GET/search/storeSingleSearch within one tenant (supports scope=all for storefront mode)
GET/search/globalMultiSearch across all tenants

Commerce

MethodEndpointTenant ModeDescription
GET/app/purchase/{tenant_id}/{issue_id}SingleIn-app purchase redirect (web route, not under /api/v2/). Coming soon, see Commerce

Reader

MethodEndpointTenant ModeDescription
POST/reader/{issue}/sessionsSingleCreate reader session
GET/reader/settings/{issue}SingleReader configuration for issue
PUT/reader/settingsSingleUpdate user reader preferences
PUT/reader/{issue}/last-locationSingleSave reading position
GET/reader/issue-text-contentSingleSearch text within an issue

Notes

MethodEndpointTenant ModeDescription
GET/reader/notesSingleList notes for current issue
POST/reader/notesSingleCreate highlight/annotation
PUT/reader/notes/{note}SingleUpdate note color/annotation
DELETE/reader/notes/{note}SingleDelete a note

Integrations

MethodEndpointTenant ModeDescription
GET/reader/integrations/ai-integrationsSingleList available AI actions
POST/reader/integrations/ai-integrationsSinglePerform AI action on text
PUT/reader/integrations/ai-integrationsSingleRate AI response
POST/reader/integrations/listenSingleText-to-speech
POST/reader/integrations/dictionarySingleDictionary lookup
POST/reader/integrations/translateSingleTranslate text

Content

MethodEndpointTenant ModeDescription
GET/content/{issue}/downloadSingleDownload data for offline reading

Settings

MethodEndpointTenant ModeDescription
GET/settingsMultiMobile app configuration (news feed, etc.)

Requires X-CustomFenice-Tenant-Id header. Returns the tenant's mobile app settings including news feed configuration:

{
"news_feed": {
"enabled": true,
"sections": [],
"tags": []
}
}

Help

MethodEndpointTenant ModeDescription
GET/helpMultiList help/support subjects
POST/helpMultiSubmit help request

Next Steps

  • Authentication - Login flows, social auth, refresh tokens, session management
  • Tenants - List tenants the user could sign up for
  • User - Profile, continue reading, my-content, push notifications
  • Library - Library browsing, shelves, favorites, storefront mode
  • Reader - Reader sessions, settings, text search, content download
  • Notes - Highlights and annotations within the reader
  • Integrations - AI, translate, dictionary, text-to-speech
  • Search - Store and global search, storefront mode
  • Commerce - Commerce fields, storefront mode, in-app purchase redirect
  • Help - Help subjects and feedback
X

Graph View