Netice app revenue data infrastructure
Monthly platform finance schema
The Netice monthly platform finance schema describes the finance_unified output for Apple App Store Connect financeReports and Google Play monthly Earnings reports. It is built for finance and data teams that need platform-reported finance data in their own warehouse or storage destination without confusing it with daily app-sales analytics.
What the monthly platform finance schema is for
The monthly platform finance schema is the Netice field contract for platform finance reporting. It is the schema used by the finance_unified source mode. The schema is intended for Apple App Store Connect financeReports and Google Play monthly Earnings reports, normalized into a source-aware monthly finance output.
The output is event-grain. That means it should not be read as “one row per app per month.” A row represents an economic event or finance report line after Netice has preserved the platform source, report family, period, event type, native currency, report currency and lineage context. Apple and Google Play do not expose identical finance reports, so the schema keeps their differences visible instead of flattening everything into a generic revenue number.
This schema applies across customer-owned destinations such as BigQuery, Snowflake, Google Cloud Storage and AWS S3. The destination changes the delivery format, not the meaning of the fields. The semantic contract remains finance_unified.
What this schema is not for
The monthly platform finance schema is not the same as Daily App Sales. Daily App Sales uses source_kind = 'SALES' and supports daily operational analytics. Finance Unified uses source_kind = 'FINANCE' and preserves monthly platform finance report semantics.
This schema should not be described as audited accounting, tax advice, bank-statement matching, GAAP, IFRS, ASC 606 compliance or general-ledger truth. It is platform-reported finance data prepared for customer-owned destinations. Final booked revenue remains the customer’s accounting process.
The current repo evidence marks Finance Unified as staging-only. Do not publish production-availability claims unless product approval supersedes that readiness state.
Source reports and source kind
The core identifier for this layer is source_kind = 'FINANCE'. This separates finance rows from daily sales rows before they ever reach a dashboard, warehouse model or AI-generated summary.
| Platform | Finance source family | Current source report values | What to avoid |
|---|---|---|---|
| Apple App Store | App Store Connect financeReports | APPLE_FINANCE_DETAIL, APPLE_FINANCIAL |
Do not call Apple Summary Sales or Sales and Trends a finance source. |
| Google Play | Google Play monthly Earnings reports | GOOGLE_PLAY_EARNINGS |
Do not call Google Play Estimated Sales a finance source. |
This distinction matters because daily app-sales tables and monthly finance tables can both contain revenue-related numbers, but they answer different questions. Finance rows are period-aware, event-aware and source-report-aware. They should not be written into daily app-sales artifacts or interpreted through daily app-sales fields such as revenue_date, estimated_net or data_completeness.
Canonical field groups
The finance schema has a stable field order that acts as the cross-destination contract. BigQuery tables, Snowflake tables, CSV bundles, schema JSON and tests all rely on the same field sequence. The field list is intentionally richer than a simple revenue table because platform finance data needs period, event, currency, finality and lineage context.
| Field group | Representative fields | Why it matters |
|---|---|---|
| Layer and source identity | platform, source, source_kind, source_report, source_schema_version |
Identifies the provider, report family and finance schema contract. |
| Payout/legal entity context | derived_payout_legal_entity, payout_entity_resolution_status |
Preserves payout-entity resolution without exposing raw vendor values. |
| Source lineage | source_file_name, source_file_uri, source_row_number, source_row_hash, source_vendor_hash |
Supports provenance, replay and duplicate review using safe references and synthetic examples. |
| Apple finance context | apple_finance_region_code, apple_finance_report_type |
Keeps Apple financeReports scope visible without treating it as buyer geography. |
| Period semantics | fiscal_period, apple_fiscal_label, calendar_period, period_start, period_end, period_calendar_type |
Separates Apple fiscal periods from Google monthly earnings periods and calendar buckets. |
| Date attribution | transaction_date, settlement_date, effective_revenue_date, effective_revenue_date_basis, source_timezone |
Explains which date was used and prevents hidden date assumptions. |
| App/product dimensions | app_id, sku, product_type, country, apple_buyer_subdivision |
Supports app, SKU, product and country analysis while preserving platform-specific meaning. |
| Event semantics | event_type, event_category, event_subtype, refund_type, commission_disclosed, quantity |
Preserves whether a row is sale, refund, platform fee, tax, adjustment or another finance event. |
| Native and report currency | native_currency, native_net_proceeds, native_customer_charge, report_currency, report_net_proceeds, report_customer_charge, fx_rate |
Keeps source-native amounts separate from report-currency presentation fields. |
| Quality, reconciliation and metadata | is_final, reconciliation_group_key, raw_metadata, ingested_at, source_available_at |
Supports finality review, aggregate diagnostics and safe metadata without exposing raw source rows. |
Field-level reference
The table below gives the practical interpretation of the most important fields. It is not a full database dump; it is the field contract a finance or data team needs before using the output in a warehouse, storage bucket or downstream BI model.
| Field | Meaning | How to read it |
|---|---|---|
source_kind |
Finance layer marker. | Finance rows use FINANCE. Daily app-sales rows use a different layer and should not be mixed into this schema. |
source_report |
Provider finance report family. | Apple rows use finance report labels such as APPLE_FINANCE_DETAIL or APPLE_FINANCIAL. Google rows use GOOGLE_PLAY_EARNINGS. |
report_grain |
Natural source row grain. | Examples include Apple finance detail, Apple finance summary, Google Earnings ledger line and Google Earnings adjustment. It is not the same as event_type. |
fiscal_period |
Platform-native statement month start. | Use this for finance-period reporting. Do not replace it with daily sales revenue_date. |
apple_fiscal_label |
Apple-facing fiscal label. | Apple-specific. It helps avoid confusing Apple fiscal periods with calendar months. |
calendar_period |
Calendar month bucket. | Useful for cross-platform analytics, but Apple calendar period should not be treated as the authoritative payout dimension when fiscal period is required. |
period_calendar_type |
Period calendar family. | Values distinguish Apple fiscal months from Google Play Earnings months. |
effective_revenue_date |
Revenue attribution date fallback. | Derived from transaction date, settlement date or period end, with effective_revenue_date_basis explaining which input was used. |
event_type |
Canonical economic event type. | Apple emits sale/refund style events. Google Earnings can preserve sale, refund, platform fee, tax and adjustment style ledger rows. |
commission_disclosed |
Whether commission/tax economics are disclosed as source facts. | Apple finance does not fabricate separate platform fee or tax rows when Apple does not disclose them. Google Earnings can include ledger rows for fees and taxes. |
native_currency |
Source-native payout or merchant currency. | Native amounts remain native. Report currency is a presentation layer, not a replacement for source currency. |
native_net_proceeds |
Signed developer-side event amount in native currency. | The primary native finance amount. It should not be overwritten by report-currency presentation logic. |
native_customer_charge |
Signed customer-side charge amount when the event is a customer charge or refund. | Expected to be null on fee, tax and adjustment rows where there is no customer charge. |
report_currency |
Customer-selected presentation currency. | Not necessarily the native source currency. |
report_net_proceeds |
Native proceeds converted into report currency when FX is available. | Missing cross-currency FX should leave this null rather than producing fake values. |
fx_rate |
Native-to-report conversion rate. | Same-currency conversion can use 1. Missing cross-currency FX must not silently become 1. |
is_final |
Derived finance finality flag. | False at ingest and later derived from period status. It is not a provider-guaranteed audit or accounting-close flag. |
raw_metadata |
Safe parser metadata. | Should contain bounded descriptors, not raw provider rows or sensitive values. |
Apple financeReports behavior
Apple finance rows in this schema come from App Store Connect financeReports, not Sales and Trends reports. That distinction is not cosmetic. Apple Summary Sales and Apple financeReports have different purposes, fields, periods and finance meaning.
Apple finance rows preserve Apple fiscal-period context. Fields such as fiscal_period, apple_fiscal_label, period_start, period_end and period_calendar_type help downstream teams avoid treating Apple fiscal periods as ordinary calendar months.
Apple finance behavior is also asymmetric with Google. Apple finance output emits sale and refund finance events where those are supported by the source. It does not fabricate separate platform fee or tax events when Apple does not disclose them as separate source facts. That is why fields such as commission_disclosed and null handling matter.
Google Play Earnings behavior
Google Play finance rows in this schema come from Google Play monthly Earnings reports, not Google Play Estimated Sales. Earnings reports are monthly finance-style reports and can preserve ledger-like event rows.
Google finance output can include event types such as SALE, REFUND, PLATFORM_FEE, PLATFORM_FEE_REVERSAL, TAX and ADJUSTMENT. Fee and tax rows can have null customer-charge fields because they are not customer charge events. This is expected and should not be interpreted as missing sales data.
Google Play Earnings should not be described as including chargebacks unless that is separately supported. The finance schema should preserve what the provider reports, not invent unsupported event categories.
Monthly, fiscal-period and calendar-period semantics
Finance output is period-based. It is not a daily date table. The schema uses fiscal_period for platform-native statement periods and calendar_period as a calendar bucket. Apple and Google are not identical here.
Apple Finance Reports use fiscal periods. Apple rows can preserve period_start, period_end, fiscal_period and apple_fiscal_label. Google Play Earnings reports are monthly, and Google fiscal period and calendar period are usually the same month start in the current mapping.
The finance replacement scope is based on finance period and source scope. It is not the same as refreshing daily app-sales windows by revenue_date. This prevents monthly finance output from being accidentally treated like a daily sales table.
Native currency, report currency and FX
Native values remain native in the finance schema. Fields such as native_currency, native_net_proceeds and native_customer_charge preserve the provider-side amount context. Report-currency fields such as report_currency, report_net_proceeds, report_customer_charge and fx_rate are presentation fields.
Same-currency conversion can use an FX rate of 1. Cross-currency conversion must have a resolvable FX rate. If the rate is missing, report-currency fields remain null rather than silently becoming fake values.
Apple and Google differ here as well. Apple native proceeds come from Apple finance report proceeds context. Google native proceeds come from Google Earnings merchant-currency amounts. Google fee, tax and adjustment rows may not have a customer charge. Apple finance does not reconstruct exact separate Apple fee/tax rows from the spread.
Null-not-zero policy
The finance schema intentionally treats unknown values differently from zero. Unknown finance amounts remain null. Real zero remains zero. That distinction is important because a fake zero can look like a real finance fact and flow into close, reconciliation or BI logic.
| Situation | Correct handling | Why |
|---|---|---|
| Unknown finance amount | Keep null | Unknown does not mean zero. |
| Real source value is zero | Keep zero | Zero is a real reported value when the source or derivation supports it. |
| Google fee row has no customer charge | Keep customer-charge fields null | A fee ledger row is not a customer sale row. |
| Apple does not disclose separate platform fee/tax finance events | Do not fabricate fee/tax rows | The schema should preserve provider truth, not invent missing rows. |
| Cross-currency FX unavailable | Keep report-currency fields null | Missing FX must not become a fake report-currency amount. |
Source lineage and safe metadata
Finance output needs traceability, but public documentation and safe summaries must not expose raw provider rows, real vendor numbers, app IDs, SKUs, object paths, source files, credentials, logs, task IDs or customer data.
The schema includes lineage fields such as source_file_name, source_file_uri, source_row_number, source_row_hash, source_vendor_hash, source_schema_version and raw_metadata. In public examples, these should always be synthetic. In product behavior, these fields support provenance and diagnostics without turning the schema into a raw source dump.
Finality and period status
The is_final field is a derived finance finality field. It is false at ingest and later derived from period status after successful materialization and source-data stability. It should not be described as a provider-guaranteed audit flag or accounting close approval.
Current evidence describes a default finality policy based on business days after period end and after the latest source data change. That is an operational finality policy for the finance output. It does not replace the customer’s accounting process.
Destination output: BigQuery, Snowflake, GCS and S3
The same finance schema applies across supported destinations. Warehouse destinations provide managed tables. Object-storage destinations provide a finance CSV and related sidecar artifacts.
| Destination | Default output example | Schema meaning |
|---|---|---|
| BigQuery | example_project.example_dataset.finance_unified |
Managed finance table with the finance_unified schema. |
| Snowflake | EXAMPLE_DATABASE.EXAMPLE_SCHEMA.FINANCE_UNIFIED |
Managed finance table with the same finance field contract. |
| Google Cloud Storage | gs://example_bucket/finance/finance_unified_EUR.csv |
Finance fact CSV plus same-stem sidecars when configured. |
| AWS S3 | s3://example_bucket/finance/finance_unified_EUR.csv |
Finance fact CSV plus same-stem sidecars when configured. |
Finance destinations should not collide with daily app-sales artifact names. A finance output should not write into daily sales tables or files, and a daily sales output should not write into finance artifacts.
Format changes and schema drift
Apple and Google can add or change source report columns. The finance schema is designed around source-specific parsers and header-based parsing rather than fragile column-position assumptions. New optional columns can be handled as metadata. Missing required headers should produce a clear failure rather than silently changing the meaning of finance rows.
Schema-drift warnings should expose bounded schema metadata, not raw row values. A provider format change is a support and data-quality condition. It is not the same thing as zero revenue.
Safe synthetic examples
The examples below are synthetic and shortened for readability. They show the shape of the finance schema without using real app IDs, SKUs, vendor numbers, source files, hashes, destinations, credentials, task IDs, logs or customer amounts.
Apple finance sale row
platform,source,source_kind,source_report,report_grain,fiscal_period,apple_fiscal_label,period_calendar_type,event_type,event_category,commission_disclosed,native_currency,native_net_proceeds,native_customer_charge,report_currency,report_net_proceeds,report_customer_charge,fx_rate,is_final,source_row_hash
IOS,APPLE_APP_STORE,FINANCE,APPLE_FINANCE_DETAIL,APPLE_FINANCE_DETAIL,2026-04-01,FY26-M04,APPLE_FISCAL_MONTH,SALE,REVENUE,false,EUR,6.990000,9.990000,EUR,6.990000,9.990000,1,false,synthetic_hash_apple_finance_001
Google Play finance ledger rows
platform,source,source_kind,source_report,report_grain,fiscal_period,period_calendar_type,event_type,event_category,event_subtype,commission_disclosed,native_currency,native_net_proceeds,native_customer_charge,report_currency,report_net_proceeds,report_customer_charge,fx_rate,is_final,source_row_hash
ANDROID,GOOGLE_PLAY,FINANCE,GOOGLE_PLAY_EARNINGS,GOOGLE_EARNINGS_LEDGER_LINE,2026-04-01,GOOGLE_PLAY_EARNINGS_MONTH,SALE,REVENUE,,true,EUR,9.990000,9.990000,EUR,9.990000,9.990000,1,false,synthetic_hash_google_charge_001
ANDROID,GOOGLE_PLAY,FINANCE,GOOGLE_PLAY_EARNINGS,GOOGLE_EARNINGS_LEDGER_LINE,2026-04-01,GOOGLE_PLAY_EARNINGS_MONTH,PLATFORM_FEE,DEDUCTION,COMMISSION,true,EUR,-3.000000,,EUR,-3.000000,,1,false,synthetic_hash_google_fee_001
In the Google fee row, the customer-charge fields are blank intentionally. That blank means null, not zero. A platform fee ledger row is not a customer charge row.
Monthly finance query
SELECT
platform,
fiscal_period,
source_report,
SUM(report_net_proceeds) AS report_net_proceeds
FROM `example_project.example_dataset.finance_unified`
WHERE fiscal_period = DATE '2026-04-01'
AND source_kind = 'FINANCE'
GROUP BY platform, fiscal_period, source_report
ORDER BY platform, source_report;
Event mix query
SELECT
platform,
source_report,
event_type,
event_category,
SUM(report_net_proceeds) AS report_net_proceeds
FROM `example_project.example_dataset.finance_unified`
WHERE fiscal_period = DATE '2026-04-01'
GROUP BY platform, source_report, event_type, event_category
ORDER BY platform, event_type;
These queries are examples for monthly platform finance output. They are not accounting close instructions and not bank reconciliation guarantees.
FAQ
What is the Monthly Platform Finance Schema?
It is the Netice finance_unified field contract for monthly Apple App Store Connect financeReports and Google Play Earnings reports. It preserves source report, period, event, native currency, report currency, finality and lineage context.
Is this the same as daily app-sales analytics?
No. Daily App Sales uses source_kind = 'SALES' and daily app-sales fields. Monthly Platform Finance uses source_kind = 'FINANCE' and finance-period fields.
Which Apple reports feed this schema?
Apple finance rows come from App Store Connect financeReports. Apple Sales and Trends or Summary Sales should not be described as feeding this finance schema.
Which Google Play reports feed this schema?
Google finance rows come from Google Play monthly Earnings reports. Google Play Estimated Sales belongs to the daily sales layer, not this finance schema.
What does source_kind=FINANCE mean?
It marks the row as monthly platform finance output rather than daily app-sales analytics. This helps downstream users avoid mixing finance rows into daily sales tables.
What is the difference between fiscal_period and calendar_period?
fiscal_period is the platform-native finance period. calendar_period is a calendar bucket useful for cross-platform analytics. Apple fiscal periods should not be flattened into calendar months without context.
Why are Apple fee and tax rows not separate events?
Apple finance output should not fabricate separate platform fee or tax events when Apple does not disclose them as separate finance facts. The schema preserves provider truth rather than inventing missing rows.
Why are Google fee and tax rows separate events?
Google Play Earnings can preserve ledger-style rows for charges, fees, tax, refunds and adjustments. Those rows should remain separate finance events when the source provides them.
What does null mean in finance output?
Null means unknown, unsupported, absent, not applicable or not disclosed depending on the field. It does not mean zero. Real zero remains zero.
What does is_final mean?
is_final is a derived finance finality field based on period status and source-data stability. It is not a provider-guaranteed audit flag or accounting-close approval.
Does this schema apply to BigQuery and object-storage outputs?
Yes. The same semantic finance schema applies to BigQuery, Snowflake, GCS and S3 outputs. The destination changes delivery format, not field meaning.
Can I use this as accounting close evidence?
Use it as platform-reported finance input. It is not a complete accounting system, tax advice, bank-statement match, GAAP/IFRS/ASC 606 proof or final booked revenue by itself.
Related guides
Use platform finance data with the right schema boundary
Netice keeps monthly platform finance output separate from daily app-sales analytics, so finance and data teams can work from source-aware platform finance reports without flattening Apple and Google Play semantics.