medianfi-com Business Events API

The Business Events API from medianfi-com — 6 operation(s) for business events.

Operations 10

GET /companies/{companyId}/business-events List business events for a company #
POST /companies/{companyId}/business-events Create a business event and post its journal entry #
GET /companies/{companyId}/business-events/{eventId} Get one business event #
PATCH /companies/{companyId}/business-events/{eventId} Update an unposted business event #
DELETE /companies/{companyId}/business-events/{eventId} Delete an orphan business event (zero GL impact) #
POST /companies/{companyId}/business-events/{eventId}/retry-post Retry posting the journal entry for a saved event #
GET /accountant/companies/{customerId}/business-events List business events for an assigned customer #
POST /accountant/companies/{customerId}/business-events Create a business event for an assigned customer #
DELETE /accountant/companies/{customerId}/business-events/{eventId} Delete an orphan business event (zero GL impact) #
POST /accountant/companies/{customerId}/business-events/{eventId}/retry-post Retry posting the journal entry for a saved event #

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-business-events-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-business-events-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Median Business Events API
  version: 0.1.0
  description: Production-grade Node.js + Express API starter template
  license:
    name: Proprietary
servers:
- url: /api/v1
security: []
tags:
- name: Business Events
paths:
  /companies/{companyId}/business-events:
    parameters:
    - $ref: '#/components/parameters/companyId'
    get:
      operationId: listBusinessEvents
      summary: List business events for a company
      description: 'Superseded events are omitted (#969): an event whose journal entries have all been voided or soft-deleted no longer has a live posting behind it. Events with no journal entry at all are still returned. A page may therefore contain fewer items than `limit` while `hasMore`/`nextCursor` keep advancing; the event is still readable by id.'
      tags:
      - Business Events
      security:
      - bearerAuth: []
      parameters:
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 500
          default: 200
      - name: cursor
        in: query
        required: false
        schema:
          type: string
      responses:
        '200':
          description: Business events, newest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/BusinessEventWire'
                  meta:
                    $ref: '#/components/schemas/BusinessEventListMeta'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
    post:
      operationId: createBusinessEvent
      summary: Create a business event and post its journal entry
      description: 'Strict by default (#1705/#1790/#1815): a request that cannot produce a journal entry — unknown event type, unresolvable accounts, or a resolve-time posting blocker (closed or missing period, filing-locked period, locked/non-postable account, out-of-domain date) — returns 422 naming the blocker, before any row is written. Pass allowWithoutJournalEntry: true to save the event with jeGenerationSkipped instead and retry-post after fixing the blocker. A client idempotencyKey identifies one create operation within this company. An identical completed request returns its existing event with 200 and idempotentReplay: true; this never posts again. A changed request or unfinished/uncertain create returns 409. Safely skipped stored outcomes remain visible on replay. A keyed posting or schedule failure returns 409 even on its first response and stays held for review because its write may already have committed. Exception (#2529): when a vendor bill''s journal entry posts but its Payables bill cannot be written, the entry is voided and the outcome is known, so the create completes with 201 and jeGenerationError naming the reason; the event stays listed and can be retried or deleted. Vendor bills (#2529) also return 422 field errors for parameters.apItemId (must be a UUID), parameters.dueDate (a real YYYY-MM-DD date, not before the bill date) and parameters.createNewApItem (boolean; not together with apItemId).'
      tags:
      - Business Events
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBusinessEventRequest'
      responses:
        '200':
          description: Completed operation replayed without creating or posting again; a safely skipped outcome remains visible
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/BusinessEventWire'
        '201':
          description: Event created (journal entry posted, or explicitly skipped via opt-in)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/BusinessEventWire'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          description: 'Same key with a different request, or creation still in progress/needs review; no new posting. Also STRIPE_CHARGE_ALREADY_BOOKED (#2424): an API-key caller booked Stripe revenue by hand (the entry credits revenue or debits Stripe Clearing) naming a ch_/pi_/txn_ id that resolves to one of this company''s Stripe balance transactions the sync has posted, holds, or will post. Nothing is written; signed-in people are not subject to this check. #2529 vendor bills (vendor_bill / accounts_payable_bill). These 409s are returned while planning, before any row is written: AP_ITEM_SELECTION_REQUIRED — an open, unposted Payables bill already matches this vendor, amount and currency; extensions.candidates lists { id, vendor, amountCents, dueDate, issueDate, billNumber } (and candidateApItemIds). Resend with parameters.apItemId set to the chosen id (and that bill''s billDate/dueDate), or with parameters.createNewApItem: true to record a separate bill; that override is audited on the new AP item. AP_ITEM_POSTING_CONFLICT — the selected bill differs in entity, status, amount, currency, bill date, vendor, expense account or due date (extensions.mismatches). AP_ITEM_ALREADY_POSTED — the selected bill already has a journal entry, source event or document. If the bill changes after planning (a concurrent writer), this is not a 409: the create completes with 201, the journal entry is voided, and jeGenerationError says why.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
        '422':
          $ref: '#/components/responses/ValidationError'
  /companies/{companyId}/business-events/{eventId}:
    parameters:
    - $ref: '#/components/parameters/companyId'
    - name: eventId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    get:
      operationId: getBusinessEvent
      summary: Get one business event
      tags:
      - Business Events
      security:
      - bearerAuth: []
      responses:
        '200':
          description: The business event
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/BusinessEventWire'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
    patch:
      operationId: updateBusinessEvent
      summary: Update an unposted business event
      description: Events with a generated journal entry or schedule cannot be edited — void and recreate instead.
      tags:
      - Business Events
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateBusinessEventRequest'
      responses:
        '200':
          description: The updated business event
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/BusinessEventWire'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: '#3864: the event''s journal is owned by its Stripe deferral schedule; an edit would drop the schedule''s keys'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
        '422':
          $ref: '#/components/responses/ValidationError'
    delete:
      operationId: deleteBusinessEvent
      summary: Delete an orphan business event (zero GL impact)
      description: Orphan cleanup only (#1705/#1815) — removes an event whose journal entry generation was skipped or failed, so it carries zero GL impact. An event linked to a posted journal entry, or one driving a derived posting schedule (whose entries post to the GL), returns 409; void the journal entry first.
      tags:
      - Business Events
      security:
      - bearerAuth: []
      responses:
        '204':
          description: Event deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Event is linked to a posted journal entry or a derived posting schedule
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
  /companies/{companyId}/business-events/{eventId}/retry-post:
    parameters:
    - $ref: '#/components/parameters/companyId'
    - name: eventId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    post:
      operationId: retryPostBusinessEvent
      summary: Retry posting the journal entry for a saved event
      description: Re-runs account resolution and posting for an event saved without a journal entry. Resolve-time posting blockers return 422 naming the blocker and leave the saved event untouched; there is no allowWithoutJournalEntry affordance on retry.
      tags:
      - Business Events
      security:
      - bearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                entityId:
                  type: string
                  format: uuid
      responses:
        '200':
          description: Event with the posted journal entry, or updated skip metadata
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/BusinessEventWire'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Event already has a posted journal entry, or its Stripe deferral schedule skipped the journal on purpose and owns its posting (#3864)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
        '422':
          $ref: '#/components/responses/ValidationError'
  /accountant/companies/{customerId}/business-events:
    parameters:
    - $ref: '#/components/parameters/customerId'
    get:
      operationId: accountantListBusinessEvents
      summary: List business events for an assigned customer
      description: Historical events remain listed for accountant review. journalEntryState and journalEntryStateCounts distinguish posted, void, deleted, missing, mixed and not-posted states. generatedJEs includes only live journal entries.
      tags:
      - Business Events
      security:
      - bearerAuth: []
      - serviceApiKey: []
      parameters:
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 500
          default: 200
      - name: cursor
        in: query
        required: false
        schema:
          type: string
      responses:
        '200':
          description: Business events, newest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/BusinessEventWire'
                  meta:
                    $ref: '#/components/schemas/BusinessEventListMeta'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
    post:
      operationId: accountantCreateBusinessEvent
      summary: Create a business event for an assigned customer
      description: 'Same strict-by-default contract as the customer endpoint: unresolvable accounts and resolve-time posting blockers (closed/missing period, locked account, out-of-domain date) return 422 before any row is written unless allowWithoutJournalEntry is true. An API-key caller (the bookkeeping service key) that books Stripe revenue by hand for a charge the Stripe sync already posted, holds, or will post gets 409 STRIPE_CHARGE_ALREADY_BOOKED (#2424). Vendor bills (#2529) also return 422 field errors for parameters.apItemId (must be a UUID), parameters.dueDate (a real YYYY-MM-DD date, not before the bill date) and parameters.createNewApItem (boolean; not together with apItemId).'
      tags:
      - Business Events
      security:
      - bearerAuth: []
      - serviceApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBusinessEventRequest'
      responses:
        '201':
          description: Event created (journal entry posted, or explicitly skipped via opt-in)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/BusinessEventWire'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          description: 'BUSINESS_EVENT_IDEMPOTENCY_CONFLICT (same key, different request) or STRIPE_CHARGE_ALREADY_BOOKED (#2424): an API-key caller booked Stripe revenue by hand (the entry credits revenue or debits Stripe Clearing) naming a ch_/pi_/txn_ id that resolves to one of this customer''s Stripe balance transactions the sync has posted, holds, or will post. The detail names the Stripe id, the balance transaction, and why. Nothing is written. #2529 vendor bills (vendor_bill / accounts_payable_bill). These 409s are returned while planning, before any row is written: AP_ITEM_SELECTION_REQUIRED — an open, unposted Payables bill already matches this vendor, amount and currency; extensions.candidates lists { id, vendor, amountCents, dueDate, issueDate, billNumber } (and candidateApItemIds). Resend with parameters.apItemId set to the chosen id (and that bill''s billDate/dueDate), or with parameters.createNewApItem: true to record a separate bill; that override is audited on the new AP item. AP_ITEM_POSTING_CONFLICT — the selected bill differs in entity, status, amount, currency, bill date, vendor, expense account or due date (extensions.mismatches). AP_ITEM_ALREADY_POSTED — the selected bill already has a journal entry, source event or document. If the bill changes after planning (a concurrent writer), this is not a 409: the create completes with 201, the journal entry is voided, and jeGenerationError says why.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
        '422':
          $ref: '#/components/responses/ValidationError'
  /accountant/companies/{customerId}/business-events/{eventId}:
    parameters:
    - $ref: '#/components/parameters/customerId'
    - name: eventId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    delete:
      operationId: accountantDeleteBusinessEvent
      summary: Delete an orphan business event (zero GL impact)
      description: Human accountants only — the bookkeeping service principal's route manifest has no DELETE rule here, so bearerAuth is the only accepted scheme (deletion stays a reviewed human action).
      tags:
      - Business Events
      security:
      - bearerAuth: []
      responses:
        '204':
          description: Event deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Event is linked to a posted journal entry or a derived posting schedule
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
  /accountant/companies/{customerId}/business-events/{eventId}/retry-post:
    parameters:
    - $ref: '#/components/parameters/customerId'
    - name: eventId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    post:
      operationId: accountantRetryPostBusinessEvent
      summary: Retry posting the journal entry for a saved event
      tags:
      - Business Events
      security:
      - bearerAuth: []
      - serviceApiKey: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                entityId:
                  type: string
                  format: uuid
      responses:
        '200':
          description: Event with the posted journal entry, or updated skip metadata
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/BusinessEventWire'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Event already has a posted journal entry, or its Stripe deferral schedule skipped the journal on purpose and owns its posting (#3864)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
        '422':
          $ref: '#/components/responses/ValidationError'
components:
  schemas:
    ApiErrorResponse:
      type: object
      required:
      - success
      - error
      properties:
        success:
          type: boolean
          enum:
          - false
        error:
          $ref: '#/components/schemas/ProblemDetail'
    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
    BusinessEventWire:
      type: object
      description: 'A business event with its generated preview lines and any posted journal entries. jeGenerationSkipped/jeGenerationError explain a null journalEntryId — skipped means a known, named blocker (or metadata-only event); error means an unexpected posting failure.

        '
      properties:
        idempotentReplay:
          type: boolean
          description: True when a completed create operation was returned without creating or posting again. Posting failures/skips retain their own fields.
        id:
          type: string
          format: uuid
        customerId:
          type: string
          format: uuid
          description: The company id (wire name kept for accountant-app compatibility).
        eventType:
          type: string
        status:
          type: string
        parameters:
          type: object
          additionalProperties: true
        journalEntryId:
          type:
          - string
          - 'null'
          format: uuid
        generatedEntries:
          type: array
          items:
            type: object
            properties:
              account:
                type: string
              accountNumber:
                type:
                - string
                - 'null'
              debit:
                type: number
              credit:
                type: number
              memo:
                type: string
        generatedJEs:
          type: array
          items:
            type: object
            additionalProperties: true
        journalEntryState:
          type: string
          enum:
          - posted
          - not_posted
          - void
          - deleted
          - missing
          - mixed
          description: Consolidated state of every journal entry owned by this event.
        journalEntryStateCounts:
          type: object
          required:
          - posted
          - void
          - deleted
          - missing
          properties:
            posted:
              type: integer
              minimum: 0
            void:
              type: integer
              minimum: 0
            deleted:
              type: integer
              minimum: 0
            missing:
              type: integer
              minimum: 0
        jeGenerationSkipped:
          type: string
          description: Why journal-entry generation was skipped (named blocker, unresolved accounts, or metadata-only event).
        jeGenerationError:
          type: string
          description: Unexpected posting failure recorded by the residual safety net (also captured to Sentry).
        journalSkippedOnPurpose:
          type: boolean
          enum:
          - true
          description: '#3864: present only when the Stripe deferral schedule skipped this journal on purpose and owns its posting; retry-post answers 409 and no retry is offered.'
        payablesApItemId:
          type: string
          format: uuid
          description: '#2529: the Payables (AP) item a posted vendor bill created or linked; its initial journal entry is this event''s journal entry.'
        unresolvedAccounts:
          type: array
          items:
            type: string
        createdAt:
          type: string
          format: date-time
        createdBy:
          type:
          - string
          - 'null'
    CreateBusinessEventRequest:
      type: object
      description: 'Business rules (supported event type, resolvable accounts, postable period/account) are enforced by the controller and the resolve-time posting guard, not this schema. Unknown extra keys are allowed.

        '
      properties:
        idempotencyKey:
          type: string
          minLength: 1
          maxLength: 128
          description: Optional trimmed client operation key, unique per company. Retain it across retries; use a new key for a new intentional operation. Keyless legacy creates remain separate. Customer creates compare canonical request values (object key order ignored) and bind the authorized primary entity; unfinished creates require review and cannot be retried as new postings.
        eventType:
          type: string
          minLength: 1
          maxLength: 100
          description: Generator key, e.g. adjusting_entry. Defaults to "custom" when absent.
        title:
          type: string
          maxLength: 300
        description:
          type:
          - string
          - 'null'
          maxLength: 5000
        amountCents:
          type: integer
        eventDate:
          type: string
          description: ISO date (YYYY-MM-DD). Derived from parameters or today when absent.
        parameters:
          type: object
          additionalProperties: true
          description: Generator parameters (e.g. debitAccount, creditAccount, amount).
        allowWithoutJournalEntry:
          type: boolean
          description: 'Opt into the save-now/fix-later flow — the event saves with metadata.jeGenerationSkipped naming the blocker instead of the request failing with 422.

            '
        entityId:
          type: string
          format: uuid
    BusinessEventListMeta:
      type: object
      description: Cursor pagination envelope meta on business-event lists.
      required:
      - nextCursor
      - hasMore
      properties:
        nextCursor:
          type:
          - string
          - 'null'
          description: Pass as `cursor` to fetch the next page; null on the last page.
        hasMore:
          type: boolean
    UpdateBusinessEventRequest:
      type: object
      description: Only unposted events (no journal entry, no schedule) can be edited.
      properties:
        eventType:
          type: string
          minLength: 1
          maxLength: 100
        title:
          type: string
          maxLength: 300
        description:
          type:
          - string
          - 'null'
          maxLength: 5000
        eventDate:
          type: string
        parameters:
          type: object
          additionalProperties: true
  responses:
    Forbidden:
      description: Insufficient permissions or not a company member
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    NotFound:
      description: Resource not found
      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'
  parameters:
    companyId:
      name: companyId
      in: path
      required: true
      schema:
        type: string
        format: uuid
    customerId:
      name: customerId
      in: path
      required: true
      schema:
        type: string
        format: uuid
  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:


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