@cavuno/board 4.69.0 → 4.71.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/{_spec-CFOj7Qdf.d.mts → _spec-OPrym0QJ.d.mts} +83 -2
  3. package/dist/{_spec-CFOj7Qdf.d.ts → _spec-OPrym0QJ.d.ts} +83 -2
  4. package/dist/{blog-BaVJi3q1.d.ts → blog-BlRb84MY.d.ts} +1 -1
  5. package/dist/{blog-DCRBPnpZ.d.mts → blog-CHQYIhHH.d.mts} +1 -1
  6. package/dist/{board-DMS3I3sJ.d.mts → board-Btc1dzQB.d.mts} +2 -2
  7. package/dist/{board-zLt7j6hj.d.ts → board-D74R4Iml.d.ts} +2 -2
  8. package/dist/{breadcrumbs-yGijUUtR.d.ts → breadcrumbs-Bv76gXvF.d.ts} +2 -2
  9. package/dist/{breadcrumbs-Dwf0yq7B.d.mts → breadcrumbs-CSm6P79s.d.mts} +2 -2
  10. package/dist/browser/cavuno-board.global.min.js +1 -1
  11. package/dist/{chunk-7SAHE7UW.mjs → chunk-AQD4OMX4.mjs} +4 -0
  12. package/dist/filters.d.mts +2 -2
  13. package/dist/filters.d.ts +2 -2
  14. package/dist/format.d.mts +4 -4
  15. package/dist/format.d.ts +4 -4
  16. package/dist/index.d.mts +92 -22
  17. package/dist/index.d.ts +92 -22
  18. package/dist/index.js +66 -8
  19. package/dist/index.mjs +63 -9
  20. package/dist/{jobs-Dz_w1jZq.d.ts → jobs-BMG0vrVI.d.ts} +1 -1
  21. package/dist/{jobs-Cew_q69W.d.mts → jobs-xjE0IrNu.d.mts} +1 -1
  22. package/dist/{search-DwvgvtEg.d.mts → search-BJkiU3Ic.d.mts} +1 -1
  23. package/dist/{search-BqAYR47P.d.ts → search-suUh-E7O.d.ts} +1 -1
  24. package/dist/{seo-CGy4fY5a.d.ts → seo-CW1JjEXH.d.ts} +1 -1
  25. package/dist/{seo-FKj1pSHZ.d.mts → seo-DGdqWPLo.d.mts} +1 -1
  26. package/dist/seo-files.d.mts +2 -2
  27. package/dist/seo-files.d.ts +2 -2
  28. package/dist/seo-files.js +6 -0
  29. package/dist/seo-files.mjs +6 -0
  30. package/dist/seo.d.mts +6 -6
  31. package/dist/seo.d.ts +6 -6
  32. package/dist/server.d.mts +6 -6
  33. package/dist/server.d.ts +6 -6
  34. package/dist/server.mjs +1 -1
  35. package/dist/sitemap.d.mts +6 -6
  36. package/dist/sitemap.d.ts +6 -6
  37. package/dist/sitemap.mjs +1 -1
  38. package/dist/suggest.d.mts +2 -2
  39. package/dist/suggest.d.ts +2 -2
  40. package/package.json +1 -1
  41. package/skills/cavuno-board-account/SKILL.md +16 -0
  42. package/skills/cavuno-board-auth/SKILL.md +3 -0
  43. package/skills/cavuno-board-job-alerts/SKILL.md +12 -0
  44. package/skills/cavuno-board-newsletter/SKILL.md +81 -0
  45. package/skills/manifest.json +8 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,60 @@
3
3
  This changelog records changes that affect Board API compatibility, exported
4
4
  types, runtime behavior, or supported integration patterns.
5
5
 
6
+ ## 4.71.0 — 2026-11-12
7
+
8
+ - `board.jobAlerts.confirm({ token })` can resolve two more statuses,
9
+ which the API already returned: `waitlisted` (the alert is confirmed and
10
+ starts once the board can send to more people) and `unsubscribed` (the
11
+ link was sent before the person's alerts were turned off, so it does not
12
+ turn them back on; they resume them from a manage link with
13
+ `board.jobAlerts.resubscribe`). `JobAlertConfirmation['status']` lists
14
+ both, so an exhaustive `switch` over it needs the two new cases.
15
+ - `JobAlertConfirmation['subscription']` is also present when a link is
16
+ refused (`expired`, `not_found` or `unsubscribed`): `marketing` for a
17
+ link from `board.subscribe`, `job_alerts` for a job alert link. Word the
18
+ refusal by it. It is still absent for an unknown token.
19
+ - `board.subscribe(...)` records the visitor's IP address and user agent
20
+ as consent evidence only when the request comes through a board built
21
+ with Cavuno's AI Builder. A frontend that calls the API from the browser
22
+ or its own server records neither, since the address and user agent the
23
+ API sees are not the visitor's.
24
+ - The place rows of the title-by-location and skill-by-location salary
25
+ pages (`childLocations`, `childLocationsByRegion[].cities` and
26
+ `otherLocations`) carry `indexable` for the page each row links to, as
27
+ the other salary list items already do. Link only rows where it is
28
+ `true` from an indexable page. Skill-by-location rows are never
29
+ indexable.
30
+ - `robotsBody()` and `robotsResponse()` from `@cavuno/board/seo-files`
31
+ add `Content-Signal: search=yes, ai-input=yes, ai-train=yes` under
32
+ `User-Agent: *`, so the board says how its content may be used by search
33
+ and AI. Sandbox boards, which are not indexed, leave it out.
34
+
35
+ ## 4.70.0 — 2026-11-12
36
+
37
+ - Company members can add gallery images and files to their company's
38
+ custom fields. `board.me.companies.uploadCustomFieldFile(slug, fieldKey,
39
+ file)` uploads one file (up to 10 MB; galleries take JPEG, PNG, WebP or
40
+ GIF) and returns a `ProfileFieldMedia` draft. Save its `id` with
41
+ `board.me.companies.updateCustomFields` to attach it. The caller must be
42
+ an approved member of the company. A key that is not an upload field is
43
+ refused with `company_custom_field_not_found`, and a field company
44
+ members cannot edit with `company_custom_field_not_editable`.
45
+ - `board.me.companies.retrieveCustomFields(slug)` and `updateCustomFields`
46
+ are typed `MyCompanyProfileFieldValues`, which adds `customFieldMedia`:
47
+ the saved files of upload fields, keyed by field, with links that also
48
+ load drafts for the company's members. `MyCompanyProfileFieldValues` is
49
+ exported.
50
+ - `board.subscribe({ email, consent, consentText, source })` signs an
51
+ address up for the board's email from a newsletter form. The person gets
52
+ a confirmation email and nothing is granted until they click it. It
53
+ always resolves `{ status: 'submitted', sendingPaused }`.
54
+ `BoardSubscribeInput` and `SubscriptionRequest` are exported.
55
+ - `board.auth.register(...)` and `board.auth.resendVerification()` answer
56
+ 422 `board_auth_email_undeliverable` when the address cannot receive
57
+ email, such as a temporary or disposable inbox. On register nothing is
58
+ created, so ask for a different address.
59
+
6
60
  ## 4.69.0 — 2026-11-12
7
61
 
8
62
  - Members-only boards: on a board whose context has
@@ -247,6 +247,8 @@ interface components {
247
247
  };
248
248
  BoardAuthConsumeMagicLinkBody: {
249
249
  token: string;
250
+ /** @description The person's IANA time zone from their browser (`Intl.DateTimeFormat().resolvedOptions().timeZone`), such as `Europe/Berlin`. Stored the first time only; an invalid value is ignored. */
251
+ timeZone?: string;
250
252
  };
251
253
  BoardAuthForgotPasswordBody: {
252
254
  /** Format: email */
@@ -303,6 +305,8 @@ interface components {
303
305
  returnTo?: string;
304
306
  /** @description The company member invite token, when the person is signing up from an invite link. When `role` is `employer` and it is a pending invite on this board sent to this same email, no verification email is sent: accepting the invite (`POST /boards/{identifier}/me/invites/accept`) verifies the address. Registration never accepts the invite itself. Any other token is ignored and the verification email is sent as usual. */
305
307
  inviteToken?: string;
308
+ /** @description The person's IANA time zone from their browser (`Intl.DateTimeFormat().resolvedOptions().timeZone`), such as `Europe/Berlin`. Stored the first time only; an invalid value is ignored. */
309
+ timeZone?: string;
306
310
  };
307
311
  BoardAuthRequestMagicLinkBody: {
308
312
  audienceAttribution?: components["schemas"]["AudienceAttribution"];
@@ -428,6 +432,17 @@ interface components {
428
432
  definition: components["schemas"]["CustomFieldDefinition"];
429
433
  };
430
434
  BoardJobFormField: components["schemas"]["BoardFormBuiltinField"] | components["schemas"]["BoardJobFormCustomField"] | components["schemas"]["BoardJobFormCollectionField"];
435
+ BoardMarketingTopic: {
436
+ /**
437
+ * @description String representing the object's type. Objects of the same type share the same value.
438
+ * @enum {string}
439
+ */
440
+ object: "marketing_topic";
441
+ /** @description The topic’s key, which a sign-up sends in `topics` when the person ticks it. */
442
+ key: string;
443
+ /** @description The topic’s name, to label its checkbox. */
444
+ name: string;
445
+ };
431
446
  /** @description An MCP Server Card (SEP-2127): what an assistant needs to find and connect to the server before it connects. It lists no tools; `tools/list` on the server does. */
432
447
  BoardMcpServerCard: {
433
448
  /** @description The Server Card JSON Schema this document follows: `https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json`. */
@@ -550,6 +565,31 @@ interface components {
550
565
  /** @description ISO 8601 timestamp of the newest content in the bucket, when the board tracks one. */
551
566
  lastModified?: string;
552
567
  };
568
+ BoardSubscribeBody: {
569
+ /**
570
+ * Format: email
571
+ * @description The address to sign up. It gets a confirmation email.
572
+ */
573
+ email: string;
574
+ /**
575
+ * @description Must be `true`: the person ticked an unticked checkbox agreeing to `consentText`.
576
+ * @enum {boolean}
577
+ */
578
+ consent: true;
579
+ /** @description The checkbox wording the person agreed to, exactly as shown, such as "Send me news and offers from Acme Jobs." It must contain the board's name (any letter case), or the request is refused with 400. Kept with the consent once the person confirms. */
580
+ consentText: string;
581
+ /** @description A label for the form, such as `blog-footer`: lowercase letters, digits and hyphens, up to 64 characters. It shows as the contact's Source. */
582
+ source: string;
583
+ /**
584
+ * Format: uri
585
+ * @description The page the form was on. Defaults to the request's `Referer`.
586
+ */
587
+ pageUrl?: string;
588
+ /** @description Honeypot. Render it as a hidden field that people leave empty; when it is filled in, the request answers `submitted` and does nothing. */
589
+ website?: string;
590
+ /** @description The person's IANA time zone from their browser (`Intl.DateTimeFormat().resolvedOptions().timeZone`), such as `Europe/Berlin`. Stored the first time only; an invalid value is ignored. */
591
+ timeZone?: string;
592
+ };
553
593
  BoardUser: {
554
594
  /** @description Board user ID. */
555
595
  id: string;
@@ -2373,6 +2413,12 @@ interface components {
2373
2413
  [key: string]: components["schemas"]["ProfileFieldMedia"][];
2374
2414
  };
2375
2415
  };
2416
+ MyCompanyProfileFieldValuesResponse: components["schemas"]["ProfileFieldValuesResponse"] & {
2417
+ /** @description Resolved files for the company’s saved `image_gallery` and `file` values, keyed by field key like `values`, in the stored order, including private fields. Each file `id` matches a value in `values`. `url` is a signed link for the company’s members that expires after at least 24 hours, so read it from the response rather than storing it. Unsaved uploads are not listed. Fields with no files are omitted. */
2418
+ customFieldMedia: {
2419
+ [key: string]: components["schemas"]["ProfileFieldMedia"][];
2420
+ };
2421
+ };
2376
2422
  MyItemVerification: components["schemas"]["ItemVerification"] & {
2377
2423
  /** @description The verification's id. For an item with no verification yet (`unverified`), its `itemKey`. */
2378
2424
  id?: string;
@@ -3348,10 +3394,15 @@ interface components {
3348
3394
  /** @enum {string} */
3349
3395
  object: "job_alert_confirmation";
3350
3396
  /**
3351
- * @description Outcome of the confirmation. Always returned with HTTP 200 so the consumer renders by status (the token may be valid, stale, or unknown).
3397
+ * @description Outcome of the confirmation. Always returned with HTTP 200 so the consumer renders by status (the token may be valid, stale, or unknown). `waitlisted`: the job alert is confirmed, but the board can't send to more people yet, so it starts once a spot opens. `unsubscribed`: a job-alert link sent before the alerts were turned off, which doesn't turn them back on. To get them again, subscribe again (`POST /boards/{identifier}/job-alerts`): an address that unsubscribed is sent a fresh confirmation email at most once every 12 hours (none while the address is suppressed, or when the board's team unsubscribed the address), and clicking it re-subscribes. The manage token (`POST /boards/{identifier}/job-alerts/resubscribe`) or a signed-in alert create also resumes them.
3352
3398
  * @enum {string}
3353
3399
  */
3354
- status: "confirmed" | "already_confirmed" | "expired" | "not_found";
3400
+ status: "confirmed" | "already_confirmed" | "expired" | "not_found" | "waitlisted" | "unsubscribed";
3401
+ /**
3402
+ * @description What the link confirms: `marketing` for a link from a newsletter sign-up (`POST /boards/{identifier}/subscribe`), which signs the person up for the board's email and never turns job alerts on, or `job_alerts`. Word the outcome by it. Present on a refused link too (`expired`, `not_found` or `unsubscribed`). Absent when the token is unknown or isn't a confirmation link.
3403
+ * @enum {string}
3404
+ */
3405
+ subscription?: "job_alerts" | "marketing";
3355
3406
  };
3356
3407
  PublicJobAlertManageResult: {
3357
3408
  /** @enum {string} */
@@ -3404,6 +3455,13 @@ interface components {
3404
3455
  */
3405
3456
  status: "submitted";
3406
3457
  };
3458
+ PublicJobAlertResubscribeResult: components["schemas"]["PublicJobAlertManageResult"] & {
3459
+ /**
3460
+ * @description `resubscribed`: the subscription is resumed; its alerts start again, or wait for a spot when the board can't send to more people yet. `confirmation_sent`: the address never confirmed, so nothing is on yet; a confirmation email went out, and the alerts start when the person clicks its link. Tell them to check their inbox, and don't show the alerts as on.
3461
+ * @enum {string}
3462
+ */
3463
+ status: "resubscribed" | "confirmation_sent";
3464
+ };
3407
3465
  PublicJobAlertSubscription: {
3408
3466
  /** @enum {string} */
3409
3467
  object: "job_alert_subscription";
@@ -3635,6 +3693,17 @@ interface components {
3635
3693
  */
3636
3694
  offset?: number;
3637
3695
  };
3696
+ PublicSubscriptionRequest: {
3697
+ /** @enum {string} */
3698
+ object: "subscription_request";
3699
+ /**
3700
+ * @description Always `submitted`, whether the address is new, waiting to confirm or already subscribed, so the response can't be used to find out who is subscribed. Unless the person already gets the board's email, a confirmation email has been sent; nothing is sent to them until they click it.
3701
+ * @enum {string}
3702
+ */
3703
+ status: "submitted";
3704
+ /** @description The board's marketing email is paused (too many bounces or spam reports). Sign-ups are still recorded; tell the person emails may be delayed. */
3705
+ sendingPaused: boolean;
3706
+ };
3638
3707
  PublicTalentPlace: {
3639
3708
  /** @enum {string} */
3640
3709
  object: "talent_place";
@@ -4229,6 +4298,8 @@ interface components {
4229
4298
  avgSalaryMin: number;
4230
4299
  avgSalaryMax: number;
4231
4300
  jobCount: number;
4301
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4302
+ indexable: boolean;
4232
4303
  }[];
4233
4304
  childLocationsByRegion: {
4234
4305
  regionName: string;
@@ -4241,6 +4312,8 @@ interface components {
4241
4312
  avgSalaryMin: number;
4242
4313
  avgSalaryMax: number;
4243
4314
  jobCount: number;
4315
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4316
+ indexable: boolean;
4244
4317
  }[];
4245
4318
  }[];
4246
4319
  otherLocations: {
@@ -4251,6 +4324,8 @@ interface components {
4251
4324
  avgSalaryMin: number;
4252
4325
  avgSalaryMax: number;
4253
4326
  jobCount: number;
4327
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4328
+ indexable: boolean;
4254
4329
  }[];
4255
4330
  topSkills: {
4256
4331
  avgSalaryMin: number;
@@ -4789,6 +4864,8 @@ interface components {
4789
4864
  avgSalaryMin: number;
4790
4865
  avgSalaryMax: number;
4791
4866
  jobCount: number;
4867
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4868
+ indexable: boolean;
4792
4869
  }[];
4793
4870
  childLocationsByRegion: {
4794
4871
  regionName: string;
@@ -4801,6 +4878,8 @@ interface components {
4801
4878
  avgSalaryMin: number;
4802
4879
  avgSalaryMax: number;
4803
4880
  jobCount: number;
4881
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4882
+ indexable: boolean;
4804
4883
  }[];
4805
4884
  }[];
4806
4885
  otherLocations: {
@@ -4811,6 +4890,8 @@ interface components {
4811
4890
  avgSalaryMin: number;
4812
4891
  avgSalaryMax: number;
4813
4892
  jobCount: number;
4893
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4894
+ indexable: boolean;
4814
4895
  }[];
4815
4896
  topSkills: {
4816
4897
  avgSalaryMin: number;
@@ -247,6 +247,8 @@ interface components {
247
247
  };
248
248
  BoardAuthConsumeMagicLinkBody: {
249
249
  token: string;
250
+ /** @description The person's IANA time zone from their browser (`Intl.DateTimeFormat().resolvedOptions().timeZone`), such as `Europe/Berlin`. Stored the first time only; an invalid value is ignored. */
251
+ timeZone?: string;
250
252
  };
251
253
  BoardAuthForgotPasswordBody: {
252
254
  /** Format: email */
@@ -303,6 +305,8 @@ interface components {
303
305
  returnTo?: string;
304
306
  /** @description The company member invite token, when the person is signing up from an invite link. When `role` is `employer` and it is a pending invite on this board sent to this same email, no verification email is sent: accepting the invite (`POST /boards/{identifier}/me/invites/accept`) verifies the address. Registration never accepts the invite itself. Any other token is ignored and the verification email is sent as usual. */
305
307
  inviteToken?: string;
308
+ /** @description The person's IANA time zone from their browser (`Intl.DateTimeFormat().resolvedOptions().timeZone`), such as `Europe/Berlin`. Stored the first time only; an invalid value is ignored. */
309
+ timeZone?: string;
306
310
  };
307
311
  BoardAuthRequestMagicLinkBody: {
308
312
  audienceAttribution?: components["schemas"]["AudienceAttribution"];
@@ -428,6 +432,17 @@ interface components {
428
432
  definition: components["schemas"]["CustomFieldDefinition"];
429
433
  };
430
434
  BoardJobFormField: components["schemas"]["BoardFormBuiltinField"] | components["schemas"]["BoardJobFormCustomField"] | components["schemas"]["BoardJobFormCollectionField"];
435
+ BoardMarketingTopic: {
436
+ /**
437
+ * @description String representing the object's type. Objects of the same type share the same value.
438
+ * @enum {string}
439
+ */
440
+ object: "marketing_topic";
441
+ /** @description The topic’s key, which a sign-up sends in `topics` when the person ticks it. */
442
+ key: string;
443
+ /** @description The topic’s name, to label its checkbox. */
444
+ name: string;
445
+ };
431
446
  /** @description An MCP Server Card (SEP-2127): what an assistant needs to find and connect to the server before it connects. It lists no tools; `tools/list` on the server does. */
432
447
  BoardMcpServerCard: {
433
448
  /** @description The Server Card JSON Schema this document follows: `https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json`. */
@@ -550,6 +565,31 @@ interface components {
550
565
  /** @description ISO 8601 timestamp of the newest content in the bucket, when the board tracks one. */
551
566
  lastModified?: string;
552
567
  };
568
+ BoardSubscribeBody: {
569
+ /**
570
+ * Format: email
571
+ * @description The address to sign up. It gets a confirmation email.
572
+ */
573
+ email: string;
574
+ /**
575
+ * @description Must be `true`: the person ticked an unticked checkbox agreeing to `consentText`.
576
+ * @enum {boolean}
577
+ */
578
+ consent: true;
579
+ /** @description The checkbox wording the person agreed to, exactly as shown, such as "Send me news and offers from Acme Jobs." It must contain the board's name (any letter case), or the request is refused with 400. Kept with the consent once the person confirms. */
580
+ consentText: string;
581
+ /** @description A label for the form, such as `blog-footer`: lowercase letters, digits and hyphens, up to 64 characters. It shows as the contact's Source. */
582
+ source: string;
583
+ /**
584
+ * Format: uri
585
+ * @description The page the form was on. Defaults to the request's `Referer`.
586
+ */
587
+ pageUrl?: string;
588
+ /** @description Honeypot. Render it as a hidden field that people leave empty; when it is filled in, the request answers `submitted` and does nothing. */
589
+ website?: string;
590
+ /** @description The person's IANA time zone from their browser (`Intl.DateTimeFormat().resolvedOptions().timeZone`), such as `Europe/Berlin`. Stored the first time only; an invalid value is ignored. */
591
+ timeZone?: string;
592
+ };
553
593
  BoardUser: {
554
594
  /** @description Board user ID. */
555
595
  id: string;
@@ -2373,6 +2413,12 @@ interface components {
2373
2413
  [key: string]: components["schemas"]["ProfileFieldMedia"][];
2374
2414
  };
2375
2415
  };
2416
+ MyCompanyProfileFieldValuesResponse: components["schemas"]["ProfileFieldValuesResponse"] & {
2417
+ /** @description Resolved files for the company’s saved `image_gallery` and `file` values, keyed by field key like `values`, in the stored order, including private fields. Each file `id` matches a value in `values`. `url` is a signed link for the company’s members that expires after at least 24 hours, so read it from the response rather than storing it. Unsaved uploads are not listed. Fields with no files are omitted. */
2418
+ customFieldMedia: {
2419
+ [key: string]: components["schemas"]["ProfileFieldMedia"][];
2420
+ };
2421
+ };
2376
2422
  MyItemVerification: components["schemas"]["ItemVerification"] & {
2377
2423
  /** @description The verification's id. For an item with no verification yet (`unverified`), its `itemKey`. */
2378
2424
  id?: string;
@@ -3348,10 +3394,15 @@ interface components {
3348
3394
  /** @enum {string} */
3349
3395
  object: "job_alert_confirmation";
3350
3396
  /**
3351
- * @description Outcome of the confirmation. Always returned with HTTP 200 so the consumer renders by status (the token may be valid, stale, or unknown).
3397
+ * @description Outcome of the confirmation. Always returned with HTTP 200 so the consumer renders by status (the token may be valid, stale, or unknown). `waitlisted`: the job alert is confirmed, but the board can't send to more people yet, so it starts once a spot opens. `unsubscribed`: a job-alert link sent before the alerts were turned off, which doesn't turn them back on. To get them again, subscribe again (`POST /boards/{identifier}/job-alerts`): an address that unsubscribed is sent a fresh confirmation email at most once every 12 hours (none while the address is suppressed, or when the board's team unsubscribed the address), and clicking it re-subscribes. The manage token (`POST /boards/{identifier}/job-alerts/resubscribe`) or a signed-in alert create also resumes them.
3352
3398
  * @enum {string}
3353
3399
  */
3354
- status: "confirmed" | "already_confirmed" | "expired" | "not_found";
3400
+ status: "confirmed" | "already_confirmed" | "expired" | "not_found" | "waitlisted" | "unsubscribed";
3401
+ /**
3402
+ * @description What the link confirms: `marketing` for a link from a newsletter sign-up (`POST /boards/{identifier}/subscribe`), which signs the person up for the board's email and never turns job alerts on, or `job_alerts`. Word the outcome by it. Present on a refused link too (`expired`, `not_found` or `unsubscribed`). Absent when the token is unknown or isn't a confirmation link.
3403
+ * @enum {string}
3404
+ */
3405
+ subscription?: "job_alerts" | "marketing";
3355
3406
  };
3356
3407
  PublicJobAlertManageResult: {
3357
3408
  /** @enum {string} */
@@ -3404,6 +3455,13 @@ interface components {
3404
3455
  */
3405
3456
  status: "submitted";
3406
3457
  };
3458
+ PublicJobAlertResubscribeResult: components["schemas"]["PublicJobAlertManageResult"] & {
3459
+ /**
3460
+ * @description `resubscribed`: the subscription is resumed; its alerts start again, or wait for a spot when the board can't send to more people yet. `confirmation_sent`: the address never confirmed, so nothing is on yet; a confirmation email went out, and the alerts start when the person clicks its link. Tell them to check their inbox, and don't show the alerts as on.
3461
+ * @enum {string}
3462
+ */
3463
+ status: "resubscribed" | "confirmation_sent";
3464
+ };
3407
3465
  PublicJobAlertSubscription: {
3408
3466
  /** @enum {string} */
3409
3467
  object: "job_alert_subscription";
@@ -3635,6 +3693,17 @@ interface components {
3635
3693
  */
3636
3694
  offset?: number;
3637
3695
  };
3696
+ PublicSubscriptionRequest: {
3697
+ /** @enum {string} */
3698
+ object: "subscription_request";
3699
+ /**
3700
+ * @description Always `submitted`, whether the address is new, waiting to confirm or already subscribed, so the response can't be used to find out who is subscribed. Unless the person already gets the board's email, a confirmation email has been sent; nothing is sent to them until they click it.
3701
+ * @enum {string}
3702
+ */
3703
+ status: "submitted";
3704
+ /** @description The board's marketing email is paused (too many bounces or spam reports). Sign-ups are still recorded; tell the person emails may be delayed. */
3705
+ sendingPaused: boolean;
3706
+ };
3638
3707
  PublicTalentPlace: {
3639
3708
  /** @enum {string} */
3640
3709
  object: "talent_place";
@@ -4229,6 +4298,8 @@ interface components {
4229
4298
  avgSalaryMin: number;
4230
4299
  avgSalaryMax: number;
4231
4300
  jobCount: number;
4301
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4302
+ indexable: boolean;
4232
4303
  }[];
4233
4304
  childLocationsByRegion: {
4234
4305
  regionName: string;
@@ -4241,6 +4312,8 @@ interface components {
4241
4312
  avgSalaryMin: number;
4242
4313
  avgSalaryMax: number;
4243
4314
  jobCount: number;
4315
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4316
+ indexable: boolean;
4244
4317
  }[];
4245
4318
  }[];
4246
4319
  otherLocations: {
@@ -4251,6 +4324,8 @@ interface components {
4251
4324
  avgSalaryMin: number;
4252
4325
  avgSalaryMax: number;
4253
4326
  jobCount: number;
4327
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4328
+ indexable: boolean;
4254
4329
  }[];
4255
4330
  topSkills: {
4256
4331
  avgSalaryMin: number;
@@ -4789,6 +4864,8 @@ interface components {
4789
4864
  avgSalaryMin: number;
4790
4865
  avgSalaryMax: number;
4791
4866
  jobCount: number;
4867
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4868
+ indexable: boolean;
4792
4869
  }[];
4793
4870
  childLocationsByRegion: {
4794
4871
  regionName: string;
@@ -4801,6 +4878,8 @@ interface components {
4801
4878
  avgSalaryMin: number;
4802
4879
  avgSalaryMax: number;
4803
4880
  jobCount: number;
4881
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4882
+ indexable: boolean;
4804
4883
  }[];
4805
4884
  }[];
4806
4885
  otherLocations: {
@@ -4811,6 +4890,8 @@ interface components {
4811
4890
  avgSalaryMin: number;
4812
4891
  avgSalaryMax: number;
4813
4892
  jobCount: number;
4893
+ /** @description Whether the salary page this item links to is worth indexing. When `false`, that page renders `<meta name="robots" content="noindex, follow">` and is left out of the board sitemap. */
4894
+ indexable: boolean;
4814
4895
  }[];
4815
4896
  topSkills: {
4816
4897
  avgSalaryMin: number;
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-CFOj7Qdf.js';
1
+ import { S as Schemas } from './_spec-OPrym0QJ.js';
2
2
 
3
3
  /** Author shape embedded on posts (no `object` discriminator). */
4
4
  type BlogAuthorEmbed = Schemas['PublicBlogAuthorEmbed'];
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-CFOj7Qdf.mjs';
1
+ import { S as Schemas } from './_spec-OPrym0QJ.mjs';
2
2
 
3
3
  /** Author shape embedded on posts (no `object` discriminator). */
4
4
  type BlogAuthorEmbed = Schemas['PublicBlogAuthorEmbed'];
@@ -1,5 +1,5 @@
1
- import { S as Schemas } from './_spec-CFOj7Qdf.mjs';
2
- import { L as ListEnvelope, v as RelatedSearch, b as CustomFieldFilter, O as ObjectReferenceFilter, a as JobCapability } from './jobs-Cew_q69W.mjs';
1
+ import { S as Schemas } from './_spec-OPrym0QJ.mjs';
2
+ import { L as ListEnvelope, v as RelatedSearch, b as CustomFieldFilter, O as ObjectReferenceFilter, a as JobCapability } from './jobs-xjE0IrNu.mjs';
3
3
 
4
4
  type PublicCompany = Schemas['CompanyPublic'];
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { S as Schemas } from './_spec-CFOj7Qdf.js';
2
- import { L as ListEnvelope, v as RelatedSearch, b as CustomFieldFilter, O as ObjectReferenceFilter, a as JobCapability } from './jobs-Dz_w1jZq.js';
1
+ import { S as Schemas } from './_spec-OPrym0QJ.js';
2
+ import { L as ListEnvelope, v as RelatedSearch, b as CustomFieldFilter, O as ObjectReferenceFilter, a as JobCapability } from './jobs-BMG0vrVI.js';
3
3
 
4
4
  type PublicCompany = Schemas['CompanyPublic'];
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { P as PublicBoard, a as CompanyCategorySalary, b as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './board-zLt7j6hj.js';
2
- import { P as PublicJob } from './jobs-Dz_w1jZq.js';
1
+ import { P as PublicBoard, a as CompanyCategorySalary, b as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './board-D74R4Iml.js';
2
+ import { P as PublicJob } from './jobs-BMG0vrVI.js';
3
3
 
4
4
  /**
5
5
  * Wire enum for `salaryTimeframe`. Defined here (not re-exported from any
@@ -1,5 +1,5 @@
1
- import { P as PublicBoard, a as CompanyCategorySalary, b as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './board-DMS3I3sJ.mjs';
2
- import { P as PublicJob } from './jobs-Cew_q69W.mjs';
1
+ import { P as PublicBoard, a as CompanyCategorySalary, b as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './board-Btc1dzQB.mjs';
2
+ import { P as PublicJob } from './jobs-xjE0IrNu.mjs';
3
3
 
4
4
  /**
5
5
  * Wire enum for `salaryTimeframe`. Defined here (not re-exported from any