@gscdump/contracts 4.5.0 → 4.7.0

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.
@@ -1,3 +1,5 @@
1
+ import { siteHoldReasonSchema } from "../entitlements.mjs";
2
+ import { watchedUrlsChangeRequestSchema, watchedUrlsChangeResponseSchema, watchedUrlsResponseSchema } from "../indexing-coverage.mjs";
1
3
  import { addPartnerTeamMemberSchema, bindPartnerSiteTeamSchema, bindPartnerTeamCatalogResponseSchema, bindPartnerTeamCatalogSchema, builderStateSchema, createPartnerTeamSchema, gscComparisonFilterSchema, gscdumpAnalysisBundleResponseSchema, gscdumpAnalysisPresetSchema, gscdumpAnalysisResponseSchema, gscdumpAvailableSiteSchema, gscdumpCanonicalMismatchesResponseSchema, gscdumpDataDetailResponseSchema, gscdumpDataResponseSchema, gscdumpDeletePartnerUserResponseSchema, gscdumpIndexPercentResponseSchema, gscdumpIndexingDiagnosticsResponseSchema, gscdumpIndexingResponseSchema, gscdumpIndexingTransitionFieldSchema, gscdumpKeywordSparklinesResponseSchema, gscdumpPageTrendResponseSchema, gscdumpQueryTrendResponseSchema, gscdumpSiteRegistrationSchema, gscdumpSitemapChangesResponseSchema, gscdumpSitemapExportQuerySchema, gscdumpSitemapExportResponseSchema, gscdumpSitemapMembershipParamsSchema, gscdumpSitemapMembershipResponseSchema, gscdumpSitemapUrlsQuerySchema, gscdumpSitemapUrlsResponseSchema, gscdumpSitemapsResponseSchema, gscdumpTeamRoleSchema, gscdumpTopAssociationResponseSchema, gscdumpUserRegistrationSchema, indexingUrlsResponseSchema, partnerSiteTeamBindingResponseSchema, partnerSitemapActionResponseSchema, partnerSitemapActionSchema, partnerTeamCreatedResponseSchema, partnerTeamDeletedResponseSchema, partnerTeamMemberAddedResponseSchema, partnerTeamMemberRemovedResponseSchema, partnerTeamMemberRoleResponseSchema, partnerTeamMembersResponseSchema, partnerTeamRenamedResponseSchema, registerPartnerSiteSchema, registerPartnerUserSchema, renamePartnerTeamSchema, searchTypeSchema, siteIntIdCrosswalkResponseSchema, sitemapChangesTruncationReasonSchema, teamCatalogRefSchema, updatePartnerUserTokensSchema } from "../schemas.mjs";
2
4
  import { bingConnectionV1Schemas } from "./bing.mjs";
3
5
  import "./version.mjs";
@@ -385,6 +387,52 @@ function createGscdumpV1Protocol() {
385
387
  ok: z.literal(true),
386
388
  keyId: partnerUserApiKeyId
387
389
  }), partnerResponseMeta);
390
+ const entitlementCount = z.number().int().nonnegative();
391
+ const entitlementUsage = defineResponseObject({
392
+ used: entitlementCount,
393
+ allowance: entitlementCount
394
+ });
395
+ const preservedRowsUsage = defineResponseObject({
396
+ used: entitlementCount.nullable(),
397
+ allowance: entitlementCount
398
+ });
399
+ const urlInspectionsUsage = defineResponseObject({
400
+ used: entitlementCount,
401
+ allowance: entitlementCount.nullable(),
402
+ resetsAt: z.iso.date()
403
+ });
404
+ const entitlementMeters = defineResponseObject({
405
+ sites: entitlementUsage.producer,
406
+ preservedRows: preservedRowsUsage.producer,
407
+ urlInspections: urlInspectionsUsage.producer
408
+ }, {
409
+ sites: entitlementUsage.client,
410
+ preservedRows: preservedRowsUsage.client,
411
+ urlInspections: urlInspectionsUsage.client
412
+ });
413
+ const heldSite = defineResponseObject({
414
+ siteId: realtimeSchemas.publicSiteId,
415
+ hold: siteHoldReasonSchema
416
+ });
417
+ const exemptEntitlements = defineResponseObject({ mode: z.literal("exempt") });
418
+ const meteredEntitlementsShape = {
419
+ mode: z.literal("metered"),
420
+ phase: z.enum(["beta", "billing"]),
421
+ sizeLimitRowsPerDay: z.number().int().positive()
422
+ };
423
+ const meteredEntitlements = defineResponseObject({
424
+ ...meteredEntitlementsShape,
425
+ meters: entitlementMeters.producer,
426
+ heldSites: z.array(heldSite.producer)
427
+ }, {
428
+ ...meteredEntitlementsShape,
429
+ meters: entitlementMeters.client,
430
+ heldSites: z.array(heldSite.client)
431
+ });
432
+ const userEntitlementsResponse = defineSuccessResponse({
433
+ producer: z.discriminatedUnion("mode", [exemptEntitlements.producer, meteredEntitlements.producer]),
434
+ client: z.discriminatedUnion("mode", [exemptEntitlements.client, meteredEntitlements.client])
435
+ }, partnerResponseMeta);
388
436
  const trendQuery = z.strictObject({
389
437
  startDate: calendarDate,
390
438
  endDate: calendarDate,
@@ -454,6 +502,8 @@ function createGscdumpV1Protocol() {
454
502
  reason: z.enum(["domain_mismatch", "rate_limited"])
455
503
  }))
456
504
  }), partnerResponseMeta);
505
+ const watchedUrlsResponse = defineSuccessResponse(defineResponseObject(watchedUrlsResponseSchema.shape), partnerResponseMeta);
506
+ const watchedUrlsChangeResponse = defineSuccessResponse(defineResponseObject(watchedUrlsChangeResponseSchema.shape), partnerResponseMeta);
457
507
  const dateRangeQuery = z.strictObject({
458
508
  startDate: calendarDate,
459
509
  endDate: calendarDate
@@ -810,6 +860,87 @@ function createGscdumpV1Protocol() {
810
860
  }
811
861
  }
812
862
  }),
863
+ getUserEntitlements: defineHttpOperation({
864
+ ...gscdumpV1OperationRoute("partner.users.entitlements.get"),
865
+ visibility: "public",
866
+ semantics: {
867
+ kind: "query",
868
+ sideEffects: "none",
869
+ idempotent: true,
870
+ retry: "idempotent",
871
+ readConsistency: "primary"
872
+ },
873
+ auth: {
874
+ credentials: ["user_key", "partner_key"],
875
+ scopes: ["users:read"],
876
+ ownership: [{
877
+ credential: "user_key",
878
+ rule: "self"
879
+ }, {
880
+ credential: "partner_key",
881
+ rule: "linked_user"
882
+ }]
883
+ },
884
+ request: {
885
+ params: z.strictObject({ userId: realtimeSchemas.publicUserId }),
886
+ query: null,
887
+ headers: requestHeaders,
888
+ body: null
889
+ },
890
+ responses: { 200: userEntitlementsResponse },
891
+ errors: partnerUserErrors,
892
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
893
+ resources: {
894
+ reads: [{
895
+ type: "partner.user",
896
+ idFrom: "params.userId"
897
+ }, {
898
+ type: "user.sites",
899
+ idFrom: "params.userId"
900
+ }],
901
+ changes: []
902
+ },
903
+ lifecycle: { introduced: "4.7.0" },
904
+ docs: {
905
+ summary: "Get user entitlements",
906
+ description: "Returns the Meters that apply to the user's partner Sites. If the partner is exempt, the response is `{ mode: \"exempt\" }` and no free allowance applies. If the partner is metered, the response gives the usage of the user's Billing owner against each free allowance, the size limit in query×page rows per day, and the held Sites the user can read. `urlInspections.allowance` is `null` when URL Inspections have no cap. `urlInspections.resetsAt` is the first UTC day of the next usage month.",
907
+ tags: ["Users"],
908
+ examples: {
909
+ request: { params: { userId: "u_01" } },
910
+ response: {
911
+ data: {
912
+ mode: "metered",
913
+ phase: "beta",
914
+ meters: {
915
+ sites: {
916
+ used: 2,
917
+ allowance: 3
918
+ },
919
+ preservedRows: {
920
+ used: 12e4,
921
+ allowance: 25e4
922
+ },
923
+ urlInspections: {
924
+ used: 310,
925
+ allowance: 5e3,
926
+ resetsAt: "2026-11-01"
927
+ }
928
+ },
929
+ sizeLimitRowsPerDay: 2500,
930
+ heldSites: [{
931
+ siteId: "s_02",
932
+ hold: "size_limit"
933
+ }]
934
+ },
935
+ meta: {
936
+ requestId: "req_01",
937
+ surface: "partner",
938
+ version: "1.0"
939
+ }
940
+ }
941
+ }
942
+ }
943
+ }),
813
944
  listAvailableSites: defineHttpOperation({
814
945
  ...gscdumpV1OperationRoute("partner.users.sites.available.list"),
815
946
  visibility: "public",
@@ -2469,6 +2600,211 @@ function createGscdumpV1Protocol() {
2469
2600
  }
2470
2601
  }
2471
2602
  }),
2603
+ listSiteWatchedUrls: defineHttpOperation({
2604
+ ...gscdumpV1OperationRoute("partner.sites.indexing.watched.list"),
2605
+ visibility: "public",
2606
+ semantics: {
2607
+ kind: "query",
2608
+ sideEffects: "none",
2609
+ idempotent: true,
2610
+ retry: "idempotent",
2611
+ readConsistency: "primary"
2612
+ },
2613
+ auth: {
2614
+ credentials: ["user_key", "partner_key"],
2615
+ scopes: ["indexing:read"],
2616
+ ownership: [{
2617
+ credential: "user_key",
2618
+ rule: "authorized_site"
2619
+ }, {
2620
+ credential: "partner_key",
2621
+ rule: "authorized_site"
2622
+ }]
2623
+ },
2624
+ request: {
2625
+ params: z.strictObject({ siteId: realtimeSchemas.publicSiteId }),
2626
+ query: null,
2627
+ headers: requestHeaders,
2628
+ body: null
2629
+ },
2630
+ responses: { 200: watchedUrlsResponse },
2631
+ errors: partnerSiteErrors,
2632
+ errorResponse: errorEnvelopeSchemas(partnerSiteErrors, realtimeSchemas.publicRequestId),
2633
+ resources: {
2634
+ reads: [{
2635
+ type: "site.indexing",
2636
+ idFrom: "params.siteId"
2637
+ }],
2638
+ changes: []
2639
+ },
2640
+ lifecycle: { introduced: "4.6.0" },
2641
+ docs: {
2642
+ summary: "List Watched URLs",
2643
+ description: "Returns the Site's Watched URLs. gscdump inspects each one every 7 days, before other scheduled URLs, and never backs off. Each Checkpoint is one scheduled URL Inspection, newest first, with the parsed coverage state and Google's coverage text.",
2644
+ tags: ["Indexing"],
2645
+ examples: {
2646
+ request: { params: { siteId: "s_01" } },
2647
+ response: {
2648
+ data: {
2649
+ watched: [{
2650
+ url: "https://example.com/guide",
2651
+ addedAt: "2026-09-30T00:00:00.000Z",
2652
+ dueAt: "2026-10-07T01:00:00.000Z",
2653
+ checkpoints: [{
2654
+ checkedAt: "2026-09-30T01:00:00.000Z",
2655
+ coverageState: "unknown_to_google",
2656
+ googleCoverageState: "URL is unknown to Google",
2657
+ verdict: "NEUTRAL",
2658
+ lastCrawlTime: null
2659
+ }]
2660
+ }],
2661
+ limit: 50,
2662
+ cadenceDays: 7,
2663
+ meta: { siteUrl: "sc-domain:example.com" }
2664
+ },
2665
+ meta: {
2666
+ requestId: "req_01",
2667
+ surface: "partner",
2668
+ version: "1.0"
2669
+ }
2670
+ }
2671
+ }
2672
+ }
2673
+ }),
2674
+ addSiteWatchedUrls: defineHttpOperation({
2675
+ ...gscdumpV1OperationRoute("partner.sites.indexing.watched.add"),
2676
+ visibility: "public",
2677
+ semantics: {
2678
+ kind: "mutation",
2679
+ sideEffects: "state",
2680
+ idempotent: true,
2681
+ retry: "idempotent",
2682
+ readConsistency: null
2683
+ },
2684
+ auth: {
2685
+ credentials: ["user_key", "partner_key"],
2686
+ scopes: ["indexing:write"],
2687
+ ownership: [{
2688
+ credential: "user_key",
2689
+ rule: "authorized_site"
2690
+ }, {
2691
+ credential: "partner_key",
2692
+ rule: "authorized_site"
2693
+ }]
2694
+ },
2695
+ request: {
2696
+ params: z.strictObject({ siteId: realtimeSchemas.publicSiteId }),
2697
+ query: null,
2698
+ headers: requestHeaders,
2699
+ body: watchedUrlsChangeRequestSchema
2700
+ },
2701
+ responses: { 200: watchedUrlsChangeResponse },
2702
+ errors: partnerSiteErrors,
2703
+ errorResponse: errorEnvelopeSchemas(partnerSiteErrors, realtimeSchemas.publicRequestId),
2704
+ resources: {
2705
+ reads: [{
2706
+ type: "site.indexing",
2707
+ idFrom: "params.siteId"
2708
+ }],
2709
+ changes: [{
2710
+ type: "site.indexing",
2711
+ idFrom: "params.siteId"
2712
+ }]
2713
+ },
2714
+ lifecycle: { introduced: "4.6.0" },
2715
+ docs: {
2716
+ summary: "Add Watched URLs",
2717
+ description: "Adds URLs on the Site host to the Site's Watched URLs, up to 50 per Site. A new Watched URL is due for inspection at once. Each scheduled inspection spends the Site's daily URL Inspection budget and the URL Inspections meter. URLs off the Site host, fragment URLs, and URLs past the limit come back in `skipped`.",
2718
+ tags: ["Indexing"],
2719
+ examples: {
2720
+ request: {
2721
+ params: { siteId: "s_01" },
2722
+ body: { urls: ["https://example.com/guide"] }
2723
+ },
2724
+ response: {
2725
+ data: {
2726
+ changed: ["https://example.com/guide"],
2727
+ unchanged: [],
2728
+ skipped: [],
2729
+ total: 1,
2730
+ limit: 50
2731
+ },
2732
+ meta: {
2733
+ requestId: "req_01",
2734
+ surface: "partner",
2735
+ version: "1.0"
2736
+ }
2737
+ }
2738
+ }
2739
+ }
2740
+ }),
2741
+ removeSiteWatchedUrls: defineHttpOperation({
2742
+ ...gscdumpV1OperationRoute("partner.sites.indexing.watched.remove"),
2743
+ visibility: "public",
2744
+ semantics: {
2745
+ kind: "mutation",
2746
+ sideEffects: "state",
2747
+ idempotent: true,
2748
+ retry: "idempotent",
2749
+ readConsistency: null
2750
+ },
2751
+ auth: {
2752
+ credentials: ["user_key", "partner_key"],
2753
+ scopes: ["indexing:write"],
2754
+ ownership: [{
2755
+ credential: "user_key",
2756
+ rule: "authorized_site"
2757
+ }, {
2758
+ credential: "partner_key",
2759
+ rule: "authorized_site"
2760
+ }]
2761
+ },
2762
+ request: {
2763
+ params: z.strictObject({ siteId: realtimeSchemas.publicSiteId }),
2764
+ query: null,
2765
+ headers: requestHeaders,
2766
+ body: watchedUrlsChangeRequestSchema
2767
+ },
2768
+ responses: { 200: watchedUrlsChangeResponse },
2769
+ errors: partnerSiteErrors,
2770
+ errorResponse: errorEnvelopeSchemas(partnerSiteErrors, realtimeSchemas.publicRequestId),
2771
+ resources: {
2772
+ reads: [{
2773
+ type: "site.indexing",
2774
+ idFrom: "params.siteId"
2775
+ }],
2776
+ changes: [{
2777
+ type: "site.indexing",
2778
+ idFrom: "params.siteId"
2779
+ }]
2780
+ },
2781
+ lifecycle: { introduced: "4.6.0" },
2782
+ docs: {
2783
+ summary: "Remove Watched URLs",
2784
+ description: "Removes URLs from the Site's Watched URLs and deletes their Checkpoints. The stored URL Inspection results stay. URLs that were not watched come back in `unchanged`.",
2785
+ tags: ["Indexing"],
2786
+ examples: {
2787
+ request: {
2788
+ params: { siteId: "s_01" },
2789
+ body: { urls: ["https://example.com/guide"] }
2790
+ },
2791
+ response: {
2792
+ data: {
2793
+ changed: ["https://example.com/guide"],
2794
+ unchanged: [],
2795
+ skipped: [],
2796
+ total: 0,
2797
+ limit: 50
2798
+ },
2799
+ meta: {
2800
+ requestId: "req_01",
2801
+ surface: "partner",
2802
+ version: "1.0"
2803
+ }
2804
+ }
2805
+ }
2806
+ }
2807
+ }),
2472
2808
  recoverSitePermission: defineHttpOperation({
2473
2809
  ...gscdumpV1OperationRoute("partner.sites.permission.recover"),
2474
2810
  visibility: "public",
@@ -5064,6 +5400,8 @@ function createGscdumpV1Protocol() {
5064
5400
  indexingTransitionsResponse,
5065
5401
  indexingUrlsQuery,
5066
5402
  indexingUrlsResponse,
5403
+ watchedUrlsResponse,
5404
+ watchedUrlsChangeResponse,
5067
5405
  bingIndexingEvidenceQuery,
5068
5406
  bingIndexingEvidenceResponse,
5069
5407
  bingConnectionResponse,
@@ -5071,6 +5409,7 @@ function createGscdumpV1Protocol() {
5071
5409
  indexNowSubmissionResponse,
5072
5410
  indexNowSubmissionReceiptsResponse,
5073
5411
  lifecycleResponse,
5412
+ userEntitlementsResponse,
5074
5413
  registerSiteRequest,
5075
5414
  sitemapChangesQuery,
5076
5415
  sitemapChangesResponse,
@@ -21,6 +21,11 @@ export declare const GSCDUMP_V1_ROUTE_CATALOG: {
21
21
  readonly method: "GET";
22
22
  readonly template: "/users/{userId}/lifecycle";
23
23
  };
24
+ readonly 'partner.users.entitlements.get': {
25
+ readonly surface: "partner";
26
+ readonly method: "GET";
27
+ readonly template: "/users/{userId}/entitlements";
28
+ };
24
29
  readonly 'partner.users.sites.available.list': {
25
30
  readonly surface: "partner";
26
31
  readonly method: "GET";
@@ -141,6 +146,21 @@ export declare const GSCDUMP_V1_ROUTE_CATALOG: {
141
146
  readonly method: "POST";
142
147
  readonly template: "/sites/{siteId}/indexing/inspect";
143
148
  };
149
+ readonly 'partner.sites.indexing.watched.list': {
150
+ readonly surface: "partner";
151
+ readonly method: "GET";
152
+ readonly template: "/sites/{siteId}/indexing/watched";
153
+ };
154
+ readonly 'partner.sites.indexing.watched.add': {
155
+ readonly surface: "partner";
156
+ readonly method: "POST";
157
+ readonly template: "/sites/{siteId}/indexing/watched";
158
+ };
159
+ readonly 'partner.sites.indexing.watched.remove': {
160
+ readonly surface: "partner";
161
+ readonly method: "POST";
162
+ readonly template: "/sites/{siteId}/indexing/watched/remove";
163
+ };
144
164
  readonly 'partner.sites.permission.recover': {
145
165
  readonly surface: "partner";
146
166
  readonly method: "POST";
@@ -8,6 +8,11 @@ const GSCDUMP_V1_ROUTE_CATALOG = {
8
8
  method: "GET",
9
9
  template: "/users/{userId}/lifecycle"
10
10
  },
11
+ "partner.users.entitlements.get": {
12
+ surface: "partner",
13
+ method: "GET",
14
+ template: "/users/{userId}/entitlements"
15
+ },
11
16
  "partner.users.sites.available.list": {
12
17
  surface: "partner",
13
18
  method: "GET",
@@ -128,6 +133,21 @@ const GSCDUMP_V1_ROUTE_CATALOG = {
128
133
  method: "POST",
129
134
  template: "/sites/{siteId}/indexing/inspect"
130
135
  },
136
+ "partner.sites.indexing.watched.list": {
137
+ surface: "partner",
138
+ method: "GET",
139
+ template: "/sites/{siteId}/indexing/watched"
140
+ },
141
+ "partner.sites.indexing.watched.add": {
142
+ surface: "partner",
143
+ method: "POST",
144
+ template: "/sites/{siteId}/indexing/watched"
145
+ },
146
+ "partner.sites.indexing.watched.remove": {
147
+ surface: "partner",
148
+ method: "POST",
149
+ template: "/sites/{siteId}/indexing/watched/remove"
150
+ },
131
151
  "partner.sites.permission.recover": {
132
152
  surface: "partner",
133
153
  method: "POST",
@@ -4,5 +4,5 @@ export declare const WEBHOOK_EVENT_HEADER = "X-GSCDump-Event";
4
4
  export declare const WEBHOOK_DELIVERY_HEADER = "X-GSCDump-Delivery";
5
5
  export declare const WEBHOOK_CONTRACT_VERSION_HEADER = "X-GSCDump-Contract-Version";
6
6
  export declare const WEBHOOK_TIMESTAMP_HEADER = "X-GSCDump-Timestamp";
7
- export declare const CANONICAL_WEBHOOK_EVENTS: readonly ["user.lifecycle.changed", "site.lifecycle.changed", "site.analytics.ready", "site.indexing.ready", "site.auth.failed", "job.failed"];
8
- export declare const VALID_WEBHOOK_EVENTS: readonly ["user.lifecycle.changed", "site.lifecycle.changed", "site.analytics.ready", "site.indexing.ready", "site.auth.failed", "job.failed"];
7
+ export declare const CANONICAL_WEBHOOK_EVENTS: readonly ["user.lifecycle.changed", "site.lifecycle.changed", "site.analytics.ready", "site.indexing.ready", "site.auth.failed", "job.failed", "user.allowance.notice"];
8
+ export declare const VALID_WEBHOOK_EVENTS: readonly ["user.lifecycle.changed", "site.lifecycle.changed", "site.analytics.ready", "site.indexing.ready", "site.auth.failed", "job.failed", "user.allowance.notice"];
@@ -10,7 +10,8 @@ const CANONICAL_WEBHOOK_EVENTS = [
10
10
  "site.analytics.ready",
11
11
  "site.indexing.ready",
12
12
  "site.auth.failed",
13
- "job.failed"
13
+ "job.failed",
14
+ "user.allowance.notice"
14
15
  ];
15
16
  const VALID_WEBHOOK_EVENTS = CANONICAL_WEBHOOK_EVENTS;
16
17
  export { CANONICAL_WEBHOOK_EVENTS, VALID_WEBHOOK_EVENTS, WEBHOOK_CONTRACT_VERSION, WEBHOOK_CONTRACT_VERSION_HEADER, WEBHOOK_DELIVERY_HEADER, WEBHOOK_EVENT_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gscdump/contracts",
3
3
  "type": "module",
4
- "version": "4.5.0",
4
+ "version": "4.7.0",
5
5
  "description": "Shared gscdump.com API, webhook, realtime, and lifecycle contracts.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",