> ## Documentation Index
> Fetch the complete documentation index at: https://docs.numi.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Get the fundamentals across every filing

> Returns the line items of a US SEC filer across its filings on Forms 10-K, 10-Q, 20-F and 40-F, of `period_type`, in the `view` you choose, ordered by metric, then period end, then period start, then filing date. Each entry is one line item with its `vintage` and the `filing` it came from. A period is the start and the end of a line item together, so a quarter's revenue and a year-to-date cash flow are different periods. Under `first` and `latest`, the filing is chosen for each metric and period, so neighbouring entries can come from different filings. History explains the four views and `as_of`.



## OpenAPI

````yaml GET /companies/{ref}/fundamentals/history
openapi: 3.1.0
info:
  title: numi API
  version: 0.1.0
  summary: Company data for US SEC filers.
  description: >
    Segments by XBRL axis (business, product or geography), each axis checked
    against the revenue that the filing reports, and fundamentals as filed.


    Every success response has the form `{ "data": ..., "meta": { "request_id":
    "...", "as_of": "..." } }`, where `as_of` is the time of the response. Every
    error response has the form `{ "error": { "code": "...", "message": "..." },
    "meta": { "request_id": "..." } }`, and some errors have more fields beside
    `code` and `message`.


    The `request_id` is also in the `x-request-id` response header. When you
    write to hello@numi.sh, quote it.
servers:
  - url: https://api.numi.sh/v1
security:
  - ApiKey: []
  - BearerKey: []
paths:
  /companies/{ref}/fundamentals/history:
    get:
      summary: Get the fundamentals across every filing
      description: >-
        Returns the line items of a US SEC filer across its filings on Forms
        10-K, 10-Q, 20-F and 40-F, of `period_type`, in the `view` you choose,
        ordered by metric, then period end, then period start, then filing date.
        Each entry is one line item with its `vintage` and the `filing` it came
        from. A period is the start and the end of a line item together, so a
        quarter's revenue and a year-to-date cash flow are different periods.
        Under `first` and `latest`, the filing is chosen for each metric and
        period, so neighbouring entries can come from different filings. History
        explains the four views and `as_of`.
      operationId: getFundamentalsHistory
      parameters:
        - $ref: '#/components/parameters/Ref'
        - $ref: '#/components/parameters/PeriodType'
        - $ref: '#/components/parameters/HistoryView'
        - $ref: '#/components/parameters/AsOf'
        - name: metric
          in: query
          description: >-
            Returns this metric only, such as `revenue` or `net_income`. Without
            `metric`, the response has every metric.
          schema:
            type: string
            enum:
              - revenue
              - cost_of_revenue
              - gross_profit
              - operating_income
              - net_income
              - eps_basic
              - eps_diluted
              - total_assets
              - total_liabilities
              - shareholders_equity
              - cash_and_equivalents
              - long_term_debt
              - operating_cash_flow
              - capital_expenditure
            example: revenue
      responses:
        '200':
          description: >-
            The line items in the view. The list is empty when no filing has a
            line item, and `reason` says why.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                  - meta
                properties:
                  data:
                    type: object
                    required:
                      - company
                      - period_type
                      - view
                      - as_of
                      - metric
                      - filings_checked
                      - reason
                      - entries
                    properties:
                      company:
                        $ref: '#/components/schemas/Company'
                      period_type:
                        $ref: '#/components/schemas/PeriodTypeName'
                      view:
                        $ref: '#/components/schemas/ViewName'
                      as_of:
                        type:
                          - string
                          - 'null'
                        format: date
                        description: >-
                          The `as_of` of the request, or null when the request
                          had none.
                      metric:
                        type:
                          - string
                          - 'null'
                        description: >-
                          The `metric` of the request, or null when the request
                          had none.
                      filings_checked:
                        type: integer
                        minimum: 0
                        description: >-
                          The number of extracted filings of the company in
                          `period_type` that numi holds, whatever `as_of` is. It
                          is 0 for a company with no such filing.
                      reason:
                        oneOf:
                          - $ref: '#/components/schemas/ReasonName'
                          - type: 'null'
                        description: >-
                          Why `entries` is empty, or null when it is not.
                          `none_before_as_of` means every filing in the data is
                          later than `as_of`.
                      entries:
                        type: array
                        items:
                          $ref: '#/components/schemas/FundamentalsHistoryEntry'
                    additionalProperties: false
                  meta:
                    $ref: '#/components/schemas/Meta'
                additionalProperties: false
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/SandboxRestricted'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  parameters:
    Ref:
      name: ref
      in: path
      required: true
      description: >-
        The company, as a ticker such as `MSFT` or `BRK.B`, or as `cik:` and the
        digits of its CIK (the SEC's Central Index Key), such as `cik:789019`. A
        ticker matches in upper or lower case, and `.` and `-` match each other,
        so `BRK.B` and `BRK-B` are the same company.
      schema:
        type: string
        pattern: ^([Cc][Ii][Kk]:[0-9]{1,10}|[A-Za-z0-9.-]{1,16})$
        example: MSFT
    PeriodType:
      name: period_type
      in: query
      description: Annual filings (10-K, 20-F, 40-F) or quarterly ones (10-Q).
      schema:
        $ref: '#/components/schemas/PeriodTypeName'
    HistoryView:
      name: view
      in: query
      description: >
        How the history reads the filings. Without `view`, the value is `own`.


        - `own` gives each filing's own period, one entry per filing, amendments
        included.

        - `first` gives each fiscal period once, from the earliest filing in
        numi's data that carries it, in any vintage.

        - `latest` gives each fiscal period once, from the newest filing that
        carries it, in any vintage: the latest recast series.

        - `all` gives every period of every filing, vintages included.
      schema:
        $ref: '#/components/schemas/ViewName'
    AsOf:
      name: as_of
      in: query
      description: >-
        A date as `YYYY-MM-DD`. Only filings with a filing date on or before it
        count, in every view. It is a snapshot by filing date, at day
        granularity, not a cut by the hour. A value that is not a date on the
        calendar, such as `2026-02-30`, is a 400.
      schema:
        type: string
        format: date
  headers:
    RequestId:
      description: >-
        The id of the request. It is also in `meta.request_id` of the body. When
        you write to hello@numi.sh, quote it.
      schema:
        $ref: '#/components/schemas/RequestId'
    RateLimitRemaining:
      description: >-
        The number of requests that the account has left today. REST and MCP
        calls count toward the same total, which is reset at midnight UTC.
      schema:
        type: integer
        minimum: 0
        example: 238
  schemas:
    Company:
      type: object
      description: >-
        One SEC filer. The SIC code and the filer facts are the company's
        metadata today, as EDGAR states it, not as it stood at each filing.
      required:
        - cik
        - ticker
        - tickers
        - name
        - exchange
        - sic
        - sic_description
        - state_of_incorporation
        - fiscal_year_end
        - filer_category
        - entity_type
      properties:
        cik:
          type: string
          pattern: ^[0-9]{10}$
          description: The CIK, zero-padded to ten digits.
          example: '0000789019'
        ticker:
          type:
            - string
            - 'null'
          description: The primary ticker.
          example: MSFT
        tickers:
          type: array
          items:
            type: string
          description: Every ticker of the company.
        name:
          type: string
          example: MICROSOFT CORPORATION
        exchange:
          type:
            - string
            - 'null'
          example: Nasdaq
        sic:
          type:
            - string
            - 'null'
          description: >-
            The four-digit SIC code that EDGAR assigns to the company today.
            Null until numi has synced the company's reference data from EDGAR.
          example: '7372'
        sic_description:
          type:
            - string
            - 'null'
          description: >-
            The name of the SIC code, as EDGAR states it. Like every company
            field below it, this is the company's metadata today, not as it
            stood at each filing.
          example: Services-Prepackaged Software
        state_of_incorporation:
          type:
            - string
            - 'null'
          description: The state or country of incorporation, as EDGAR states it today.
          example: WA
        fiscal_year_end:
          type:
            - string
            - 'null'
          description: >-
            The month and day that the company's fiscal year ends, as EDGAR
            states it today, in the form MMDD.
          example: '0630'
        filer_category:
          type:
            - string
            - 'null'
          description: >-
            The filer category, as EDGAR states it today, such as Large
            accelerated filer.
          example: Large accelerated filer
        entity_type:
          type:
            - string
            - 'null'
          description: The entity type, as EDGAR states it today, such as operating.
          example: operating
      additionalProperties: false
    PeriodTypeName:
      type: string
      enum:
        - annual
        - quarterly
      default: annual
    ViewName:
      type: string
      enum:
        - own
        - first
        - latest
        - all
      description: >-
        How a history read the filings. `own` is each filing's own period,
        `first` the earliest filing that carries each fiscal period, `latest`
        the newest, and `all` every period of every filing.
    ReasonName:
      type: string
      enum:
        - not_covered
        - no_extracted_data
        - not_extracted
        - no_filings
        - no_such_filing
        - no_note
        - none_before_as_of
      description: >
        Why a request found nothing. A `not_found` error can carry it as
        `reason`, and an empty history carries it beside `entries`. Each value
        says what numi holds, not what a filing contains. New values can be
        added; none is renamed.


        - `not_covered`: no company that numi holds matches the ref.

        - `no_extracted_data`: filings of the company are held and no such data
        was read from them. The filing may still describe it in its segment
        note.

        - `not_extracted`: the company's filings are in the data but have not
        been read. A pending filing is read in the next daily run.

        - `no_filings`: the company is known and no filing of it is held yet.

        - `no_such_filing`: the company has no extracted filing with that
        `filing_id`.

        - `no_note`: the filing has no segment note on file.

        - `none_before_as_of`: filings of the period type are held for the
        company, and every one was filed after `as_of`.
    FundamentalsHistoryEntry:
      type: object
      description: One line item of one filing, with the filing beside it.
      allOf:
        - $ref: '#/components/schemas/LineItemBody'
      required:
        - filing
      properties:
        filing:
          $ref: '#/components/schemas/Filing'
      unevaluatedProperties: false
    Meta:
      type: object
      description: The metadata of one success response.
      required:
        - request_id
        - as_of
      properties:
        request_id:
          $ref: '#/components/schemas/RequestId'
        as_of:
          type: string
          format: date-time
          description: The time of the response, in UTC.
          example: '2026-10-19T12:34:56.789Z'
      additionalProperties: false
    RequestId:
      type: string
      pattern: ^req_[A-Za-z0-9_-]{16}$
      description: The id of one request.
      example: req_Qm3xYb9Kd2LpR7wA
    LineItemBody:
      type: object
      description: The fields of one line item.
      required:
        - metric
        - vintage
        - concept
        - value
        - unit
        - currency
        - period_start
        - period_end
        - decimals
      properties:
        metric:
          type: string
          description: >-
            The name of the line item, such as revenue, net_income or
            eps_diluted.
          example: revenue
        vintage:
          type: integer
          minimum: 0
          description: >-
            0 for the filing's own period, 1 for the comparative one year
            earlier, 2 for two years earlier
        concept:
          type: string
          description: >-
            The XBRL concept that the value comes from, without its taxonomy
            prefix.
          example: RevenueFromContractWithCustomerExcludingAssessedTax
        value:
          type: number
        unit:
          type:
            - string
            - 'null'
          description: >-
            The id of the unit as filed, such as U_USD. Each filer names its
            units its own way, and the currency code is in `currency`.
        currency:
          type:
            - string
            - 'null'
          description: >-
            The currency code of the filing's own unit for the value. It is the
            filing's label, not a converted or verified measure.
          example: USD
        period_start:
          type:
            - string
            - 'null'
          format: date
          description: Null for a figure at one date, such as total assets.
        period_end:
          type: string
          format: date
        decimals:
          type:
            - integer
            - 'null'
          description: >-
            The precision of the value as filed, in XBRL decimals. -6 means
            rounded to millions.
    Filing:
      type: object
      description: One extracted filing of the company.
      required:
        - id
        - form_type
        - filing_date
        - period_end
        - fiscal_year
        - fiscal_period
        - period_type
        - is_amendment
        - extractor_version
        - has_segments
        - has_note
        - accession_number
        - accepted_at
        - match_basis
        - source_url
        - document_url
      properties:
        id:
          type: integer
          description: The id of the filing, for `filing_id`.
        form_type:
          type: string
          description: The form, such as 10-K, 10-Q, 20-F, 40-F or an amendment of one.
          example: 10-K
        filing_date:
          type: string
          format: date
        period_end:
          type:
            - string
            - 'null'
          format: date
          description: The end of the period that the filing reports on.
        fiscal_year:
          type:
            - integer
            - 'null'
        fiscal_period:
          type:
            - string
            - 'null'
          description: FY for a year, Q1 to Q4 for a quarter.
          example: FY
        period_type:
          oneOf:
            - $ref: '#/components/schemas/PeriodTypeName'
            - type: 'null'
        is_amendment:
          type: boolean
        extractor_version:
          type:
            - string
            - 'null'
          description: >-
            The version of the extractor that produced the filing's rows, such
            as `2026.11.1`. Null for a filing extracted before numi recorded it.
            When the extractor changes, the changelog says what changed, and the
            nightly refresh re-reads every filing over a few nights.
          example: 2026.11.1
        has_segments:
          type: boolean
          description: Whether the filing has at least one segment axis.
        has_note:
          type: boolean
          description: Whether the filing has a segment note.
        accession_number:
          type:
            - string
            - 'null'
          description: >-
            The accession number of the filing on EDGAR. Null when numi has not
            matched the filing to an EDGAR submission yet.
          example: 0000950170-25-100235
        accepted_at:
          type:
            - string
            - 'null'
          description: >-
            The acceptance time as EDGAR states it, unchanged. For some filers
            EDGAR writes Eastern wall-clock time with a Z suffix.
          example: '2025-07-30T16:06:04.000Z'
        match_basis:
          oneOf:
            - type: string
              enum:
                - form_date_period
                - form_date
                - form_period
            - type: 'null'
          description: >-
            How numi matched the filing to its EDGAR submission.
            form_date_period means that the form, the filing date and the period
            end all agree. form_date means that the form and the filing date
            agree and the period end was not available to check. form_period:
            the form and the period end match, and EDGAR's filing date is one to
            four days after the stored one, as for a filing accepted after
            hours. Null when the filing is not matched.
          example: form_date_period
        source_url:
          type:
            - string
            - 'null'
          format: uri
          description: >-
            The filing's index page on EDGAR, or null when numi has not matched
            the filing to an EDGAR submission yet.
        document_url:
          type:
            - string
            - 'null'
          format: uri
          description: >-
            The filing's primary document on EDGAR, or null when numi has not
            matched the filing or EDGAR names no primary document.
      additionalProperties: false
    ErrorEnvelope:
      type: object
      description: The body of every error response.
      required:
        - error
        - meta
      properties:
        error:
          $ref: '#/components/schemas/ErrorBody'
        meta:
          type: object
          description: The metadata of one error response.
          required:
            - request_id
          properties:
            request_id:
              $ref: '#/components/schemas/RequestId'
          additionalProperties: false
      additionalProperties: false
    ErrorBody:
      type: object
      description: >-
        The error. Some errors have more fields beside the code and the message.
        A `rate_limit_exceeded` error has `retry_after` and `scope`, and a
        `sandbox_restricted` error has `sandbox_companies`, the tickers of the
        companies that you can read with a sandbox key, and a `not_found` error
        for a company, a filing or a note can have `reason`, which says why numi
        has nothing to show.
      required:
        - code
        - message
      properties:
        code:
          type: string
          enum:
            - unauthorized
            - invalid_key
            - rate_limit_exceeded
            - bad_request
            - not_found
            - plan_required
            - sandbox_restricted
            - key_limit
            - conflict
            - internal_error
            - service_unavailable
          description: >
            A code for programs to branch on.


            - `unauthorized`: the request has no API key, or an account route
            has no session.

            - `invalid_key`: the key is not valid, or it was revoked.

            - `rate_limit_exceeded`: the account is at the request limit of its
            plan for the minute or the day, or the IP address is at its limit
            for the minute.

            - `bad_request`: a parameter is missing or wrong, or the body is not
            valid JSON or is too large.

            - `not_found`: nothing matches the request.

            - `plan_required`: the plan of the account does not include the
            endpoint, such as on-demand extraction on the sandbox plan.

            - `sandbox_restricted`: the request is for a company outside the
            sandbox, with a sandbox key.

            - `key_limit`: the account has as many active keys as its plan
            allows.

            - `conflict`: a checkout for an account that is on the Builder plan
            already, or the billing portal for an account with no subscription.

            - `internal_error`: the server failed. When you write to
            hello@numi.sh, quote the request id.

            - `service_unavailable`: the server is not configured for the
            feature, such as accounts, billing or bulk files.
        message:
          type: string
          description: >-
            A sentence that says what went wrong and, where it helps, what to
            do.
        reason:
          anyOf:
            - $ref: '#/components/schemas/ReasonName'
            - type: string
          description: >-
            Why nothing was found, on a `not_found` error that has a reason. A
            later server can send a value that `ReasonName` does not list yet,
            so a client keeps an unknown value as text.
      additionalProperties: true
  responses:
    BadRequest:
      description: >-
        A parameter is missing or wrong, or the body is not valid JSON or is too
        large.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: bad_request
              message: 'limit: must be from 1 to 50'
            meta:
              request_id: req_Qm3xYb9Kd2LpR7wA
    Unauthorized:
      description: The request has no API key, or the key is not valid or was revoked.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: unauthorized
              message: >-
                The request has no API key. Send a numi API key in the X-API-Key
                header.
            meta:
              request_id: req_Qm3xYb9Kd2LpR7wA
    SandboxRestricted:
      description: >-
        The request is for a company outside the sandbox, with a sandbox key.
        `sandbox_companies` has the tickers of the companies that you can read
        with a sandbox key. On the Builder plan, you can read every company.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: sandbox_restricted
              message: >-
                TSLA is not in the sandbox. With a sandbox key, you can read 10
                companies: MSFT, AAPL, NVDA, AMZN, GOOGL, META, NFLX, CVX, JPM
                and SONY. To read every company, upgrade to the Builder plan at
                https://numi.sh/account.
              sandbox_companies:
                - MSFT
                - AAPL
                - NVDA
                - AMZN
                - GOOGL
                - META
                - NFLX
                - CVX
                - JPM
                - SONY
            meta:
              request_id: req_Qm3xYb9Kd2LpR7wA
    NotFound:
      description: Nothing matches the request.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: not_found
              message: >-
                The API has no route for GET /v1/nothing. Find the routes of the
                API at https://docs.numi.sh.
            meta:
              request_id: req_Qm3xYb9Kd2LpR7wA
    RateLimited:
      description: >-
        The account is at the request limit of its plan for the minute or the
        day, or the IP address is at its limit for the minute. Wait the number
        of seconds in the `Retry-After` header. `scope` is `minute` or `day`,
        for the limit that was reached.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          description: The number of seconds to wait before the next request.
          schema:
            type: integer
            minimum: 1
            example: 12
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: rate_limit_exceeded
              message: >-
                The sandbox plan has a limit of 20 requests a minute. Retry in
                12 seconds.
              retry_after: 12
              scope: minute
            meta:
              request_id: req_Qm3xYb9Kd2LpR7wA
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: A numi API key, sent in the `X-API-Key` header.
    BearerKey:
      type: http
      scheme: bearer
      description: 'A numi API key, sent as `Authorization: Bearer <key>`.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.