{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Daily App Sales schema",
  "description": "Complete reference record shape. Nullable logical fields; see source documentation for report-specific availability.",
  "$comment": "https://netice.fi/product/documentation/unified-app-sales-daily-schema/",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "revenue_date",
    "platform",
    "app_id",
    "source_kind",
    "source",
    "country",
    "report_currency",
    "estimated_gross",
    "estimated_net",
    "estimated_tax",
    "estimated_fee",
    "native_currency",
    "gross_local",
    "net_local",
    "tax_local",
    "fee_local",
    "apple_proceeds_currency",
    "apple_proceeds_native",
    "gross_fx",
    "net_fx",
    "tax_fx",
    "fee_fx",
    "net_method",
    "fee_method",
    "tax_method",
    "data_completeness",
    "source_report",
    "event_has_revenue",
    "subscription_period",
    "units",
    "item_id",
    "item_name",
    "transaction_type",
    "source_file_uri",
    "source_row_number",
    "source_row_hash",
    "ingested_at",
    "meta_json"
  ],
  "properties": {
    "revenue_date": {
      "description": "Daily source reporting date. Keep its source date meaning when grouping trends; it is not an ingestion timestamp.",
      "type": [
        "string",
        "null"
      ],
      "format": "date"
    },
    "platform": {
      "description": "Platform code, such as IOS or ANDROID .",
      "type": [
        "string",
        "null"
      ]
    },
    "app_id": {
      "description": "App identifier from the source. Apple identifiers and Google package names need not use the same format.",
      "type": [
        "string",
        "null"
      ]
    },
    "source_kind": {
      "description": "SALES for this output.",
      "type": [
        "string",
        "null"
      ]
    },
    "source": {
      "description": "Provider code, such as APPLE_APP_STORE or GOOGLE_PLAY .",
      "type": [
        "string",
        "null"
      ]
    },
    "country": {
      "description": "Buyer or storefront country code where available.",
      "type": [
        "string",
        "null"
      ]
    },
    "report_currency": {
      "description": "Configured currency of the four estimated_* amount columns.",
      "type": [
        "string",
        "null"
      ]
    },
    "estimated_gross": {
      "description": "Gross analytical amount in report currency. It can be sourced, derived or supplied through an estimation fallback.",
      "type": [
        "number",
        "null"
      ]
    },
    "estimated_net": {
      "description": "Estimated developer-side net proceeds in report currency. Read net_method alongside it.",
      "type": [
        "number",
        "null"
      ]
    },
    "estimated_tax": {
      "description": "Tax analytical amount in report currency. tax_method distinguishes source tax, residual estimates and assumptions.",
      "type": [
        "number",
        "null"
      ]
    },
    "estimated_fee": {
      "description": "Estimated platform fee in report currency, with its basis in fee_method .",
      "type": [
        "number",
        "null"
      ]
    },
    "native_currency": {
      "description": "Shared currency label for the *_local columns. It prioritizes the gross component currency, then net, tax and fee currency; report currency is the final fallback.",
      "type": [
        "string",
        "null"
      ]
    },
    "gross_local": {
      "description": "Gross component in native_currency , when available or estimated.",
      "type": [
        "number",
        "null"
      ]
    },
    "net_local": {
      "description": "Net component in native_currency . Null when its component currency differs; Apple proceeds may still be present in their separate fields.",
      "type": [
        "number",
        "null"
      ]
    },
    "tax_local": {
      "description": "Tax component in native_currency , when available or estimated; null when the component uses another currency.",
      "type": [
        "number",
        "null"
      ]
    },
    "fee_local": {
      "description": "Fee component in native_currency , when available or estimated; null when the component uses another currency.",
      "type": [
        "number",
        "null"
      ]
    },
    "apple_proceeds_currency": {
      "description": "Currency of the Apple proceeds component. Empty or null for Google rows.",
      "type": [
        "string",
        "null"
      ]
    },
    "apple_proceeds_native": {
      "description": "Apple proceeds component at row level in apple_proceeds_currency . Summary Sales per-unit proceeds are multiplied by signed units before this output; analytical fallback can apply if source amounts are unavailable.",
      "type": [
        "number",
        "null"
      ]
    },
    "gross_fx": {
      "description": "Conversion factor used for the gross component to report currency, where resolved.",
      "type": [
        "number",
        "null"
      ]
    },
    "net_fx": {
      "description": "Conversion factor used for the net component to report currency. Its source currency can differ from native_currency on Apple rows.",
      "type": [
        "number",
        "null"
      ]
    },
    "tax_fx": {
      "description": "Conversion factor used for the tax component to report currency, where resolved.",
      "type": [
        "number",
        "null"
      ]
    },
    "fee_fx": {
      "description": "Conversion factor used for the fee component to report currency, where resolved.",
      "type": [
        "number",
        "null"
      ]
    },
    "net_method": {
      "description": "Calculation or source basis for net proceeds. Labels containing ESTIMATED or ASSUMED_ZERO describe analytical assumptions.",
      "type": [
        "string",
        "null"
      ]
    },
    "fee_method": {
      "description": "Fee calculation basis, including whether the estimate uses proceeds, gross or a Google fee rule.",
      "type": [
        "string",
        "null"
      ]
    },
    "tax_method": {
      "description": "Tax basis. Examples include GOOGLE_TAXES_COLLECTED , an Apple residual estimate, and unavailable-tax zero assumptions.",
      "type": [
        "string",
        "null"
      ]
    },
    "data_completeness": {
      "description": "Age-based daily status: LIVE , T_PLUS_2_STABILIZED or MATURE . It does not certify settlement, exact FX or absence of future corrections.",
      "type": [
        "string",
        "null"
      ]
    },
    "source_report": {
      "description": "Report family, such as ASC_SUMMARY_SALES or GP_ESTIMATED_SALES ; subscription reports have separate labels.",
      "type": [
        "string",
        "null"
      ]
    },
    "event_has_revenue": {
      "description": "Revenue/lifecycle indicator. It helps distinguish state-change-only events, but does not certify a nonzero or source-verified amount.",
      "type": [
        "boolean",
        "null"
      ]
    },
    "subscription_period": {
      "description": "Normalized subscription duration, such as P1M or P1Y , when available.",
      "type": [
        "string",
        "null"
      ]
    },
    "units": {
      "description": "Signed source units where disclosed. Do not infer the number of individual purchases from a row count.",
      "type": [
        "number",
        "null"
      ]
    },
    "item_id": {
      "description": "Product or SKU identifier supplied by the source.",
      "type": [
        "string",
        "null"
      ]
    },
    "item_name": {
      "description": "Product name or title, where available.",
      "type": [
        "string",
        "null"
      ]
    },
    "transaction_type": {
      "description": "Normalized transaction or lifecycle label, including purchase, new sale, renewal, refund and supported subscription events.",
      "type": [
        "string",
        "null"
      ]
    },
    "source_file_uri": {
      "description": "Source artifact or report request reference. A reference is not necessarily a publicly downloadable URL.",
      "type": [
        "string",
        "null"
      ]
    },
    "source_row_number": {
      "description": "One-based source row position where available. It may be absent for aggregated sources.",
      "type": [
        "integer",
        "null"
      ]
    },
    "source_row_hash": {
      "description": "Fingerprint of the source row for traceability across reads. Combine with report and source context; do not assume it is a purchase ID.",
      "type": [
        "string",
        "null"
      ]
    },
    "ingested_at": {
      "description": "UTC time when the row was materialized. It is separate from revenue_date .",
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "meta_json": {
      "description": "Additional source context and derivation details. Gross calculation basis appears as gross_method here, not as a separate column in the 38-field contract. FX details can include effective date and fallback information.",
      "type": [
        "string",
        "null"
      ],
      "contentMediaType": "application/json"
    }
  }
}
