Download

The HTTP surface, by journey

Contract docs/api-contract/http.md

Generated. Do not edit by hand. implementation_scripts/api_contract.py writes this file from the running FastAPI application; verification_scripts/test_api_contract.py regenerates it and fails on any difference. Regenerate with python -m implementation_scripts.api_contract --write.

207 routes, over 49 register rows: 44 rows are carried by at least one route and 5 are not. Every route appears in at least one table — the guard fails when one does not.

How to read a row

Auth. token means the request must carry Authorization: Bearer <this backend's token>, a loopback Host on this backend’s own port, and — when it is a browser request, which is to say when it carries an Origin — this app’s renderer origin. The MCP server and Electron’s main process send no Origin and are judged on the token alone. signed link means the guard lets the request past the token check and the route checks a per-destination HMAC instead. The full model, including what it does not defend, is local-api-security.md; the classes here are computed from api_auth.AUTH_EXEMPT_PATHS and api_auth.AUTH_SIGNED_PATHS rather than transcribed from that page.

SSE. yes means the handler answers with text/event-stream. The response is a sequence of events, not a JSON body, and a client that reads it with an ordinary fetch-and-parse will hang.

Purpose. The first line of the endpoint’s docstring, for the 114 of 207 routes that have one. The remaining 93 show FastAPI’s generated summary instead, in italics: it is the function’s own name with the underscores taken out, and it is here because an invented sentence would read like documentation without being any.

Response. The response_model the route declares, for the 171 of 207 routes that declare one — openapi.json carries its schema under that name, and a typed client can be generated from it. The remaining 36 show —: they declare no model, so openapi.json describes their 200 body as the empty schema {} and what they answer with is described in prose in README.md and in the five feature contracts beside this file. Nothing here guesses at a response shape.

A declared model is a lower bound on the body, not an exact description. Every one of them is an additionalProperties: true schema, because FastAPI filters a response against its model and a key nobody declared would otherwise be dropped from the reply silently; implementation_scripts/response_models.py sets that out in full and verification_scripts/test_response_models.py holds every model to it by comparing each route’s body with what its handler returned on the same request. So a client may rely on a declared field being there, and may not rely on there being nothing else.

What survives is the key. An undeclared value is re-serialized by pydantic rather than by FastAPI’s jsonable_encoder, and the two disagree for three types: a Decimal becomes a string rather than a float, a PurePath raises instead of serializing (the concrete Path beside it is fine, which is the trap), and inf/nan become a quiet null where an unmodeled route answered 500. None is reachable in the routes modeled today; the table and the test that keeps it true are in response_models.py, and anyone modeling a further route should read it first.

J01 — Deep Dive

MethodPathAuthSSEResponsePurpose
GET/api/executions/{exec_id}/progress/eventstoken——Get Execution Progress Events
GET/api/executions/{exec_id}/progress/streamtokenyes—Stream Progress
POST/api/search/divetoken—RunStartedSearch Dive
GET/api/search/repositoriestoken—listSearch Repositories

J02 — Deep Sweep

MethodPathAuthSSEResponsePurpose
GET/api/executions/{exec_id}/progress/eventstoken——Get Execution Progress Events
GET/api/executions/{exec_id}/progress/streamtokenyes—Stream Progress
GET/api/search/repositoriestoken—listSearch Repositories
POST/api/search/sweeptoken—RunStartedSearch Sweep

J03 — Routines

MethodPathAuthSSEResponsePurpose
GET/api/routinestoken—listList Routines
POST/api/routinestoken—RoutineCreatedCreate Routine
DELETE/api/routines/{routine_id}token——Delete Routine Endpoint
GET/api/routines/{routine_id}token—RoutineFetch a single routine by ID.
PUT/api/routines/{routine_id}token—RoutineUpdatedUpdate Routine Endpoint
POST/api/routines/{routine_id}/activatetoken—RoutineActivationActivate Routine
POST/api/routines/{routine_id}/deactivatetoken—RoutineActivationDeactivate Routine
GET/api/routines/{routine_id}/documentstoken—RoutineDocumentsThe papers this routine’s runs collected: a watch’s constellation.
POST/api/routines/{routine_id}/runtoken—RoutineRunStartedRun a routine immediately, outside its schedule.
GET/api/scheduler/jobstoken——Get Scheduler Jobs
GET/api/scheduler/statustoken—SchedulerStatusWhether this database’s active routines will fire, and what decides it.

J04 — Background daemon

MethodPathAuthSSEResponsePurpose
GET/api/scheduler/statustoken—SchedulerStatusWhether this database’s active routines will fire, and what decides it.
GET/api/service/daemon-statustoken—DaemonStatusReturn ground-truth daemon status read from daemon.lock.
POST/api/service/installtoken—ServiceInstalledRender the platform unit template and write it to the install path.
GET/api/service/statustoken—ServiceStatusReturn whether the daemon unit file is installed and its path.
POST/api/service/uninstalltoken—ServiceUninstalledRemove the unit file; optionally deregister with the OS first.

J05 — Analytics

MethodPathAuthSSEResponsePurpose
GET/api/analytics/discovery-lagtoken—DiscoveryLagMedian days between publication and resmon first seeing each paper.
GET/api/analytics/keyword-contributiontoken—KeywordContributionPer keyword: papers it found that no other keyword did.
GET/api/analytics/overviewtoken—AnalyticsOverviewEverything the Analytics page needs, in one round trip.
GET/api/analytics/publication-volumetoken—PublicationVolumePapers per publication month, split by source or subject category.
GET/api/analytics/routine-healthtoken—RoutineHealthPer routine: new results per run, and whether it has gone quiet.
GET/api/analytics/source-contributiontoken—SourceContributionPer source: papers delivered, and how many nothing else found.
GET/api/analytics/summarytoken—CorpusSummaryAnalytics Summary

J06 — Watchdog

MethodPathAuthSSEResponsePurpose
GET/api/documents/{doc_id}/lifecycletoken——Lifecycle events recorded against one paper.
GET/api/lifecycletoken—LifecycleReportRecorded lifecycle events, and how much of the corpus they cover.
POST/api/lifecycle/checktoken—LifecycleCheckStartedStart a bounded lifecycle check over the least recently checked papers.
POST/api/lifecycle/for-documentstoken—LifecycleForDocumentsLifecycle events for a page of results, in one round trip.
POST/api/lifecycle/stoptoken—LifecycleStopAnswerAsk a running check to stop before its next request.
GET/api/profiles/{profile_id}/lifecycletoken—WatchProfileLifecycleRetractions and other lifecycle findings on this profile’s papers.
GET/api/watchdogtoken—WatchdogReportFindings, what could not be judged yet, and the thresholds used.
POST/api/watchdog/mutetoken—WatchdogMuteAckAcknowledge one finding so it stops counting toward the alarm total.
POST/api/watchdog/unmutetoken—WatchdogMuteAckUn-acknowledge a finding, returning it to the alarm total.

J07 — Watch profiles

MethodPathAuthSSEResponsePurpose
GET/api/profilestoken—WatchProfileListList Watch Profiles
POST/api/profilestoken—WatchProfileCreate Watch Profile
POST/api/profiles/importtoken—WatchProfileImportResultImport one or more exported profiles.
POST/api/profiles/matches/for-documentstoken—WatchProfileMatchesByDocumentWhich watch profiles matched a page of papers, and on what basis.
GET/api/profiles/startertoken—StarterWatchProfileListThe curated set that ships with the app, not yet anybody’s profile.
DELETE/api/profiles/{profile_id}token—WatchProfileDeletedRemove a profile and its matches. The corpus is untouched.
GET/api/profiles/{profile_id}token—WatchProfileGet Watch Profile
PUT/api/profiles/{profile_id}token—WatchProfileUpdate Watch Profile
GET/api/profiles/{profile_id}/exporttoken—WatchProfileExportExport Watch Profile
GET/api/profiles/{profile_id}/lifecycletoken—WatchProfileLifecycleRetractions and other lifecycle findings on this profile’s papers.
GET/api/profiles/{profile_id}/matchestoken—WatchProfileMatchPagePapers matched to this profile, each with the basis it was matched on.

No route of its own. The capability is in the normaliser, the catalog’s entity_search syntax and api_base.search_entity; it reaches a user through the routes of J01, J02 and J07.

MethodPathAuthSSEResponsePurpose
GET/api/documents/{document_id}/similartoken——The papers nearest this one, with distances and their sources.
POST/api/embeddings/backfilltoken——Embed every document lacking a vector for the active model.
POST/api/embeddings/backfill/canceltoken——Stop after the batch in flight. Vectors already written are kept.
GET/api/embeddings/estimatetoken——What a backfill would cost, before it starts.
POST/api/embeddings/probetoken——Ask the configured (or supplied) lane to embed one short string.
POST/api/embeddings/rebuildtoken——Rebuild the vector index from the canonical table.
GET/api/embeddings/statustoken—EmbeddingStatusN of M embedded with model X, the run, the index, and the extension.
POST/api/explorer/searchtoken—ExplorerPageSearch the whole corpus. POST because the filter set is a structure.
GET/api/settings/embeddingstoken—EmbeddingSettingsPageThe stored settings, plus everything the tab needs to render honestly.
PUT/api/settings/embeddingstoken—EmbeddingSettingsSavedStore the settings, refusing a provider that cannot embed.
MethodPathAuthSSEResponsePurpose
GET/api/documents/{document_id}/linkstoken——What else in the corpus looks like the same work as this paper.
POST/api/links/collapse-previewtoken—CollapsePreviewWhich of these ids a collapse would fold, without folding anything.
POST/api/links/for-documentstoken—PaperLinksLinks for a page of results in one round trip.
POST/api/links/scantoken——Find near-duplicates across the corpus. Returns immediately.
POST/api/links/scan/canceltoken——Stop after the document in flight. Links already written are kept.
GET/api/links/statustoken——How many links are stored, by method, and the scan’s state.

J11 — Coverage audit

MethodPathAuthSSEResponsePurpose
GET/api/routines/{routine_id}/coveragetoken—RoutineCoverageIs this routine finding what its owner meant, and what is it missing?

J12 — Explorer

MethodPathAuthSSEResponsePurpose
GET/api/documents/{doc_id}token—PaperOne paper as stored, and where it stands in the reading queue.
GET/api/documents/{doc_id}/whytoken—PaperWhyWhat is locally verifiable about why this paper is in the corpus.
POST/api/explorer/exporttoken——Export everything matching the current filters, not just the page shown.
POST/api/explorer/facetstoken——Available filter values and their counts, for the current filters.
POST/api/explorer/searchtoken—ExplorerPageSearch the whole corpus. POST because the filter set is a structure.

J13 — The assistant (CLI lane)

MethodPathAuthSSEResponsePurpose
GET/api/ai/cli/sign-intoken—AiCliSignInAsk the command itself whether it is signed in. No model call, no cost.
POST/api/ai/cli/sign-intoken—AiCliSignInOpenedStart the command’s own login in a terminal, or say the command to run.
GET/api/ai/last-answeredtoken—AiLastAnsweredWhich model last answered each requested alias, from answers already kept.
POST/api/assistant/permissionstoken—AssistantPermissionDecisionAsk the person, and hold this request open until they answer.
POST/api/assistant/permissions/{request_id}token—AssistantPermissionAnsweredThe panel’s Allow / Deny.
GET/api/assistant/sessionstoken—AssistantSessionsList Assistant Sessions
POST/api/assistant/sessionstoken—AssistantSessionCreate Assistant Session
GET/api/assistant/sessions/{session_id}token—AssistantTranscriptGet Assistant Session
POST/api/assistant/sessions/{session_id}/canceltoken—AssistantTurnCancelledStop the running turn. Idempotent, and it says which happened.
POST/api/assistant/sessions/{session_id}/messagestokenyes—Send Assistant Message
GET/api/assistant/statustoken—AssistantStatusWhether the assistant can run, and if not, the reason in one sentence.
GET/api/settings/ai/cli-statustoken—AiCliStatusReport whether each subscription-lane CLI can be found, and where.
GET/api/settings/assistanttoken—AssistantSettingsGet Assistant Settings
PUT/api/settings/assistanttoken—SettingsSavedUpdate Assistant Settings

J14 — The assistant on a key

MethodPathAuthSSEResponsePurpose
POST/api/ai/modelstoken——Return the list of model IDs the BYOK credential can access.
GET/api/assistant/statustoken—AssistantStatusWhether the assistant can run, and if not, the reason in one sentence.

J15 — First-run card

MethodPathAuthSSEResponsePurpose
GET/api/onboardingtoken—OnboardingStateWhat the first-run card renders, as facts rather than as prose.
POST/api/onboarding/dismisstoken—OnboardingDismissedPut the card away for good.

J16 — Weekly live-network job

No route. A GitHub Actions workflow over verification_scripts/live_suite.py and live_quarantine.json.

J17 — AI summarization lanes

MethodPathAuthSSEResponsePurpose
GET/api/ai/cli/sign-intoken—AiCliSignInAsk the command itself whether it is signed in. No model call, no cost.
POST/api/ai/cli/sign-intoken—AiCliSignInOpenedStart the command’s own login in a terminal, or say the command to run.
GET/api/ai/last-answeredtoken—AiLastAnsweredWhich model last answered each requested alias, from answers already kept.
POST/api/ai/modelstoken——Return the list of model IDs the BYOK credential can access.
GET/api/settings/aitoken—AiSettingsGet Ai Settings
PUT/api/settings/aitoken—SettingsSavedUpdate Ai Settings

J18 — Reports and exports

MethodPathAuthSSEResponsePurpose
GET/api/executionstoken—listList Executions
POST/api/executions/archivetoken——The same archive POST /api/executions/export writes, as bytes.
POST/api/executions/exporttoken——Bundle the reports and logs for the selected executions into a .zip.
DELETE/api/executions/{exec_id}token——Delete a run’s record; its report and log files stay where they were written.
GET/api/executions/{exec_id}token—RunGet Execution
GET/api/executions/{exec_id}/bundletoken——One run’s bundle as bytes: the archive POST /api/executions/export writes.
GET/api/executions/{exec_id}/documentstoken—RunPapersPageOne page of the papers this run found, each with its stored id.
GET/api/executions/{exec_id}/logtoken—RunLogGet Execution Log
GET/api/executions/{exec_id}/referencestoken——Export one run; JSON can explicitly include corpus IDs for follow-up reads.
GET/api/executions/{exec_id}/reporttoken—RunReportGet Execution Report
GET/api/executions/{exec_id}/search-recordtoken——The complete, dated account of one search.
POST/api/export/referencestoken——Render one selection, with one entry per stored document ID.

J19 — Live monitoring

MethodPathAuthSSEResponsePurpose
GET/api/executions/activetoken—ActiveRunsActive Executions
POST/api/executions/{exec_id}/canceltoken—RunCancelRequestedRequest cooperative cancellation of a running execution.
GET/api/executions/{exec_id}/progress/eventstoken——Get Execution Progress Events
GET/api/executions/{exec_id}/progress/streamtokenyes—Stream Progress

J20 — Calendar

MethodPathAuthSSEResponsePurpose
GET/api/calendar/eventstoken—listCalendar Events

J21 — Saved configurations

MethodPathAuthSSEResponsePurpose
GET/api/configurationstoken—listList Configurations
POST/api/configurationstoken—ConfigurationCreatedCreate Configuration
POST/api/configurations/archivetoken——The same archive POST /api/configurations/export writes, as bytes.
POST/api/configurations/exporttoken—ConfigurationExportExport Configurations
POST/api/configurations/importtoken—ConfigurationImportResultImport Configurations
DELETE/api/configurations/{config_id}token—ConfigurationDeletedDelete Configuration Endpoint
PUT/api/configurations/{config_id}token—ConfigurationUpdatedUpdate Configuration Endpoint

J22 — Repositories and keys

MethodPathAuthSSEResponsePurpose
GET/api/credentialstoken—CredentialsPresenceReturn per-credential status for every known credential name.
POST/api/credentials/validatetoken——Test a key against its provider: one typed here, or the AI key already stored.
DELETE/api/credentials/{key_name}token—CredentialChangedDelete Credential Endpoint
PUT/api/credentials/{key_name}token—CredentialChangedStore Credential Endpoint
GET/api/repositories/catalogtoken—listReturn the static repository catalog (never returns secrets).
GET/api/search/repositoriestoken—listSearch Repositories

J23 — Notifications and email

MethodPathAuthSSEResponsePurpose
GET/api/settings/emailtoken—EmailSettingsGet Email Settings
PUT/api/settings/emailtoken—SettingsSavedUpdate Email Settings
POST/api/settings/email/testtoken—TestEmailSentSend a test email using the currently-stored SMTP settings.
GET/api/settings/notificationstoken—NotificationSettingsGet Notification Settings
PUT/api/settings/notificationstoken—SettingsSavedUpdate Notification Settings

J24 — Google Drive backup

MethodPathAuthSSEResponsePurpose
POST/api/backuptoken—BackupWrittenWrite one bundle: the snapshotted database, the vault’s bytes, optionally reports.
POST/api/backup/drive-upload-notice/acknowledgetoken—DriveUploadNoticeAcknowledgedDismiss the notice that the upload to Google Drive is gone, by deleting the settings it is read from.
GET/api/backup/lasttoken—BackupLastThe last bundle, the last restore outcome, and whether an undo copy exists.
GET/api/settings/storagetoken—StorageSettingsGet Storage Settings
PUT/api/settings/storagetoken—SettingsSavedUpdate Storage Settings

J25 — In-app documentation

No route. The tutorials and every PageHelp entry are renderer assets, shipped inside the app rather than fetched.

J26 — Danger Zone

MethodPathAuthSSEResponsePurpose
POST/api/admin/erase-ai-keystoken—AiKeysErasedAdmin Erase Ai Keys
POST/api/admin/erase-app-datatoken—AppDataErasedErase the corpus + configs + executions + every API key.
POST/api/admin/erase-configstoken—ConfigurationsErasedAdmin Erase Configs
POST/api/admin/erase-corpustoken—CorpusErasedErase every collected paper. Executions, configs and keys are kept.
POST/api/admin/erase-execution-datatoken—ExecutionDataErasedErase all configs + all executions. Settings and API keys untouched.
POST/api/admin/erase-executionstoken—ExecutionsErasedAdmin Erase Executions
POST/api/admin/erase-repo-keystoken—RepositoryKeysErasedAdmin Erase Repo Keys
POST/api/admin/factory-resettoken—FactoryResetErase every secret, config, execution, setting, and collected paper.
POST/api/admin/reset-settingstoken—SettingsResetReset every setting plus erase every API key. Configs/executions kept.

J27 — Citation graph

No route. Recorded in the register as not carried forward.

J28 — Reading queue

MethodPathAuthSSEResponsePurpose
GET/api/reading-queuetoken—ReadingQueuePageOne page of saved papers. status omitted (or all) means both.
POST/api/reading-queuetoken—ReadingQueueEntrySave a stored paper. Saving one already saved returns it unchanged.
DELETE/api/reading-queue/{document_id}token—ReadingQueueRemovalTake a paper out of the queue. The paper itself is not touched.
PUT/api/reading-queue/{document_id}token—ReadingQueueEntryMark a saved paper read or unread.

J29 — Recorded-source coverage

MethodPathAuthSSEResponsePurpose
GET/api/coverage/source-walltoken—SourceWallEvery source’s recorded answer to each of the last limit runs.
GET/api/executions/{exec_id}token—RunGet Execution
GET/api/executions/{exec_id}/search-recordtoken——The complete, dated account of one search.

J30 — Runtime identity

MethodPathAuthSSEResponsePurpose
GET/api/healthtoken—HealthLiveness endpoint. Returns process identity so clients can attach-or-spawn.
POST/api/renderer/heartbeattoken—RendererHeartbeatRenderer-presence ping.

J31 — Readable Ask

MethodPathAuthSSEResponsePurpose
POST/api/assistant/sessions/{session_id}/messagestokenyes—Send Assistant Message

J32 — Chats and export

MethodPathAuthSSEResponsePurpose
GET/api/assistant/sessionstoken—AssistantSessionsList Assistant Sessions
GET/api/assistant/sessions/browsetoken—AssistantSessionPageBrowse Assistant Sessions
DELETE/api/assistant/sessions/{session_id}token—AssistantSessionDeletedDelete Assistant Session
GET/api/assistant/sessions/{session_id}token—AssistantTranscriptGet Assistant Session
GET/api/assistant/sessions/{session_id}/exporttoken—AssistantExportExport Assistant Session

J33 — Composer choices

MethodPathAuthSSEResponsePurpose
POST/api/assistant/sessions/{session_id}/messagestokenyes—Send Assistant Message

J34 — Owned Library

MethodPathAuthSSEResponsePurpose
GET/api/librarytoken—LibraryStatusLibrary Status
GET/api/library/exporttoken—LibraryInventoryLibrary Inventory
GET/api/library/filestoken—LibraryFilesLibrary List
POST/api/library/filestoken—LibraryImportedLibrary Import
GET/api/library/files/{file_id}token—LibraryFileDetailLibrary Detail
POST/api/library/files/{file_id}/opentoken—LibraryOpenedLibrary Open
POST/api/library/files/{file_id}/paper-linkstoken—LibraryLinkedLibrary Link
GET/api/library/files/{file_id}/shared-wordingtoken—SharedWordingLibraryThe last comparison of this file since the engine started, or that there is none.
POST/api/library/files/{file_id}/shared-wordingtoken—SharedWordingLibraryCompare this file, page by page, with the abstracts and the other Library files.
GET/api/library/files/{file_id}/texttoken—LibraryTextLibrary Read Text
POST/api/library/vaulttoken—LibraryStatusLibrary Create Vault

J35 — Evidence workspace

MethodPathAuthSSEResponsePurpose
GET/api/evidence/projectstoken—EvidenceProjectsEvidence Projects
POST/api/evidence/projectstoken—EvidenceProjectDetailEvidence Create Project
GET/api/evidence/projects/{project_id}token—EvidenceProjectDetailEvidence Project Detail
PATCH/api/evidence/projects/{project_id}token—EvidenceProjectDetailEvidence Rename Project
POST/api/evidence/projects/{project_id}/bundletoken——Evidence Bundle
GET/api/evidence/projects/{project_id}/filestoken—EvidenceMembersEvidence Files
POST/api/evidence/projects/{project_id}/filestoken—EvidenceMemberAddedEvidence Add File
DELETE/api/evidence/projects/{project_id}/files/{file_id}token—EvidenceMemberRemovedEvidence Remove File
GET/api/evidence/projects/{project_id}/notestoken—EvidenceNotesEvidence Notes
POST/api/evidence/projects/{project_id}/notestoken—EvidenceNoteSavedEvidence Create Note
PATCH/api/evidence/projects/{project_id}/notes/{note_id}token—EvidenceNoteSavedEvidence Edit Note
GET/api/evidence/projects/{project_id}/reader/{file_id}token—EvidencePageTextEvidence Read

J36 — Selected-evidence answers

MethodPathAuthSSEResponsePurpose
POST/api/evidence/projects/{project_id}/answer-previewstoken—SelectedPreviewSelected Answer Preview
GET/api/evidence/projects/{project_id}/answerstoken—SelectedAnswersSelected Answer History
POST/api/evidence/projects/{project_id}/answerstoken—SelectedAnswerSelected Answer Send
GET/api/evidence/projects/{project_id}/answers/{answer_id}token—SelectedAnswerSelected Answer Detail
POST/api/evidence/projects/{project_id}/answers/{answer_id}/canceltoken—SelectedAnswerSelected Answer Cancel
GET/api/evidence/projects/{project_id}/answers/{answer_id}/eventstokenyes—Selected Answer Events
GET/api/evidence/projects/{project_id}/answers/{answer_id}/exporttoken——Selected Answer Export

J37 — Portable saved-answer HTML

MethodPathAuthSSEResponsePurpose
GET/api/evidence/projects/{project_id}/answers/{answer_id}/exporttoken——Selected Answer Export

J38 — Interrupted runs and Restart

MethodPathAuthSSEResponsePurpose
GET/api/executions/{exec_id}token—RunGet Execution
POST/api/executions/{exec_id}/restarttoken—RunRestartedStart a fresh execution with the source’s parameters, linked back to it.
POST/api/renderer/heartbeattoken—RendererHeartbeatRenderer-presence ping.

J39 — One run per routine, one per submission, missed fires

MethodPathAuthSSEResponsePurpose
GET/api/routines/{routine_id}token—RoutineFetch a single routine by ID.
POST/api/routines/{routine_id}/runtoken—RoutineRunStartedRun a routine immediately, outside its schedule.
POST/api/search/divetoken—RunStartedSearch Dive
POST/api/search/sweeptoken—RunStartedSearch Sweep
GET/api/settings/executiontoken—ExecutionSettingsGet Execution Settings
PUT/api/settings/executiontoken—ExecutionSettingsSavedUpdate Execution Settings

J40 — Delivery: where a report goes, and whether it got there

MethodPathAuthSSEResponsePurpose
GET/api/deliveries/{delivery_id}/bundlesigned link——The report bundle a webhook envelope linked to, for whoever holds the link.
POST/api/deliveries/{delivery_id}/delivertoken—DeliveryActedRelease a delivery that was waiting for review. The only promotion.
POST/api/deliveries/{delivery_id}/retrytoken—DeliveryActedStart the attempt sequence again, after the backoff has given up.
POST/api/deliveries/{delivery_id}/skiptoken—DeliveryActedSkip Delivery
GET/api/executions/{exec_id}/deliveriestoken——List Execution Deliveries
GET/api/routines/{routine_id}/deliveriestoken—RoutineDeliveriesList Routine Deliveries
GET/api/routines/{routine_id}/delivery-targetstoken—DeliveryTargetsList Routine Delivery Targets
POST/api/routines/{routine_id}/delivery-targetstoken—DeliveryTargetAddedAdd Routine Delivery Target
DELETE/api/routines/{routine_id}/delivery-targets/{target_id}token——Delete Routine Delivery Target
PUT/api/routines/{routine_id}/delivery-targets/{target_id}token——Update Routine Delivery Target

J41 — Backup and restore

MethodPathAuthSSEResponsePurpose
POST/api/backuptoken—BackupWrittenWrite one bundle: the snapshotted database, the vault’s bytes, optionally reports.
GET/api/backup/lasttoken—BackupLastThe last bundle, the last restore outcome, and whether an undo copy exists.
POST/api/backup/verifytoken—BundleReportRecompute every hash and report what a restore would and would not do.
POST/api/restoretoken—RestoreStagedVerify a bundle and stage it. The restore itself happens on the next start.
POST/api/restore/acknowledgetoken—RestoreAcknowledgedDismiss the one-time “what a restore did not bring back” card.
POST/api/restore/canceltoken—RestoreCancelledForget a staged restore. Nothing had been moved yet, so nothing is undone.
POST/api/restore/undo-copy/deletetoken—RestoreUndoCopiesDeletedDelete the database copies a restore set aside. Irreversible, so confirm-gated.
GET/api/settings/storagetoken—StorageSettingsGet Storage Settings
PUT/api/settings/storagetoken—SettingsSavedUpdate Storage Settings

J42 — Local API locked to this app

MethodPathAuthSSEResponsePurpose
POST/api/auth/renderer-origintoken——Allow one more exact renderer origin on this backend.
GET/api/deliveries/{delivery_id}/bundlesigned link——The report bundle a webhook envelope linked to, for whoever holds the link.

The guard is in front of all 207 routes, not only the two listed here: AUTH_EXEMPT_PATHS is an explicitly empty constant and a test fails if it grows. The two rows above are the routes that are about the guard — the one that registers a renderer origin (and refuses to do so for a request carrying an Origin, because a browser must not be able to widen the allowlist), and the one route that proves itself with a signature instead of the token.

J43 — Upgrade in place

No route. Migrations run inside database.init_db at start; the journey is exercised by test_cumulative_upgrade.py against the committed upgrade fixtures.

J44 — Driving resmon from an external harness (MCP)

MethodPathAuthSSEResponsePurpose
GET/api/analytics/discovery-lagtoken—DiscoveryLagMedian days between publication and resmon first seeing each paper.
GET/api/analytics/keyword-contributiontoken—KeywordContributionPer keyword: papers it found that no other keyword did.
GET/api/analytics/overviewtoken—AnalyticsOverviewEverything the Analytics page needs, in one round trip.
GET/api/analytics/publication-volumetoken—PublicationVolumePapers per publication month, split by source or subject category.
GET/api/analytics/routine-healthtoken—RoutineHealthPer routine: new results per run, and whether it has gone quiet.
GET/api/analytics/source-contributiontoken—SourceContributionPer source: papers delivered, and how many nothing else found.
GET/api/credentialstoken—CredentialsPresenceReturn per-credential status for every known credential name.
GET/api/documents/{doc_id}/lifecycletoken——Lifecycle events recorded against one paper.
GET/api/documents/{doc_id}/whytoken—PaperWhyWhat is locally verifiable about why this paper is in the corpus.
GET/api/documents/{document_id}/similartoken——The papers nearest this one, with distances and their sources.
GET/api/executionstoken—listList Executions
GET/api/executions/{exec_id}token—RunGet Execution
GET/api/executions/{exec_id}/referencestoken——Export one run; JSON can explicitly include corpus IDs for follow-up reads.
GET/api/executions/{exec_id}/search-recordtoken——The complete, dated account of one search.
POST/api/explorer/searchtoken—ExplorerPageSearch the whole corpus. POST because the filter set is a structure.
POST/api/export/referencestoken——Render one selection, with one entry per stored document ID.
GET/api/healthtoken—HealthLiveness endpoint. Returns process identity so clients can attach-or-spawn.
GET/api/profilestoken—WatchProfileListList Watch Profiles
POST/api/profilestoken—WatchProfileCreate Watch Profile
GET/api/profiles/{profile_id}token—WatchProfileGet Watch Profile
GET/api/profiles/{profile_id}/matchestoken—WatchProfileMatchPagePapers matched to this profile, each with the basis it was matched on.
GET/api/repositories/catalogtoken—listReturn the static repository catalog (never returns secrets).
GET/api/routinestoken—listList Routines
POST/api/routinestoken—RoutineCreatedCreate Routine
GET/api/routines/{routine_id}token—RoutineFetch a single routine by ID.
POST/api/routines/{routine_id}/activatetoken—RoutineActivationActivate Routine
GET/api/routines/{routine_id}/coveragetoken—RoutineCoverageIs this routine finding what its owner meant, and what is it missing?
POST/api/routines/{routine_id}/deactivatetoken—RoutineActivationDeactivate Routine
GET/api/routines/{routine_id}/deliveriestoken—RoutineDeliveriesList Routine Deliveries
POST/api/routines/{routine_id}/runtoken—RoutineRunStartedRun a routine immediately, outside its schedule.
POST/api/search/sweeptoken—RunStartedSearch Sweep
GET/api/watchdogtoken—WatchdogReportFindings, what could not be judged yet, and the thresholds used.

Read out of resmon_scripts/mcp_server.py rather than transcribed: api_contract.mcp_driven_routes() parses every backend.request(method, path) call in that module — method included, so a path the harness only reads does not appear here as a path it also deletes — and matches each against the route table.

Calls in mcp_server.py that resolve to no single route, and so are not in the table above: GET /api/settings/{}, PUT /api/settings/{}. The settings path is built from a tool argument and reaches the GET/PUT /api/settings/* routes; it is named here rather than dropped, because a table that quietly omits what it could not read is worse than one that says so.

J45 — Source wall: what every source did on recent runs

MethodPathAuthSSEResponsePurpose
GET/api/coverage/source-walltoken—SourceWallEvery source’s recorded answer to each of the last limit runs.

J46 — Appearance: theme and accent

MethodPathAuthSSEResponsePurpose
GET/api/appearancetoken—AppearanceGet Appearance
PUT/api/appearancetoken—AppearanceUpdate Appearance

J47 — Collection map: where every paper sits

MethodPathAuthSSEResponsePurpose
POST/api/documents/briefstoken—listA line about each paper asked for, for the plate’s hover: title, authors,
GET/api/executions/{exec_id}/document-idstoken—RunDocumentIdsEvery paper this run stored that is still in the collection, by id.
GET/api/maptoken—CollectionMapWhere every paper sits on the Atlas plate, and on what basis.
GET/api/map/facetstoken—MapFacetsWhat the map’s filters and colors read about every paper: its source,
GET/api/map/findtoken—MapFindThe papers whose title or authors contain q, newest first, for
GET/api/map/views/{name}token—MapViewThe filters and colors a map was last left with, and how the list
PUT/api/map/views/{name}token—MapViewPut Map View

J48 — Today: the papers since you last looked

MethodPathAuthSSEResponsePurpose
POST/api/documents/briefstoken—listA line about each paper asked for, for the plate’s hover: title, authors,
GET/api/todaytoken—TodayThe papers resmon first collected since Today was last looked at, by watch.
POST/api/today/lookedtoken—TodayLookedRecord that Today was looked at now: the next window starts here.

J49 — Shared wording across papers

MethodPathAuthSSEResponsePurpose
GET/api/library/files/{file_id}/shared-wordingtoken—SharedWordingLibraryThe last comparison of this file since the engine started, or that there is none.
POST/api/library/files/{file_id}/shared-wordingtoken—SharedWordingLibraryCompare this file, page by page, with the abstracts and the other Library files.
GET/api/shared-wordingtoken—SharedWordingThe last scan, the scan in progress, and the pairs it found by group.
GET/api/shared-wording/pairs/{a}/{b}token—SharedWordingPairTwo abstracts side by side, the passages they share, and the numbers.
GET/api/shared-wording/papers/{document_id}token—SharedWordingForPaperThe pairs one paper is in, for its page.
POST/api/shared-wording/scantoken—SharedWordingJobCompare every abstract with every other, in the background. Returns at once.
POST/api/shared-wording/scan/canceltoken—SharedWordingCancelStop the scan in progress. The answer stored before it is kept.

Closed vocabularies

Every list below is generated from the object named beside it and tested equal to it. A value added to the code and not to this file, or to this file and not to the code, is a failing test.

Execution status — from the executions.status CHECK in database._EXECUTIONS_V19_DDL. 5 values:

running · completed · failed · cancelled · interrupted

Interrupted reason — from database.INTERRUPTED_REASONS. 3 values:

owner_dead · daemon_restart · unknown

Zero reason — from zero_reason.ZERO_REASONS. 11 values:

missing_key · retired · window_unanswerable · upstream_failure · parse_failure · rights_filtered · records_unusable · entity_unsupported · answered_in_part · answered_empty · not_recorded

Zero reasons that mean the source did not answer — from zero_reason.DID_NOT_ANSWER. 6 values:

entity_unsupported · missing_key · parse_failure · retired · upstream_failure · window_unanswerable

Delivery state — from database.DELIVERY_STATES. 6 values:

queued · awaiting_review · delivering · delivered · failed · skipped

Delivery channel — from database.DELIVERY_CHANNELS. 4 values:

email · folder · webhook · feed

Delivery channels with an adapter behind them — from delivery.SHIPPED_CHANNELS. 4 values:

email · folder · webhook · feed

Delivery target mode — from database.DELIVERY_TARGET_MODES. 2 values:

automatic · review

Guard refusal — from the _refusal(...) calls in api_auth.check. 4 values:

401 token_invalid · 401 token_missing · 403 host_refused · 403 origin_refused

NULL is a fourth value interrupted_reason may hold, and means the row was never interrupted rather than that the reason was lost. not_recorded is the tenth zero reason and means resmon did not observe why the source returned nothing; it is not a reason, and it is never rendered as one.

Admission, and the one 429

POST /api/search/dive and POST /api/search/sweep are refused 429 when the admission controller has no free slot for a manual run. The body is FastAPI’s ordinary {"detail": "<sentence>"} — a sentence naming the current cap, not a code — and the answer carries Retry-After: 5. A resubmission of a run that is already going is answered with that run instead, before the cap is consulted: it is not new demand on capacity. Routine fires are not refused; they queue. The controller is implementation_scripts/admission.py, and the cap is GET/PUT /api/settings/execution.