@curviate/sdk 0.25.0 → 0.27.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.
@@ -2513,7 +2513,7 @@ export interface paths {
2513
2513
  };
2514
2514
  /**
2515
2515
  * List webhook event types
2516
- * @description Returns the complete canonical event catalogue (28 events) grouped by source: messaging (8), user (2), account_status (15), plus 3 tier-gated events. A local catalogue read: no platform call is made.
2516
+ * @description Returns the complete canonical event catalogue (27 events) grouped by source: messaging (7), user (2), account_status (15), plus 3 tier-gated events. A local catalogue read: no platform call is made.
2517
2517
  */
2518
2518
  get: operations["getV1WebhooksEvents"];
2519
2519
  put?: never;
@@ -2591,7 +2591,7 @@ export interface paths {
2591
2591
  head?: never;
2592
2592
  /**
2593
2593
  * Update an account's safety policy
2594
- * @description The single safety-policy write. Send only the fields you are changing: everything you omit is left byte-identical, and sending `null` for a field clears your override and restores the Curviate default. Any limit may be set to any value: Curviate does not clamp, cap or refuse a change on the grounds that the number is unsafe. A value above the Curviate default is reported back in the response, and on every later read, with the default and its source class attached; there is no way to acknowledge it away, and setting the value back to the default removes it. A value that is not a value, such as a negative ceiling or an unknown row name, is a 400. Every field whose value CHANGES is appended to the account's action ledger with the previous value, the new value, the Curviate default, the actor and the time; a field you send whose value already equals its current effective value is not ledgered and is not stored as an override, so reading the policy and sending the document back changes nothing. Four fields on the read are derived rather than configured: `effective_ceiling`, `posture_source`, `over_default` and each row's `warm_up_state`. Send them and they are accepted and ignored, never stored and never ledgered, so the document you read can go straight back. To pin a row's ramp, set `warm_up_factor`. `activity_window` is not accepted: send its settable subfields instead, which for the zone is the top-level `timezone`. And read `changes nothing` as `changes no limit`: the `posture` fields are OVERRIDES at every scope, so writing back a posture a scope merely inherits PINS it there and appends one ledger entry per pinned scope. That is what stops a later account- or tenant-wide change from moving it. A pin already in place is a no-op. An agent-authenticated write is accepted on exactly the same footing as an operator's. There is no bulk import, file upload or policy template: configuring many rows or many accounts is a loop over this operation. One field is not account-scoped: `tenant_default_posture` sets the default for EVERY account in the tenant, not just the one in the path, which is what makes it a one-call change for a whole workspace of personas. It is reported back at the top of every policy response, so a change to it is visible even on an account that overrides it. One other field is not row-scoped: `limit_profile` selects which of the four Curviate default sets this account's rows resolve from, so it moves the default under every row at once while leaving every value you have configured explicitly exactly as you set it. It is the platform product active on the account, not your Curviate seat entitlement, and the two can disagree: a lapsed subscription leaves the seat untouched. Curviate detects it when the account connects and re-detects it on every reconnect; setting it here is an operator override of that result, and it holds until the next connect. When the seat and the detected product disagree, the detected product wins the numbers and the read reports the disagreement as `seat_tier_mismatch`.
2594
+ * @description The single safety-policy write. Send only the fields you are changing: everything you omit is left byte-identical, and sending `null` for a field clears your override and restores the Curviate default. Any limit may be set to any value: Curviate does not clamp, cap or refuse a change on the grounds that the number is unsafe. A value above the Curviate default is reported back in the response, and on every later read, with the default and its source class attached; there is no way to acknowledge it away, and setting the value back to the default removes it. A value that is not a value, such as a negative ceiling or an unknown row name, is a 400. Every field whose value CHANGES is appended to the account's action ledger with the previous value, the new value, the Curviate default, the actor and the time; a field you send whose value already equals its current effective value is not ledgered and is not stored as an override, so reading the policy and sending the document back changes nothing. Six fields on the read are derived rather than configured: `effective_ceiling`, `interface_ceiling`, `effective_interface_ceiling`, `posture_source`, `over_default` and each row's `warm_up_state`. Send them and they are accepted and ignored, never stored and never ledgered, so the document you read can go straight back. To pin a row's ramp, set `warm_up_factor`. `activity_window` is not accepted: send its settable subfields instead, the top-level `timezone` for the zone, and per row `activity_window_start`, `activity_window_end`, `activity_window_timezone` and `activity_window_applies_to`. The 400 this produces names those subfields, not just the refused object. And read `changes nothing` as `changes no limit`: the `posture` fields are OVERRIDES at every scope, so writing back a posture a scope merely inherits PINS it there and appends one ledger entry per pinned scope. That is what stops a later account- or tenant-wide change from moving it. A pin already in place is a no-op. An agent-authenticated write is accepted on exactly the same footing as an operator's. There is no bulk import, file upload or policy template: configuring many rows or many accounts is a loop over this operation. One field is not account-scoped: `tenant_default_posture` sets the default for EVERY account in the tenant, not just the one in the path, which is what makes it a one-call change for a whole workspace of personas. It is reported back at the top of every policy response, so a change to it is visible even on an account that overrides it. One other field is not row-scoped: `limit_profile` selects which of the four Curviate default sets this account's rows resolve from, so it moves the default under every row at once while leaving every value you have configured explicitly exactly as you set it. It is the platform product active on the account, not your Curviate seat entitlement, and the two can disagree: a lapsed subscription leaves the seat untouched. Curviate detects it when the account connects and re-detects it on every reconnect; setting it here is an operator override of that result, and it holds until the next connect. When the seat and the detected product disagree, the detected product wins the numbers and the read reports the disagreement as `seat_tier_mismatch`.
2595
2595
  */
2596
2596
  patch: operations["patchV1AccountIdSafetyPolicy"];
2597
2597
  trace?: never;
@@ -2650,9 +2650,9 @@ export interface components {
2650
2650
  * @enum {string}
2651
2651
  */
2652
2652
  required_tier?: "core" | "sales_nav" | "recruiter";
2653
- /** @description Present on a PLATFORM_RATE_LIMIT raised because one account-safety budget row is paused: LinkedIn refused a recent call on that row, so this one was refused locally without reaching LinkedIn. Names the paused row (for example profile_views, connection_requests_no_note). The pause is scoped to this row on this account; every other row keeps working. Absent on every other rate limit. Also present on BUDGET_EXHAUSTED, where it names the row that hit its CEILING rather than one LinkedIn paused: read the code to tell the two apart, because the recovery differs. */
2654
- row?: string;
2655
- /** @description Present on BUDGET_EXHAUSTED: when this row's budget frees up, as an absolute instant rather than a duration, so it stays true however long you hold it. Null for the pending_invites row, whose backlog falls when invitations are accepted or withdrawn rather than at any window boundary, so there is no instant to name. */
2653
+ /** @description Present on a PLATFORM_RATE_LIMIT raised because one account-safety budget row is paused: LinkedIn refused a recent call on that row, so this one was refused locally without reaching LinkedIn. Names the paused row (for example profile_views, connection_requests_no_note). The pause is scoped to this row on this account; every other row keeps working. Absent on every other rate limit. Also present on BUDGET_EXHAUSTED, where it names the row that hit its CEILING rather than one LinkedIn paused: read the code to tell the two apart, because the recovery differs. Null on a BUDGET_EXHAUSTED whose reason is activity_window and whose action spends no budget of its own, because there is no row to name; hint.parameter still names the setting to change. Never null on a rate limit. */
2654
+ row?: string | null;
2655
+ /** @description Present on BUDGET_EXHAUSTED: the instant the refusal lifts, as an absolute instant rather than a duration, so it stays true however long you hold it. It is the window roll on a ceiling refusal and the next window open on an activity-window one. It is null in the two cases where no clock frees the account: the pending_invites gauge, whose backlog falls when invitations are accepted or withdrawn, and an InMail credit exhaustion (row inmail), which LinkedIn regrants on a schedule this product cannot read. */
2656
2656
  reset_at?: string | null;
2657
2657
  /** @description Present on BUDGET_EXHAUSTED: the exact setting to change, as a field rather than as prose. parameter is addressable on PATCH /v1/{account_id}/safety-policy, so an agent can decide between waiting until reset_at, escalating to a human, and reconfiguring, without parsing the message. */
2658
2658
  hint?: {
@@ -2702,27 +2702,27 @@ export interface components {
2702
2702
  }[];
2703
2703
  };
2704
2704
  /**
2705
- * @description Present on a successful response when this account crossed an account-safety ceiling while the affected budget row is on the default warn posture. The action still happened. Field-identical to the BUDGET_EXHAUSTED error body except that blocked is false, so one branch handles both postures and switching the account to enforce is a configuration change rather than a client rewrite.
2705
+ * @description Present on a successful response when this account crossed an account-safety ceiling while the affected budget row is on the default warn posture. The action still happened. Field-identical to the BUDGET_EXHAUSTED error body except that blocked is false and hint.message describes the outcome, so one branch handles both postures and switching the account to enforce is a configuration change rather than a client rewrite.
2706
2706
  * @example {
2707
2707
  * "row": "profile_views",
2708
2708
  * "reset_at": "2026-09-05T00:00:00.000Z",
2709
2709
  * "hint": {
2710
2710
  * "parameter": "profile_views.ceiling",
2711
- * "message": "This account is at its configured ceiling for profile_views."
2711
+ * "message": "This account is at its ceiling for profile_views. This action went through because profile_views.posture is warn, and it counted: 101 of 100 this window. Raise profile_views.ceiling, or wait for the window to reset at 2026-09-05T00:00:00.000Z."
2712
2712
  * },
2713
2713
  * "reason": "ceiling",
2714
2714
  * "blocked": false
2715
2715
  * }
2716
2716
  */
2717
2717
  SafetyWarning: {
2718
- /** @description The budget row that breached, for example profile_views or pending_invites. */
2719
- row: string;
2720
- /** @description When the row frees up, as an absolute instant. Null for the pending_invites gauge. */
2718
+ /** @description The budget row that breached, for example profile_views or pending_invites. Null when the breach is not about a row: an activity_window warning on an action that spends no budget of its own (editing a message, dismissing a notification, a Recruiter or Sales Navigator admin action) is still governed by the hours the account works in. Read hint.parameter for what to change; whenever this is null it names posture, because the activity window edges are set per action type and this action has none, so the levers that reach it are the account timezone and posture. */
2719
+ row: string | null;
2720
+ /** @description The instant the refusal lifts: the window roll on a ceiling refusal, the next window open on an activity-window one. Null in the two cases no clock frees, the pending_invites gauge and InMail credits (row inmail). */
2721
2721
  reset_at: string | null;
2722
2722
  hint: {
2723
2723
  /** @description The settable parameter on PATCH /v1/{account_id}/safety-policy. */
2724
2724
  parameter: string;
2725
- /** @description What the condition is and what changing that parameter would do. */
2725
+ /** @description What the condition is and what changing that parameter would do. This is the one field whose text differs from the BUDGET_EXHAUSTED refusal: here it says the action went through, and on a ceiling breach how far past the ceiling this row now stands, rather than telling you to set posture to warn when it already is. Branch on parameter, reason and blocked, never on this text. */
2726
2726
  message: string;
2727
2727
  };
2728
2728
  /**
@@ -6710,13 +6710,13 @@ export interface operations {
6710
6710
  }[];
6711
6711
  /** @description Opaque cursor for the next page, or null at end-of-list. */
6712
6712
  cursor: string | null;
6713
- /** @description Present only when expand=public_identifier was asked for and this page held more people needing a profile lookup than one request performs. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
6713
+ /** @description Present only when expand=public_identifier was asked for and some people on this page went unresolved for a reason the payload cannot show: more of them needed a profile lookup than one request performs, the account is outside its activity window at this hour and enforces it, or the account's profile_views budget is at its configured ceiling and enforces that. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
6714
6714
  notices?: {
6715
6715
  /**
6716
- * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone.
6716
+ * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone. EXPANSION_WITHHELD_ACTIVITY_WINDOW: the profile lookups this page needed were refused because the account is outside its activity window at this hour and enforces it, so those people carry public_identifier null and their null does not mean they have no public profile either. Ask again inside the window, or widen the window on this account's safety policy. EXPANSION_WITHHELD_CEILING: the profile lookups this page needed were refused because the account's profile_views budget is at its configured ceiling and it enforces that, so those people carry public_identifier null and their null does not mean they have no public profile either. Raise the profile_views ceiling on this account's safety policy, or ask for a smaller page.
6717
6717
  * @enum {string}
6718
6718
  */
6719
- code: "EXPANSION_LIMIT_REACHED";
6719
+ code: "EXPANSION_LIMIT_REACHED" | "EXPANSION_WITHHELD_ACTIVITY_WINDOW" | "EXPANSION_WITHHELD_CEILING";
6720
6720
  /** @description One sentence explaining the condition and how to resolve it. */
6721
6721
  message: string;
6722
6722
  /** @description The request field the notice is about, here expand. */
@@ -6893,13 +6893,13 @@ export interface operations {
6893
6893
  /** @description Message body (content pass-through, never stored). */
6894
6894
  text?: string | null;
6895
6895
  } | null;
6896
- /** @description Present only when expand=public_identifier was asked for and this page held more people needing a profile lookup than one request performs. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
6896
+ /** @description Present only when expand=public_identifier was asked for and some people on this page went unresolved for a reason the payload cannot show: more of them needed a profile lookup than one request performs, the account is outside its activity window at this hour and enforces it, or the account's profile_views budget is at its configured ceiling and enforces that. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
6897
6897
  notices?: {
6898
6898
  /**
6899
- * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone.
6899
+ * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone. EXPANSION_WITHHELD_ACTIVITY_WINDOW: the profile lookups this page needed were refused because the account is outside its activity window at this hour and enforces it, so those people carry public_identifier null and their null does not mean they have no public profile either. Ask again inside the window, or widen the window on this account's safety policy. EXPANSION_WITHHELD_CEILING: the profile lookups this page needed were refused because the account's profile_views budget is at its configured ceiling and it enforces that, so those people carry public_identifier null and their null does not mean they have no public profile either. Raise the profile_views ceiling on this account's safety policy, or ask for a smaller page.
6900
6900
  * @enum {string}
6901
6901
  */
6902
- code: "EXPANSION_LIMIT_REACHED";
6902
+ code: "EXPANSION_LIMIT_REACHED" | "EXPANSION_WITHHELD_ACTIVITY_WINDOW" | "EXPANSION_WITHHELD_CEILING";
6903
6903
  /** @description One sentence explaining the condition and how to resolve it. */
6904
6904
  message: string;
6905
6905
  /** @description The request field the notice is about, here expand. */
@@ -7069,13 +7069,13 @@ export interface operations {
7069
7069
  }[];
7070
7070
  /** @description Opaque cursor for the next page, or null at end-of-list. */
7071
7071
  cursor: string | null;
7072
- /** @description Present only when expand=public_identifier was asked for and this page held more people needing a profile lookup than one request performs. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
7072
+ /** @description Present only when expand=public_identifier was asked for and some people on this page went unresolved for a reason the payload cannot show: more of them needed a profile lookup than one request performs, the account is outside its activity window at this hour and enforces it, or the account's profile_views budget is at its configured ceiling and enforces that. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
7073
7073
  notices?: {
7074
7074
  /**
7075
- * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone.
7075
+ * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone. EXPANSION_WITHHELD_ACTIVITY_WINDOW: the profile lookups this page needed were refused because the account is outside its activity window at this hour and enforces it, so those people carry public_identifier null and their null does not mean they have no public profile either. Ask again inside the window, or widen the window on this account's safety policy. EXPANSION_WITHHELD_CEILING: the profile lookups this page needed were refused because the account's profile_views budget is at its configured ceiling and it enforces that, so those people carry public_identifier null and their null does not mean they have no public profile either. Raise the profile_views ceiling on this account's safety policy, or ask for a smaller page.
7076
7076
  * @enum {string}
7077
7077
  */
7078
- code: "EXPANSION_LIMIT_REACHED";
7078
+ code: "EXPANSION_LIMIT_REACHED" | "EXPANSION_WITHHELD_ACTIVITY_WINDOW" | "EXPANSION_WITHHELD_CEILING";
7079
7079
  /** @description One sentence explaining the condition and how to resolve it. */
7080
7080
  message: string;
7081
7081
  /** @description The request field the notice is about, here expand. */
@@ -7412,13 +7412,13 @@ export interface operations {
7412
7412
  sent_at: number;
7413
7413
  /** @description Message body (content pass-through, never stored). */
7414
7414
  text?: string | null;
7415
- /** @description Present only when expand=public_identifier was asked for and this page held more people needing a profile lookup than one request performs. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
7415
+ /** @description Present only when expand=public_identifier was asked for and some people on this page went unresolved for a reason the payload cannot show: more of them needed a profile lookup than one request performs, the account is outside its activity window at this hour and enforces it, or the account's profile_views budget is at its configured ceiling and enforces that. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
7416
7416
  notices?: {
7417
7417
  /**
7418
- * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone.
7418
+ * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone. EXPANSION_WITHHELD_ACTIVITY_WINDOW: the profile lookups this page needed were refused because the account is outside its activity window at this hour and enforces it, so those people carry public_identifier null and their null does not mean they have no public profile either. Ask again inside the window, or widen the window on this account's safety policy. EXPANSION_WITHHELD_CEILING: the profile lookups this page needed were refused because the account's profile_views budget is at its configured ceiling and it enforces that, so those people carry public_identifier null and their null does not mean they have no public profile either. Raise the profile_views ceiling on this account's safety policy, or ask for a smaller page.
7419
7419
  * @enum {string}
7420
7420
  */
7421
- code: "EXPANSION_LIMIT_REACHED";
7421
+ code: "EXPANSION_LIMIT_REACHED" | "EXPANSION_WITHHELD_ACTIVITY_WINDOW" | "EXPANSION_WITHHELD_CEILING";
7422
7422
  /** @description One sentence explaining the condition and how to resolve it. */
7423
7423
  message: string;
7424
7424
  /** @description The request field the notice is about, here expand. */
@@ -7618,13 +7618,13 @@ export interface operations {
7618
7618
  * @enum {boolean}
7619
7619
  */
7620
7620
  filter_effective?: true;
7621
- /** @description Present only when expand=public_identifier was asked for and this page held more people needing a profile lookup than one request performs. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
7621
+ /** @description Present only when expand=public_identifier was asked for and some people on this page went unresolved for a reason the payload cannot show: more of them needed a profile lookup than one request performs, the account is outside its activity window at this hour and enforces it, or the account's profile_views budget is at its configured ceiling and enforces that. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
7622
7622
  notices?: {
7623
7623
  /**
7624
- * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone.
7624
+ * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone. EXPANSION_WITHHELD_ACTIVITY_WINDOW: the profile lookups this page needed were refused because the account is outside its activity window at this hour and enforces it, so those people carry public_identifier null and their null does not mean they have no public profile either. Ask again inside the window, or widen the window on this account's safety policy. EXPANSION_WITHHELD_CEILING: the profile lookups this page needed were refused because the account's profile_views budget is at its configured ceiling and it enforces that, so those people carry public_identifier null and their null does not mean they have no public profile either. Raise the profile_views ceiling on this account's safety policy, or ask for a smaller page.
7625
7625
  * @enum {string}
7626
7626
  */
7627
- code: "EXPANSION_LIMIT_REACHED";
7627
+ code: "EXPANSION_LIMIT_REACHED" | "EXPANSION_WITHHELD_ACTIVITY_WINDOW" | "EXPANSION_WITHHELD_CEILING";
7628
7628
  /** @description One sentence explaining the condition and how to resolve it. */
7629
7629
  message: string;
7630
7630
  /** @description The request field the notice is about, here expand. */
@@ -10265,13 +10265,13 @@ export interface operations {
10265
10265
  }[];
10266
10266
  /** @description Next-page cursor; follow until items is empty (presence is not a has-more guarantee). */
10267
10267
  cursor?: string | null;
10268
- /** @description Present only when expand=public_identifier was asked for and this page held more people needing a profile lookup than one request performs. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
10268
+ /** @description Present only when expand=public_identifier was asked for and some people on this page went unresolved for a reason the payload cannot show: more of them needed a profile lookup than one request performs, the account is outside its activity window at this hour and enforces it, or the account's profile_views budget is at its configured ceiling and enforces that. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
10269
10269
  notices?: {
10270
10270
  /**
10271
- * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone.
10271
+ * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone. EXPANSION_WITHHELD_ACTIVITY_WINDOW: the profile lookups this page needed were refused because the account is outside its activity window at this hour and enforces it, so those people carry public_identifier null and their null does not mean they have no public profile either. Ask again inside the window, or widen the window on this account's safety policy. EXPANSION_WITHHELD_CEILING: the profile lookups this page needed were refused because the account's profile_views budget is at its configured ceiling and it enforces that, so those people carry public_identifier null and their null does not mean they have no public profile either. Raise the profile_views ceiling on this account's safety policy, or ask for a smaller page.
10272
10272
  * @enum {string}
10273
10273
  */
10274
- code: "EXPANSION_LIMIT_REACHED";
10274
+ code: "EXPANSION_LIMIT_REACHED" | "EXPANSION_WITHHELD_ACTIVITY_WINDOW" | "EXPANSION_WITHHELD_CEILING";
10275
10275
  /** @description One sentence explaining the condition and how to resolve it. */
10276
10276
  message: string;
10277
10277
  /** @description The request field the notice is about, here expand. */
@@ -10687,13 +10687,13 @@ export interface operations {
10687
10687
  /** @description The vanity slug from the profile URL, for example jane-smith. Present only when the request asks for it with expand=public_identifier, and then always present, carrying the slug or null when the platform surfaces none for this person. */
10688
10688
  public_identifier?: string | null;
10689
10689
  };
10690
- /** @description Present only when expand=public_identifier was asked for and this page held more people needing a profile lookup than one request performs. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
10690
+ /** @description Present only when expand=public_identifier was asked for and some people on this page went unresolved for a reason the payload cannot show: more of them needed a profile lookup than one request performs, the account is outside its activity window at this hour and enforces it, or the account's profile_views budget is at its configured ceiling and enforces that. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
10691
10691
  notices?: {
10692
10692
  /**
10693
- * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone.
10693
+ * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone. EXPANSION_WITHHELD_ACTIVITY_WINDOW: the profile lookups this page needed were refused because the account is outside its activity window at this hour and enforces it, so those people carry public_identifier null and their null does not mean they have no public profile either. Ask again inside the window, or widen the window on this account's safety policy. EXPANSION_WITHHELD_CEILING: the profile lookups this page needed were refused because the account's profile_views budget is at its configured ceiling and it enforces that, so those people carry public_identifier null and their null does not mean they have no public profile either. Raise the profile_views ceiling on this account's safety policy, or ask for a smaller page.
10694
10694
  * @enum {string}
10695
10695
  */
10696
- code: "EXPANSION_LIMIT_REACHED";
10696
+ code: "EXPANSION_LIMIT_REACHED" | "EXPANSION_WITHHELD_ACTIVITY_WINDOW" | "EXPANSION_WITHHELD_CEILING";
10697
10697
  /** @description One sentence explaining the condition and how to resolve it. */
10698
10698
  message: string;
10699
10699
  /** @description The request field the notice is about, here expand. */
@@ -11047,13 +11047,13 @@ export interface operations {
11047
11047
  }[];
11048
11048
  /** @description Next-page cursor; follow until items is empty. */
11049
11049
  cursor?: string | null;
11050
- /** @description Present only when expand=public_identifier was asked for and this page held more people needing a profile lookup than one request performs. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
11050
+ /** @description Present only when expand=public_identifier was asked for and some people on this page went unresolved for a reason the payload cannot show: more of them needed a profile lookup than one request performs, the account is outside its activity window at this hour and enforces it, or the account's profile_views budget is at its configured ceiling and enforces that. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
11051
11051
  notices?: {
11052
11052
  /**
11053
- * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone.
11053
+ * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone. EXPANSION_WITHHELD_ACTIVITY_WINDOW: the profile lookups this page needed were refused because the account is outside its activity window at this hour and enforces it, so those people carry public_identifier null and their null does not mean they have no public profile either. Ask again inside the window, or widen the window on this account's safety policy. EXPANSION_WITHHELD_CEILING: the profile lookups this page needed were refused because the account's profile_views budget is at its configured ceiling and it enforces that, so those people carry public_identifier null and their null does not mean they have no public profile either. Raise the profile_views ceiling on this account's safety policy, or ask for a smaller page.
11054
11054
  * @enum {string}
11055
11055
  */
11056
- code: "EXPANSION_LIMIT_REACHED";
11056
+ code: "EXPANSION_LIMIT_REACHED" | "EXPANSION_WITHHELD_ACTIVITY_WINDOW" | "EXPANSION_WITHHELD_CEILING";
11057
11057
  /** @description One sentence explaining the condition and how to resolve it. */
11058
11058
  message: string;
11059
11059
  /** @description The request field the notice is about, here expand. */
@@ -11423,13 +11423,13 @@ export interface operations {
11423
11423
  [key: string]: unknown;
11424
11424
  };
11425
11425
  };
11426
- /** @description Present only when expand=public_identifier was asked for and this page held more people needing a profile lookup than one request performs. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
11426
+ /** @description Present only when expand=public_identifier was asked for and some people on this page went unresolved for a reason the payload cannot show: more of them needed a profile lookup than one request performs, the account is outside its activity window at this hour and enforces it, or the account's profile_views budget is at its configured ceiling and enforces that. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
11427
11427
  notices?: {
11428
11428
  /**
11429
- * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone.
11429
+ * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone. EXPANSION_WITHHELD_ACTIVITY_WINDOW: the profile lookups this page needed were refused because the account is outside its activity window at this hour and enforces it, so those people carry public_identifier null and their null does not mean they have no public profile either. Ask again inside the window, or widen the window on this account's safety policy. EXPANSION_WITHHELD_CEILING: the profile lookups this page needed were refused because the account's profile_views budget is at its configured ceiling and it enforces that, so those people carry public_identifier null and their null does not mean they have no public profile either. Raise the profile_views ceiling on this account's safety policy, or ask for a smaller page.
11430
11430
  * @enum {string}
11431
11431
  */
11432
- code: "EXPANSION_LIMIT_REACHED";
11432
+ code: "EXPANSION_LIMIT_REACHED" | "EXPANSION_WITHHELD_ACTIVITY_WINDOW" | "EXPANSION_WITHHELD_CEILING";
11433
11433
  /** @description One sentence explaining the condition and how to resolve it. */
11434
11434
  message: string;
11435
11435
  /** @description The request field the notice is about, here expand. */
@@ -12000,7 +12000,7 @@ export interface operations {
12000
12000
  getV1AccountIdChatsSearch: {
12001
12001
  parameters: {
12002
12002
  query: {
12003
- /** @description The search term: matches both participant names and message content (e.g. 'sophie keller'). */
12003
+ /** @description The search term: matches both participant names and message content (e.g. 'sophie keller'). Terms of 3 or more characters are fast; a 1-2 character term is slower. */
12004
12004
  query: string;
12005
12005
  /** @description Maximum chats to return per page (1-100, default 20). The server may walk a few internal pages to fill one page. */
12006
12006
  limit?: number;
@@ -12629,13 +12629,13 @@ export interface operations {
12629
12629
  }[];
12630
12630
  /** @description Next-page cursor. Follow until items is empty. */
12631
12631
  cursor?: string | null;
12632
- /** @description Present only when expand=public_identifier was asked for and this page held more people needing a profile lookup than one request performs. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
12632
+ /** @description Present only when expand=public_identifier was asked for and some people on this page went unresolved for a reason the payload cannot show: more of them needed a profile lookup than one request performs, the account is outside its activity window at this hour and enforces it, or the account's profile_views budget is at its configured ceiling and enforces that. Absent whenever there is nothing to report, so a response that resolved everyone carries no such key. Branch on each entry's code, never on its message. */
12633
12633
  notices?: {
12634
12634
  /**
12635
- * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone.
12635
+ * @description EXPANSION_LIMIT_REACHED: more people on this page needed a profile lookup than one request performs, so the ones past the budget carry public_identifier null without ever having been looked up. Their null therefore does not mean the person has no public profile. Ask for a smaller page to resolve everyone. EXPANSION_WITHHELD_ACTIVITY_WINDOW: the profile lookups this page needed were refused because the account is outside its activity window at this hour and enforces it, so those people carry public_identifier null and their null does not mean they have no public profile either. Ask again inside the window, or widen the window on this account's safety policy. EXPANSION_WITHHELD_CEILING: the profile lookups this page needed were refused because the account's profile_views budget is at its configured ceiling and it enforces that, so those people carry public_identifier null and their null does not mean they have no public profile either. Raise the profile_views ceiling on this account's safety policy, or ask for a smaller page.
12636
12636
  * @enum {string}
12637
12637
  */
12638
- code: "EXPANSION_LIMIT_REACHED";
12638
+ code: "EXPANSION_LIMIT_REACHED" | "EXPANSION_WITHHELD_ACTIVITY_WINDOW" | "EXPANSION_WITHHELD_CEILING";
12639
12639
  /** @description One sentence explaining the condition and how to resolve it. */
12640
12640
  message: string;
12641
12641
  /** @description The request field the notice is about, here expand. */
@@ -12889,7 +12889,7 @@ export interface operations {
12889
12889
  "application/json": components["schemas"]["Error"];
12890
12890
  };
12891
12891
  };
12892
- /** @description A temporary upstream error occurred, or the upstream response could not be interpreted. Please try again. */
12892
+ /** @description A temporary upstream error occurred, or the upstream response could not be interpreted. Check `retry_likely_to_succeed`: a temporary error is worth retrying, a response that could not be interpreted is not, and carries `retry_hint: {"kind": "never"}`. */
12893
12893
  502: {
12894
12894
  headers: {
12895
12895
  [name: string]: unknown;
@@ -27860,6 +27860,10 @@ export interface operations {
27860
27860
  ceiling: number | null;
27861
27861
  /** @description What this row is ACTUALLY held to right now: `ceiling` with the account's warm-up ramp applied. Compare `used` against THIS one, and `band` is computed against it too. While an account is new, thinly connected, dormant or recovering from a restriction the two differ, and on a five-day-old account they differ by a factor of about seven. Equal to `ceiling` once the ramp is over, and `null` wherever `ceiling` is null. The account's ramp, its factor and the triggers behind it are on GET /v1/{account_id}/safety-policy as `warm_up`. */
27862
27862
  effective_ceiling?: number | null;
27863
+ /** @description What a call through the matching ELEVATED interface is held to on this row: the `/v1/{account_id}/sales-navigator/...` and `/v1/{account_id}/recruiter/...` operations. Null when this row and limit profile have no such figure, which is every row on `basic` and `premium` and most rows everywhere. Everything else on this row (`ceiling`, `effective_ceiling`, `band` and `over_default`) is the STANDARD-interface figure, because one counter serves both interfaces and the standard side is the conservative one to band against. The consequence is worth reading: on a `sales_navigator` or `recruiter` account a row can report `band: "over"` with `posture: "enforce"` while a call through the elevated interface still succeeds; the refusal the band predicts is the one a standard call gets. */
27864
+ interface_ceiling?: number | null;
27865
+ /** @description `interface_ceiling` with the account's warm-up ramp applied, and null wherever `interface_ceiling` is null. Read THIS to know where an elevated-interface call stops, for the same reason `effective_ceiling` rather than `ceiling` answers that for a standard one. */
27866
+ effective_interface_ceiling?: number | null;
27863
27867
  /**
27864
27868
  * @description Where `used` sits against this row's own bands. `green` routine, `amber` at or past the routine band, `hard` at or past the warn-louder band, `over` at or past the ceiling. `over` is what `posture` acts on: `warn` reports it and lets the action through, `enforce` refuses. A row with no figures reports `green` at every value, because there is nothing to be past.
27865
27869
  * @enum {string}
@@ -29653,7 +29657,7 @@ export interface operations {
29653
29657
  value: string;
29654
29658
  }[];
29655
29659
  /** @description Messaging events to subscribe to (default: [message.received]) */
29656
- events?: ("message.received" | "message.delivered" | "message.read" | "message.reaction" | "message.edited" | "message.deleted" | "chat.updated" | "chat.deleted")[];
29660
+ events?: ("message.received" | "message.read" | "message.reaction" | "message.edited" | "message.deleted" | "chat.updated" | "chat.deleted")[];
29657
29661
  /**
29658
29662
  * @description Field-remapping keys for the messaging delivery payload
29659
29663
  * @default []
@@ -30331,7 +30335,7 @@ export interface operations {
30331
30335
  /** @description The account this policy governs. */
30332
30336
  account_id?: string;
30333
30337
  /**
30334
- * @description Which set of Curviate defaults every row below is resolved from. Each profile inherits the one before it and raises a few rows: `premium` adds a daily invitation band and open-profile InMail, `sales_navigator` raises profile views and search, `recruiter` raises profile views again. This is the platform product active on the account, not the Curviate seat entitlement. The two can disagree, and this is the one that governs the numbers. The elevated Sales Navigator and Recruiter figures apply only to calls made through the matching interface, the `/v1/{account_id}/sales-navigator/...` and `/v1/{account_id}/recruiter/...` operations. A standard-interface call still lives under the `basic` or `premium` figure for its row, and Curviate does not yet track that difference: on a non-`basic` profile the numbers here are the headroom of the elevated interface, not of every call, so read them as an upper bound rather than as your budget for a standard call.
30338
+ * @description Which set of Curviate defaults every row below is resolved from. Each profile inherits the one before it and raises a few rows: `premium` adds a daily invitation band and open-profile InMail, `sales_navigator` raises profile views and search, `recruiter` raises profile views again. This is the platform product active on the account, not the Curviate seat entitlement. The two can disagree, and this is the one that governs the numbers. The elevated Sales Navigator and Recruiter figures apply only to calls made through the matching interface, the `/v1/{account_id}/sales-navigator/...` and `/v1/{account_id}/recruiter/...` operations, and Curviate holds each call to the figure for the interface it goes through. The numbers here are therefore the ones a standard-interface call is held to, on every profile; a call through one of those operations resolves from the elevated set instead, and each row publishes that figure as `interface_ceiling`.
30335
30339
  * @enum {string}
30336
30340
  */
30337
30341
  limit_profile?: "basic" | "premium" | "sales_navigator" | "recruiter";
@@ -30414,7 +30418,7 @@ export interface operations {
30414
30418
  /** @description IANA zone name the activity window is read in. Null disables the window entirely. */
30415
30419
  activity_window_timezone?: string | null;
30416
30420
  /**
30417
- * @description What the activity window governs. `writes` (the default) covers live writes to LinkedIn; `all` widens it to live reads as well, which is the setting for a persona that should not be seen browsing at 03:00. It is broader than it sounds: `all` covers every live read, including the ones about the account itself, so a nightly analytics or invitation-backlog poll is refused at 03:00 too. Stored reads and inbound events are never subject to the window under either setting, at any hour.
30421
+ * @description What the activity window governs. `writes` (the default) covers live writes to LinkedIn; `all` widens it to live reads as well, which is the setting for a persona that should not be seen browsing at 03:00. It is broader than it sounds: `all` covers every live read, including the ones about the account itself, so a nightly analytics or invitation-backlog poll is refused at 03:00 too. A read Curviate answers from its own store never reaches LinkedIn, so it is never subject to the window under either setting, at any hour; the same read IS covered when the store cannot answer it, or when you ask for it live. Inbound events are never subject to it either.
30418
30422
  * @enum {string}
30419
30423
  */
30420
30424
  activity_window_applies_to?: "writes" | "all";
@@ -30438,7 +30442,11 @@ export interface operations {
30438
30442
  source_class?: "substrate" | "linkedin_official" | "practitioner" | "inferred" | "unseeded";
30439
30443
  /** @description What this row is ACTUALLY held to right now: `ceiling` with the account's warm-up ramp applied. Read this one, not `ceiling`, to know where the next call will be stopped. On an account in warm-up the two differ, and on a five-day-old account they differ by a factor of about seven. Null when the row has no ceiling to ramp. `warm_up_state` and `warm_up_factor` beside it are the values ACTIVE on this row, not the seeded ones. */
30440
30444
  effective_ceiling?: number | null;
30441
- /** @description Empty when nothing on this row is above default. */
30445
+ /** @description What a call through the matching ELEVATED interface is held to on this row: the `/v1/{account_id}/sales-navigator/...` and `/v1/{account_id}/recruiter/...` operations. Null when this row and limit profile have no such figure, which is every row on `basic` and `premium` and most rows everywhere. Everything else on this row (`ceiling`, `effective_ceiling`, `band` and `over_default`) is the STANDARD-interface figure, because one counter serves both interfaces and the standard side is the conservative one to band against. The consequence is worth reading: on a `sales_navigator` or `recruiter` account a row can report `band: "over"` with `posture: "enforce"` while a call through the elevated interface still succeeds; the refusal the band predicts is the one a standard call gets. */
30446
+ interface_ceiling?: number | null;
30447
+ /** @description `interface_ceiling` with the account's warm-up ramp applied, and null wherever `interface_ceiling` is null. Read THIS to know where an elevated-interface call stops, for the same reason `effective_ceiling` rather than `ceiling` answers that for a standard one. */
30448
+ effective_interface_ceiling?: number | null;
30449
+ /** @description Empty when nothing on this row is above default. Computed against the STANDARD-interface default, like `band` and for the same reason. */
30442
30450
  over_default?: {
30443
30451
  /**
30444
30452
  * @description The field whose configured value is above default.
@@ -30497,7 +30505,7 @@ export interface operations {
30497
30505
  content: {
30498
30506
  "application/json": {
30499
30507
  /**
30500
- * @description Which set of Curviate defaults this account's rows resolve from: `basic`, `premium`, `sales_navigator` or `recruiter`. Each inherits the one before it and raises a few rows. This is the platform product active on the account, NOT the Curviate seat entitlement, and the two can disagree: a lapsed subscription leaves the seat untouched. Automatic detection at connect is not built yet, so setting this is currently the only way an account leaves `basic`; set it back to `basic` to undo. The change is recorded in the ledger and it moves the defaults under every row at once, so any row you have configured explicitly keeps your value. The elevated Sales Navigator and Recruiter figures apply only to calls made through the matching interface, the `/v1/{account_id}/sales-navigator/...` and `/v1/{account_id}/recruiter/...` operations. A standard-interface call still lives under the `basic` or `premium` figure for its row, and Curviate does not yet track that difference: on a non-`basic` profile the numbers here are the headroom of the elevated interface, not of every call, so read them as an upper bound rather than as your budget for a standard call.
30508
+ * @description Which set of Curviate defaults this account's rows resolve from: `basic`, `premium`, `sales_navigator` or `recruiter`. Each inherits the one before it and raises a few rows. This is the platform product active on the account, NOT the Curviate seat entitlement, and the two can disagree: a lapsed subscription leaves the seat untouched. Curviate detects it from the platform when the account connects and re-detects it on every reconnect; setting it here is an operator override of that result and holds until the next connect. Set it back to `basic` to undo. The change is recorded in the ledger and it moves the defaults under every row at once, so any row you have configured explicitly keeps your value. The elevated Sales Navigator and Recruiter figures apply only to calls made through the matching interface, the `/v1/{account_id}/sales-navigator/...` and `/v1/{account_id}/recruiter/...` operations, and Curviate holds each call to the figure for the interface it goes through. The numbers here are therefore the ones a standard-interface call is held to, on every profile; a call through one of those operations resolves from the elevated set instead, and each row publishes that figure as `interface_ceiling`.
30501
30509
  * @enum {string}
30502
30510
  */
30503
30511
  limit_profile?: "basic" | "premium" | "sales_navigator" | "recruiter";
@@ -30547,7 +30555,7 @@ export interface operations {
30547
30555
  /** @description IANA zone name the activity window is read in, e.g. `Europe/Berlin`. Must be a real zone; anything else is a 400. Null DISABLES the activity window: a guessed zone inverts it, which is worse than not having one. */
30548
30556
  activity_window_timezone?: string | null;
30549
30557
  /**
30550
- * @description What the activity window governs. `writes` (the default) covers live writes to LinkedIn; `all` widens it to live reads that Curviate cannot serve from its store; a read it may serve from the store (a profile by key, for one) stays exempt. Stored reads and inbound events are never subject to the window under either setting, at any hour.
30558
+ * @description What the activity window governs. `writes` (the default) covers live writes to LinkedIn; `all` widens it to live reads. A read Curviate answers from its own store never reaches LinkedIn and so is never covered; the same read IS covered when the store cannot answer it, or when you ask for it live. Stored reads and inbound events are never subject to the window under either setting, at any hour.
30551
30559
  * @enum {string|null}
30552
30560
  */
30553
30561
  activity_window_applies_to?: "writes" | "all" | null;
@@ -30571,6 +30579,10 @@ export interface operations {
30571
30579
  source_class?: "substrate" | "linkedin_official" | "practitioner" | "inferred" | "unseeded" | null;
30572
30580
  /** @description READ-ONLY. `ceiling` with the account's warm-up ramp applied, which is what this row is actually held to. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
30573
30581
  effective_ceiling?: unknown;
30582
+ /** @description READ-ONLY. What a call through the matching elevated interface (`/v1/{account_id}/sales-navigator/...`, `/v1/{account_id}/recruiter/...`) is held to on this row, or null when this row and limit profile have no such figure. `ceiling`, `effective_ceiling`, `band` and `over_default` are all the STANDARD-interface figure, so on a `sales_navigator` or `recruiter` account a row can report `over` while a call through the elevated interface still succeeds. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
30583
+ interface_ceiling?: unknown;
30584
+ /** @description READ-ONLY. `interface_ceiling` with the account's warm-up ramp applied. Read THIS to know where an elevated-interface call stops, for the same reason `effective_ceiling` and not `ceiling` answers that for a standard one. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
30585
+ effective_interface_ceiling?: unknown;
30574
30586
  /** @description READ-ONLY. Which scope supplied this row's effective `posture`. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
30575
30587
  posture_source?: unknown;
30576
30588
  /** @description READ-ONLY. The fields on this row configured above the Curviate default. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
@@ -30586,6 +30598,8 @@ export interface operations {
30586
30598
  posture_source?: unknown;
30587
30599
  /** @description READ-ONLY. The account's DERIVED warm-up ramp, recomputed on every read. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
30588
30600
  warm_up?: unknown;
30601
+ /** @description NOT ACCEPTED. Send its settable subfields instead: the top-level `timezone`, and per row `activity_window_start`, `activity_window_end`, `activity_window_timezone`, `activity_window_applies_to`. */
30602
+ activity_window?: unknown;
30589
30603
  };
30590
30604
  };
30591
30605
  };
@@ -30607,7 +30621,7 @@ export interface operations {
30607
30621
  /** @description The account this policy governs. */
30608
30622
  account_id?: string;
30609
30623
  /**
30610
- * @description Which set of Curviate defaults every row below is resolved from. Each profile inherits the one before it and raises a few rows: `premium` adds a daily invitation band and open-profile InMail, `sales_navigator` raises profile views and search, `recruiter` raises profile views again. This is the platform product active on the account, not the Curviate seat entitlement. The two can disagree, and this is the one that governs the numbers. The elevated Sales Navigator and Recruiter figures apply only to calls made through the matching interface, the `/v1/{account_id}/sales-navigator/...` and `/v1/{account_id}/recruiter/...` operations. A standard-interface call still lives under the `basic` or `premium` figure for its row, and Curviate does not yet track that difference: on a non-`basic` profile the numbers here are the headroom of the elevated interface, not of every call, so read them as an upper bound rather than as your budget for a standard call.
30624
+ * @description Which set of Curviate defaults every row below is resolved from. Each profile inherits the one before it and raises a few rows: `premium` adds a daily invitation band and open-profile InMail, `sales_navigator` raises profile views and search, `recruiter` raises profile views again. This is the platform product active on the account, not the Curviate seat entitlement. The two can disagree, and this is the one that governs the numbers. The elevated Sales Navigator and Recruiter figures apply only to calls made through the matching interface, the `/v1/{account_id}/sales-navigator/...` and `/v1/{account_id}/recruiter/...` operations, and Curviate holds each call to the figure for the interface it goes through. The numbers here are therefore the ones a standard-interface call is held to, on every profile; a call through one of those operations resolves from the elevated set instead, and each row publishes that figure as `interface_ceiling`.
30611
30625
  * @enum {string}
30612
30626
  */
30613
30627
  limit_profile?: "basic" | "premium" | "sales_navigator" | "recruiter";
@@ -30690,7 +30704,7 @@ export interface operations {
30690
30704
  /** @description IANA zone name the activity window is read in. Null disables the window entirely. */
30691
30705
  activity_window_timezone?: string | null;
30692
30706
  /**
30693
- * @description What the activity window governs. `writes` (the default) covers live writes to LinkedIn; `all` widens it to live reads as well, which is the setting for a persona that should not be seen browsing at 03:00. It is broader than it sounds: `all` covers every live read, including the ones about the account itself, so a nightly analytics or invitation-backlog poll is refused at 03:00 too. Stored reads and inbound events are never subject to the window under either setting, at any hour.
30707
+ * @description What the activity window governs. `writes` (the default) covers live writes to LinkedIn; `all` widens it to live reads as well, which is the setting for a persona that should not be seen browsing at 03:00. It is broader than it sounds: `all` covers every live read, including the ones about the account itself, so a nightly analytics or invitation-backlog poll is refused at 03:00 too. A read Curviate answers from its own store never reaches LinkedIn, so it is never subject to the window under either setting, at any hour; the same read IS covered when the store cannot answer it, or when you ask for it live. Inbound events are never subject to it either.
30694
30708
  * @enum {string}
30695
30709
  */
30696
30710
  activity_window_applies_to?: "writes" | "all";
@@ -30714,7 +30728,11 @@ export interface operations {
30714
30728
  source_class?: "substrate" | "linkedin_official" | "practitioner" | "inferred" | "unseeded";
30715
30729
  /** @description What this row is ACTUALLY held to right now: `ceiling` with the account's warm-up ramp applied. Read this one, not `ceiling`, to know where the next call will be stopped. On an account in warm-up the two differ, and on a five-day-old account they differ by a factor of about seven. Null when the row has no ceiling to ramp. `warm_up_state` and `warm_up_factor` beside it are the values ACTIVE on this row, not the seeded ones. */
30716
30730
  effective_ceiling?: number | null;
30717
- /** @description Empty when nothing on this row is above default. */
30731
+ /** @description What a call through the matching ELEVATED interface is held to on this row: the `/v1/{account_id}/sales-navigator/...` and `/v1/{account_id}/recruiter/...` operations. Null when this row and limit profile have no such figure, which is every row on `basic` and `premium` and most rows everywhere. Everything else on this row (`ceiling`, `effective_ceiling`, `band` and `over_default`) is the STANDARD-interface figure, because one counter serves both interfaces and the standard side is the conservative one to band against. The consequence is worth reading: on a `sales_navigator` or `recruiter` account a row can report `band: "over"` with `posture: "enforce"` while a call through the elevated interface still succeeds; the refusal the band predicts is the one a standard call gets. */
30732
+ interface_ceiling?: number | null;
30733
+ /** @description `interface_ceiling` with the account's warm-up ramp applied, and null wherever `interface_ceiling` is null. Read THIS to know where an elevated-interface call stops, for the same reason `effective_ceiling` rather than `ceiling` answers that for a standard one. */
30734
+ effective_interface_ceiling?: number | null;
30735
+ /** @description Empty when nothing on this row is above default. Computed against the STANDARD-interface default, like `band` and for the same reason. */
30718
30736
  over_default?: {
30719
30737
  /**
30720
30738
  * @description The field whose configured value is above default.
@@ -30824,15 +30842,15 @@ export interface operations {
30824
30842
  /** @description The event's id. Also the value encoded in the next page's cursor. */
30825
30843
  id: string;
30826
30844
  /**
30827
- * @description The budget row that breached. It is not always a row the call itself spends: an invitation refused because the outstanding backlog is at its ceiling reports `pending_invites`, which is the thing that breached.
30845
+ * @description The budget row that breached. It is not always a row the call itself spends: an invitation refused because the outstanding backlog is at its ceiling reports `pending_invites`, which is the thing that breached. `*` means the event was not about a row at all: the activity window closing on an action that spends no budget of its own, such as editing a message or a Recruiter admin action. The `budget_row` filter accepts real row names only, so page without it to see those.
30828
30846
  * @enum {string}
30829
30847
  */
30830
- budget_row: "connection_requests_with_note" | "connection_requests_no_note" | "messages_first_degree" | "inmail" | "open_profile_inmail" | "profile_views" | "search" | "comments" | "post_likes" | "follows" | "content_poll" | "job_poll" | "posts" | "endorsements" | "invite_responses" | "withdrawal_sweep" | "total_actions" | "pending_invites";
30848
+ budget_row: "connection_requests_with_note" | "connection_requests_no_note" | "messages_first_degree" | "inmail" | "open_profile_inmail" | "profile_views" | "search" | "comments" | "post_likes" | "follows" | "content_poll" | "job_poll" | "posts" | "endorsements" | "invite_responses" | "withdrawal_sweep" | "total_actions" | "pending_invites" | "*";
30831
30849
  /**
30832
- * @description Why it was flagged. `budget_exhausted`: the account reached the ceiling configured for that row, which you can raise on the safety policy. `rate_limited`: the platform itself refused this account on that row recently and Curviate is holding the row until the pause expires, which no configuration change lifts.
30850
+ * @description Which rule flagged it, and each one calls for a different response. `budget_exhausted`: the account reached the ceiling configured for that row, which you can raise on the safety policy. `activity_window`: the account was acting outside its configured activity window, so no ceiling was the constraint. Wait for the window to open, move `activity_window_start` or `activity_window_end`, or check `activity_window_timezone` is the zone you meant. `rate_limited`: the platform itself refused this account on that row recently and Curviate is holding the row until the pause expires, which no configuration change lifts.
30833
30851
  * @enum {string}
30834
30852
  */
30835
- reason: "budget_exhausted" | "rate_limited";
30853
+ reason: "budget_exhausted" | "activity_window" | "rate_limited";
30836
30854
  /** @description Whether the action was stopped. `false` is a warning: the action went through, and this record is the only lasting trace that it crossed a limit. Under the default `warn` posture every event is a warning, which is what makes reading this surface the point of running it. */
30837
30855
  blocked: boolean;
30838
30856
  /** @description The operation the caller was running when it breached. */