medianfi-com Recommendations API

The Recommendations API from medianfi-com — 11 operation(s) for recommendations.

Operations 17

GET /companies/{companyId}/recommendations List recommendations for a company #
POST /companies/{companyId}/recommendations Create a recommendation #
GET /companies/{companyId}/recommendations/activity List recent recommendation activity for the Insights rail #
GET /companies/{companyId}/recommendations/{id} Get a recommendation by ID #
PATCH /companies/{companyId}/recommendations/{id} Update a recommendation #
DELETE /companies/{companyId}/recommendations/{id} Delete a recommendation #
POST /companies/{companyId}/recommendations/{id}/pin Pin a recommendation #
DELETE /companies/{companyId}/recommendations/{id}/pin Unpin a recommendation #
POST /companies/{companyId}/recommendations/{id}/suppress Suppress a recommendation temporarily #
POST /companies/{companyId}/recommendations/{id}/dismiss-with-reason Dismiss a recommendation with a nonblank reason #
GET /accountant/companies/{customerId}/recommendations List recommendations for an assigned customer #
POST /accountant/companies/{customerId}/recommendations Add an accountant-authored recommendation for an assigned customer #
POST /accountant/companies/{customerId}/recommendations/{id}/pin Pin a customer recommendation as an accountant #
DELETE /accountant/companies/{customerId}/recommendations/{id}/pin Unpin a customer recommendation as an accountant #
POST /accountant/companies/{customerId}/recommendations/{id}/suppress Snooze a customer recommendation as an accountant #
POST /accountant/companies/{customerId}/recommendations/{id}/note Add an accountant note to a customer recommendation #
POST /accountant/companies/{customerId}/recommendations/{id}/customer-action-expected Mark whether a customer recommendation expects founder action #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/medianfi-com:medianfi-com-recommendations-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

medianfi-com-recommendations-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Median Recommendations API
  version: 0.1.0
  description: Production-grade Node.js + Express API starter template
  license:
    name: Proprietary
servers:
- url: /api/v1
security: []
tags:
- name: Recommendations
paths:
  /companies/{companyId}/recommendations:
    parameters:
    - $ref: '#/components/parameters/companyId'
    get:
      operationId: listRecommendations
      summary: List recommendations for a company
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      parameters:
      - $ref: '#/components/parameters/limit'
      - $ref: '#/components/parameters/cursor'
      - name: status
        in: query
        schema:
          type: string
          enum:
          - pending
          - active
          - completed
          - dismissed
      - name: category
        in: query
        schema:
          type: string
      - name: pinned
        in: query
        schema:
          type: boolean
      - name: excludeSuppressed
        in: query
        schema:
          type: boolean
          default: true
      responses:
        '200':
          description: Paginated list of recommendations
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationsListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
    post:
      operationId: createRecommendation
      summary: Create a recommendation
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateRecommendationInput'
      responses:
        '201':
          description: Recommendation created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /companies/{companyId}/recommendations/activity:
    parameters:
    - $ref: '#/components/parameters/companyId'
    get:
      operationId: listRecommendationActivity
      summary: List recent recommendation activity for the Insights rail
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      parameters:
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 25
          default: 10
      responses:
        '200':
          description: Sanitized recommendation audit activity
          content:
            application/json:
              schema:
                type: object
                required:
                - success
                - data
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      type: object
                      required:
                      - id
                      - recommendationId
                      - actor
                      - action
                      - summary
                      - timestamp
                      properties:
                        id:
                          type: string
                          format: uuid
                        recommendationId:
                          type: string
                          format: uuid
                        actor:
                          type: string
                          enum:
                          - accountant
                          - founder
                          - system
                        action:
                          type: string
                        summary:
                          type: string
                        timestamp:
                          type: string
                          format: date-time
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
  /companies/{companyId}/recommendations/{id}:
    parameters:
    - $ref: '#/components/parameters/companyId'
    - $ref: '#/components/parameters/resourceId'
    get:
      operationId: getRecommendation
      summary: Get a recommendation by ID
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Recommendation found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: Recommendation not found
    patch:
      operationId: updateRecommendation
      summary: Update a recommendation
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateRecommendationInput'
      responses:
        '200':
          description: Recommendation updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: Recommendation not found
        '422':
          $ref: '#/components/responses/ValidationError'
    delete:
      operationId: deleteRecommendation
      summary: Delete a recommendation
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      responses:
        '204':
          description: Recommendation deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: Recommendation not found
  /companies/{companyId}/recommendations/{id}/pin:
    parameters:
    - $ref: '#/components/parameters/companyId'
    - $ref: '#/components/parameters/resourceId'
    post:
      operationId: pinRecommendation
      summary: Pin a recommendation
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                role:
                  type: string
                  enum:
                  - founder
                  - accountant
                  default: founder
      responses:
        '200':
          description: Recommendation pinned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
    delete:
      operationId: unpinRecommendation
      summary: Unpin a recommendation
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Recommendation unpinned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
  /companies/{companyId}/recommendations/{id}/suppress:
    parameters:
    - $ref: '#/components/parameters/companyId'
    - $ref: '#/components/parameters/resourceId'
    post:
      operationId: suppressRecommendation
      summary: Suppress a recommendation temporarily
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                role:
                  type: string
                  enum:
                  - founder
                  - accountant
                  default: founder
                days:
                  type: integer
                  minimum: 1
                  maximum: 365
                  default: 30
                suppressedUntil:
                  type: string
                  description: Explicit suppression end; must parse to a valid date. When omitted, days determines the end.
                reason:
                  type: string
      responses:
        '200':
          description: Recommendation suppressed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
        '422':
          description: Invalid suppression date; no recommendation or audit change is written
  /companies/{companyId}/recommendations/{id}/dismiss-with-reason:
    parameters:
    - $ref: '#/components/parameters/companyId'
    - $ref: '#/components/parameters/resourceId'
    post:
      operationId: dismissRecommendationWithReason
      summary: Dismiss a recommendation with a nonblank reason
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - reason
              properties:
                reason:
                  type: string
                  minLength: 1
                  maxLength: 1000
                  pattern: \S
      responses:
        '200':
          description: Recommendation dismissed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
        '422':
          description: Missing, blank, or overlong dismissal reason; no recommendation or audit change is written
  /accountant/companies/{customerId}/recommendations:
    parameters:
    - name: customerId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    get:
      operationId: listAccountantCustomerRecommendations
      summary: List recommendations for an assigned customer
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      - serviceApiKey: []
      parameters:
      - $ref: '#/components/parameters/limit'
      - $ref: '#/components/parameters/cursor'
      - name: status
        in: query
        schema:
          type: string
          enum:
          - pending
          - active
          - completed
          - dismissed
      - name: category
        in: query
        schema:
          type: string
      responses:
        '200':
          description: Customer recommendation queue
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationsListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
    post:
      operationId: createAccountantCustomerRecommendation
      summary: Add an accountant-authored recommendation for an assigned customer
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateRecommendationInput'
      responses:
        '201':
          description: Recommendation created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
  /accountant/companies/{customerId}/recommendations/{id}/pin:
    parameters:
    - name: customerId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    - $ref: '#/components/parameters/resourceId'
    post:
      operationId: pinAccountantCustomerRecommendation
      summary: Pin a customer recommendation as an accountant
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Recommendation pinned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
    delete:
      operationId: unpinAccountantCustomerRecommendation
      summary: Unpin a customer recommendation as an accountant
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Recommendation unpinned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
  /accountant/companies/{customerId}/recommendations/{id}/suppress:
    parameters:
    - name: customerId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    - $ref: '#/components/parameters/resourceId'
    post:
      operationId: suppressAccountantCustomerRecommendation
      summary: Snooze a customer recommendation as an accountant
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                days:
                  type: integer
                  minimum: 1
                  maximum: 365
                  default: 30
                reason:
                  type: string
      responses:
        '200':
          description: Recommendation suppressed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
  /accountant/companies/{customerId}/recommendations/{id}/note:
    parameters:
    - name: customerId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    - $ref: '#/components/parameters/resourceId'
    post:
      operationId: addAccountantCustomerRecommendationNote
      summary: Add an accountant note to a customer recommendation
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - note
              properties:
                note:
                  type: string
                  minLength: 1
                  maxLength: 5000
      responses:
        '200':
          description: Recommendation updated with accountant note
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
  /accountant/companies/{customerId}/recommendations/{id}/customer-action-expected:
    parameters:
    - name: customerId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    - $ref: '#/components/parameters/resourceId'
    post:
      operationId: setAccountantCustomerRecommendationActionExpected
      summary: Mark whether a customer recommendation expects founder action
      tags:
      - Recommendations
      security:
      - bearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                expected:
                  type: boolean
                  default: true
      responses:
        '200':
          description: Recommendation updated with customer-action expectation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationResponse'
components:
  responses:
    Forbidden:
      description: Insufficient permissions or not a company member
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    Unauthorized:
      description: Authentication required
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    ValidationError:
      description: Request failed validation
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
  schemas:
    ProblemDetail:
      type: object
      properties:
        type:
          type: string
        title:
          type: string
          description: 'For application errors, a stable UPPER_SNAKE machine code (for example `NOT_FOUND`, `FORECAST_NOT_FOUND`, `VALIDATION_ERROR`). Clients branch on this, never on `detail` wording. A few transport level responses use a short human title instead.

            '
        status:
          type: integer
        detail:
          type: string
          description: 'Human-readable explanation; correlate a failure with `traceId`. A NOT_FOUND-family 404 names the resource type (for example "Company not found"), not its id. Some legacy messages still include an id (tracked in #2666).

            '
        instance:
          type: string
        traceId:
          type: string
        retryAfter:
          type: integer
          minimum: 0
          description: Whole seconds until retry is allowed for a 429 response
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              message:
                type: string
        extensions:
          type: object
          additionalProperties: true
    UpdateRecommendationInput:
      type: object
      properties:
        priority:
          type: string
          enum:
          - HIGH
          - MEDIUM
        category:
          type: string
          minLength: 1
          maxLength: 100
        title:
          type: string
          minLength: 1
          maxLength: 500
        summary:
          type: string
          minLength: 1
          maxLength: 5000
        details:
          type:
          - object
          - 'null'
          additionalProperties: true
        action:
          type:
          - string
          - 'null'
          maxLength: 1000
        investmentCents:
          type:
          - integer
          - 'null'
        expectedAnnualReturnCents:
          type:
          - integer
          - 'null'
        currency:
          type: string
          minLength: 3
          maxLength: 3
          pattern: ^[A-Za-z]{3}$
          description: Accepted case-insensitively and normalized to uppercase by the server.
        timeframe:
          type:
          - string
          - 'null'
          maxLength: 200
        confidencePct:
          type:
          - number
          - 'null'
        dataSource:
          type:
          - string
          - 'null'
          maxLength: 200
        status:
          type: string
          enum:
          - pending
          - active
          - completed
          - dismissed
        dismissedReason:
          type:
          - string
          - 'null'
          maxLength: 1000
        sourceRefs:
          type: array
          maxItems: 25
          items:
            $ref: '#/components/schemas/RecommendationSourceRefInput'
    PaginationMeta:
      type: object
      properties:
        nextCursor:
          type:
          - string
          - 'null'
        hasMore:
          type: boolean
    RecommendationsListResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          type: array
          items:
            $ref: '#/components/schemas/Recommendation'
        meta:
          $ref: '#/components/schemas/PaginationMeta'
    Recommendation:
      type: object
      required:
      - currency
      - minorUnitExponent
      properties:
        id:
          type: string
          format: uuid
        companyId:
          type: string
          format: uuid
        priority:
          type: string
          enum:
          - HIGH
          - MEDIUM
        category:
          type: string
        title:
          type: string
        summary:
          type: string
        details:
          type:
          - object
          - 'null'
          additionalProperties: true
        action:
          type:
          - string
          - 'null'
        investmentCents:
          type:
          - integer
          - 'null'
        expectedAnnualReturnCents:
          type:
          - integer
          - 'null'
        currency:
          type: string
          pattern: ^[A-Z]{3}$
        minorUnitExponent:
          type: integer
          const: 2
        timeframe:
          type:
          - string
          - 'null'
        confidencePct:
          type:
          - number
          - 'null'
        dataSource:
          type:
          - string
          - 'null'
        status:
          type: string
          enum:
          - pending
          - active
          - completed
          - dismissed
        dismissedReason:
          type:
          - string
          - 'null'
        sourceRefs:
          type: array
          items:
            $ref: '#/components/schemas/RecommendationSourceRef'
        pinnedByRoles:
          type: array
          items:
            type: string
            enum:
            - founder
            - accountant
        suppressedUntil:
          type:
          - string
          - 'null'
          format: date-time
        createdAt:
          type: string
          format: date-time
        completedAt:
          type:
          - string
          - 'null'
          format: date-time
    RecommendationSourceRef:
      type: object
      required:
      - type
      - id
      properties:
        type:
          type: string
        id:
          type: string
        label:
          type: string
        metadata:
          type: object
          additionalProperties: true
    CreateRecommendationInput:
      type: object
      required:
      - priority
      - category
      - title
      - summary
      - currency
      properties:
        priority:
          type: string
          enum:
          - HIGH
          - MEDIUM
        category:
          type: string
          minLength: 1
          maxLength: 100
        title:
          type: string
          minLength: 1
          maxLength: 500
        summary:
          type: string
          minLength: 1
          maxLength: 5000
        details:
          type: object
          additionalProperties: true
        action:
          type: string
          maxLength: 1000
        investmentCents:
          type: integer
          minimum: 0
        expectedAnnualReturnCents:
          type: integer
        currency:
          type: string
          minLength: 3
          maxLength: 3
          pattern: ^[A-Za-z]{3}$
          description: Accepted case-insensitively and normalized to uppercase by the server.
        timeframe:
          type: string
          maxLength: 200
        confidencePct:
          type: number
          minimum: 0
          maximum: 100
        dataSource:
          type: string
          maxLength: 200
        sourceRefs:
          type: array
          maxItems: 25
          items:
            $ref: '#/components/schemas/RecommendationSourceRefInput'
    RecommendationSourceRefInput:
      type: object
      required:
      - type
      - id
      properties:
        type:
          type: string
          minLength: 1
          maxLength: 100
        id:
          type: string
          minLength: 1
          maxLength: 255
        label:
          type: string
          maxLength: 500
        metadata:
          type: object
          additionalProperties: true
    RecommendationResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          $ref: '#/components/schemas/Recommendation'
  parameters:
    companyId:
      name: companyId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    resourceId:
      name: id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    cursor:
      name: cursor
      in: query
      schema:
        type: string
    limit:
      name: limit
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 50
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    serviceApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: 'Persistent credential for the configured cloud-bookkeeping service principal. The key must carry accountant:* and is accepted only on accountant operations that explicitly list this scheme. Ordinary API keys, and service keys presented to bearer-only operations, are denied.

        '
    refreshSessionCookie:
      type: apiKey
      in: cookie
      name: __Secure-median_refresh
      description: 'Exact production HttpOnly refresh-session cookie. Local non-secure development uses median_refresh.

        '
    passkeyEnrollmentGrantCookie:
      type: apiKey
      in: cookie
      name: __Secure-median_passkey_enrollment
      description: 'Exact production HttpOnly passkey-enrollment grant cookie. Local non-secure development uses median_passkey_enrollment.

        '
    webAuthnCeremonyCookie:
      type: apiKey
      in: cookie
      name: __Secure-median_webauthn
      description: 'Exact production HttpOnly WebAuthn ceremony cookie. Local non-secure development uses median_webauthn.

        '
x-median-quarantined-authorities:
  decision: ADR-0001-model-a
  runtimeStatus: unmounted
  description: 'Migrations 267-272 modeled legal entities as separate company tenants. These paths are not runtime API authority while their preserved accounting math is re-keyed to legal entities inside one company workspace.

    '
  paths:
  - /companies/{companyId}/consolidation-groups
  - /companies/{companyId}/consolidation-groups/{groupId}/versions/{groupVersionId}/report-rollups
  - /companies/{companyId}/consolidation-groups/{groupId}/versions/{groupVersionId}/report-rollups/{rollupId}
  - /companies/{companyId}/consolidation-groups/{groupId}/versions/{groupVersionId}/translation-adjustments
  - /companies/{companyId}/consolidation-groups/{groupId}/versions/{groupVersionId}/translation-adjustments/{adjustmentId}
x-median-demo-parity-customer-surface:
  runtimeStatus: mounted-lifecycle-only
  description: 'v2 customer-app capabilities available to JWT-authenticated members of any active or test company — the v2 app is the product, not a rollout cohort, so no allowlist applies to the markerless path. Production customer calls omit X-Median-App-Surface. Test-company calls may carry X-Median-App-Surface: qa to select the QA bundle; that marker branch alone still requires membership in CUSTOMER_APP_DEMO_PARITY_COMPANY_IDS. An API key, unknown marker, malformed company id, inactive company, missing gate dependency, or failed company lookup receives the standard hidden-resource 404 contract. The held surfaces riding these prefixes (AR/AP, Forecast, Insights) carry their own additional allowlist gate — see x-median-forecast-hold and x-median-ar-ap-hold.

    '
  headerContract: '#/components/parameters/demoParityCustomerAppSurface'
  routePrefixes:
  - /companies/{companyId}/ar
  - /companies/{companyId}/ap
  - /companies/{companyId}/customers
  - /companies/{companyId}/vendors
  - /companies/{companyId}/contracts
  - /companies/{companyId}/receivables
  - /companies/{companyId}/entities
  - /companies/{companyId}/currencies
  - /companies/{companyId}/reporting-scopes
  - /companies/{companyId}/reporting-scopes/{reportingScopeId}/versions/{versionId}/rollups
  - /companies/{companyId}/reporting-scopes/{reportingScopeId}/versions/{versionId}/translation-adjustments
  - /companies/{companyId}/presentation-report-snapshots
  - /companies/{companyId}/reporting-trial-balances
  - /companies/{companyId}/reporting-scopes/{reportingScopeId}/versions/{versionId}/trial-balances
  - /companies/{companyId}/reporting-scopes/{reportingScopeId}/versions/{versionId}/intercompany
  - /companies/{companyId}/weekly-email
  - /companies/{companyId}/forecast
  - /companies/{companyId}/books
  - /companies/{companyId}/sub-ledgers
x-median-forecast-hold:
  runtimeStatus: mounted-only-with-server-gate
  description: 'Forecast is held. Beyond the lifecycle-only customer surface above, every operation under the prefix below also requires the company to appear in the held-surface allowlist CUSTOMER_APP_DEMO_PARITY_COMPANY_IDS — the one operator-set list that opens AR/AP, Forecast and Insights (the legacy CUSTOMER_APP_FORECAST_COMPANY_IDS variable is no longer consulted). It is empty by default, so the v2 rollout alone never exposes Forecast. A company off the list receives the same hidden-resource 404 contract as one for which the surface does not exist. The auth-context featureFlags key `forecast` mirrors this verdict for the customer app shell.

    '
  featureFlag: forecast
  routePrefixes:
  - /companies/{companyId}/forecast
x-median-ar-ap-hold:
  runtimeStatus: mounted-only-with-server-gate
  description: 'Receivables/Payables are held behind TWO required authorities. Beyond the lifecycle-only customer surface above, every operation under the prefixes below requires the company to appear in the held-surface allowlist CUSTOMER_APP_DEMO_PARITY_COMPANY_IDS (requireDemoParityAllowlistedCompany) AND to satisfy the company_subledger_flags conversion chain (requireArApItemsEnabled — the same authority the public /pay page, aging and the accountant portal consult); failing either answers the opaque 404. The auth-context featureFlags key `arApItems` mirrors exactly that conjunction, resolved server-side, so the customer shell hides the Receivables/Payables nav and pages instead of offering menu entries these routes 404. Default is FALSE for every company while the list is empty or the conversion has not run.

    '
  featureFlag: arApItems
  routePrefixes:
  - /companies/{companyId}/ar
  - /companies/{companyId}/ap
  - /companies/{companyId}/customers
  - /companies/{companyId}/vendors
  - /companies/{companyId}/contracts
  - /companies/{companyId}/receivables
x-median-demo-parity-qa-only:
  runtimeStatus: mounted-only-with-server-gate
  description: 'Strict test-company-only routes. Every interactive call requires X-Median-App-Surface: qa in addition to JWT authentication, the server allowlist, and persisted client_status=test. A copied header, API key, active company, missing gate dependency, or failed company lookup receives the standard hidden-resource 404 contract.

    '
  headerContract: '#/components/parameters/qaAppSurface'
  routePrefixes:
  - /companies/{companyId}/gl-accounts/{id}/monetary-classification
  - /companies/{companyId}/fx-account-roles
  - /companies/{companyId}/gl-periods/{periodId}/fx-revaluation
  - /accountant/companies/{customerId}/gl-accounts/{id}/monetary-classification
  - /accountant/companies/{customerId}/fx-account-roles
  - /accountant/companies/{customerId}/gl-periods/{periodId}/fx-revaluation
  - /accountant/companies/{customerId}/ar/{id}
  - /accountant/companies/{customerId}/ap/{id}
x-median-onboarding-v3-surface:
  runtimeStatus: promoted
  promotionFlag: ONBOARDING_V3_QA_ONLY=false
  description: 'Promoted. The deployment this contract describes runs ONBOARDING_V3_QA_ONLY=false, so none of the onboarding-v3 auth, pricing, or setup paths below requires X-Median-App-Surface: qa. An unmarked request is served and reaches ordinary authentication, so an unauthenticated call now answers 401 rather than the hidden-resource 404. Mounting is still conditional: with ONBOARDING_V3_ENABLED false every path below returns the hidden-resource 404 before body parsing or authentication. The header stays defined and is still honoured, because a deployment left at ONBOARDING_V3_QA_ONLY=true keeps requiring it on every path below and 404s unmarked traffic; setting that flag back to true is the rollback. On either setting the header is a pre-company bundle marker, never tenant authorization.

    '
  headerContract: '#/components/parameters/onboardingV3QaSurface'
  routePaths:
  - /auth/otp/start


# --- truncated at 32 KB (33 KB total) ---
# Full source: https://artifacts.apis.io/medianfi-com/openapi/medianfi-com-recommendations-api-openapi.yml