openapi: 3.1.0
info:
  title: Belfort Data API
  version: 1.0.0-pilot
  description: "Company financial data extracted only from SEC filings, with a source filing on every figure. Source: U.S. Securities and Exchange Commission. Not affiliated with or endorsed by the SEC. Values are as filed. A blank in a filing is null, never zero. What the data sets behind statements leave out is listed in docs/known-limits.md. A metric figure can change or disappear when a later filing arrives, and figures aren't versioned: this is the current reading, with no way to ask for an earlier one. See docs/known-limits.md."
servers:
  - url: https://belfort-data-api.vercel.app
    description: Belfort Data API (pilot)
security:
  - ApiKey: []
paths:
  /v1/status:
    get:
      operationId: getStatus
      summary: Data age for each kind of data. Needs no key.
      security: []
      responses:
        "200":
          description: Current snapshots and their age.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusResponse"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}:
    get:
      operationId: getCompany
      summary: One company by ticker or CIK.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
      responses:
        "200":
          description: The company.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}/metrics:
    get:
      operationId: getCompanyMetrics
      summary: Key metrics, newest period first. Unknown query parameters get 400.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
        - name: metric
          in: query
          required: false
          schema:
            $ref: "#/components/schemas/MetricKey"
        - name: frequency
          in: query
          required: false
          schema:
            $ref: "#/components/schemas/Frequency"
      responses:
        "200":
          description: Metric points.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MetricsResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}/statements:
    get:
      operationId: getCompanyStatements
      summary: Statements as filed, one document per filing and statement, newest filing first. Unknown query parameters get 400.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
        - name: statement
          in: query
          required: false
          schema:
            $ref: "#/components/schemas/StatementKind"
        - name: form
          in: query
          required: false
          description: Filing form, such as 10-K or 10-Q.
          schema:
            type: string
        - name: limit
          in: query
          required: false
          description: Documents per page.
          schema:
            type: integer
            minimum: 1
            maximum: 20
            default: 4
        - name: cursor
          in: query
          required: false
          description: The `next_cursor` of the previous page.
          schema:
            type: string
      responses:
        "200":
          description: One page of statement documents.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatementsResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}/ownership:
    get:
      operationId: getCompanyOwnership
      summary: Schedule 13D/13G reporting-owner records for this issuer, newest filing first. Structured XML filings from 2024-12-18 only. Unknown query parameters get 400.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
        - name: form
          in: query
          required: false
          description: Filing form, such as SCHEDULE 13G or SCHEDULE 13D/A.
          schema:
            type: string
        - name: limit
          in: query
          required: false
          description: Records per page.
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
      responses:
        "200":
          description: Ownership records for the issuer.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OwnershipResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}/insider-trades:
    get:
      operationId: getCompanyInsiderTrades
      summary: Form 3/4/5 insider transactions for an issuer, newest first. Blank price is null.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 50
            default: 20
        - name: cursor
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: One page of insider transaction documents.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DocumentPageResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}/form13f:
    get:
      operationId: getCompanyForm13f
      summary: Form 13F holdings for a manager CIK. value_unit is thousands_usd or usd; ticker is null.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 50
            default: 20
        - name: cursor
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: One page of 13F holding documents.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DocumentPageResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}/filings:
    get:
      operationId: getCompanyFilings
      summary: Filings list from SEC submissions, newest first.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 50
            default: 20
        - name: cursor
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: One page of filing list documents.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DocumentPageResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}/earnings-releases:
    get:
      operationId: listCompanyEarningsReleases
      summary: 8-K Item 2.02 press-release exhibits, newest filed first. List items omit text (a document page). Optional from/to filter on filed date.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: cursor
          in: query
          required: false
          schema:
            type: string
        - name: from
          in: query
          required: false
          description: Inclusive lower bound on filed (YYYY-MM-DD).
          schema:
            type: string
            format: date
        - name: to
          in: query
          required: false
          description: Inclusive upper bound on filed (YYYY-MM-DD).
          schema:
            type: string
            format: date
      responses:
        "200":
          description: One page of earnings release summaries (no text).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EarningsReleasePageResponse"
              examples:
                page:
                  value:
                    data:
                      - accession: 0000320193-25-000001
                        filed: 2025-01-31
                        period: 2024-12-28
                        title: Apple Reports First Quarter Results
                        title_source: llm_verified
                        exhibit_type: EX-99.1
                        exhibit_description: EX-99.1
                        items:
                          - "2.02"
                          - "9.01"
                        exhibit_url: https://www.sec.gov/Archives/edgar/data/320193/000032019325000001/ex991.htm
                        filing_url: https://www.sec.gov/Archives/edgar/data/320193/000032019325000001/0000320193-25-000001-index.htm
                    meta:
                      snapshot_id: earn-1
                      as_of: 2026-11-06T05:08:32Z
                      next_cursor: null
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}/earnings-releases/{accession}:
    get:
      operationId: getCompanyEarningsRelease
      summary: One earnings release with its plain-text exhibit body.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
        - name: accession
          in: path
          required: true
          schema:
            type: string
            pattern: ^\d{10}-\d{2}-\d{6}$
      responses:
        "200":
          description: One earnings release including text.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EarningsReleaseResponse"
              examples:
                release:
                  value:
                    data:
                      accession: 0000320193-25-000001
                      filed: 2025-01-31
                      period: 2024-12-28
                      title: Apple Reports First Quarter Results
                      title_source: llm_verified
                      exhibit_type: EX-99.1
                      exhibit_description: EX-99.1
                      items:
                        - "2.02"
                        - "9.01"
                      exhibit_url: https://www.sec.gov/Archives/edgar/data/320193/000032019325000001/ex991.htm
                      filing_url: https://www.sec.gov/Archives/edgar/data/320193/000032019325000001/0000320193-25-000001-index.htm
                      text: Apple Reports First Quarter Results\n\nCupertino — …
                    meta:
                      snapshot_id: earn-1
                      as_of: 2026-11-06T05:08:32Z
                      next_cursor: null
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}/financials:
    get:
      operationId: getCompanyFinancials
      summary: Normalized core financials from printed statement lines, newest period first. Only fields that passed the publish bar are served. Unknown query parameters get 400.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
        - name: field
          in: query
          required: false
          description: "Served today (25): revenue, gross_profit, operating_income, sga, research_development, pretax_income, income_tax, net_income, basic_eps, diluted_eps, weighted_diluted_shares, cash_and_equivalents, receivables, current_assets, ppe_net, intangibles, total_assets, accounts_payable, current_liabilities, total_liabilities, retained_earnings, total_equity, operating_cash_flow, investing_cash_flow and financing_cash_flow. Any other NormalizedField value returns 400."
          schema:
            $ref: "#/components/schemas/NormalizedField"
        - name: period
          in: query
          required: false
          description: annual keeps quarters 4 (flows) and balances (quarters 0) dated on a fiscal year end, meaning the company has a quarters-4 figure ending that day; quarterly keeps quarters 1 and every balance.
          schema:
            $ref: "#/components/schemas/Frequency"
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 40
        - name: cursor
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: One page of normalized facts.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FinancialsResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}/segments:
    get:
      operationId: getCompanySegments
      summary: Single-axis product, geographic and business-segment revenue figures from SEC Financial Statement Data Sets (including rows folded from ConsolidationItems=OperatingSegments). Multi-axis cross-tabs and sign-sensitive expense lines are not served. Newest filing first.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
        - name: axis
          in: query
          required: false
          schema:
            type: string
            enum:
              - ProductOrService
              - ProductsAndServices
              - Producttype
              - BusinessLine
              - Geographical
              - GeographicalAreas
              - GeographicDistribution
              - BusinessSegments
              - Segments
              - Subsegments
        - name: period_end
          in: query
          required: false
          description: Filing period end (YYYY-MM-DD), matching the document's period field.
          schema:
            type: string
            format: date
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 50
            default: 20
        - name: cursor
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: One page of segment documents. Every figure carries its source accession.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DocumentPageResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/companies/{id}/holders:
    get:
      operationId: getCompanyHolders
      summary: Form 13F holders of an issuer for one report period (newest when period is omitted). Top 25 by value_usd by default; page the full list with limit and cursor. About 35% of 13F rows cannot be linked to a company with two pieces of evidence and are left out.
      parameters:
        - $ref: "#/components/parameters/CompanyId"
        - name: period
          in: query
          required: false
          description: Report period end (YYYY-MM-DD). Defaults to the newest period on file.
          schema:
            type: string
            format: date
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
        - name: cursor
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: One page of holder rows. Every row carries its source accession.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DocumentPageResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
  /v1/macro/{series}:
    get:
      operationId: getMacroSeries
      summary: One official macro series document. Series included only when the source's own terms clearly allow resale. Unknown query parameters get 400.
      parameters:
        - name: series
          in: path
          required: true
          schema:
            type: string
            enum:
              - cpi_u_all_items_sa
              - unemployment_rate_sa
      responses:
        "200":
          description: The series document.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MacroResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/Internal"
        "503":
          $ref: "#/components/responses/Unavailable"
components:
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-Key
  parameters:
    CompanyId:
      name: id
      in: path
      required: true
      description: A ticker in any case (`BRK.B` and `BRK-B` reach the same company) or a CIK with or without leading zeros.
      schema:
        type: string
  responses:
    BadRequest:
      description: The request is malformed or has an unknown query parameter.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Unauthorized:
      description: The key is missing, unknown or revoked.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    NotFound:
      description: No company matches this ticker or CIK.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    RateLimited:
      description: The key is over its per-minute limit.
      headers:
        Retry-After:
          description: Seconds to wait before trying again.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Internal:
      description: Something failed on our side.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Unavailable:
      description: The database can't be reached, or no data is loaded yet for this route. The code is `internal`. Try again after the wait given in Retry-After.
      headers:
        Retry-After:
          description: Seconds to wait before trying again.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
  schemas:
    Error:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - unauthorized
                - not_found
                - bad_request
                - rate_limited
                - internal
            message:
              type: string
    Meta:
      type: object
      additionalProperties: false
      required:
        - snapshot_id
        - as_of
        - next_cursor
      properties:
        snapshot_id:
          type:
            - string
            - "null"
          description: The snapshot served. Null only on /v1/status.
        as_of:
          type:
            - string
            - "null"
          format: date-time
          description: When the source data was published. Null only on /v1/status with nothing loaded.
        next_cursor:
          type:
            - string
            - "null"
          description: Pass as `cursor` for the next page. Null on the last page.
    MetricKey:
      type: string
      enum:
        - revenue
        - net_income
        - diluted_eps
        - operating_cash_flow
        - cash_and_equivalents
    Frequency:
      type: string
      enum:
        - annual
        - quarterly
    StatementKind:
      type: string
      description: Balance sheet, income, cash flow, comprehensive income.
      enum:
        - BS
        - IS
        - CF
        - CI
    Source:
      type: object
      description: The filing a figure came from.
      additionalProperties: false
      required:
        - accession
        - filing_url
        - form
        - filed
      properties:
        accession:
          type: string
          pattern: ^\d{10}-\d{2}-\d{6}$
        filing_url:
          type: string
          format: uri
        form:
          type: string
        filed:
          type: string
          format: date
    FirstReported:
      type: object
      description: The first filing to report this figure's exact period under this tag and unit, and the value it reported. Equal to `source` and `value` when the figure was never restated. Periodic reports rank first, the same rule `source` follows, so an 8-K or proxy counts only when no periodic report carries the period. A first report under an older tag is not traced.
      additionalProperties: false
      required:
        - value
        - accession
        - filed
      properties:
        value:
          type: number
        accession:
          type: string
          pattern: ^\d{10}-\d{2}-\d{6}$
        filed:
          type: string
          format: date
    Operand:
      type: object
      description: One of the two filed figures a derived quarter is computed from. The figure is minuend minus subtrahend.
      additionalProperties: false
      required:
        - role
        - accession
        - filing_url
        - form
        - filed
        - start
        - end
        - value
      properties:
        role:
          type: string
          enum:
            - minuend
            - subtrahend
        accession:
          type: string
          pattern: ^\d{10}-\d{2}-\d{6}$
        filing_url:
          type: string
          format: uri
        form:
          type: string
        filed:
          type: string
          format: date
        start:
          type: string
          format: date
        end:
          type: string
          format: date
        value:
          type: number
    Adjustment:
      type: object
      description: |
        Something the extractor did beyond copying one filed figure. The value depends on the kind:
        - `scale_corrected_from`: filings of this figure differ by a thousand or a million, and another filing's was taken. Usually the replaced figure was mis-tagged. A real 1-for-1000 split can look the same. Value is the figure replaced; `value` on the point and `source` are the sibling that was used.
        - `scale_dispute_resolved`: another filing states this figure at a thousand or a million times this value, and the series, the other frequency or the count of filings backs this one. Value is the other filing's figure, which can also be `first_reported`.
        - `negative_replaced_from`: the tag held a negative sub-line for this period, such as intersegment sales, so `value` is the listed total. Value is the figure replaced.
        - `negative_kept`: the figure is negative and was kept. Value is `total_over:<tag>` when the tag is the filer's total in other periods and `<tag>` is a positive part of it, or `no_listed_figure` when no listed tag has a positive figure for the period.
        - `source_replaced_from`: the newest filing of this period was a form that can carry another company's figures, such as an 8-K, so the figure comes from the filer's own filing of it. Value is the accession passed over.
        - `cash_aligned_from`: the annual and quarterly series held different figures for this balance under one tag, and this point now holds the newest figure a periodic filing's balance sheet shows for the date, named in `source`. Value is the figure replaced.
        - `cash_measure`: the figure includes restricted cash, because the company tags no cash and cash equivalents figure without it for this date. Value `includes_restricted`.
        - `balance_sheet_cash_over`: a figure that includes restricted cash was also filed for this date; the point takes the cash and cash equivalents figure the filing tags without it. Value is the tag passed over.
        - `zero_replaced_from`: a filed zero was replaced by a figure from another tag. Value is that tag.
        - `stitched_under`: this period came from an older tag, under the series' main tag. Value is the main tag.
        - `revenue_total_over`: the series uses a larger total over a tag that looked like a sub-line. Value is the tag passed over. Listed on every point of the series.
        - `fallback_measure`: the series uses a different measure, because no listed tag covers it. Value is the measure's tag. Listed on every point of the series.
        - `fallback_promoted_over`: the listed tags stopped being filed. Value is their last period end. Listed on every point of the series.
        - `ladder_stitched`: older tags filled in periods. Value is `tag:count`, comma separated.
        - `ambiguous_overlap`: other tags reported periods this series covers, and this series' figure was kept. Value is `tag:count`, comma separated.
        - `ignored_currency`: the filer also reported this tag in another unit, such as a convenience translation. Value lists the units.
      additionalProperties: false
      required:
        - kind
        - value
      properties:
        kind:
          type: string
          enum:
            - scale_corrected_from
            - scale_dispute_resolved
            - negative_replaced_from
            - negative_kept
            - source_replaced_from
            - cash_aligned_from
            - cash_measure
            - balance_sheet_cash_over
            - zero_replaced_from
            - stitched_under
            - revenue_total_over
            - fallback_measure
            - fallback_promoted_over
            - ladder_stitched
            - ambiguous_overlap
            - ignored_currency
        value:
          type:
            - string
            - number
    MetricPoint:
      type: object
      description: One figure. A filed figure names its filing, usually the newest within this frequency of it in `source` and the first in `first_reported`. A derived quarter has `source` and `first_reported` null and names both filings in `operands`.
      additionalProperties: false
      required:
        - metric
        - value
        - currency
        - period_end
        - start
        - frequency
        - fiscal_year
        - fiscal_quarter
        - concept
        - derived
        - adjustments
        - source
        - first_reported
        - operands
      properties:
        metric:
          $ref: "#/components/schemas/MetricKey"
        value:
          type: number
        currency:
          type:
            - string
            - "null"
        period_end:
          type: string
          format: date
        start:
          type:
            - string
            - "null"
          format: date
          description: First day of the period the figure covers. Null for a balance-sheet figure, or a filing that stated no start. On a derived quarter, the day after the subtrahend ends.
        frequency:
          $ref: "#/components/schemas/Frequency"
        fiscal_year:
          type:
            - integer
            - "null"
        fiscal_quarter:
          type:
            - integer
            - "null"
          minimum: 1
          maximum: 4
        concept:
          type: string
          description: The XBRL tag the figure was filed under.
        derived:
          type: boolean
        adjustments:
          type: array
          items:
            $ref: "#/components/schemas/Adjustment"
        source:
          oneOf:
            - $ref: "#/components/schemas/Source"
            - type: "null"
        first_reported:
          oneOf:
            - $ref: "#/components/schemas/FirstReported"
            - type: "null"
        operands:
          oneOf:
            - type: array
              minItems: 2
              maxItems: 2
              items:
                $ref: "#/components/schemas/Operand"
            - type: "null"
      if:
        properties:
          derived:
            const: true
      then:
        properties:
          source:
            type: "null"
          first_reported:
            type: "null"
          operands:
            type: array
      else:
        properties:
          source:
            $ref: "#/components/schemas/Source"
          first_reported:
            $ref: "#/components/schemas/FirstReported"
          operands:
            type: "null"
    MetricDocument:
      type: object
      description: The stored form, one per company, metric and frequency, in the `doc` column of `metric_docs.tsv.gz`. Not a response. Points are newest first.
      additionalProperties: false
      required:
        - metric
        - frequency
        - points
      properties:
        metric:
          $ref: "#/components/schemas/MetricKey"
        frequency:
          $ref: "#/components/schemas/Frequency"
        points:
          type: array
          items:
            $ref: "#/components/schemas/MetricPoint"
    StatementValue:
      type: object
      additionalProperties: false
      required:
        - period_end
        - quarters
        - value
        - display_value
        - unit
      if:
        properties:
          value:
            type: "null"
        required:
          - value
      then:
        properties:
          display_value:
            type: "null"
      properties:
        period_end:
          type: string
          format: date
          description: The SEC rounds this to the nearest month end, so Sep. 27, 2025 reads 2025-09-30 and a period ending Jan. 14, 2025 reads 2024-12-31. A metric point keeps the filed date, so the two can differ by days.
        quarters:
          type: integer
          minimum: 0
          description: The value's duration in whole quarters, which the SEC rounds to the nearest whole number. So 3 can be eight months, and two periods that round to the same month end and quarters share one value, because the data sets keep one. 0 means under about six weeks, which is a balance or a short period. On a balance sheet it is always a balance, and on an income or comprehensive income statement always a short period. On a cash flow statement it is a balance for opening and closing cash, and a short period on a flow line, and the value does not say which. Across the pilot's documents, 4,445 of the 241,550 cash flow values with 0 are short periods.
        value:
          type:
            - number
            - "null"
          description: The value as tagged in the filing, with no sign change. Null when the filing left it blank, never 0.
        display_value:
          type:
            - number
            - "null"
          description: "The figure with the sign the filing displays: `value`, or its opposite when `negating` is true. Null when `value` is null, or when `negating` is null."
        unit:
          type:
            - string
            - "null"
          description: "The unit of this value, such as USD or USD/shares. It sits on the value because one tag and period can be filed in two units (Pemex: MXN and USD), and both are listed."
    StatementEntry:
      type: object
      description: One tag on one statement. Values sit on the tag, not on a display line, because the data sets don't say which period each line shows. A tag the filing lists twice, typically beginning and ending cash, is one entry with two labels. No claim is made about which label a value belongs to. A tag with nothing reported has empty `values`. Lines tagged with a dimension, such as Apple's Products and Services net sales or figures for variable interest entities, are left out while totals are kept, so a statement can have lines its document lacks, and a line whose figures are all dimensional has empty `values`.
      additionalProperties: false
      required:
        - tag
        - taxonomy
        - is_custom
        - labels
        - line_numbers
        - negating
        - values
      if:
        properties:
          negating:
            type: "null"
        required:
          - negating
      then:
        properties:
          values:
            items:
              properties:
                display_value:
                  type: "null"
      properties:
        tag:
          type: string
        taxonomy:
          type: string
          description: The tag's taxonomy and version
          such as us-gaap/2024.: null
        is_custom:
          type: boolean
          description: True when the filer defined this tag itself.
        labels:
          type: array
          minItems: 1
          description: "The filing's own labels for this tag, in statement order. The data sets hold ASCII only, so other characters are lost: `stockholders’` reads `stockholders`."
          items:
            type: string
        line_numbers:
          type: array
          minItems: 1
          description: The tag's positions on the statement, in order, matching `labels`.
          items:
            type: integer
        negating:
          type:
            - boolean
            - "null"
          description: "True when the filing displays this tag with the opposite sign, which `display_value` applies and `value` does not. Null when the tag's lines disagree, so no single displayed sign exists: 28 of the 6,629 multi-line tags in 2026q3."
        values:
          type: array
          items:
            $ref: "#/components/schemas/StatementValue"
    StatementDocument:
      type: object
      description: One statement of one filing. Periodic forms only (10-K, 10-Q, 20-F, 40-F, 10-KT and their amendments).
      additionalProperties: false
      required:
        - accession
        - filing_url
        - statement
        - form
        - amends
        - fiscal_year
        - fiscal_period
        - period
        - filed
        - entries
      properties:
        accession:
          type: string
          pattern: ^\d{10}-\d{2}-\d{6}$
        filing_url:
          type: string
          format: uri
        statement:
          $ref: "#/components/schemas/StatementKind"
        form:
          type: string
        amends:
          type: boolean
          description: True when this filing is an amendment. The data sets don't name the filing it amends.
        fiscal_year:
          type:
            - integer
            - "null"
        fiscal_period:
          type:
            - string
            - "null"
        period:
          type:
            - string
            - "null"
          format: date
          description: The filing's balance-sheet date, rounded by the SEC to the nearest month end.
        filed:
          type: string
          format: date
        entries:
          type: array
          items:
            $ref: "#/components/schemas/StatementEntry"
    Company:
      type: object
      additionalProperties: false
      required:
        - cik
        - name
        - sic
        - country
        - fiscal_year_end
        - tickers
        - metrics_from
        - statements_from
        - reorganization
      properties:
        cik:
          type: string
          pattern: ^\d{10}$
        name:
          type: string
        sic:
          type:
            - string
            - "null"
        country:
          type:
            - string
            - "null"
        fiscal_year_end:
          type:
            - string
            - "null"
          description: Month and day as MMDD.
        tickers:
          type: array
          description: "Every ticker that reaches this company. Empty for a filer with none, which still works by CIK. A ticker reaches one CIK, and may not be where the SEC's ticker file lists it: see `reorganization`."
          items:
            type: string
        metrics_from:
          type:
            - string
            - "null"
          format: date
        statements_from:
          type:
            - string
            - "null"
          format: date
        reorganization:
          oneOf:
            - $ref: "#/components/schemas/Reorganization"
            - type: "null"
    Reorganization:
      type: object
      description: This company is one of two CIKs of one business, after a holding company reorganization or a change of domicile, and the record is the same on both. The SEC's ticker file lists the tickers under `new_cik`, while the older statements sit under `filings_cik`. The tickers reach `filings_cik` until `new_cik` has statements of its own, then `new_cik`. Each CIK's metrics and statements come from that CIK alone and are never joined, so ask for the other CIK by number to see its figures. Until the tickers move, newer figures can sit under `new_cik`.
      additionalProperties: false
      required:
        - new_cik
        - filings_cik
        - tickers
        - evidence
      properties:
        new_cik:
          type: string
          pattern: ^\d{10}$
        filings_cik:
          type: string
          pattern: ^\d{10}$
        tickers:
          type: array
          minItems: 1
          items:
            type: string
        evidence:
          type: string
          description: The SEC filings that show the reorganization.
    DataAge:
      type: object
      additionalProperties: false
      required:
        - snapshot_id
        - as_of
        - loaded_at
        - age_hours
      properties:
        snapshot_id:
          type: string
        as_of:
          type: string
          format: date-time
        loaded_at:
          type: string
          format: date-time
        age_hours:
          type: number
    OwnershipRecord:
      type: object
      description: One reporting owner on one Schedule 13D or 13G filing. Multiple owners on one filing are separate records; their shares must not be summed as if they were separate holdings. `shares` and `percent_of_class` are text as filed. Blank is null, never zero. Pre-2024-12-18 SC 13D/13G text filings are out of scope.
      additionalProperties: false
      required:
        - issuer_cik
        - owner_name
        - owner_cik
        - form
        - event_date
        - filed
        - shares
        - percent_of_class
        - amendment_number
        - prior_accession
        - accession
        - filing_url
      properties:
        issuer_cik:
          type: string
          pattern: ^\d{10}$
        owner_name:
          type:
            - string
            - "null"
        owner_cik:
          type:
            - string
            - "null"
          pattern: ^\d{10}$
        form:
          type: string
        event_date:
          type:
            - string
            - "null"
          format: date
        filed:
          type: string
          format: date
        shares:
          type:
            - string
            - "null"
          description: Aggregate amount owned
          as filed text.: null
        percent_of_class:
          type:
            - string
            - "null"
          description: Percent of class as filed text.
        amendment_number:
          type:
            - integer
            - "null"
          minimum: 0
        prior_accession:
          type:
            - string
            - "null"
          pattern: ^\d{10}-\d{2}-\d{6}$
          description: An earlier accession named by an amendment, when present.
        accession:
          type: string
          pattern: ^\d{10}-\d{2}-\d{6}$
        filing_url:
          type: string
          format: uri
    MacroPoint:
      type: object
      additionalProperties: false
      required:
        - date
        - value
        - unit
        - source_url
        - fetched_at
        - seasonal_adjustment
        - revision_status
      properties:
        date:
          type: string
          format: date
        value:
          type:
            - number
            - string
            - "null"
        unit:
          type: string
        source_url:
          type: string
          format: uri
        fetched_at:
          type: string
          format: date-time
        seasonal_adjustment:
          type: string
        revision_status:
          type: string
    MacroDocument:
      type: object
      additionalProperties: false
      required:
        - series
        - series_id
        - title
        - unit
        - seasonal_adjustment
        - revision_status
        - keep_vintages
        - source_url
        - fetched_at
        - points
      properties:
        series:
          type: string
        series_id:
          type: string
        title:
          type: string
        unit:
          type: string
        seasonal_adjustment:
          type: string
        revision_status:
          type: string
        keep_vintages:
          type: boolean
          description: False for the pilot. CPI and unemployment are revised; this build keeps the latest published reading only, not vintages.
        source_url:
          type: string
          format: uri
        fetched_at:
          type: string
          format: date-time
        points:
          type: array
          items:
            $ref: "#/components/schemas/MacroPoint"
    NormalizedField:
      type: string
      enum:
        - revenue
        - cost_of_revenue
        - gross_profit
        - operating_income
        - net_income
        - net_income_attributable
        - basic_eps
        - diluted_eps
        - weighted_diluted_shares
        - sga
        - research_development
        - interest_expense
        - income_tax
        - pretax_income
        - cash_and_equivalents
        - total_assets
        - total_liabilities
        - total_equity
        - equity_attributable
        - current_assets
        - current_liabilities
        - receivables
        - inventory
        - ppe_net
        - goodwill
        - intangibles
        - long_term_debt
        - short_term_debt
        - accounts_payable
        - retained_earnings
        - operating_cash_flow
        - investing_cash_flow
        - financing_cash_flow
        - capital_expenditure
        - depreciation_amortization
        - dividends_paid
        - share_repurchases
        - stock_compensation
    NormalizedFact:
      type: object
      additionalProperties: false
      required:
        - cik
        - period_end
        - quarters
        - field
        - value
        - unit
        - derived
        - source_accession
        - tag
      properties:
        cik:
          type: string
          pattern: ^[0-9]{10}$
        period_end:
          type: string
          format: date
        quarters:
          type: integer
          minimum: 0
        field:
          $ref: "#/components/schemas/NormalizedField"
        value:
          type: number
        unit:
          oneOf:
            - type: string
            - type: "null"
        derived:
          type: boolean
        source_accession:
          type: string
        tag:
          oneOf:
            - type: string
            - type: "null"
    Status:
      type: object
      additionalProperties: false
      required:
        - metrics
        - statements
        - ownership
        - macro
        - insider
        - form13f
        - filings
        - normalized
        - segments
        - holders
        - earnings
      properties:
        metrics:
          oneOf:
            - $ref: "#/components/schemas/DataAge"
            - type: "null"
        statements:
          oneOf:
            - $ref: "#/components/schemas/DataAge"
            - type: "null"
        ownership:
          oneOf:
            - $ref: "#/components/schemas/DataAge"
            - type: "null"
        macro:
          oneOf:
            - $ref: "#/components/schemas/DataAge"
            - type: "null"
        insider:
          oneOf:
            - $ref: "#/components/schemas/DataAge"
            - type: "null"
        form13f:
          oneOf:
            - $ref: "#/components/schemas/DataAge"
            - type: "null"
        filings:
          oneOf:
            - $ref: "#/components/schemas/DataAge"
            - type: "null"
        normalized:
          oneOf:
            - $ref: "#/components/schemas/DataAge"
            - type: "null"
        segments:
          oneOf:
            - $ref: "#/components/schemas/DataAge"
            - type: "null"
        holders:
          oneOf:
            - $ref: "#/components/schemas/DataAge"
            - type: "null"
        earnings:
          oneOf:
            - $ref: "#/components/schemas/DataAge"
            - type: "null"
    EarningsReleaseListItem:
      type: object
      additionalProperties: false
      required:
        - accession
        - filed
        - period
        - title
        - title_source
        - exhibit_type
        - exhibit_description
        - items
        - exhibit_url
        - filing_url
      properties:
        accession:
          type: string
          pattern: ^\d{10}-\d{2}-\d{6}$
        filed:
          oneOf:
            - type: string
              format: date
            - type: "null"
        period:
          oneOf:
            - type: string
              format: date
            - type: "null"
        title:
          oneOf:
            - type: string
            - type: "null"
        title_source:
          oneOf:
            - type: string
            - type: "null"
        exhibit_type:
          oneOf:
            - type: string
            - type: "null"
        exhibit_description:
          oneOf:
            - type: string
            - type: "null"
        items:
          type: array
          items:
            type: string
        exhibit_url:
          type: string
          format: uri
        filing_url:
          type: string
          format: uri
    EarningsRelease:
      type: object
      additionalProperties: false
      required:
        - accession
        - filed
        - period
        - title
        - title_source
        - exhibit_type
        - exhibit_description
        - items
        - exhibit_url
        - filing_url
        - text
      properties:
        accession:
          type: string
          pattern: ^\d{10}-\d{2}-\d{6}$
        filed:
          oneOf:
            - type: string
              format: date
            - type: "null"
        period:
          oneOf:
            - type: string
              format: date
            - type: "null"
        title:
          oneOf:
            - type: string
            - type: "null"
        title_source:
          oneOf:
            - type: string
            - type: "null"
        exhibit_type:
          oneOf:
            - type: string
            - type: "null"
        exhibit_description:
          oneOf:
            - type: string
            - type: "null"
        items:
          type: array
          items:
            type: string
        exhibit_url:
          type: string
          format: uri
        filing_url:
          type: string
          format: uri
        text:
          oneOf:
            - type: string
            - type: "null"
    EarningsReleasePageResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/EarningsReleaseListItem"
        meta:
          $ref: "#/components/schemas/Meta"
    EarningsReleaseResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          $ref: "#/components/schemas/EarningsRelease"
        meta:
          $ref: "#/components/schemas/Meta"
    FinancialsResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/NormalizedFact"
        meta:
          $ref: "#/components/schemas/Meta"
    DocumentPageResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          type: array
          items:
            type: object
        meta:
          $ref: "#/components/schemas/Meta"
    StatusResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          $ref: "#/components/schemas/Status"
        meta:
          $ref: "#/components/schemas/Meta"
    CompanyResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          $ref: "#/components/schemas/Company"
        meta:
          $ref: "#/components/schemas/Meta"
    MetricsResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/MetricPoint"
        meta:
          $ref: "#/components/schemas/Meta"
    StatementsResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/StatementDocument"
        meta:
          $ref: "#/components/schemas/Meta"
    OwnershipResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/OwnershipRecord"
        meta:
          $ref: "#/components/schemas/Meta"
    MacroResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          $ref: "#/components/schemas/MacroDocument"
        meta:
          $ref: "#/components/schemas/Meta"
