@cavuno/board 4.8.0 → 4.10.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 (49) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/{_spec-DePC7a05.d.mts → _spec-BwUP7Wni.d.mts} +100 -1
  3. package/dist/{_spec-DePC7a05.d.ts → _spec-BwUP7Wni.d.ts} +100 -1
  4. package/dist/bin.mjs +174 -19
  5. package/dist/{blog-DbFr4VPW.d.mts → blog-C_xXYOxc.d.mts} +1 -1
  6. package/dist/{blog-ummlt6Uq.d.ts → blog-DC4BfQqF.d.ts} +1 -1
  7. package/dist/{board-zWyHbyi4.d.ts → board-CG8rDGTY.d.mts} +5 -3
  8. package/dist/{board-DxTMBgIf.d.mts → board-zdQ875ck.d.ts} +5 -3
  9. package/dist/{breadcrumbs-P4qh0zML.d.mts → breadcrumbs-BK7AqNp2.d.mts} +2 -2
  10. package/dist/{breadcrumbs-kbmspmfk.d.ts → breadcrumbs-qs9DC0yh.d.ts} +2 -2
  11. package/dist/browser/cavuno-board.global.min.js +1 -1
  12. package/dist/{chunk-IWWPHFK2.mjs → chunk-XEJWXRLK.mjs} +10 -0
  13. package/dist/doctor.d.mts +3 -1
  14. package/dist/doctor.d.ts +3 -1
  15. package/dist/doctor.js +169 -17
  16. package/dist/doctor.mjs +169 -17
  17. package/dist/filters.d.mts +2 -2
  18. package/dist/filters.d.ts +2 -2
  19. package/dist/format.d.mts +4 -4
  20. package/dist/format.d.ts +4 -4
  21. package/dist/index.d.mts +118 -24
  22. package/dist/index.d.ts +118 -24
  23. package/dist/index.js +127 -9
  24. package/dist/index.mjs +118 -10
  25. package/dist/{jobs-twt5TO9l.d.ts → jobs-B-uO7ffG.d.ts} +1 -1
  26. package/dist/{jobs-DTLDt57G.d.mts → jobs-BToqhRuU.d.mts} +1 -1
  27. package/dist/{search-f2UNlTfv.d.mts → search-CvwKD0Va.d.mts} +1 -1
  28. package/dist/{search-CHD6peIl.d.ts → search-Sl9-xi1z.d.ts} +1 -1
  29. package/dist/seo-B9b2AkSE.d.mts +12 -0
  30. package/dist/seo-D1Vc_0HF.d.ts +12 -0
  31. package/dist/seo-files.d.mts +36 -0
  32. package/dist/seo-files.d.ts +36 -0
  33. package/dist/seo-files.js +102 -0
  34. package/dist/seo-files.mjs +81 -0
  35. package/dist/seo.d.mts +6 -6
  36. package/dist/seo.d.ts +6 -6
  37. package/dist/server.d.mts +6 -5
  38. package/dist/server.d.ts +6 -5
  39. package/dist/server.mjs +1 -1
  40. package/dist/sitemap.d.mts +6 -5
  41. package/dist/sitemap.d.ts +6 -5
  42. package/dist/suggest.d.mts +2 -2
  43. package/dist/suggest.d.ts +2 -2
  44. package/package.json +11 -1
  45. package/skills/cavuno-board-account/SKILL.md +3 -1
  46. package/skills/cavuno-board-filters/SKILL.md +17 -3
  47. package/skills/cavuno-board-setup/SKILL.md +1 -0
  48. package/skills/cavuno-board-talent-access/SKILL.md +149 -0
  49. package/skills/manifest.json +8 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,54 @@
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.10.0 — 2026-08-28
7
+
8
+ - **Employer talent-access paywall** (a different buyer from the candidate
9
+ paywall): `board.me.talentAccess` gains `retrieveCandidate`, `checkout`
10
+ (connected-account embedded mount kit, `origin: talent_access`),
11
+ `retrieveCheckout`, `unlock` (idempotent credit spend), and `upgrade`
12
+ (in-place plan swap; never a second checkout). `retrieve()` now also
13
+ returns `accessModel`, `companyId`, `unlockCreditsRemaining`,
14
+ `messageCreditsRemaining`, and `hasUnlimitedMessages`.
15
+ - **Company billing portal**: `board.me.companies.billingPortal.create(slug)`
16
+ mints a Stripe Customer Portal session covering every subscription on the
17
+ company's Stripe customer (job posting + talent access).
18
+ - **Public talent reads**: `TalentDirectoryEntry` and `TalentProfile` gain
19
+ `id` (the board-user id, the opaque `/p/{id}` route key). When a board
20
+ sells profile unlocks, list and retrieve-by-id responses are redacted for
21
+ viewers without entitlement; retrieve-by-handle stays the named-route
22
+ share bypass.
23
+ - **Error codes**: `talent_access_unavailable`, `company_required`,
24
+ `already_on_plan`, `talent_access_required`,
25
+ `messaging_talent_access_required`, and `stripe_not_connected` join
26
+ `BOARD_API_ERROR_CODES`.
27
+ - **New skill** `cavuno-board-talent-access` covering the full employer
28
+ flow (CTA gating, checkout, unlock, upgrade, portal, message credits).
29
+
30
+ ## 4.9.0 — 2026-08-27
31
+
32
+ - **`@cavuno/board/seo-files`**: new dependency-free subpath with
33
+ `robotsResponse`, `adsTxtResponse`, `indexNowResponse`, and
34
+ `googleSiteVerificationMeta`. Headless frontends serve `robots.txt`,
35
+ `ads.txt`, and `indexnow-key.txt` byte-identically to hosted boards from
36
+ `board.seo()`; the robots body now includes `Disallow: /go/` and
37
+ `Disallow: /t/` like hosted boards.
38
+ - **Doctor**: `--frontend` probes gained `read.adsTxt`, `read.indexNow`,
39
+ `read.googleVerification`, and `read.oauthCallback`, and `read.robots` now
40
+ checks the `Sitemap:` line and `/go/` disallow. Results gained an additive
41
+ `warn` status (`DoctorSummary.warned`) that never fails the run; a file that
42
+ is served while unconfigured in the dashboard, or a missing OAuth callback
43
+ forward, warns instead of failing. Read probes run serially and retry a
44
+ 503 child sitemap once.
45
+ - **`board.context()`**: exposes `ads` (`enabled`, `clientId`) and
46
+ `jobForm` visibility, typed as `PublicBoardAds` and `PublicBoardJobForm`.
47
+ Employer companies expose `deletionEnabled`.
48
+ - **Taxonomy lists** accept `sort: 'jobCount'` to order collections by live
49
+ job count.
50
+ - **Generated types** cover the `candidate.profile.updated` webhook event
51
+ and the operator candidate sync resources (`CandidateSyncSnapshot`,
52
+ `CandidateReconcileResult`, and related bodies).
53
+
6
54
  ## 4.8.0 — 2026-08-23
7
55
 
8
56
  - **Country-gated Apply flows**: compatible starters can use
@@ -381,6 +381,14 @@ interface components {
381
381
  slug: string;
382
382
  website: string | null;
383
383
  };
384
+ CompanyBillingPortalBody: {
385
+ returnPath?: string;
386
+ };
387
+ CompanyBillingPortalSession: {
388
+ /** @enum {string} */
389
+ object: "portal_session";
390
+ url: string;
391
+ };
384
392
  CompanyCategorySalary: {
385
393
  /** @enum {string} */
386
394
  object: "company_category_salary";
@@ -961,6 +969,8 @@ interface components {
961
969
  linkedinUrl: string | null;
962
970
  facebookUrl: string | null;
963
971
  logoUrl: string | null;
972
+ /** @description Whether company admins may delete this company. Mirrors the board Features toggle `employerCompanyDeletionEnabled`. Absent board config defaults to `true`. When `false`, DELETE returns 403 `company_deletion_disabled` and clients should hide the danger zone. */
973
+ deletionEnabled: boolean;
964
974
  };
965
975
  EmployerCreateJobBody: {
966
976
  /** @description Long-form description of the role. Up to 25,000 characters. */
@@ -1616,6 +1626,7 @@ interface components {
1616
1626
  /** @enum {string} */
1617
1627
  channel: "messageEmails" | "applicationEmails" | "recommendedJobEmails";
1618
1628
  subscribed: boolean;
1629
+ waitlisted: boolean;
1619
1630
  updatedAt: number | null;
1620
1631
  };
1621
1632
  PaywallOffer: {
@@ -1789,6 +1800,10 @@ interface components {
1789
1800
  showCavunoBranding: boolean;
1790
1801
  features: {
1791
1802
  jobAlerts: boolean;
1803
+ /** @description Whether personalized candidate job recommendations are available on this board. Absent board config defaults to `true`. */
1804
+ jobRecommendationsEnabled: boolean;
1805
+ /** @description Whether the board-level Recommended talent toggle is enabled. The endpoint additionally requires the Candidate area and a non-off talent directory. Absent board config defaults to `false`. */
1806
+ recommendedTalentEnabled: boolean;
1792
1807
  candidates: boolean;
1793
1808
  employers: boolean;
1794
1809
  blog: boolean;
@@ -1814,11 +1829,37 @@ interface components {
1814
1829
  linkedInPartnerId: string | null;
1815
1830
  cookieConsentRequired: boolean;
1816
1831
  };
1832
+ /** @description Public AdSense switch + publisher id from board advertising settings. Not the slot map (Puck/Cavuno placements) and not `ads.txt` (`board.seo()`). */
1833
+ ads: {
1834
+ /** @description Whether AdSense is turned on for this board (Settings → Advertising). Headless frontends render their own placements only when this is true and `clientId` is a valid `ca-pub-` publisher id. Per-placement slot ids are not on this resource — applications own geometry. */
1835
+ enabled: boolean;
1836
+ /** @description AdSense publisher id (`ca-pub-` + 16 digits), or null when ads are off or the stored value is malformed. Already public on hosted pages as `data-ad-client`. */
1837
+ clientId: string | null;
1838
+ };
1817
1839
  /** @description Operator-defined custom field definitions keyed by model (currently only `job`). Each key holds that model's definitions in display order. Company and talent keys are added when those models ship. The frontend uses these to render and localize each record's opaque `customFieldValues`. Display-only: not filterable or searchable in v1. */
1818
1840
  customFields: {
1819
1841
  /** @description This model's custom-field definitions in display order. Empty when the board defines none for the model. */
1820
1842
  job: components["schemas"]["CustomFieldDefinition"][];
1821
1843
  };
1844
+ /** @description Built-in job-form field visibility from Settings → Job form. Does not include custom fields (`customFields.job`) or operator-only constraints (required, bounds, allowlists). */
1845
+ jobForm: {
1846
+ salary: {
1847
+ /** @description Whether salary is captured on posting forms and shown on public job cards. Absent board config defaults to `true`. */
1848
+ visible: boolean;
1849
+ };
1850
+ seniority: {
1851
+ /** @description Whether seniority is captured on posting forms. Absent board config defaults to `true`. */
1852
+ visible: boolean;
1853
+ };
1854
+ location: {
1855
+ /** @description Whether office location is captured on posting forms. Absent board config defaults to `true`. */
1856
+ visible: boolean;
1857
+ };
1858
+ sponsorship: {
1859
+ /** @description Whether visa sponsorship is captured on posting forms. Absent board config defaults to `true`. */
1860
+ visible: boolean;
1861
+ };
1862
+ };
1822
1863
  /** @description Operator-authored contact and social identity (settings › Contact & company details). Extracted from the former `footer` group in 4.0.0: contact is identity data, not layout. Brand/social URLs are sanitized to absolute http(s). */
1823
1864
  contact: {
1824
1865
  /** @description Public contact email (render as `mailto:`). Operator-set in settings › Contact & company details. */
@@ -2195,6 +2236,8 @@ interface components {
2195
2236
  canonicalSlug: string;
2196
2237
  /** @description Board-language name with source-name fallback. */
2197
2238
  displayName: string;
2239
+ /** @description Live published-job count for this term on the board. Maintained as jobs publish and expire — not a tally of the current list page. */
2240
+ jobCount: number;
2198
2241
  };
2199
2242
  PublicVerifyBoardPasswordBody: {
2200
2243
  /** @description The board password. */
@@ -2528,14 +2571,52 @@ interface components {
2528
2571
  isEmployer: boolean;
2529
2572
  /** @description Whether this board sells talent access (a public `talent_access` plan exists). When `false` the talent surfaces are not credit-gated for employers. */
2530
2573
  paywallActive: boolean;
2531
- /** @description The CTA answer: the viewer is an approved employer AND either the board has no talent paywall or one of their companies holds an active talent_access subscription or a succeeded credit pack. Always `false` for candidates; anonymous viewers get 401. */
2574
+ /** @description The CTA answer: the viewer is an approved employer AND either the board has no talent paywall or one of their companies holds an active talent_access subscription or a succeeded credit pack. Always `false` for candidates; anonymous viewers get 401. Never cached. */
2532
2575
  hasTalentAccess: boolean;
2533
2576
  /** @description True when any active talent_access subscription carries the unlimited profile-unlock sentinel on its feature snapshot. */
2534
2577
  hasUnlimitedUnlocks: boolean;
2578
+ /**
2579
+ * @description `none` when the paywall is off. Otherwise the board charging model: paid messaging only, or paid unlocks and messaging. Inferred from public plan unlock credits when the stored config is unset.
2580
+ * @enum {string}
2581
+ */
2582
+ accessModel: "none" | "paid_messaging" | "paid_unlocks_and_messaging";
2583
+ /** @description The approved company to charge checkout/unlock against when the viewer has exactly one membership. `null` when they have none or more than one (pass `companyId` on write). */
2584
+ companyId: string | null;
2585
+ /** @description Summed finite remaining profile-unlock credits across the viewer’s companies. `0` when unlimited or when they hold no spendable credits. */
2586
+ unlockCreditsRemaining: number;
2587
+ /** @description Summed finite remaining first-message credits. `0` when unlimited or when they hold no spendable credits. */
2588
+ messageCreditsRemaining: number;
2589
+ /** @description True when any active talent_access subscription carries the unlimited message-credit sentinel. */
2590
+ hasUnlimitedMessages: boolean;
2591
+ };
2592
+ TalentAccessCheckoutBody: {
2593
+ planId: string;
2594
+ returnPath: string;
2595
+ /** @enum {string} */
2596
+ colorMode: "light" | "dark";
2597
+ companyId?: string;
2598
+ };
2599
+ TalentAccessUpgradeBody: {
2600
+ planId: string;
2601
+ companyId?: string;
2602
+ };
2603
+ TalentCandidateAccess: {
2604
+ /** @enum {string} */
2605
+ object: "talent_candidate_access";
2606
+ candidateId: string;
2607
+ companyId: string | null;
2608
+ alreadyUnlocked: boolean;
2609
+ unlockCreditsRemaining: number;
2610
+ messageCreditsRemaining: number;
2611
+ hasUnlimitedUnlocks: boolean;
2612
+ hasUnlimitedMessages: boolean;
2613
+ hasActiveTalentSubscription: boolean;
2535
2614
  };
2536
2615
  TalentDirectoryEntry: {
2537
2616
  /** @enum {string} */
2538
2617
  object: "talent_directory_entry";
2618
+ /** @description The candidate’s board-user id. When a public talent_access plan exists, directory cards link to the opaque `/p/{id}` route so profile unlocks can apply. The named `/p/{handle}` route is the share bypass. */
2619
+ id: string;
2539
2620
  handle: string | null;
2540
2621
  displayName: string | null;
2541
2622
  headline: string | null;
@@ -2565,6 +2646,8 @@ interface components {
2565
2646
  TalentProfile: {
2566
2647
  /** @enum {string} */
2567
2648
  object: "talent_profile";
2649
+ /** @description The candidate’s board-user id. The opaque talent-paywall route key (`/p/{id}`); `handle` is the named-share bypass. */
2650
+ id: string;
2568
2651
  handle: string | null;
2569
2652
  displayName: string | null;
2570
2653
  headline: string | null;
@@ -2614,6 +2697,22 @@ interface components {
2614
2697
  proficiency: string;
2615
2698
  }[];
2616
2699
  };
2700
+ TalentUnlock: {
2701
+ /** @enum {string} */
2702
+ object: "talent_unlock";
2703
+ alreadyUnlocked: boolean;
2704
+ unlockCreditsRemaining: number | null;
2705
+ };
2706
+ TalentUnlockBody: {
2707
+ candidateId: string;
2708
+ companyId?: string;
2709
+ };
2710
+ TalentUpgrade: {
2711
+ /** @enum {string} */
2712
+ object: "talent_upgrade";
2713
+ /** @enum {boolean} */
2714
+ ok: true;
2715
+ };
2617
2716
  /** @description Geo for place resolutions; `null` for category/skill. */
2618
2717
  TaxonomyGeo: {
2619
2718
  lat: number | null;
@@ -381,6 +381,14 @@ interface components {
381
381
  slug: string;
382
382
  website: string | null;
383
383
  };
384
+ CompanyBillingPortalBody: {
385
+ returnPath?: string;
386
+ };
387
+ CompanyBillingPortalSession: {
388
+ /** @enum {string} */
389
+ object: "portal_session";
390
+ url: string;
391
+ };
384
392
  CompanyCategorySalary: {
385
393
  /** @enum {string} */
386
394
  object: "company_category_salary";
@@ -961,6 +969,8 @@ interface components {
961
969
  linkedinUrl: string | null;
962
970
  facebookUrl: string | null;
963
971
  logoUrl: string | null;
972
+ /** @description Whether company admins may delete this company. Mirrors the board Features toggle `employerCompanyDeletionEnabled`. Absent board config defaults to `true`. When `false`, DELETE returns 403 `company_deletion_disabled` and clients should hide the danger zone. */
973
+ deletionEnabled: boolean;
964
974
  };
965
975
  EmployerCreateJobBody: {
966
976
  /** @description Long-form description of the role. Up to 25,000 characters. */
@@ -1616,6 +1626,7 @@ interface components {
1616
1626
  /** @enum {string} */
1617
1627
  channel: "messageEmails" | "applicationEmails" | "recommendedJobEmails";
1618
1628
  subscribed: boolean;
1629
+ waitlisted: boolean;
1619
1630
  updatedAt: number | null;
1620
1631
  };
1621
1632
  PaywallOffer: {
@@ -1789,6 +1800,10 @@ interface components {
1789
1800
  showCavunoBranding: boolean;
1790
1801
  features: {
1791
1802
  jobAlerts: boolean;
1803
+ /** @description Whether personalized candidate job recommendations are available on this board. Absent board config defaults to `true`. */
1804
+ jobRecommendationsEnabled: boolean;
1805
+ /** @description Whether the board-level Recommended talent toggle is enabled. The endpoint additionally requires the Candidate area and a non-off talent directory. Absent board config defaults to `false`. */
1806
+ recommendedTalentEnabled: boolean;
1792
1807
  candidates: boolean;
1793
1808
  employers: boolean;
1794
1809
  blog: boolean;
@@ -1814,11 +1829,37 @@ interface components {
1814
1829
  linkedInPartnerId: string | null;
1815
1830
  cookieConsentRequired: boolean;
1816
1831
  };
1832
+ /** @description Public AdSense switch + publisher id from board advertising settings. Not the slot map (Puck/Cavuno placements) and not `ads.txt` (`board.seo()`). */
1833
+ ads: {
1834
+ /** @description Whether AdSense is turned on for this board (Settings → Advertising). Headless frontends render their own placements only when this is true and `clientId` is a valid `ca-pub-` publisher id. Per-placement slot ids are not on this resource — applications own geometry. */
1835
+ enabled: boolean;
1836
+ /** @description AdSense publisher id (`ca-pub-` + 16 digits), or null when ads are off or the stored value is malformed. Already public on hosted pages as `data-ad-client`. */
1837
+ clientId: string | null;
1838
+ };
1817
1839
  /** @description Operator-defined custom field definitions keyed by model (currently only `job`). Each key holds that model's definitions in display order. Company and talent keys are added when those models ship. The frontend uses these to render and localize each record's opaque `customFieldValues`. Display-only: not filterable or searchable in v1. */
1818
1840
  customFields: {
1819
1841
  /** @description This model's custom-field definitions in display order. Empty when the board defines none for the model. */
1820
1842
  job: components["schemas"]["CustomFieldDefinition"][];
1821
1843
  };
1844
+ /** @description Built-in job-form field visibility from Settings → Job form. Does not include custom fields (`customFields.job`) or operator-only constraints (required, bounds, allowlists). */
1845
+ jobForm: {
1846
+ salary: {
1847
+ /** @description Whether salary is captured on posting forms and shown on public job cards. Absent board config defaults to `true`. */
1848
+ visible: boolean;
1849
+ };
1850
+ seniority: {
1851
+ /** @description Whether seniority is captured on posting forms. Absent board config defaults to `true`. */
1852
+ visible: boolean;
1853
+ };
1854
+ location: {
1855
+ /** @description Whether office location is captured on posting forms. Absent board config defaults to `true`. */
1856
+ visible: boolean;
1857
+ };
1858
+ sponsorship: {
1859
+ /** @description Whether visa sponsorship is captured on posting forms. Absent board config defaults to `true`. */
1860
+ visible: boolean;
1861
+ };
1862
+ };
1822
1863
  /** @description Operator-authored contact and social identity (settings › Contact & company details). Extracted from the former `footer` group in 4.0.0: contact is identity data, not layout. Brand/social URLs are sanitized to absolute http(s). */
1823
1864
  contact: {
1824
1865
  /** @description Public contact email (render as `mailto:`). Operator-set in settings › Contact & company details. */
@@ -2195,6 +2236,8 @@ interface components {
2195
2236
  canonicalSlug: string;
2196
2237
  /** @description Board-language name with source-name fallback. */
2197
2238
  displayName: string;
2239
+ /** @description Live published-job count for this term on the board. Maintained as jobs publish and expire — not a tally of the current list page. */
2240
+ jobCount: number;
2198
2241
  };
2199
2242
  PublicVerifyBoardPasswordBody: {
2200
2243
  /** @description The board password. */
@@ -2528,14 +2571,52 @@ interface components {
2528
2571
  isEmployer: boolean;
2529
2572
  /** @description Whether this board sells talent access (a public `talent_access` plan exists). When `false` the talent surfaces are not credit-gated for employers. */
2530
2573
  paywallActive: boolean;
2531
- /** @description The CTA answer: the viewer is an approved employer AND either the board has no talent paywall or one of their companies holds an active talent_access subscription or a succeeded credit pack. Always `false` for candidates; anonymous viewers get 401. */
2574
+ /** @description The CTA answer: the viewer is an approved employer AND either the board has no talent paywall or one of their companies holds an active talent_access subscription or a succeeded credit pack. Always `false` for candidates; anonymous viewers get 401. Never cached. */
2532
2575
  hasTalentAccess: boolean;
2533
2576
  /** @description True when any active talent_access subscription carries the unlimited profile-unlock sentinel on its feature snapshot. */
2534
2577
  hasUnlimitedUnlocks: boolean;
2578
+ /**
2579
+ * @description `none` when the paywall is off. Otherwise the board charging model: paid messaging only, or paid unlocks and messaging. Inferred from public plan unlock credits when the stored config is unset.
2580
+ * @enum {string}
2581
+ */
2582
+ accessModel: "none" | "paid_messaging" | "paid_unlocks_and_messaging";
2583
+ /** @description The approved company to charge checkout/unlock against when the viewer has exactly one membership. `null` when they have none or more than one (pass `companyId` on write). */
2584
+ companyId: string | null;
2585
+ /** @description Summed finite remaining profile-unlock credits across the viewer’s companies. `0` when unlimited or when they hold no spendable credits. */
2586
+ unlockCreditsRemaining: number;
2587
+ /** @description Summed finite remaining first-message credits. `0` when unlimited or when they hold no spendable credits. */
2588
+ messageCreditsRemaining: number;
2589
+ /** @description True when any active talent_access subscription carries the unlimited message-credit sentinel. */
2590
+ hasUnlimitedMessages: boolean;
2591
+ };
2592
+ TalentAccessCheckoutBody: {
2593
+ planId: string;
2594
+ returnPath: string;
2595
+ /** @enum {string} */
2596
+ colorMode: "light" | "dark";
2597
+ companyId?: string;
2598
+ };
2599
+ TalentAccessUpgradeBody: {
2600
+ planId: string;
2601
+ companyId?: string;
2602
+ };
2603
+ TalentCandidateAccess: {
2604
+ /** @enum {string} */
2605
+ object: "talent_candidate_access";
2606
+ candidateId: string;
2607
+ companyId: string | null;
2608
+ alreadyUnlocked: boolean;
2609
+ unlockCreditsRemaining: number;
2610
+ messageCreditsRemaining: number;
2611
+ hasUnlimitedUnlocks: boolean;
2612
+ hasUnlimitedMessages: boolean;
2613
+ hasActiveTalentSubscription: boolean;
2535
2614
  };
2536
2615
  TalentDirectoryEntry: {
2537
2616
  /** @enum {string} */
2538
2617
  object: "talent_directory_entry";
2618
+ /** @description The candidate’s board-user id. When a public talent_access plan exists, directory cards link to the opaque `/p/{id}` route so profile unlocks can apply. The named `/p/{handle}` route is the share bypass. */
2619
+ id: string;
2539
2620
  handle: string | null;
2540
2621
  displayName: string | null;
2541
2622
  headline: string | null;
@@ -2565,6 +2646,8 @@ interface components {
2565
2646
  TalentProfile: {
2566
2647
  /** @enum {string} */
2567
2648
  object: "talent_profile";
2649
+ /** @description The candidate’s board-user id. The opaque talent-paywall route key (`/p/{id}`); `handle` is the named-share bypass. */
2650
+ id: string;
2568
2651
  handle: string | null;
2569
2652
  displayName: string | null;
2570
2653
  headline: string | null;
@@ -2614,6 +2697,22 @@ interface components {
2614
2697
  proficiency: string;
2615
2698
  }[];
2616
2699
  };
2700
+ TalentUnlock: {
2701
+ /** @enum {string} */
2702
+ object: "talent_unlock";
2703
+ alreadyUnlocked: boolean;
2704
+ unlockCreditsRemaining: number | null;
2705
+ };
2706
+ TalentUnlockBody: {
2707
+ candidateId: string;
2708
+ companyId?: string;
2709
+ };
2710
+ TalentUpgrade: {
2711
+ /** @enum {string} */
2712
+ object: "talent_upgrade";
2713
+ /** @enum {boolean} */
2714
+ ok: true;
2715
+ };
2617
2716
  /** @description Geo for place resolutions; `null` for category/skill. */
2618
2717
  TaxonomyGeo: {
2619
2718
  lat: number | null;