Skip to content

Management API Contract

Status: supported portal contract · Tracking: AB#7666

The Project Marvin portal uses the same-origin /marvin-api management API. With the exception of bootstrap, authentication callbacks, and provider webhooks, every operation requires an authenticated workspace session.

Response envelopes

Successful JSON operations return an object with ok: true and operation-specific fields. Callers must ignore additional fields so the contract can be extended compatibly.

Errors use one stable envelope:

json
{
  "ok": false,
  "code": "VALIDATION_ERROR",
  "error": "Missing required fields: profileName",
  "action": "Complete the required fields and try again.",
  "retryable": false
}

code is machine-readable. error and action are safe operator-facing text. retryable indicates whether repeating the same operation without changing input may succeed. Authentication failures additionally return requiresLogin: true.

Portal operations

Method and pathAuthenticationRequestSuccessful response
GET /marvin-api/bootstrapNoNoneDeployment, authentication, operator, and current redacted configuration state
GET /marvin-api/auth/entra/startNoNoneRedirect to Microsoft Entra
GET /marvin-api/auth/entra/callbackNoEntra callback queryBound session cookie and redirect to the portal
POST /marvin-api/auth/devLoopback development onlyEmpty objectLocal development session; always unavailable in hosted mode
POST /marvin-api/logoutOptionalEmpty objectCleared session cookie
GET /marvin-api/config?profileName=YesProfile queryRedacted effective configuration and readiness evidence
POST /marvin-api/save-configYesWorkspace configurationPersisted redacted configuration
POST /marvin-api/account-upsertYesprofileName, account, optional configuration fieldsUpdated redacted configuration
POST /marvin-api/account-removeYesprofileName, accountIdUpdated configuration; this operation does not delete provider events
GET /marvin-api/connections?profileName=YesProfile queryConnection and redacted token-status evidence
POST /marvin-api/connection-beginYesprofileName, calendarIdProvider launch URL or validation result
POST /marvin-api/connection-updateYesConnection state updateUpdated redacted configuration
POST /marvin-api/microsoft/discoverYesprofileName, calendarIdVerified Graph identity and discovered calendar metadata
POST /marvin-api/microsoft/confirm-identityYesprofileName, calendarId, confirmed: trueExplicit mismatch confirmation and updated configuration
POST /marvin-api/microsoft/select-calendarsYesprofileName, calendarId, writable providerCalendarIdsStable provider-calendar selections and updated configuration
POST /marvin-api/microsoft/capabilitiesYesprofileName, calendarIdSeparate non-mutating read, write, refresh, and subscription results
POST /marvin-api/apple/discoverYesprofileName, calendarIdCalDAV principal, calendar home, and collection discovery metadata
POST /marvin-api/apple/select-calendarsYesprofileName, calendarId, writable providerCalendarIdsStable Apple collection selections and updated configuration
POST /marvin-api/apple/capabilitiesYesprofileName, calendarIdNon-mutating authentication, discovery, read, write, and polling evidence
POST /marvin-api/connection-validateYesprofileName, calendarIdLive capability result and configuration
POST /marvin-api/connection-validate-allYesprofileNamePer-calendar validation results and summary
GET /marvin-api/provider-requirements?profileName=YesProfile queryRequired provider deployment configuration
GET /marvin-api/provider-plan?profileName=&provider=YesProfile and provider querySafe registration plan without secret values
POST /marvin-api/provider-configYesProvider public configuration and secret inputsRedacted effective configuration
GET /marvin-api/runtime-status?profileName=YesProfile queryRuntime process, activity, and subscription evidence
POST /marvin-api/runtime-startYesprofileNameRuntime process and configuration; rejected until readiness passes
POST /marvin-api/runtime-stopYesprofileNameIdempotent stopped runtime evidence
POST /marvin-api/runtime-retryYesprofileNameQueued idempotent reconciliation for the most recent failed calendars
GET /api/health/liveNoNoneMinimal process liveness without workspace metadata
GET /api/health/readyNoNoneRedacted ready, setup-required, attention, or degraded state
GET /marvin-api/healthYesNoneRedacted runtime, poll, token, subscription, and alert metrics
POST /marvin-api/deployYes, local onlyDeployment inputsDeployment result; hosted self-deployment is forbidden

Health ready indicates that the management service can safely accept traffic. Use state and the redacted provider metrics to assess calendar operations: attention with PROVIDER_AUTH_REQUIRED means the portal and runtime are available but one or more configured calendars still needs authorization, calendar selection, or capability validation. Only state: ready means every configured calendar currently has the required provider evidence.

OAuth calendar callbacks are provider-facing browser routes under /marvin-api/oauth/{provider}. Microsoft and Google webhook routes are unauthenticated provider callbacks and validate provider-specific notification material before queuing work.

Stable error codes

CodeMeaningRetry behavior
AUTH_REQUIREDNo valid workspace sessionSign in, then retry
FORBIDDENAuthenticated operation or path is not allowedDo not retry unchanged
NOT_FOUNDProfile, calendar, connection, or route does not existRefresh or select an existing resource
VALIDATION_ERRORRequired or formatted input is invalidCorrect input, then retry
READINESS_REQUIREDRuntime prerequisites are incompleteComplete the returned readiness actions
UNSUPPORTED_OPERATIONProvider or operation is outside the supported contractDo not retry unchanged
CONFLICTCurrent state conflicts with the commandRefresh evidence before deciding whether to retry
PROVIDER_UNAVAILABLEA provider returned a transient failureRetry with backoff
INTERNAL_ERRORUnexpected server failureRetry once, then use Diagnostics

Compatibility rules

  • Existing fields are not renamed or removed without a versioned migration.
  • Secret values are accepted only in request bodies and are never returned.
  • New optional response fields are backward-compatible.
  • Calendar removal is configuration-only; provider event deletion is a separate engine-owned operation and is never implied by this API.