API
The application exposes several API endpoints for frontend interactivity and external integrations.
Authentication
Devise (User Session)
All API controllers inherit from API::BaseController (app/controllers/api/base_controller.rb), which enforces authenticate_user! via Devise. Requests must include a valid session cookie.
The API::V1::StudyEventsController skips CSRF verification to support external clients (e.g., Anki desktop/mobile).
API Key (Runtime)
The APIKeyAuth concern (app/controllers/concerns/api_key_auth.rb) provides header-based authentication via X-API-Key. It uses secure comparison against Rails.configuration.x.langruntime.api_key.
Endpoints
Study Events – POST /api/v1/study_events
Logs study activity from external clients (Anki sync, mobile apps).
Controller: API::V1::StudyEventsController
Parameters:
- Single resource:
resource_type,resource_id - Multi-resource:
resources[]array withresource_type,resource_id - Metadata:
event_type,source,modality,happened_at - Scheduling:
ease_button,interval_days,review_type,total_reviews,lapses
Whitelisted resource types: Sentence, Conjugation, VerbLemma, GrammarNote, Infinitive
Response: { success: true, events_created: N, ids: [...] }
Document Translation – GET /api/frontend/documents/document_sentences/:id/translate
Translates a document sentence on demand.
Controller: API::Frontend::Documents::DocumentSentencesController
Response: { id, audio_url, translatedContent }
Calls Resources::API::TranslateTextService if no translation exists, enqueues RelateDocumentSentenceJob asynchronously, ensures audio via Resources::API::AttachAudioService, returns a signed audio URL.
Word Translation – GET /api/frontend/documents/document_words/:id/translate
Same pattern as sentence translation but for individual words.
Controller: API::Frontend::Documents::DocumentWordsController
Audio Generation – POST /api/resources/audio
Generates TTS audio for a resource and returns a signed URL.
Controller: API::Resources::AudioController
Parameters:
resource_type– Conjugation, Sentence, or Wordresource_idtext_field– optional (auto-detected); whitelisted: “sentence”, “conjugation”, “word”
Response: { success: true, audio_url } or error
Routes
Defined in config/routes/api.rb:
namespace :api do
namespace :v1 do
resources :study_events, only: [:create]
end
namespace :frontend do
namespace :documents do
resources :document_sentences, only: [] do
member { get :translate }
end
resources :document_words, only: [] do
member { get :translate }
end
end
end
namespace :resources do
resources :audio, only: [:create]
end
end
Response Patterns
- Success:
200 :okor201 :createdwith JSON body - Client error:
400 :bad_requestor404 :not_found - Server error:
500 :internal_server_error - Audio URLs are signed ActiveStorage links with expiration