late-sdk 0.0.613 → 0.0.615

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -0
  3. data/docs/AdCampaignsApi.md +6 -0
  4. data/docs/AdCreative.md +2 -0
  5. data/docs/AnalyticsApi.md +78 -2
  6. data/docs/FacebookPostEarningsResponse.md +32 -0
  7. data/docs/FacebookPostEarningsResponseMetricsValue.md +22 -0
  8. data/docs/FacebookPostEarningsResponseUnavailableMetricsInner.md +22 -0
  9. data/docs/InstagramAccountInsightsResponse.md +3 -1
  10. data/docs/InstagramAccountInsightsResponseMetricsValue.md +6 -2
  11. data/docs/InstagramAccountInsightsResponseUnavailableMetricsInner.md +22 -0
  12. data/lib/zernio-sdk/api/ad_campaigns_api.rb +9 -0
  13. data/lib/zernio-sdk/api/analytics_api.rb +76 -2
  14. data/lib/zernio-sdk/models/ad_creative.rb +12 -1
  15. data/lib/zernio-sdk/models/facebook_post_earnings_response.rb +253 -0
  16. data/lib/zernio-sdk/models/facebook_post_earnings_response_metrics_value.rb +203 -0
  17. data/lib/zernio-sdk/models/facebook_post_earnings_response_unavailable_metrics_inner.rb +202 -0
  18. data/lib/zernio-sdk/models/instagram_account_insights_response.rb +14 -2
  19. data/lib/zernio-sdk/models/instagram_account_insights_response_metrics_value.rb +60 -5
  20. data/lib/zernio-sdk/models/instagram_account_insights_response_unavailable_metrics_inner.rb +202 -0
  21. data/lib/zernio-sdk/version.rb +1 -1
  22. data/lib/zernio-sdk.rb +4 -0
  23. data/openapi.yaml +326 -2
  24. data/spec/api/ad_campaigns_api_spec.rb +3 -0
  25. data/spec/api/analytics_api_spec.rb +15 -1
  26. data/spec/models/ad_creative_spec.rb +6 -0
  27. data/spec/models/facebook_post_earnings_response_metrics_value_spec.rb +52 -0
  28. data/spec/models/facebook_post_earnings_response_spec.rb +82 -0
  29. data/spec/models/facebook_post_earnings_response_unavailable_metrics_inner_spec.rb +52 -0
  30. data/spec/models/instagram_account_insights_response_metrics_value_spec.rb +16 -0
  31. data/spec/models/instagram_account_insights_response_spec.rb +6 -0
  32. data/spec/models/instagram_account_insights_response_unavailable_metrics_inner_spec.rb +52 -0
  33. data/zernio-sdk-0.0.615.gem +0 -0
  34. metadata +18 -2
  35. data/zernio-sdk-0.0.613.gem +0 -0
data/openapi.yaml CHANGED
@@ -1871,6 +1871,14 @@ components:
1871
1871
  description: |
1872
1872
  Object keyed by metric name. For time_series: each metric has "total" (number) and "values" (array of {date, value}).
1873
1873
  For total_value: each metric has "total" (number) and optionally "breakdowns" (array of {dimension, value}).
1874
+
1875
+ Monetary metrics additionally carry "unit" and "currency". Zernio never rescales money:
1876
+ "total" and every "values[].value" are the platform's raw numbers in the stated unit.
1877
+ Monetary metrics also keep "values" on metricType=total_value, because their "total" is the
1878
+ sum of the daily buckets the platform returned over the range: keep the series so you can
1879
+ reconcile that sum against the platform's own reporting before invoicing on it.
1880
+ A metric that could not be served is absent from this object and listed in
1881
+ "unavailableMetrics" instead, so an unavailable metric is never reported as a zero.
1874
1882
  additionalProperties:
1875
1883
  type: object
1876
1884
  properties:
@@ -1879,7 +1887,7 @@ components:
1879
1887
  description: Sum or aggregate value for the metric
1880
1888
  values:
1881
1889
  type: array
1882
- description: Daily values (only for time_series)
1890
+ description: Daily values (for time_series, and always on monetary metrics)
1883
1891
  items:
1884
1892
  type: object
1885
1893
  properties:
@@ -1898,9 +1906,149 @@ components:
1898
1906
  type: string
1899
1907
  value:
1900
1908
  type: number
1909
+ unit:
1910
+ type: string
1911
+ enum: [micro_amount, unspecified]
1912
+ description: |
1913
+ Present on monetary metrics only. The scale of "total" and of every "values[].value",
1914
+ exactly as the platform returned them.
1915
+
1916
+ "micro_amount": the platform returned an object shape carrying a micro amount, and the
1917
+ values are that integer, summed, unconverted. Zernio does not publish a divisor because
1918
+ Meta does not document one; divide by the scale you have verified against the Page's own
1919
+ Meta Business Suite export. On Facebook Page insights this is always
1920
+ content_monetization_earnings.
1921
+
1922
+ "unspecified": the platform returned a bare number with no unit metadata. It is passed
1923
+ through as-is; the platform does not state whether it is major or minor currency units.
1924
+ On Facebook Page insights this is always monetization_approximate_earnings.
1925
+ currency:
1926
+ type: [string, "null"]
1927
+ description: |
1928
+ ISO 4217 currency of a monetary metric, or null when the platform omitted it.
1929
+ Always null on monetization_approximate_earnings, which Meta returns as a bare number
1930
+ with no currency; always present on content_monetization_earnings.
1931
+ example: "USD"
1932
+ unavailableMetrics:
1933
+ type: array
1934
+ description: |
1935
+ Requested metrics that could not be served. Present only when at least one metric is
1936
+ unavailable, and absent otherwise. Each listed metric is OMITTED from "metrics" rather than
1937
+ reported as 0, which is how an unavailable metric is distinguished from a genuine zero.
1938
+ The request itself still succeeds with HTTP 200.
1939
+ items:
1940
+ type: object
1941
+ properties:
1942
+ metric:
1943
+ type: string
1944
+ description: The requested metric name.
1945
+ reason:
1946
+ type: string
1947
+ enum: [not_enrolled, permission_missing, unsupported_metric, no_data, unreadable_value, mixed_currency, upstream_error]
1948
+ description: |
1949
+ "not_enrolled": the account is not enrolled in the program behind this metric.
1950
+ "permission_missing": the connected user lacks access to this metric.
1951
+ "unsupported_metric": the platform does not accept this metric name on the API version Zernio uses.
1952
+ "no_data": the platform returned no bucket for this metric over the requested range.
1953
+ "unreadable_value": the platform returned a value shape Zernio cannot read, so no total is reported.
1954
+ "mixed_currency": readable values disagree on currency or unit within the range.
1955
+ "upstream_error": any other platform failure.
1956
+
1957
+ "no_data" is the common case in practice. The others are defensive: "not_enrolled" and
1958
+ "unsupported_metric" in particular have not been observed on live Facebook traffic, since
1959
+ a non-enrolled Page returns zeros rather than an error and metric names are validated
1960
+ before any platform call.
1961
+ message:
1962
+ type: string
1963
+ description: 'Platform-provided explanation when available (access tokens redacted), otherwise Zernio copy.'
1901
1964
  dataDelay:
1902
1965
  type: string
1903
1966
  example: "Data may be delayed up to 48 hours"
1967
+ FacebookPostEarningsResponse:
1968
+ type: object
1969
+ description: |
1970
+ Lifetime monetization earnings for one Facebook post. Same "unit" / "currency" contract and
1971
+ same unavailable-vs-zero contract as the Page-level response; there is no date range, no
1972
+ metricType, and no daily "values", because the single lifetime bucket IS the total.
1973
+ properties:
1974
+ success:
1975
+ type: boolean
1976
+ example: true
1977
+ accountId:
1978
+ type: string
1979
+ example: "64e1a2b3c4d5e6f7a8b9c0d1"
1980
+ postId:
1981
+ type: string
1982
+ description: 'The platform post ID that was queried, echoed back.'
1983
+ example: "123456789_987654321"
1984
+ platform:
1985
+ type: string
1986
+ example: "facebook"
1987
+ period:
1988
+ type: string
1989
+ enum: [lifetime]
1990
+ description: |
1991
+ Always "lifetime": the total is cumulative since publication and must not be summed
1992
+ across dates or across posts.
1993
+ metrics:
1994
+ type: object
1995
+ description: |
1996
+ One entry per served metric. A metric reported here with "total": 0 genuinely earned
1997
+ nothing (or its Page is not enrolled, which Meta reports identically).
1998
+ additionalProperties:
1999
+ type: object
2000
+ properties:
2001
+ total:
2002
+ type: number
2003
+ description: 'Lifetime earnings in "unit", exactly as Meta returned them. Never rescaled.'
2004
+ unit:
2005
+ type: string
2006
+ enum: [micro_amount, unspecified]
2007
+ description: |
2008
+ "micro_amount": Meta returned an object shape carrying a micro amount, and "total" is
2009
+ that integer, unconverted. Zernio does not publish a divisor because Meta does not
2010
+ document one; divide by the scale you have verified against the Page's own Meta
2011
+ Business Suite export. This is always content_monetization_earnings.
2012
+
2013
+ "unspecified": Meta returned a bare number with no unit metadata, passed through as-is;
2014
+ Meta does not state whether it is major or minor currency units. This is always
2015
+ monetization_approximate_earnings.
2016
+ currency:
2017
+ type: [string, "null"]
2018
+ description: |
2019
+ ISO 4217 currency, or null when Meta omitted it. Always null on
2020
+ monetization_approximate_earnings; always present on content_monetization_earnings.
2021
+ example: "USD"
2022
+ unavailableMetrics:
2023
+ type: array
2024
+ description: |
2025
+ Requested metrics Meta could not serve. Present only when at least one metric is
2026
+ unavailable, and absent otherwise. Each listed metric is OMITTED from "metrics" rather than
2027
+ reported as 0. The request itself still succeeds with HTTP 200.
2028
+ items:
2029
+ type: object
2030
+ properties:
2031
+ metric:
2032
+ type: string
2033
+ description: The requested metric name.
2034
+ reason:
2035
+ type: string
2036
+ enum: [not_enrolled, permission_missing, unsupported_metric, no_data, unreadable_value, mixed_currency, upstream_error]
2037
+ description: |
2038
+ "not_enrolled": the account is not enrolled in the program behind this metric.
2039
+ "permission_missing": the connected user lacks access to this metric.
2040
+ "unsupported_metric": Meta does not accept this metric name on the API version Zernio uses.
2041
+ "no_data": Meta returned no bucket for this metric.
2042
+ "unreadable_value": Meta returned a value shape Zernio cannot read, so no total is reported.
2043
+ "mixed_currency": readable values disagree on currency or unit.
2044
+ "upstream_error": any other platform failure.
2045
+
2046
+ "no_data" is the common case in practice; the others are defensive.
2047
+ message:
2048
+ type: string
2049
+ description: 'Platform-provided explanation when available (access tokens redacted), otherwise Zernio copy.'
2050
+ dataDelay:
2051
+ type: string
1904
2052
  InstagramDemographicsResponse:
1905
2053
  type: object
1906
2054
  properties:
@@ -6733,6 +6881,7 @@ components:
6733
6881
  objectType: { type: string, description: "Meta creative object_type (e.g. SHARE, VIDEO, PRIVACY_CHECK_FAIL, POST_DELETED). Use this to render state-aware previews — when Meta moderation strips image/video fields, only thumbnailUrl at 64x64 is available." }
6734
6882
  objectStoryId: { type: [string, "null"], description: "Meta creative `object_story_id` (the SHARE reference). Frequently absent — Meta omits it for SHARE creatives. Use effectiveObjectStoryId instead." }
6735
6883
  effectiveObjectStoryId: { type: [string, "null"], description: "Meta `effective_object_story_id` — `{pageId}_{postId}` of the Facebook post the ad's engagement (comments) lives on. Pass to GET /v1/ads?effectiveObjectStoryId= to map a Business-Manager-visible post back to this ad; GET /v1/ads/{adId}/comments resolves comments against it." }
6884
+ pageId: { type: [string, "null"], description: "Facebook Page backing the creative (Meta only). What the `pageId` filter on /v1/ads, /v1/ads/campaigns and /v1/ads/tree matches against. Absent for non-Meta ads and rare Meta creatives with no page signal." }
6736
6885
  effectiveInstagramMediaId: { type: [string, "null"], description: "Meta `effective_instagram_media_id` — the Instagram media ID of the boosted post the ad's engagement lives on. Pass to GET /v1/ads?effectiveInstagramMediaId= to map a Business-Manager-visible IG post back to this ad." }
6737
6886
  instagramUserId: { type: [string, "null"], description: "Meta `instagram_user_id` — the Instagram-scoped business ID that owns the boosted media." }
6738
6887
  instagramPermalinkUrl: { type: [string, "null"], description: "Meta `instagram_permalink_url` — public Instagram post URL of the boosted media." }
@@ -9349,6 +9498,31 @@ paths:
9349
9498
  left by the page_fan_adds / page_fan_removes deprecation):
9350
9499
  - followers_gained
9351
9500
  - followers_lost
9501
+
9502
+ Monetization (opt-in, not in the defaults):
9503
+ - content_monetization_earnings
9504
+ - monetization_approximate_earnings
9505
+
9506
+ Each monetization metric is fetched with its own separate Graph call, so requesting both
9507
+ adds two calls. Values are approximate and Meta restates them after the fact.
9508
+
9509
+ content_monetization_earnings returns an object per day and always carries unit
9510
+ "micro_amount" plus an ISO 4217 "currency". monetization_approximate_earnings returns a bare
9511
+ number per day, so its unit is always "unspecified" and its "currency" is always null. The two
9512
+ are on different scales and are not comparable to each other. Both keep their daily "values"
9513
+ on every metricType and are never rescaled by Zernio.
9514
+
9515
+ Earnings here are Page-level daily buckets and "total" is their sum. Meta does not
9516
+ document whether a bucket carries that day's earnings or a running total, and every
9517
+ Page measured so far earned exactly 0, so reconcile "total" against the Page's own Meta
9518
+ export before relying on it; the daily "values" are always returned for that purpose.
9519
+ Per-post lifetime earnings are served by GET /v1/analytics/facebook/post-earnings.
9520
+
9521
+ A Page that is not enrolled in monetization, or that earned nothing, returns normal daily
9522
+ buckets of 0 in "metrics": Meta does not distinguish the two, so a 0 total here does NOT mean
9523
+ the Page is enrolled. "unavailableMetrics" covers the narrower case where Meta returned no
9524
+ bucket for the metric at all ("no_data") or rejected the request outright, and the metric is
9525
+ then omitted from "metrics" rather than reported as 0.
9352
9526
  - name: since
9353
9527
  in: query
9354
9528
  schema: { type: string, format: date }
@@ -9398,7 +9572,49 @@ paths:
9398
9572
  values:
9399
9573
  - { date: "2026-03-01", value: 1 }
9400
9574
  - { date: "2026-03-02", value: 0 }
9401
- dataDelay: "Meta page insights may be delayed up to 24 hours. Metrics reflect the current (post-November 2025) Graph API names."
9575
+ dataDelay: "Meta page insights may be delayed up to 24 hours. Metrics reflect the current (post-November 2025) Graph API names. Monetization earnings are approximate and Meta restates them after the fact."
9576
+ monetization:
9577
+ summary: 'Both monetization metrics, each at its own scale'
9578
+ value:
9579
+ success: true
9580
+ accountId: "64e1a2b3c4d5e6f7a8b9c0d1"
9581
+ platform: "facebook"
9582
+ dateRange: { since: "2026-06-01", until: "2026-06-30" }
9583
+ metricType: "total_value"
9584
+ metrics:
9585
+ page_media_view:
9586
+ total: 125000
9587
+ content_monetization_earnings:
9588
+ total: 1234000000
9589
+ unit: "micro_amount"
9590
+ currency: "USD"
9591
+ values:
9592
+ - { date: "2026-06-01", value: 634000000 }
9593
+ - { date: "2026-06-02", value: 600000000 }
9594
+ monetization_approximate_earnings:
9595
+ total: 1234
9596
+ unit: "unspecified"
9597
+ currency: null
9598
+ values:
9599
+ - { date: "2026-06-01", value: 700 }
9600
+ - { date: "2026-06-02", value: 534 }
9601
+ dataDelay: "Meta page insights may be delayed up to 24 hours. Metrics reflect the current (post-November 2025) Graph API names. Monetization earnings are approximate and Meta restates them after the fact."
9602
+ monetizationUnavailable:
9603
+ summary: 'A monetization metric Meta returned no bucket for'
9604
+ value:
9605
+ success: true
9606
+ accountId: "64e1a2b3c4d5e6f7a8b9c0d1"
9607
+ platform: "facebook"
9608
+ dateRange: { since: "2026-06-01", until: "2026-06-30" }
9609
+ metricType: "total_value"
9610
+ metrics:
9611
+ page_media_view:
9612
+ total: 125000
9613
+ unavailableMetrics:
9614
+ - metric: "content_monetization_earnings"
9615
+ reason: "no_data"
9616
+ message: "Meta returned no data for this monetization metric."
9617
+ dataDelay: "Meta page insights may be delayed up to 24 hours. Metrics reflect the current (post-November 2025) Graph API names. Monetization earnings are approximate and Meta restates them after the fact."
9402
9618
  '400':
9403
9619
  description: |
9404
9620
  Bad request. Common cases:
@@ -9412,6 +9628,111 @@ paths:
9412
9628
  '404':
9413
9629
  description: Account not found
9414
9630
 
9631
+ /v1/analytics/facebook/post-earnings:
9632
+ get:
9633
+ operationId: getFacebookPostEarnings
9634
+ tags: [Analytics]
9635
+ summary: Get Facebook post monetization earnings
9636
+ description: |
9637
+ Returns lifetime monetization earnings for ONE Facebook post, read live from Meta on every
9638
+ request. Requires the Analytics add-on.
9639
+
9640
+ Earnings are CUMULATIVE since the post was published, not earnings within a date range, so
9641
+ this endpoint takes no since/until and the totals must not be summed across dates or across
9642
+ posts. Page-level daily earnings live on /v1/analytics/facebook/page-insights.
9643
+
9644
+ A post on a Page that is not enrolled in monetization, or that earned nothing, returns
9645
+ "total": 0 rather than an error: Meta does not distinguish the two. A metric Meta returned no
9646
+ bucket for at all is reported in "unavailableMetrics" and omitted from "metrics", never as a 0.
9647
+
9648
+ Amounts are the platform's raw numbers in the stated "unit" and are never rescaled by Zernio.
9649
+ Breakdown dimensions are not exposed and a "breakdown" param is rejected with 400. So are
9650
+ "since", "until", "period", and "metricType": scoping this endpoint to a window is not
9651
+ possible, and silently returning the lifetime total for one would let a caller sum a year of
9652
+ weekly requests into a figure ~52x the post's real earnings.
9653
+ parameters:
9654
+ - name: accountId
9655
+ in: query
9656
+ required: true
9657
+ schema: { type: string }
9658
+ description: The Zernio SocialAccount ID for the connected Facebook Page.
9659
+ - name: postId
9660
+ in: query
9661
+ required: true
9662
+ schema: { type: string }
9663
+ description: |
9664
+ The platform post ID, exactly as returned in platformAnalytics[].platformPostId by
9665
+ /v1/analytics: "{pageId}_{postId}", or the bare video ID for Reels.
9666
+ - name: metrics
9667
+ in: query
9668
+ schema: { type: string }
9669
+ description: |
9670
+ Comma-separated list of monetization metrics. Defaults to both:
9671
+ - content_monetization_earnings
9672
+ - monetization_approximate_earnings
9673
+
9674
+ content_monetization_earnings always carries unit "micro_amount" plus an ISO 4217
9675
+ "currency". monetization_approximate_earnings is always a bare number, so its unit is
9676
+ "unspecified" and its "currency" is null. The two are on different scales and are not
9677
+ comparable to each other. Any other metric name is rejected with 400.
9678
+ responses:
9679
+ '200':
9680
+ description: Lifetime per-post monetization earnings
9681
+ content:
9682
+ application/json:
9683
+ schema:
9684
+ $ref: '#/components/schemas/FacebookPostEarningsResponse'
9685
+ examples:
9686
+ served:
9687
+ summary: 'Both metrics served, each at its own scale'
9688
+ value:
9689
+ success: true
9690
+ accountId: "64e1a2b3c4d5e6f7a8b9c0d1"
9691
+ postId: "123456789_987654321"
9692
+ platform: "facebook"
9693
+ period: "lifetime"
9694
+ metrics:
9695
+ content_monetization_earnings:
9696
+ total: 1234000000
9697
+ unit: "micro_amount"
9698
+ currency: "USD"
9699
+ monetization_approximate_earnings:
9700
+ total: 1234
9701
+ unit: "unspecified"
9702
+ currency: null
9703
+ dataDelay: "Meta restates monetization earnings after the fact. Per-post earnings are lifetime cumulative: they are the total since publication, not earnings within a date range, and must not be summed across dates."
9704
+ partiallyUnavailable:
9705
+ summary: 'One metric served, one with no bucket returned by Meta'
9706
+ value:
9707
+ success: true
9708
+ accountId: "64e1a2b3c4d5e6f7a8b9c0d1"
9709
+ postId: "123456789_987654321"
9710
+ platform: "facebook"
9711
+ period: "lifetime"
9712
+ metrics:
9713
+ monetization_approximate_earnings:
9714
+ total: 0
9715
+ unit: "unspecified"
9716
+ currency: null
9717
+ unavailableMetrics:
9718
+ - metric: "content_monetization_earnings"
9719
+ reason: "no_data"
9720
+ message: "Meta returned no data for this monetization metric."
9721
+ dataDelay: "Meta restates monetization earnings after the fact. Per-post earnings are lifetime cumulative: they are the total since publication, not earnings within a date range, and must not be summed across dates."
9722
+ '400':
9723
+ description: |
9724
+ Bad request. Common cases:
9725
+ - Invalid accountId format, or a metric name that is not a monetization metric
9726
+ - A "breakdown" param was supplied (breakdown dimensions are not exposed)
9727
+ - A "since", "until", "period", or "metricType" param was supplied (this endpoint returns a lifetime total and takes no date range)
9728
+ - Account has no Page access token (metadata.pageAccessToken missing)
9729
+ - Account is not a Facebook account
9730
+ '401': { $ref: '#/components/responses/Unauthorized' }
9731
+ '402':
9732
+ description: Analytics access required. Legacy plans need the Analytics add-on; included by default on usage-based plans.
9733
+ '404':
9734
+ description: Account not found
9735
+
9415
9736
  /v1/analytics/instagram/account-insights:
9416
9737
  get:
9417
9738
  operationId: getInstagramAccountInsights
@@ -34083,6 +34404,7 @@ paths:
34083
34404
  - { name: platform, in: query, schema: { type: string, enum: [facebook, instagram, tiktok, linkedin, pinterest, google, twitter, openai] } }
34084
34405
  - { name: accountId, in: query, schema: { type: string }, description: Social account ID }
34085
34406
  - { name: adAccountId, in: query, schema: { type: string }, description: "Platform ad account ID (e.g. act_123 for Meta). Mirrors the same filter on /v1/ads/campaigns and /v1/ads/tree." }
34407
+ - { name: pageId, in: query, schema: { type: string }, description: "Meta only: Facebook Page ID. Returns only ads whose creative is backed by this Page (a Meta ad account serves ads for every Page in the Business Manager). Matches each ad's `creative.pageId`; ads with no page signal (rare IG-only creatives) never match. Mirrors the same filter on /v1/ads/campaigns and /v1/ads/tree." }
34086
34408
  - { name: profileId, in: query, schema: { type: string }, description: Profile ID }
34087
34409
  - { name: campaignId, in: query, schema: { type: string }, description: Platform campaign ID (filter ads within a campaign) }
34088
34410
  - { name: platformAdId, in: query, schema: { type: string }, description: "Meta ad ID. Returns the ad with this platform-side ad ID." }
@@ -34197,6 +34519,7 @@ paths:
34197
34519
  - { name: platform, in: query, schema: { type: string, enum: [facebook, instagram, tiktok, linkedin, pinterest, google, twitter, openai] } }
34198
34520
  - { name: status, in: query, schema: { $ref: '#/components/schemas/AdStatus' }, description: Filter by derived campaign status (post-aggregation) }
34199
34521
  - { name: adAccountId, in: query, schema: { type: string }, description: Platform ad account ID (e.g. act_123 for Meta) }
34522
+ - { name: pageId, in: query, schema: { type: string }, description: "Meta only: Facebook Page ID. Campaigns have no Page of their own, so this keeps campaigns having at least one ad backed by this Page, with adCount and metrics computed over those ads only. Mirrors the same filter on /v1/ads and /v1/ads/tree." }
34200
34523
  - { name: accountId, in: query, schema: { type: string }, description: Social account ID }
34201
34524
  - { name: profileId, in: query, schema: { type: string }, description: Profile ID }
34202
34525
  - { name: fromDate, in: query, schema: { type: string, format: date }, description: "Start of metrics date range (YYYY-MM-DD, inclusive). Defaults to 90 days ago when both date params are omitted." }
@@ -34866,6 +35189,7 @@ paths:
34866
35189
  - { name: platform, in: query, schema: { type: string, enum: [facebook, instagram, tiktok, linkedin, pinterest, google, twitter, openai] } }
34867
35190
  - { name: status, in: query, schema: { $ref: '#/components/schemas/AdStatus' }, description: Filter by derived campaign status (post-aggregation) }
34868
35191
  - { name: adAccountId, in: query, schema: { type: string }, description: Platform ad account ID }
35192
+ - { name: pageId, in: query, schema: { type: string }, description: "Meta only: Facebook Page ID. Prunes the tree to ads whose creative is backed by this Page — campaigns and ad sets with no ad on the Page drop out, and rolled-up metrics cover only the Page's ads. Mirrors the same filter on /v1/ads and /v1/ads/campaigns." }
34869
35193
  - { name: accountId, in: query, schema: { type: string }, description: Social account ID }
34870
35194
  - { name: profileId, in: query, schema: { type: string }, description: Profile ID }
34871
35195
  - { name: campaignId, in: query, schema: { type: string }, description: "Restrict the tree to a single campaign by its platform campaign id (the id the platform assigns, e.g. Meta's numeric campaign id). Filters the campaign set itself, so it works regardless of account size and pagination — pass this when you already hold a campaign id instead of paging the tree to find it. Mirrors the `campaignId` filter on GET /v1/ads." }
@@ -181,6 +181,7 @@ describe 'AdCampaignsApi' do
181
181
  # @option opts [String] :platform
182
182
  # @option opts [AdStatus] :status Filter by derived campaign status (post-aggregation)
183
183
  # @option opts [String] :ad_account_id Platform ad account ID
184
+ # @option opts [String] :page_id Meta only: Facebook Page ID. Prunes the tree to ads whose creative is backed by this Page — campaigns and ad sets with no ad on the Page drop out, and rolled-up metrics cover only the Page's ads. Mirrors the same filter on /v1/ads and /v1/ads/campaigns.
184
185
  # @option opts [String] :account_id Social account ID
185
186
  # @option opts [String] :profile_id Profile ID
186
187
  # @option opts [String] :campaign_id Restrict the tree to a single campaign by its platform campaign id (the id the platform assigns, e.g. Meta's numeric campaign id). Filters the campaign set itself, so it works regardless of account size and pagination — pass this when you already hold a campaign id instead of paging the tree to find it. Mirrors the `campaignId` filter on GET /v1/ads.
@@ -222,6 +223,7 @@ describe 'AdCampaignsApi' do
222
223
  # @option opts [String] :platform
223
224
  # @option opts [AdStatus] :status Filter by derived campaign status (post-aggregation)
224
225
  # @option opts [String] :ad_account_id Platform ad account ID (e.g. act_123 for Meta)
226
+ # @option opts [String] :page_id Meta only: Facebook Page ID. Campaigns have no Page of their own, so this keeps campaigns having at least one ad backed by this Page, with adCount and metrics computed over those ads only. Mirrors the same filter on /v1/ads and /v1/ads/tree.
225
227
  # @option opts [String] :account_id Social account ID
226
228
  # @option opts [String] :profile_id Profile ID
227
229
  # @option opts [Date] :from_date Start of metrics date range (YYYY-MM-DD, inclusive). Defaults to 90 days ago when both date params are omitted.
@@ -266,6 +268,7 @@ describe 'AdCampaignsApi' do
266
268
  # @option opts [String] :platform
267
269
  # @option opts [String] :account_id Social account ID
268
270
  # @option opts [String] :ad_account_id Platform ad account ID (e.g. act_123 for Meta). Mirrors the same filter on /v1/ads/campaigns and /v1/ads/tree.
271
+ # @option opts [String] :page_id Meta only: Facebook Page ID. Returns only ads whose creative is backed by this Page (a Meta ad account serves ads for every Page in the Business Manager). Matches each ad's `creative.pageId`; ads with no page signal (rare IG-only creatives) never match. Mirrors the same filter on /v1/ads/campaigns and /v1/ads/tree.
269
272
  # @option opts [String] :profile_id Profile ID
270
273
  # @option opts [String] :campaign_id Platform campaign ID (filter ads within a campaign)
271
274
  # @option opts [String] :platform_ad_id Meta ad ID. Returns the ad with this platform-side ad ID.
@@ -107,7 +107,7 @@ describe 'AnalyticsApi' do
107
107
  # Returns page-level Facebook insights (media views, views, post engagements, video metrics, follower counts). Response shape matches /v1/analytics/instagram/account-insights so the same client handling works across platforms. Metric names track the current (post-November 2025) Meta Graph API. The legacy page_impressions / page_fans / page_fan_adds / page_fan_removes metrics were deprecated by Meta on November 15, 2025 and are NOT accepted by this endpoint. Use the replacements below. Because Meta did not provide direct adds/removes replacements, Zernio synthesizes followers_gained / followers_lost from the daily follower snapshotter. Max 89 days, defaults to last 30 days. Requires the Analytics add-on.
108
108
  # @param account_id The Zernio SocialAccount ID for the connected Facebook Page.
109
109
  # @param [Hash] opts the optional parameters
110
- # @option opts [String] :metrics Comma-separated list of metrics. Defaults to \"page_media_view,page_post_engagements,page_follows,followers_gained,followers_lost\". Live Meta metrics (current names, post-Nov-2025): - page_media_view (replaces deprecated page_impressions) - page_views_total - page_post_engagements - page_video_views - page_video_view_time - page_follows (replaces deprecated page_fans) Zernio-synthesized from daily follower snapshots (filling the Nov-2025 gap left by the page_fan_adds / page_fan_removes deprecation): - followers_gained - followers_lost
110
+ # @option opts [String] :metrics Comma-separated list of metrics. Defaults to \"page_media_view,page_post_engagements,page_follows,followers_gained,followers_lost\". Live Meta metrics (current names, post-Nov-2025): - page_media_view (replaces deprecated page_impressions) - page_views_total - page_post_engagements - page_video_views - page_video_view_time - page_follows (replaces deprecated page_fans) Zernio-synthesized from daily follower snapshots (filling the Nov-2025 gap left by the page_fan_adds / page_fan_removes deprecation): - followers_gained - followers_lost Monetization (opt-in, not in the defaults): - content_monetization_earnings - monetization_approximate_earnings Each monetization metric is fetched with its own separate Graph call, so requesting both adds two calls. Values are approximate and Meta restates them after the fact. content_monetization_earnings returns an object per day and always carries unit \"micro_amount\" plus an ISO 4217 \"currency\". monetization_approximate_earnings returns a bare number per day, so its unit is always \"unspecified\" and its \"currency\" is always null. The two are on different scales and are not comparable to each other. Both keep their daily \"values\" on every metricType and are never rescaled by Zernio. Earnings here are Page-level daily buckets and \"total\" is their sum. Meta does not document whether a bucket carries that day's earnings or a running total, and every Page measured so far earned exactly 0, so reconcile \"total\" against the Page's own Meta export before relying on it; the daily \"values\" are always returned for that purpose. Per-post lifetime earnings are served by GET /v1/analytics/facebook/post-earnings. A Page that is not enrolled in monetization, or that earned nothing, returns normal daily buckets of 0 in \"metrics\": Meta does not distinguish the two, so a 0 total here does NOT mean the Page is enrolled. \"unavailableMetrics\" covers the narrower case where Meta returned no bucket for the metric at all (\"no_data\") or rejected the request outright, and the metric is then omitted from \"metrics\" rather than reported as 0.
111
111
  # @option opts [Date] :since Start date (YYYY-MM-DD). Defaults to 30 days ago.
112
112
  # @option opts [Date] :_until End date (YYYY-MM-DD). Defaults to today.
113
113
  # @option opts [String] :metric_type \"total_value\" (default) returns aggregated totals only. \"time_series\" returns daily values in the \"values\" array.
@@ -118,6 +118,20 @@ describe 'AnalyticsApi' do
118
118
  end
119
119
  end
120
120
 
121
+ # unit tests for get_facebook_post_earnings
122
+ # Get Facebook post monetization earnings
123
+ # Returns lifetime monetization earnings for ONE Facebook post, read live from Meta on every request. Requires the Analytics add-on. Earnings are CUMULATIVE since the post was published, not earnings within a date range, so this endpoint takes no since/until and the totals must not be summed across dates or across posts. Page-level daily earnings live on /v1/analytics/facebook/page-insights. A post on a Page that is not enrolled in monetization, or that earned nothing, returns \"total\": 0 rather than an error: Meta does not distinguish the two. A metric Meta returned no bucket for at all is reported in \"unavailableMetrics\" and omitted from \"metrics\", never as a 0. Amounts are the platform's raw numbers in the stated \"unit\" and are never rescaled by Zernio. Breakdown dimensions are not exposed and a \"breakdown\" param is rejected with 400. So are \"since\", \"until\", \"period\", and \"metricType\": scoping this endpoint to a window is not possible, and silently returning the lifetime total for one would let a caller sum a year of weekly requests into a figure ~52x the post's real earnings.
124
+ # @param account_id The Zernio SocialAccount ID for the connected Facebook Page.
125
+ # @param post_id The platform post ID, exactly as returned in platformAnalytics[].platformPostId by /v1/analytics: \"{pageId}_{postId}\", or the bare video ID for Reels.
126
+ # @param [Hash] opts the optional parameters
127
+ # @option opts [String] :metrics Comma-separated list of monetization metrics. Defaults to both: - content_monetization_earnings - monetization_approximate_earnings content_monetization_earnings always carries unit \"micro_amount\" plus an ISO 4217 \"currency\". monetization_approximate_earnings is always a bare number, so its unit is \"unspecified\" and its \"currency\" is null. The two are on different scales and are not comparable to each other. Any other metric name is rejected with 400.
128
+ # @return [FacebookPostEarningsResponse]
129
+ describe 'get_facebook_post_earnings test' do
130
+ it 'should work' do
131
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
132
+ end
133
+ end
134
+
121
135
  # unit tests for get_facebook_post_reactions
122
136
  # Get Facebook post reactions
123
137
  # Returns the reaction breakdown for a Facebook Page post: a count per reaction type plus the overall total. The whole breakdown is fetched in a single Graph call. Note that the post analytics endpoint reports only an aggregate reaction count (surfaced there as `likes`), so use this endpoint when you need per-type counts.
@@ -69,6 +69,12 @@ describe Zernio::AdCreative do
69
69
  end
70
70
  end
71
71
 
72
+ describe 'test attribute "page_id"' do
73
+ it 'should work' do
74
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
75
+ end
76
+ end
77
+
72
78
  describe 'test attribute "effective_instagram_media_id"' do
73
79
  it 'should work' do
74
80
  # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
@@ -0,0 +1,52 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
5
+
6
+ The version of the OpenAPI document: 1.0.4
7
+ Contact: support@zernio.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'spec_helper'
14
+ require 'json'
15
+ require 'date'
16
+
17
+ # Unit tests for Zernio::FacebookPostEarningsResponseMetricsValue
18
+ # Automatically generated by openapi-generator (https://openapi-generator.tech)
19
+ # Please update as you see appropriate
20
+ describe Zernio::FacebookPostEarningsResponseMetricsValue do
21
+ #let(:instance) { Zernio::FacebookPostEarningsResponseMetricsValue.new }
22
+
23
+ describe 'test an instance of FacebookPostEarningsResponseMetricsValue' do
24
+ it 'should create an instance of FacebookPostEarningsResponseMetricsValue' do
25
+ # uncomment below to test the instance creation
26
+ #expect(instance).to be_instance_of(Zernio::FacebookPostEarningsResponseMetricsValue)
27
+ end
28
+ end
29
+
30
+ describe 'test attribute "total"' do
31
+ it 'should work' do
32
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
33
+ end
34
+ end
35
+
36
+ describe 'test attribute "unit"' do
37
+ it 'should work' do
38
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
39
+ # validator = Petstore::EnumTest::EnumAttributeValidator.new('String', ["micro_amount", "unspecified"])
40
+ # validator.allowable_values.each do |value|
41
+ # expect { instance.unit = value }.not_to raise_error
42
+ # end
43
+ end
44
+ end
45
+
46
+ describe 'test attribute "currency"' do
47
+ it 'should work' do
48
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,82 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
5
+
6
+ The version of the OpenAPI document: 1.0.4
7
+ Contact: support@zernio.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'spec_helper'
14
+ require 'json'
15
+ require 'date'
16
+
17
+ # Unit tests for Zernio::FacebookPostEarningsResponse
18
+ # Automatically generated by openapi-generator (https://openapi-generator.tech)
19
+ # Please update as you see appropriate
20
+ describe Zernio::FacebookPostEarningsResponse do
21
+ #let(:instance) { Zernio::FacebookPostEarningsResponse.new }
22
+
23
+ describe 'test an instance of FacebookPostEarningsResponse' do
24
+ it 'should create an instance of FacebookPostEarningsResponse' do
25
+ # uncomment below to test the instance creation
26
+ #expect(instance).to be_instance_of(Zernio::FacebookPostEarningsResponse)
27
+ end
28
+ end
29
+
30
+ describe 'test attribute "success"' do
31
+ it 'should work' do
32
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
33
+ end
34
+ end
35
+
36
+ describe 'test attribute "account_id"' do
37
+ it 'should work' do
38
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
39
+ end
40
+ end
41
+
42
+ describe 'test attribute "post_id"' do
43
+ it 'should work' do
44
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
45
+ end
46
+ end
47
+
48
+ describe 'test attribute "platform"' do
49
+ it 'should work' do
50
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
51
+ end
52
+ end
53
+
54
+ describe 'test attribute "period"' do
55
+ it 'should work' do
56
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
57
+ # validator = Petstore::EnumTest::EnumAttributeValidator.new('String', ["lifetime"])
58
+ # validator.allowable_values.each do |value|
59
+ # expect { instance.period = value }.not_to raise_error
60
+ # end
61
+ end
62
+ end
63
+
64
+ describe 'test attribute "metrics"' do
65
+ it 'should work' do
66
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
67
+ end
68
+ end
69
+
70
+ describe 'test attribute "unavailable_metrics"' do
71
+ it 'should work' do
72
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
73
+ end
74
+ end
75
+
76
+ describe 'test attribute "data_delay"' do
77
+ it 'should work' do
78
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
79
+ end
80
+ end
81
+
82
+ end