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.
Download .md
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:
Layer Purpose 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)
Header Description Required AuthorizationBearer {jwt_token}All authenticated endpoints X-Farfalla-Tenant-IdTenant ID for single-tenant endpoints Single-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 string Optional, help/feedback X-FeniceBase-VersionFenice base framework version Optional, help/feedback Acceptapplication/jsonAll endpoints Content-Typeapplication/jsonPOST/PUT endpoints
Used by library and search endpoints:
{ "meta" : { "current_page" : 1 , "from" : 1 , "to" : 10 , "last_page" : 5 , "per_page" : 10 , "total" : 48 } }
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
Code Meaning 200 Success 201 Created (login init, help request) 204 No Content (feature disabled, unsubscribe) 401 Unauthenticated (invalid/expired JWT) 404 Not Found 412 Precondition Failed (wrong tenant header mode) 422 Validation Error 500 Server 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
Method Endpoint Description 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
Method Endpoint Tenant Mode Description GET /userMulti User profile and tenant list GET /user/continue-readingMulti Continue reading across tenants GET /user/my-contentMulti All accessible content across tenants (paginated) POST /user/push-notificationsMulti Register FCM token DELETE /user/push-notificationsMulti Unregister FCM token
Tenants
Method Endpoint Tenant Mode Description GET /tenantsMulti List tenants the user could sign up for (filter by country, name, cursor)
Library
Method Endpoint Tenant Mode Description GET /librarySingle Library shelves and sections (supports scope=all for storefront mode) GET /library/filterSingle Filtered library section (supports scope=all for storefront mode) GET /library/{issue}/favorite-issuesSingle Check if issue is favorited POST /library/{issue}/favorite-issuesSingle Toggle favorite status
Search
Method Endpoint Tenant Mode Description GET /search/storeSingle Search within one tenant (supports scope=all for storefront mode) GET /search/globalMulti Search across all tenants
Commerce
Method Endpoint Tenant Mode Description GET /app/purchase/{tenant_id}/{issue_id}Single In-app purchase redirect (web route, not under /api/v2/). Coming soon, see Commerce
Reader
Method Endpoint Tenant Mode Description POST /reader/{issue}/sessionsSingle Create reader session GET /reader/settings/{issue}Single Reader configuration for issue PUT /reader/settingsSingle Update user reader preferences PUT /reader/{issue}/last-locationSingle Save reading position GET /reader/issue-text-contentSingle Search text within an issue
Notes
Method Endpoint Tenant Mode Description GET /reader/notesSingle List notes for current issue POST /reader/notesSingle Create highlight/annotation PUT /reader/notes/{note}Single Update note color/annotation DELETE /reader/notes/{note}Single Delete a note
Integrations
Method Endpoint Tenant Mode Description GET /reader/integrations/ai-integrationsSingle List available AI actions POST /reader/integrations/ai-integrationsSingle Perform AI action on text PUT /reader/integrations/ai-integrationsSingle Rate AI response POST /reader/integrations/listenSingle Text-to-speech POST /reader/integrations/dictionarySingle Dictionary lookup POST /reader/integrations/translateSingle Translate text
Content
Method Endpoint Tenant Mode Description GET /content/{issue}/downloadSingle Download data for offline reading
Settings
Method Endpoint Tenant Mode Description GET /settingsMulti Mobile 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
Method Endpoint Tenant Mode Description GET /helpMulti List help/support subjects POST /helpMulti Submit 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