@gscdump/contracts 1.2.0 → 1.3.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.
package/dist/v1/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { accountNextActions, accountStatuses, analyticsNextActions, analyticsStatuses, builderStateSchema, gscComparisonFilterSchema, gscdumpAnalysisBundleResponseSchema, gscdumpAnalysisPresetSchema, gscdumpAnalysisResponseSchema, gscdumpAvailableSiteSchema, gscdumpCanonicalMismatchesResponseSchema, gscdumpDataDetailResponseSchema, gscdumpDataResponseSchema, gscdumpIndexPercentResponseSchema, gscdumpIndexingDiagnosticsResponseSchema, gscdumpIndexingResponseSchema, gscdumpKeywordSparklinesResponseSchema, gscdumpPageTrendResponseSchema, gscdumpQueryTrendResponseSchema, gscdumpSiteRegistrationSchema, gscdumpSitemapChangesResponseSchema, gscdumpSitemapsResponseSchema, gscdumpTopAssociationResponseSchema, gscdumpUserRegistrationSchema, indexingNextActions, indexingStatuses, indexingUrlsResponseSchema, lifecycleErrorCodes, propertyNextActions, propertyStatuses, querySourceModes, registerPartnerSiteSchema, registerPartnerUserSchema, searchTypeSchema, sitemapNextActions, sitemapStatuses, updatePartnerUserTokensSchema } from "../_chunks/schemas.mjs";
1
+ import { accountNextActions, accountStatuses, addPartnerTeamMemberSchema, analyticsNextActions, analyticsStatuses, bindPartnerSiteTeamSchema, bindPartnerTeamCatalogResponseSchema, bindPartnerTeamCatalogSchema, builderStateSchema, createPartnerTeamSchema, gscComparisonFilterSchema, gscdumpAnalysisBundleResponseSchema, gscdumpAnalysisPresetSchema, gscdumpAnalysisResponseSchema, gscdumpAvailableSiteSchema, gscdumpCanonicalMismatchesResponseSchema, gscdumpDataDetailResponseSchema, gscdumpDataResponseSchema, gscdumpDeletePartnerUserResponseSchema, gscdumpIndexPercentResponseSchema, gscdumpIndexingDiagnosticsResponseSchema, gscdumpIndexingResponseSchema, gscdumpKeywordSparklinesResponseSchema, gscdumpPageTrendResponseSchema, gscdumpQueryTrendResponseSchema, gscdumpSiteRegistrationSchema, gscdumpSitemapChangesResponseSchema, gscdumpSitemapMembershipParamsSchema, gscdumpSitemapMembershipResponseSchema, gscdumpSitemapsResponseSchema, gscdumpTeamRoleSchema, gscdumpTopAssociationResponseSchema, gscdumpUserRegistrationSchema, indexingNextActions, indexingStatuses, indexingUrlsResponseSchema, lifecycleErrorCodes, partnerSiteTeamBindingResponseSchema, partnerSitemapActionResponseSchema, partnerSitemapActionSchema, partnerTeamCreatedResponseSchema, partnerTeamDeletedResponseSchema, partnerTeamMemberAddedResponseSchema, partnerTeamMemberRemovedResponseSchema, partnerTeamMemberRoleResponseSchema, partnerTeamMembersResponseSchema, partnerTeamRenamedResponseSchema, propertyNextActions, propertyStatuses, querySourceModes, registerPartnerSiteSchema, registerPartnerUserSchema, renamePartnerTeamSchema, searchTypeSchema, siteIntIdCrosswalkResponseSchema, sitemapNextActions, sitemapStatuses, teamCatalogRefSchema, updatePartnerUserTokensSchema } from "../_chunks/schemas.mjs";
2
2
  import { z } from "zod";
3
3
  const HTTP_V1_SURFACES = [
4
4
  "partner",
@@ -1194,6 +1194,88 @@ function createGscdumpV1Protocol() {
1194
1194
  });
1195
1195
  const indexPercentResponse = defineSuccessResponse(defineResponseObject(gscdumpIndexPercentResponseSchema.shape), partnerResponseMeta);
1196
1196
  const contentVelocityQuery = z.strictObject({ days: z.coerce.number().int().min(1).max(365).optional() });
1197
+ const sitemapActionRequest = partnerSitemapActionSchema;
1198
+ const sitemapActionResponse = defineSuccessResponse({
1199
+ producer: partnerSitemapActionResponseSchema,
1200
+ client: partnerSitemapActionResponseSchema
1201
+ }, partnerResponseMeta);
1202
+ const sitemapMembershipRequest = gscdumpSitemapMembershipParamsSchema.strict();
1203
+ const sitemapMembershipResponse = defineSuccessResponse(defineResponseObject(gscdumpSitemapMembershipResponseSchema.shape), partnerResponseMeta);
1204
+ const createTeamRequest = createPartnerTeamSchema.strict();
1205
+ const teamCreatedResponse = defineSuccessResponse(defineResponseObject(partnerTeamCreatedResponseSchema.shape), partnerResponseMeta);
1206
+ const renameTeamRequest = renamePartnerTeamSchema.strict();
1207
+ const teamRenamedResponse = defineSuccessResponse(defineResponseObject(partnerTeamRenamedResponseSchema.shape), partnerResponseMeta);
1208
+ const teamDeletedResponse = defineSuccessResponse(defineResponseObject(partnerTeamDeletedResponseSchema.shape), partnerResponseMeta);
1209
+ const teamMembersResponse = defineSuccessResponse(defineResponseObject(partnerTeamMembersResponseSchema.shape), partnerResponseMeta);
1210
+ const addTeamMemberRequest = addPartnerTeamMemberSchema.strict();
1211
+ const teamMemberAddedResponse = defineSuccessResponse(defineResponseObject(partnerTeamMemberAddedResponseSchema.shape), partnerResponseMeta);
1212
+ const updateTeamMemberRoleRequest = z.strictObject({ role: gscdumpTeamRoleSchema });
1213
+ const teamMemberRoleResponse = defineSuccessResponse(defineResponseObject(partnerTeamMemberRoleResponseSchema.shape), partnerResponseMeta);
1214
+ const teamMemberRemovedResponse = defineSuccessResponse(defineResponseObject(partnerTeamMemberRemovedResponseSchema.shape), partnerResponseMeta);
1215
+ const bindSiteTeamRequest = bindPartnerSiteTeamSchema.strict();
1216
+ const siteTeamBindingResponse = defineSuccessResponse(defineResponseObject(partnerSiteTeamBindingResponseSchema.shape), partnerResponseMeta);
1217
+ const teamCatalogResponse = defineSuccessResponse(defineResponseObject(teamCatalogRefSchema.shape), partnerResponseMeta);
1218
+ const bindTeamCatalogRequest = bindPartnerTeamCatalogSchema.strict();
1219
+ const teamCatalogBindResponse = defineSuccessResponse(defineResponseObject(bindPartnerTeamCatalogResponseSchema.shape), partnerResponseMeta);
1220
+ const siteIntIdCrosswalkResponse = defineSuccessResponse(defineResponseObject(siteIntIdCrosswalkResponseSchema.shape), partnerResponseMeta);
1221
+ const deletePartnerUserResponse = defineSuccessResponse(defineResponseObject(gscdumpDeletePartnerUserResponseSchema.shape), partnerResponseMeta);
1222
+ const verificationMethodSchema = z.enum([
1223
+ "META",
1224
+ "FILE",
1225
+ "DNS_TXT",
1226
+ "DNS_CNAME",
1227
+ "ANALYTICS",
1228
+ "TAG_MANAGER"
1229
+ ]);
1230
+ const verificationTokenRequest = z.strictObject({
1231
+ siteUrl: z.string().min(1),
1232
+ method: verificationMethodSchema.optional()
1233
+ });
1234
+ const verificationSiteShape = z.object({
1235
+ type: z.string(),
1236
+ identifier: z.string()
1237
+ }).loose();
1238
+ const verificationTokenResponse = defineSuccessResponse(defineResponseObject({
1239
+ siteUrl: z.string(),
1240
+ site: verificationSiteShape,
1241
+ method: z.string(),
1242
+ token: z.string(),
1243
+ metaContent: z.string().nullable(),
1244
+ dnsRecord: z.object({
1245
+ type: z.enum(["TXT", "CNAME"]),
1246
+ host: z.string(),
1247
+ value: z.string()
1248
+ }).nullable()
1249
+ }), partnerResponseMeta);
1250
+ const addAndVerifySiteRequest = verificationTokenRequest;
1251
+ const addAndVerifySiteResponse = defineSuccessResponse(defineResponseObject({
1252
+ siteUrl: z.string(),
1253
+ site: verificationSiteShape,
1254
+ method: z.string(),
1255
+ verified: z.literal(true),
1256
+ owners: z.array(z.string()).optional()
1257
+ }), partnerResponseMeta);
1258
+ const crossSourceRequest = z.strictObject({
1259
+ queryKey: z.enum([
1260
+ "crawl-error-losing-impressions",
1261
+ "declining-clicks-poor-lcp",
1262
+ "striking-distance-slow-pages",
1263
+ "top-impressions-low-performance"
1264
+ ]),
1265
+ rangeDays: z.number().int().positive().max(180).optional(),
1266
+ limit: z.number().int().positive().max(500).optional()
1267
+ });
1268
+ const crossSourceResponse = defineSuccessResponse(defineResponseObject({
1269
+ reason: z.string().optional(),
1270
+ sources: z.array(z.string()),
1271
+ rows: z.array(z.record(z.string(), z.json()))
1272
+ }), partnerResponseMeta);
1273
+ const enrichKeywordsRequest = z.strictObject({ keywords: z.array(z.string().min(1)).min(1).max(500) });
1274
+ const enrichKeywordsResponse = defineSuccessResponse(defineResponseObject({ metrics: z.record(z.string(), z.object({
1275
+ difficulty: z.number().nullable(),
1276
+ searchVolume: z.number().nullable(),
1277
+ cpc: z.number().nullable()
1278
+ }).loose()) }), partnerResponseMeta);
1197
1279
  const responseStreamHead = defineResponseObject({
1198
1280
  streamId: realtimeSchemas.streamId,
1199
1281
  sequence: realtimeSchemas.sequence
@@ -3174,6 +3256,1199 @@ function createGscdumpV1Protocol() {
3174
3256
  }
3175
3257
  }
3176
3258
  }
3259
+ }),
3260
+ createSitemapAction: defineHttpOperation({
3261
+ id: "partner.sites.sitemaps.action.create",
3262
+ method: "POST",
3263
+ path: "/sites/{siteId}/sitemaps/actions",
3264
+ visibility: "public",
3265
+ semantics: {
3266
+ kind: "mutation",
3267
+ sideEffects: "state",
3268
+ idempotent: false,
3269
+ retry: "never",
3270
+ readConsistency: null
3271
+ },
3272
+ auth: {
3273
+ credentials: ["user_key", "partner_key"],
3274
+ scopes: ["sitemaps:write"],
3275
+ ownership: [{
3276
+ credential: "user_key",
3277
+ rule: "authorized_site"
3278
+ }, {
3279
+ credential: "partner_key",
3280
+ rule: "authorized_site"
3281
+ }]
3282
+ },
3283
+ request: {
3284
+ params: z.strictObject({ siteId: realtimeSchemas.publicSiteId }),
3285
+ query: null,
3286
+ headers: requestHeaders,
3287
+ body: sitemapActionRequest
3288
+ },
3289
+ responses: { 200: sitemapActionResponse },
3290
+ errors: partnerSiteErrors,
3291
+ errorResponse: errorEnvelopeSchemas(partnerSiteErrors, realtimeSchemas.publicRequestId),
3292
+ resources: {
3293
+ reads: [{
3294
+ type: "site.sitemaps",
3295
+ idFrom: "params.siteId"
3296
+ }],
3297
+ changes: [{
3298
+ type: "site.sitemaps",
3299
+ idFrom: "params.siteId"
3300
+ }]
3301
+ },
3302
+ lifecycle: { introduced: "1.3.0" },
3303
+ docs: {
3304
+ summary: "Run a sitemap action",
3305
+ description: "Submits, deletes, refreshes, or auto-discovers a site's sitemap; the response shape depends on the requested action.",
3306
+ tags: ["Sitemaps"],
3307
+ examples: {
3308
+ request: {
3309
+ params: { siteId: "s_01" },
3310
+ body: { action: "refresh" }
3311
+ },
3312
+ response: {
3313
+ data: {
3314
+ success: true,
3315
+ action: "refreshed",
3316
+ sitemapCount: 0,
3317
+ changed: false
3318
+ },
3319
+ meta: {
3320
+ requestId: "req_01",
3321
+ surface: "partner",
3322
+ version: "1.0"
3323
+ }
3324
+ }
3325
+ }
3326
+ }
3327
+ }),
3328
+ querySitemapMembership: defineHttpOperation({
3329
+ id: "partner.sites.sitemaps.membership.query",
3330
+ method: "POST",
3331
+ path: "/sites/{siteId}/sitemaps/membership",
3332
+ visibility: "public",
3333
+ semantics: {
3334
+ kind: "query",
3335
+ sideEffects: "none",
3336
+ idempotent: true,
3337
+ retry: "idempotent",
3338
+ readConsistency: "primary"
3339
+ },
3340
+ auth: {
3341
+ credentials: ["user_key", "partner_key"],
3342
+ scopes: ["sitemaps:read"],
3343
+ ownership: [{
3344
+ credential: "user_key",
3345
+ rule: "authorized_site"
3346
+ }, {
3347
+ credential: "partner_key",
3348
+ rule: "authorized_site"
3349
+ }]
3350
+ },
3351
+ request: {
3352
+ params: z.strictObject({ siteId: realtimeSchemas.publicSiteId }),
3353
+ query: null,
3354
+ headers: requestHeaders,
3355
+ body: sitemapMembershipRequest
3356
+ },
3357
+ responses: { 200: sitemapMembershipResponse },
3358
+ errors: partnerSiteErrors,
3359
+ errorResponse: errorEnvelopeSchemas(partnerSiteErrors, realtimeSchemas.publicRequestId),
3360
+ resources: {
3361
+ reads: [{
3362
+ type: "site.sitemaps",
3363
+ idFrom: "params.siteId"
3364
+ }],
3365
+ changes: []
3366
+ },
3367
+ lifecycle: { introduced: "1.3.0" },
3368
+ docs: {
3369
+ summary: "Query sitemap membership",
3370
+ description: "Checks whether each requested URL is present in the site's known sitemaps, subject to a freshness cap.",
3371
+ tags: ["Sitemaps"],
3372
+ examples: {
3373
+ request: {
3374
+ params: { siteId: "s_01" },
3375
+ body: {
3376
+ urls: ["https://example.com/"],
3377
+ maxAgeDays: 30
3378
+ }
3379
+ },
3380
+ response: {
3381
+ data: {
3382
+ urls: [],
3383
+ meta: {
3384
+ available: true,
3385
+ reason: null,
3386
+ requested: 1,
3387
+ checked: 1,
3388
+ matched: 0,
3389
+ newestFetchedAt: null
3390
+ }
3391
+ },
3392
+ meta: {
3393
+ requestId: "req_01",
3394
+ surface: "partner",
3395
+ version: "1.0"
3396
+ }
3397
+ }
3398
+ }
3399
+ }
3400
+ }),
3401
+ createTeam: defineHttpOperation({
3402
+ id: "partner.teams.create",
3403
+ method: "POST",
3404
+ path: "/teams",
3405
+ visibility: "public",
3406
+ semantics: {
3407
+ kind: "mutation",
3408
+ sideEffects: "state",
3409
+ idempotent: false,
3410
+ retry: "never",
3411
+ readConsistency: null
3412
+ },
3413
+ auth: {
3414
+ credentials: ["partner_key"],
3415
+ scopes: ["teams:write"],
3416
+ ownership: [{
3417
+ credential: "partner_key",
3418
+ rule: "partner_tenant"
3419
+ }]
3420
+ },
3421
+ request: {
3422
+ params: null,
3423
+ query: null,
3424
+ headers: requestHeaders,
3425
+ body: createTeamRequest
3426
+ },
3427
+ responses: { 200: teamCreatedResponse },
3428
+ errors: partnerUserErrors,
3429
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
3430
+ resources: {
3431
+ reads: [],
3432
+ changes: [{
3433
+ type: "partner.team",
3434
+ idFrom: "principal.id"
3435
+ }]
3436
+ },
3437
+ lifecycle: { introduced: "1.3.0" },
3438
+ docs: {
3439
+ summary: "Create a team",
3440
+ description: "Creates a team owned by a user linked to the authenticated partner tenant.",
3441
+ tags: ["Teams"],
3442
+ examples: {
3443
+ request: { body: {
3444
+ ownerUserId: "u_01",
3445
+ name: "Acme Team"
3446
+ } },
3447
+ response: {
3448
+ data: { team: {
3449
+ id: "t_01",
3450
+ ownerId: 1,
3451
+ name: "Acme Team",
3452
+ personalTeam: false,
3453
+ createdAt: 0,
3454
+ updatedAt: 0
3455
+ } },
3456
+ meta: {
3457
+ requestId: "req_01",
3458
+ surface: "partner",
3459
+ version: "1.0"
3460
+ }
3461
+ }
3462
+ }
3463
+ }
3464
+ }),
3465
+ renameTeam: defineHttpOperation({
3466
+ id: "partner.teams.rename",
3467
+ method: "PATCH",
3468
+ path: "/teams/{teamId}",
3469
+ visibility: "public",
3470
+ semantics: {
3471
+ kind: "mutation",
3472
+ sideEffects: "state",
3473
+ idempotent: true,
3474
+ retry: "idempotent",
3475
+ readConsistency: null
3476
+ },
3477
+ auth: {
3478
+ credentials: ["partner_key"],
3479
+ scopes: ["teams:write"],
3480
+ ownership: [{
3481
+ credential: "partner_key",
3482
+ rule: "partner_tenant"
3483
+ }]
3484
+ },
3485
+ request: {
3486
+ params: z.strictObject({ teamId: realtimeSchemas.publicTeamId }),
3487
+ query: null,
3488
+ headers: requestHeaders,
3489
+ body: renameTeamRequest
3490
+ },
3491
+ responses: { 200: teamRenamedResponse },
3492
+ errors: partnerUserErrors,
3493
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
3494
+ resources: {
3495
+ reads: [{
3496
+ type: "partner.team",
3497
+ idFrom: "params.teamId"
3498
+ }],
3499
+ changes: [{
3500
+ type: "partner.team",
3501
+ idFrom: "params.teamId"
3502
+ }]
3503
+ },
3504
+ lifecycle: { introduced: "1.3.0" },
3505
+ docs: {
3506
+ summary: "Rename a team",
3507
+ description: "Renames a team owned by the authenticated partner tenant.",
3508
+ tags: ["Teams"],
3509
+ examples: {
3510
+ request: {
3511
+ params: { teamId: "t_01" },
3512
+ body: { name: "New name" }
3513
+ },
3514
+ response: {
3515
+ data: {
3516
+ ok: true,
3517
+ name: "New name"
3518
+ },
3519
+ meta: {
3520
+ requestId: "req_01",
3521
+ surface: "partner",
3522
+ version: "1.0"
3523
+ }
3524
+ }
3525
+ }
3526
+ }
3527
+ }),
3528
+ deleteTeam: defineHttpOperation({
3529
+ id: "partner.teams.delete",
3530
+ method: "DELETE",
3531
+ path: "/teams/{teamId}",
3532
+ visibility: "public",
3533
+ semantics: {
3534
+ kind: "mutation",
3535
+ sideEffects: "state",
3536
+ idempotent: true,
3537
+ retry: "idempotent",
3538
+ readConsistency: null
3539
+ },
3540
+ auth: {
3541
+ credentials: ["partner_key"],
3542
+ scopes: ["teams:write"],
3543
+ ownership: [{
3544
+ credential: "partner_key",
3545
+ rule: "partner_tenant"
3546
+ }]
3547
+ },
3548
+ request: {
3549
+ params: z.strictObject({ teamId: realtimeSchemas.publicTeamId }),
3550
+ query: null,
3551
+ headers: requestHeaders,
3552
+ body: null
3553
+ },
3554
+ responses: { 200: teamDeletedResponse },
3555
+ errors: partnerUserErrors,
3556
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
3557
+ resources: {
3558
+ reads: [{
3559
+ type: "partner.team",
3560
+ idFrom: "params.teamId"
3561
+ }],
3562
+ changes: [{
3563
+ type: "partner.team",
3564
+ idFrom: "params.teamId"
3565
+ }]
3566
+ },
3567
+ lifecycle: { introduced: "1.3.0" },
3568
+ docs: {
3569
+ summary: "Delete a team",
3570
+ description: "Deletes a team owned by the authenticated partner tenant.",
3571
+ tags: ["Teams"],
3572
+ examples: {
3573
+ request: { params: { teamId: "t_01" } },
3574
+ response: {
3575
+ data: { ok: true },
3576
+ meta: {
3577
+ requestId: "req_01",
3578
+ surface: "partner",
3579
+ version: "1.0"
3580
+ }
3581
+ }
3582
+ }
3583
+ }
3584
+ }),
3585
+ listTeamMembers: defineHttpOperation({
3586
+ id: "partner.teams.members.list",
3587
+ method: "GET",
3588
+ path: "/teams/{teamId}/members",
3589
+ visibility: "public",
3590
+ semantics: {
3591
+ kind: "query",
3592
+ sideEffects: "none",
3593
+ idempotent: true,
3594
+ retry: "idempotent",
3595
+ readConsistency: "primary"
3596
+ },
3597
+ auth: {
3598
+ credentials: ["partner_key"],
3599
+ scopes: ["teams:read"],
3600
+ ownership: [{
3601
+ credential: "partner_key",
3602
+ rule: "partner_tenant"
3603
+ }]
3604
+ },
3605
+ request: {
3606
+ params: z.strictObject({ teamId: realtimeSchemas.publicTeamId }),
3607
+ query: null,
3608
+ headers: requestHeaders,
3609
+ body: null
3610
+ },
3611
+ responses: { 200: teamMembersResponse },
3612
+ errors: partnerUserErrors,
3613
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
3614
+ resources: {
3615
+ reads: [{
3616
+ type: "partner.team",
3617
+ idFrom: "params.teamId"
3618
+ }],
3619
+ changes: []
3620
+ },
3621
+ lifecycle: { introduced: "1.3.0" },
3622
+ docs: {
3623
+ summary: "List team members",
3624
+ description: "Lists the members of a team owned by the authenticated partner tenant.",
3625
+ tags: ["Teams"],
3626
+ examples: {
3627
+ request: { params: { teamId: "t_01" } },
3628
+ response: {
3629
+ data: { members: [] },
3630
+ meta: {
3631
+ requestId: "req_01",
3632
+ surface: "partner",
3633
+ version: "1.0"
3634
+ }
3635
+ }
3636
+ }
3637
+ }
3638
+ }),
3639
+ addTeamMember: defineHttpOperation({
3640
+ id: "partner.teams.members.add",
3641
+ method: "POST",
3642
+ path: "/teams/{teamId}/members",
3643
+ visibility: "public",
3644
+ semantics: {
3645
+ kind: "mutation",
3646
+ sideEffects: "state",
3647
+ idempotent: true,
3648
+ retry: "idempotent",
3649
+ readConsistency: null
3650
+ },
3651
+ auth: {
3652
+ credentials: ["partner_key"],
3653
+ scopes: ["teams:write"],
3654
+ ownership: [{
3655
+ credential: "partner_key",
3656
+ rule: "partner_tenant"
3657
+ }]
3658
+ },
3659
+ request: {
3660
+ params: z.strictObject({ teamId: realtimeSchemas.publicTeamId }),
3661
+ query: null,
3662
+ headers: requestHeaders,
3663
+ body: addTeamMemberRequest
3664
+ },
3665
+ responses: { 200: teamMemberAddedResponse },
3666
+ errors: partnerUserErrors,
3667
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
3668
+ resources: {
3669
+ reads: [{
3670
+ type: "partner.team",
3671
+ idFrom: "params.teamId"
3672
+ }],
3673
+ changes: [{
3674
+ type: "partner.team",
3675
+ idFrom: "params.teamId"
3676
+ }]
3677
+ },
3678
+ lifecycle: { introduced: "1.3.0" },
3679
+ docs: {
3680
+ summary: "Add a team member",
3681
+ description: "Adds a user to a team owned by the authenticated partner tenant, or reports it was already a member.",
3682
+ tags: ["Teams"],
3683
+ examples: {
3684
+ request: {
3685
+ params: { teamId: "t_01" },
3686
+ body: {
3687
+ userId: "u_02",
3688
+ role: "editor"
3689
+ }
3690
+ },
3691
+ response: {
3692
+ data: {
3693
+ ok: true,
3694
+ role: "editor"
3695
+ },
3696
+ meta: {
3697
+ requestId: "req_01",
3698
+ surface: "partner",
3699
+ version: "1.0"
3700
+ }
3701
+ }
3702
+ }
3703
+ }
3704
+ }),
3705
+ updateTeamMemberRole: defineHttpOperation({
3706
+ id: "partner.teams.members.role.update",
3707
+ method: "PATCH",
3708
+ path: "/teams/{teamId}/members/{userId}",
3709
+ visibility: "public",
3710
+ semantics: {
3711
+ kind: "mutation",
3712
+ sideEffects: "state",
3713
+ idempotent: true,
3714
+ retry: "idempotent",
3715
+ readConsistency: null
3716
+ },
3717
+ auth: {
3718
+ credentials: ["partner_key"],
3719
+ scopes: ["teams:write"],
3720
+ ownership: [{
3721
+ credential: "partner_key",
3722
+ rule: "partner_tenant"
3723
+ }]
3724
+ },
3725
+ request: {
3726
+ params: z.strictObject({
3727
+ teamId: realtimeSchemas.publicTeamId,
3728
+ userId: realtimeSchemas.publicUserId
3729
+ }),
3730
+ query: null,
3731
+ headers: requestHeaders,
3732
+ body: updateTeamMemberRoleRequest
3733
+ },
3734
+ responses: { 200: teamMemberRoleResponse },
3735
+ errors: partnerUserErrors,
3736
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
3737
+ resources: {
3738
+ reads: [{
3739
+ type: "partner.team",
3740
+ idFrom: "params.teamId"
3741
+ }, {
3742
+ type: "partner.user",
3743
+ idFrom: "params.userId"
3744
+ }],
3745
+ changes: [{
3746
+ type: "partner.team",
3747
+ idFrom: "params.teamId"
3748
+ }, {
3749
+ type: "partner.user",
3750
+ idFrom: "params.userId"
3751
+ }]
3752
+ },
3753
+ lifecycle: { introduced: "1.3.0" },
3754
+ docs: {
3755
+ summary: "Update a team member role",
3756
+ description: "Updates the role of an existing member of a team owned by the authenticated partner tenant.",
3757
+ tags: ["Teams"],
3758
+ examples: {
3759
+ request: {
3760
+ params: {
3761
+ teamId: "t_01",
3762
+ userId: "u_02"
3763
+ },
3764
+ body: { role: "admin" }
3765
+ },
3766
+ response: {
3767
+ data: {
3768
+ ok: true,
3769
+ role: "admin"
3770
+ },
3771
+ meta: {
3772
+ requestId: "req_01",
3773
+ surface: "partner",
3774
+ version: "1.0"
3775
+ }
3776
+ }
3777
+ }
3778
+ }
3779
+ }),
3780
+ removeTeamMember: defineHttpOperation({
3781
+ id: "partner.teams.members.remove",
3782
+ method: "DELETE",
3783
+ path: "/teams/{teamId}/members/{userId}",
3784
+ visibility: "public",
3785
+ semantics: {
3786
+ kind: "mutation",
3787
+ sideEffects: "state",
3788
+ idempotent: true,
3789
+ retry: "idempotent",
3790
+ readConsistency: null
3791
+ },
3792
+ auth: {
3793
+ credentials: ["partner_key"],
3794
+ scopes: ["teams:write"],
3795
+ ownership: [{
3796
+ credential: "partner_key",
3797
+ rule: "partner_tenant"
3798
+ }]
3799
+ },
3800
+ request: {
3801
+ params: z.strictObject({
3802
+ teamId: realtimeSchemas.publicTeamId,
3803
+ userId: realtimeSchemas.publicUserId
3804
+ }),
3805
+ query: null,
3806
+ headers: requestHeaders,
3807
+ body: null
3808
+ },
3809
+ responses: { 200: teamMemberRemovedResponse },
3810
+ errors: partnerUserErrors,
3811
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
3812
+ resources: {
3813
+ reads: [{
3814
+ type: "partner.team",
3815
+ idFrom: "params.teamId"
3816
+ }, {
3817
+ type: "partner.user",
3818
+ idFrom: "params.userId"
3819
+ }],
3820
+ changes: [{
3821
+ type: "partner.team",
3822
+ idFrom: "params.teamId"
3823
+ }, {
3824
+ type: "partner.user",
3825
+ idFrom: "params.userId"
3826
+ }]
3827
+ },
3828
+ lifecycle: { introduced: "1.3.0" },
3829
+ docs: {
3830
+ summary: "Remove a team member",
3831
+ description: "Removes a member from a team owned by the authenticated partner tenant.",
3832
+ tags: ["Teams"],
3833
+ examples: {
3834
+ request: { params: {
3835
+ teamId: "t_01",
3836
+ userId: "u_02"
3837
+ } },
3838
+ response: {
3839
+ data: { ok: true },
3840
+ meta: {
3841
+ requestId: "req_01",
3842
+ surface: "partner",
3843
+ version: "1.0"
3844
+ }
3845
+ }
3846
+ }
3847
+ }
3848
+ }),
3849
+ updateSiteTeam: defineHttpOperation({
3850
+ id: "partner.sites.team.update",
3851
+ method: "PATCH",
3852
+ path: "/sites/{siteId}/team",
3853
+ visibility: "public",
3854
+ semantics: {
3855
+ kind: "mutation",
3856
+ sideEffects: "state",
3857
+ idempotent: true,
3858
+ retry: "idempotent",
3859
+ readConsistency: null
3860
+ },
3861
+ auth: {
3862
+ credentials: ["partner_key"],
3863
+ scopes: ["sites:write"],
3864
+ ownership: [{
3865
+ credential: "partner_key",
3866
+ rule: "authorized_site"
3867
+ }]
3868
+ },
3869
+ request: {
3870
+ params: z.strictObject({ siteId: realtimeSchemas.publicSiteId }),
3871
+ query: null,
3872
+ headers: requestHeaders,
3873
+ body: bindSiteTeamRequest
3874
+ },
3875
+ responses: { 200: siteTeamBindingResponse },
3876
+ errors: partnerSiteErrors,
3877
+ errorResponse: errorEnvelopeSchemas(partnerSiteErrors, realtimeSchemas.publicRequestId),
3878
+ resources: {
3879
+ reads: [{
3880
+ type: "site.registration",
3881
+ idFrom: "params.siteId"
3882
+ }],
3883
+ changes: [{
3884
+ type: "site.registration",
3885
+ idFrom: "params.siteId"
3886
+ }]
3887
+ },
3888
+ lifecycle: { introduced: "1.3.0" },
3889
+ docs: {
3890
+ summary: "Bind a site to a team",
3891
+ description: "Binds or unbinds (teamId: null) a partner-owned site to a partner-owned team.",
3892
+ tags: ["Teams"],
3893
+ examples: {
3894
+ request: {
3895
+ params: { siteId: "s_01" },
3896
+ body: { teamId: "t_01" }
3897
+ },
3898
+ response: {
3899
+ data: {
3900
+ ok: true,
3901
+ teamId: "t_01"
3902
+ },
3903
+ meta: {
3904
+ requestId: "req_01",
3905
+ surface: "partner",
3906
+ version: "1.0"
3907
+ }
3908
+ }
3909
+ }
3910
+ }
3911
+ }),
3912
+ getTeamCatalog: defineHttpOperation({
3913
+ id: "partner.teams.catalog.get",
3914
+ method: "GET",
3915
+ path: "/teams/{teamId}/catalog",
3916
+ visibility: "public",
3917
+ semantics: {
3918
+ kind: "query",
3919
+ sideEffects: "none",
3920
+ idempotent: true,
3921
+ retry: "idempotent",
3922
+ readConsistency: "primary"
3923
+ },
3924
+ auth: {
3925
+ credentials: ["partner_key"],
3926
+ scopes: ["teams:read"],
3927
+ ownership: [{
3928
+ credential: "partner_key",
3929
+ rule: "partner_tenant"
3930
+ }]
3931
+ },
3932
+ request: {
3933
+ params: z.strictObject({ teamId: realtimeSchemas.publicTeamId }),
3934
+ query: null,
3935
+ headers: requestHeaders,
3936
+ body: null
3937
+ },
3938
+ responses: { 200: teamCatalogResponse },
3939
+ errors: partnerUserErrors,
3940
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
3941
+ resources: {
3942
+ reads: [{
3943
+ type: "partner.team",
3944
+ idFrom: "params.teamId"
3945
+ }],
3946
+ changes: []
3947
+ },
3948
+ lifecycle: { introduced: "1.3.0" },
3949
+ docs: {
3950
+ summary: "Get a team catalog",
3951
+ description: "Returns the Iceberg catalog reference bound to a partner-owned team, if any.",
3952
+ tags: ["Teams"],
3953
+ examples: {
3954
+ request: { params: { teamId: "t_01" } },
3955
+ response: {
3956
+ data: {
3957
+ teamId: "t_01",
3958
+ catalogUri: null,
3959
+ warehouse: null,
3960
+ bucket: null,
3961
+ namespace: null,
3962
+ provisioningState: null,
3963
+ keyEncoding: null,
3964
+ catalogTablesReady: false,
3965
+ readsEnabled: false
3966
+ },
3967
+ meta: {
3968
+ requestId: "req_01",
3969
+ surface: "partner",
3970
+ version: "1.0"
3971
+ }
3972
+ }
3973
+ }
3974
+ }
3975
+ }),
3976
+ bindTeamCatalog: defineHttpOperation({
3977
+ id: "partner.teams.catalog.bind",
3978
+ method: "POST",
3979
+ path: "/teams/{teamId}/catalog",
3980
+ visibility: "public",
3981
+ semantics: {
3982
+ kind: "mutation",
3983
+ sideEffects: "state",
3984
+ idempotent: true,
3985
+ retry: "idempotent",
3986
+ readConsistency: null
3987
+ },
3988
+ auth: {
3989
+ credentials: ["partner_key"],
3990
+ scopes: ["teams:write"],
3991
+ ownership: [{
3992
+ credential: "partner_key",
3993
+ rule: "partner_tenant"
3994
+ }]
3995
+ },
3996
+ request: {
3997
+ params: z.strictObject({ teamId: realtimeSchemas.publicTeamId }),
3998
+ query: null,
3999
+ headers: requestHeaders,
4000
+ body: bindTeamCatalogRequest
4001
+ },
4002
+ responses: { 200: teamCatalogBindResponse },
4003
+ errors: partnerUserErrors,
4004
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
4005
+ resources: {
4006
+ reads: [{
4007
+ type: "partner.team",
4008
+ idFrom: "params.teamId"
4009
+ }],
4010
+ changes: [{
4011
+ type: "partner.team",
4012
+ idFrom: "params.teamId"
4013
+ }]
4014
+ },
4015
+ lifecycle: { introduced: "1.3.0" },
4016
+ docs: {
4017
+ summary: "Bind a team catalog",
4018
+ description: "Binds an Iceberg catalog (URI, warehouse, and optional bucket/namespace) to a partner-owned team.",
4019
+ tags: ["Teams"],
4020
+ examples: {
4021
+ request: {
4022
+ params: { teamId: "t_01" },
4023
+ body: {
4024
+ catalogUri: "gs://bucket/catalog",
4025
+ warehouse: "primary",
4026
+ namespace: "ns1",
4027
+ bucket: "bucket1"
4028
+ }
4029
+ },
4030
+ response: {
4031
+ data: {
4032
+ teamId: "t_01",
4033
+ status: "ready",
4034
+ catalogUri: "gs://bucket/catalog",
4035
+ warehouse: "primary",
4036
+ bucket: "bucket1",
4037
+ namespace: "ns1"
4038
+ },
4039
+ meta: {
4040
+ requestId: "req_01",
4041
+ surface: "partner",
4042
+ version: "1.0"
4043
+ }
4044
+ }
4045
+ }
4046
+ }
4047
+ }),
4048
+ getSiteIntIdCrosswalk: defineHttpOperation({
4049
+ id: "partner.users.sites.crosswalk.get",
4050
+ method: "GET",
4051
+ path: "/users/{userId}/sites/crosswalk",
4052
+ visibility: "public",
4053
+ semantics: {
4054
+ kind: "query",
4055
+ sideEffects: "none",
4056
+ idempotent: true,
4057
+ retry: "idempotent",
4058
+ readConsistency: "primary"
4059
+ },
4060
+ auth: {
4061
+ credentials: ["user_key", "partner_key"],
4062
+ scopes: ["sites:read"],
4063
+ ownership: [{
4064
+ credential: "user_key",
4065
+ rule: "self"
4066
+ }, {
4067
+ credential: "partner_key",
4068
+ rule: "linked_user"
4069
+ }]
4070
+ },
4071
+ request: {
4072
+ params: z.strictObject({ userId: realtimeSchemas.publicUserId }),
4073
+ query: null,
4074
+ headers: requestHeaders,
4075
+ body: null
4076
+ },
4077
+ responses: { 200: siteIntIdCrosswalkResponse },
4078
+ errors: partnerUserErrors,
4079
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
4080
+ resources: {
4081
+ reads: [{
4082
+ type: "partner.user",
4083
+ idFrom: "params.userId"
4084
+ }, {
4085
+ type: "user.sites",
4086
+ idFrom: "params.userId"
4087
+ }],
4088
+ changes: []
4089
+ },
4090
+ lifecycle: { introduced: "1.3.0" },
4091
+ docs: {
4092
+ summary: "Get the site int-id crosswalk",
4093
+ description: "Maps a user's public site IDs to their internal integer IDs, for partners that need the legacy numeric identifier.",
4094
+ tags: ["Sites"],
4095
+ examples: {
4096
+ request: { params: { userId: "u_01" } },
4097
+ response: {
4098
+ data: {
4099
+ crosswalk: {},
4100
+ sites: []
4101
+ },
4102
+ meta: {
4103
+ requestId: "req_01",
4104
+ surface: "partner",
4105
+ version: "1.0"
4106
+ }
4107
+ }
4108
+ }
4109
+ }
4110
+ }),
4111
+ deleteUser: defineHttpOperation({
4112
+ id: "partner.users.delete",
4113
+ method: "DELETE",
4114
+ path: "/users/{userId}",
4115
+ visibility: "public",
4116
+ semantics: {
4117
+ kind: "mutation",
4118
+ sideEffects: "state",
4119
+ idempotent: true,
4120
+ retry: "idempotent",
4121
+ readConsistency: null
4122
+ },
4123
+ auth: {
4124
+ credentials: ["partner_key"],
4125
+ scopes: ["users:write"],
4126
+ ownership: [{
4127
+ credential: "partner_key",
4128
+ rule: "linked_user"
4129
+ }]
4130
+ },
4131
+ request: {
4132
+ params: z.strictObject({ userId: realtimeSchemas.publicUserId }),
4133
+ query: null,
4134
+ headers: requestHeaders,
4135
+ body: null
4136
+ },
4137
+ responses: { 200: deletePartnerUserResponse },
4138
+ errors: partnerUserErrors,
4139
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
4140
+ resources: {
4141
+ reads: [{
4142
+ type: "partner.user",
4143
+ idFrom: "params.userId"
4144
+ }],
4145
+ changes: [{
4146
+ type: "partner.user",
4147
+ idFrom: "params.userId"
4148
+ }, {
4149
+ type: "user.sites",
4150
+ idFrom: "params.userId"
4151
+ }]
4152
+ },
4153
+ lifecycle: { introduced: "1.3.0" },
4154
+ docs: {
4155
+ summary: "Delete a partner user",
4156
+ description: "Queues cascade deletion of a partner-linked user and their sites.",
4157
+ tags: ["Users"],
4158
+ examples: {
4159
+ request: { params: { userId: "u_01" } },
4160
+ response: {
4161
+ data: {
4162
+ ok: true,
4163
+ queued: true,
4164
+ userId: 1,
4165
+ publicId: "u_01"
4166
+ },
4167
+ meta: {
4168
+ requestId: "req_01",
4169
+ surface: "partner",
4170
+ version: "1.0"
4171
+ }
4172
+ }
4173
+ }
4174
+ }
4175
+ }),
4176
+ createVerificationToken: defineHttpOperation({
4177
+ id: "partner.users.verification.token.create",
4178
+ method: "POST",
4179
+ path: "/users/{userId}/verification-token",
4180
+ visibility: "public",
4181
+ semantics: {
4182
+ kind: "query",
4183
+ sideEffects: "none",
4184
+ idempotent: true,
4185
+ retry: "idempotent",
4186
+ readConsistency: "primary"
4187
+ },
4188
+ auth: {
4189
+ credentials: ["user_key", "partner_key"],
4190
+ scopes: ["sites:write"],
4191
+ ownership: [{
4192
+ credential: "user_key",
4193
+ rule: "self"
4194
+ }, {
4195
+ credential: "partner_key",
4196
+ rule: "linked_user"
4197
+ }]
4198
+ },
4199
+ request: {
4200
+ params: z.strictObject({ userId: realtimeSchemas.publicUserId }),
4201
+ query: null,
4202
+ headers: requestHeaders,
4203
+ body: verificationTokenRequest
4204
+ },
4205
+ responses: { 200: verificationTokenResponse },
4206
+ errors: partnerUserErrors,
4207
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
4208
+ resources: {
4209
+ reads: [{
4210
+ type: "partner.user",
4211
+ idFrom: "params.userId"
4212
+ }, {
4213
+ type: "user.sites",
4214
+ idFrom: "params.userId"
4215
+ }],
4216
+ changes: []
4217
+ },
4218
+ lifecycle: { introduced: "1.3.0" },
4219
+ docs: {
4220
+ summary: "Create a site verification token",
4221
+ description: "Mints a Search Console site-ownership verification token (meta tag or DNS record) for a not-yet-registered site.",
4222
+ tags: ["Sites"],
4223
+ examples: {
4224
+ request: {
4225
+ params: { userId: "u_01" },
4226
+ body: {
4227
+ siteUrl: "https://example.com",
4228
+ method: "DNS_TXT"
4229
+ }
4230
+ },
4231
+ response: {
4232
+ data: {
4233
+ siteUrl: "https://example.com",
4234
+ site: {
4235
+ type: "INET_DOMAIN",
4236
+ identifier: "example.com"
4237
+ },
4238
+ method: "DNS_TXT",
4239
+ token: "abc123",
4240
+ metaContent: null,
4241
+ dnsRecord: {
4242
+ type: "TXT",
4243
+ host: "_gsc.example.com",
4244
+ value: "abc123"
4245
+ }
4246
+ },
4247
+ meta: {
4248
+ requestId: "req_01",
4249
+ surface: "partner",
4250
+ version: "1.0"
4251
+ }
4252
+ }
4253
+ }
4254
+ }
4255
+ }),
4256
+ addAndVerifySite: defineHttpOperation({
4257
+ id: "partner.users.sites.verify.create",
4258
+ method: "POST",
4259
+ path: "/users/{userId}/sites/verify",
4260
+ visibility: "public",
4261
+ semantics: {
4262
+ kind: "mutation",
4263
+ sideEffects: "state",
4264
+ idempotent: true,
4265
+ retry: "idempotent",
4266
+ readConsistency: null
4267
+ },
4268
+ auth: {
4269
+ credentials: ["user_key", "partner_key"],
4270
+ scopes: ["sites:write"],
4271
+ ownership: [{
4272
+ credential: "user_key",
4273
+ rule: "self"
4274
+ }, {
4275
+ credential: "partner_key",
4276
+ rule: "linked_user"
4277
+ }]
4278
+ },
4279
+ request: {
4280
+ params: z.strictObject({ userId: realtimeSchemas.publicUserId }),
4281
+ query: null,
4282
+ headers: requestHeaders,
4283
+ body: addAndVerifySiteRequest
4284
+ },
4285
+ responses: { 200: addAndVerifySiteResponse },
4286
+ errors: partnerUserErrors,
4287
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
4288
+ resources: {
4289
+ reads: [{
4290
+ type: "partner.user",
4291
+ idFrom: "params.userId"
4292
+ }],
4293
+ changes: [{
4294
+ type: "user.sites",
4295
+ idFrom: "params.userId"
4296
+ }]
4297
+ },
4298
+ lifecycle: { introduced: "1.3.0" },
4299
+ docs: {
4300
+ summary: "Add and verify a site",
4301
+ description: "Verifies Search Console ownership of a site for a user via the given method and records the verified ownership.",
4302
+ tags: ["Sites"],
4303
+ examples: {
4304
+ request: {
4305
+ params: { userId: "u_01" },
4306
+ body: {
4307
+ siteUrl: "https://example.com",
4308
+ method: "DNS_TXT"
4309
+ }
4310
+ },
4311
+ response: {
4312
+ data: {
4313
+ siteUrl: "https://example.com",
4314
+ site: {
4315
+ type: "INET_DOMAIN",
4316
+ identifier: "example.com"
4317
+ },
4318
+ method: "DNS_TXT",
4319
+ verified: true,
4320
+ owners: ["owner@example.com"]
4321
+ },
4322
+ meta: {
4323
+ requestId: "req_01",
4324
+ surface: "partner",
4325
+ version: "1.0"
4326
+ }
4327
+ }
4328
+ }
4329
+ }
4330
+ }),
4331
+ queryCrossSource: defineHttpOperation({
4332
+ id: "partner.sites.cross.source.query",
4333
+ method: "POST",
4334
+ path: "/sites/{siteId}/cross-source",
4335
+ visibility: "public",
4336
+ semantics: {
4337
+ kind: "query",
4338
+ sideEffects: "none",
4339
+ idempotent: true,
4340
+ retry: "idempotent",
4341
+ readConsistency: "primary"
4342
+ },
4343
+ auth: {
4344
+ credentials: ["partner_key"],
4345
+ scopes: ["analytics:read"],
4346
+ ownership: [{
4347
+ credential: "partner_key",
4348
+ rule: "authorized_site"
4349
+ }]
4350
+ },
4351
+ request: {
4352
+ params: z.strictObject({ siteId: realtimeSchemas.publicSiteId }),
4353
+ query: null,
4354
+ headers: requestHeaders,
4355
+ body: crossSourceRequest
4356
+ },
4357
+ responses: { 200: crossSourceResponse },
4358
+ errors: partnerSiteErrors,
4359
+ errorResponse: errorEnvelopeSchemas(partnerSiteErrors, realtimeSchemas.publicRequestId),
4360
+ resources: {
4361
+ reads: [{
4362
+ type: "site.analytics",
4363
+ idFrom: "params.siteId"
4364
+ }],
4365
+ changes: []
4366
+ },
4367
+ lifecycle: { introduced: "1.3.0" },
4368
+ docs: {
4369
+ summary: "Query cross-source analysis",
4370
+ description: "Runs one predefined cross-source query joining crawl, CWV, and GSC signals for a site.",
4371
+ tags: ["Analytics"],
4372
+ examples: {
4373
+ request: {
4374
+ params: { siteId: "s_01" },
4375
+ body: {
4376
+ queryKey: "crawl-error-losing-impressions",
4377
+ rangeDays: 28,
4378
+ limit: 50
4379
+ }
4380
+ },
4381
+ response: {
4382
+ data: {
4383
+ sources: ["crawl", "gsc"],
4384
+ rows: []
4385
+ },
4386
+ meta: {
4387
+ requestId: "req_01",
4388
+ surface: "partner",
4389
+ version: "1.0"
4390
+ }
4391
+ }
4392
+ }
4393
+ }
4394
+ }),
4395
+ enrichKeywords: defineHttpOperation({
4396
+ id: "partner.keywords.enrich.query",
4397
+ method: "POST",
4398
+ path: "/keywords/enrich",
4399
+ visibility: "public",
4400
+ semantics: {
4401
+ kind: "query",
4402
+ sideEffects: "none",
4403
+ idempotent: true,
4404
+ retry: "idempotent",
4405
+ readConsistency: "primary"
4406
+ },
4407
+ auth: {
4408
+ credentials: ["user_key", "partner_key"],
4409
+ scopes: ["analytics:read"],
4410
+ ownership: [{
4411
+ credential: "user_key",
4412
+ rule: "self"
4413
+ }, {
4414
+ credential: "partner_key",
4415
+ rule: "partner_tenant"
4416
+ }]
4417
+ },
4418
+ request: {
4419
+ params: null,
4420
+ query: null,
4421
+ headers: requestHeaders,
4422
+ body: enrichKeywordsRequest
4423
+ },
4424
+ responses: { 200: enrichKeywordsResponse },
4425
+ errors: partnerUserErrors,
4426
+ errorResponse: errorEnvelopeSchemas(partnerUserErrors, realtimeSchemas.publicRequestId),
4427
+ resources: {
4428
+ reads: [],
4429
+ changes: []
4430
+ },
4431
+ lifecycle: { introduced: "1.3.0" },
4432
+ docs: {
4433
+ summary: "Enrich keywords with metrics",
4434
+ description: "Returns difficulty, search volume, and CPC estimates for up to 500 keywords.",
4435
+ tags: ["Analytics"],
4436
+ examples: {
4437
+ request: { body: { keywords: ["nuxt seo"] } },
4438
+ response: {
4439
+ data: { metrics: { "nuxt seo": {
4440
+ difficulty: 40,
4441
+ searchVolume: 100,
4442
+ cpc: 1.2
4443
+ } } },
4444
+ meta: {
4445
+ requestId: "req_01",
4446
+ surface: "partner",
4447
+ version: "1.0"
4448
+ }
4449
+ }
4450
+ }
4451
+ }
3177
4452
  })
3178
4453
  }
3179
4454
  });