@curviate/sdk 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -847,7 +847,7 @@ interface paths {
847
847
  put?: never;
848
848
  /**
849
849
  * Start a chat
850
- * @description Starts a new chat with one or more members from a connected account. Send application/json; attach files as base64-encoded attachments (max 5 MiB per file, and 9 MiB for the whole request body; base64 makes a file about a third larger in the body than on disk). Message content passes through to the platform and is never stored. Company pages are reply-only and cannot start a conversation; reply using a `COMPANY_` chat id from GET /v1/{account_id}/inboxes/{inbox_id}/chats instead.
850
+ * @description Starts a new chat with one or more members from a connected account. Send application/json; attach files as base64-encoded attachments (max 5 MiB per file, and 9 MiB for the whole request body; base64 makes a file about a third larger in the body than on disk). This call keeps nothing and logs nothing. Once sent it is a message in the account's inbox, so reading that conversation back through Curviate stores its body in your tenant's inbox records, with no expiry. Company pages are reply-only and cannot start a conversation; reply using a `COMPANY_` chat id from GET /v1/{account_id}/inboxes/{inbox_id}/chats instead.
851
851
  */
852
852
  post: operations["postV1AccountIdChats"];
853
853
  delete?: never;
@@ -895,7 +895,7 @@ interface paths {
895
895
  put?: never;
896
896
  /**
897
897
  * Send a message
898
- * @description Sends a message into an existing chat. Send application/json with text, base64 attachments (max 5 MiB per file, and 9 MiB for the whole request body; base64 makes a file about a third larger in the body than on disk), or both; at least one of text or attachments is required. Message content passes through to the platform and is never stored. Sending on behalf of a company page: use a COMPANY_ chat id (from GET /v1/{account_id}/inboxes/{inbox_id}/chats) and the message sends AS THE PAGE, no separate parameter needed. The response's sent_as field names the acting identity that was actually used. Company pages are reply-only: this endpoint can answer an existing conversation on a page's behalf, but a page can never start a new one.
898
+ * @description Sends a message into an existing chat. Send application/json with text, base64 attachments (max 5 MiB per file, and 9 MiB for the whole request body; base64 makes a file about a third larger in the body than on disk), or both; at least one of text or attachments is required. This call keeps nothing and logs nothing. Once sent it is a message in the account's inbox, so reading that conversation back through Curviate stores its body in your tenant's inbox records, with no expiry. Sending on behalf of a company page: use a COMPANY_ chat id (from GET /v1/{account_id}/inboxes/{inbox_id}/chats) and the message sends AS THE PAGE, no separate parameter needed. The response's sent_as field names the acting identity that was actually used. Company pages are reply-only: this endpoint can answer an existing conversation on a page's behalf, but a page can never start a new one.
899
899
  */
900
900
  post: operations["postV1AccountIdChatsChatIdMessages"];
901
901
  delete?: never;
@@ -2398,6 +2398,26 @@ interface paths {
2398
2398
  patch: operations["patchV1AccountsAccountId"];
2399
2399
  trace?: never;
2400
2400
  };
2401
+ "/v1/accounts/seats": {
2402
+ parameters: {
2403
+ query?: never;
2404
+ header?: never;
2405
+ path?: never;
2406
+ cookie?: never;
2407
+ };
2408
+ /**
2409
+ * List seats
2410
+ * @description List the workspace's seats: each `seat_id`, whether an account occupies it, and that `account_id`. Pass an unoccupied `seat_id` to POST /v1/auth/intent to connect a new account. Every unoccupied seat listed is a valid connect target. Not paginated.
2411
+ */
2412
+ get: operations["getV1AccountsSeats"];
2413
+ put?: never;
2414
+ post?: never;
2415
+ delete?: never;
2416
+ options?: never;
2417
+ head?: never;
2418
+ patch?: never;
2419
+ trace?: never;
2420
+ };
2401
2421
  "/v1/auth/intent": {
2402
2422
  parameters: {
2403
2423
  query?: never;
@@ -2409,7 +2429,7 @@ interface paths {
2409
2429
  put?: never;
2410
2430
  /**
2411
2431
  * Start a credential/cookie authentication
2412
- * @description Authenticate a LinkedIn account directly with credentials or a session cookie. The credential fields are NESTED, not top level: `auth_method: "credentials"` reads `credentials: { email, password }`, and `auth_method: "cookie"` reads `cookie: { li_at }` plus a top-level `user_agent`. Omit `account_id` to connect a NEW account into an empty `seat_id` (every seat id is listed with click-to-copy in the seat table on your dashboard); include `account_id` (in the body) to re-authenticate an EXISTING account in place. Returns the account on success (201 new / 200 reconnect), or a checkpoint challenge (202) carrying the account_id when LinkedIn requires verification. Complete the challenge with POST /v1/auth/checkpoint/solve (codes) or POST /v1/auth/checkpoint/poll (mobile-app approval). Connection scope (which LinkedIn products are enabled) is not something you list: the connection asks for every product and LinkedIn activates the ones the account actually has. The recorded scope is readable as `requested_products` on the account. One LinkedIn account can hold only one of the two premium surfaces, and when both are asked for Sales Navigator takes precedence, so pass the optional `linkedin_premium` (`sales_navigator` or `recruiter`) if the account holds both and you want the other one. Omit it and nothing is narrowed. It applies per connection and is not remembered, so state it on every connect and reconnect where Recruiter must win. A reconnect that changes scope must use credentials (a saved cookie cannot change scope), which includes any reconnect of an account connected before the full product set became the default. Pin a managed proxy with the optional `country`/`ip` or supply a `proxy` to override it.
2432
+ * @description Authenticate a LinkedIn account directly with credentials or a session cookie. The credential fields are NESTED, not top level: `auth_method: "credentials"` reads `credentials: { email, password }`, and `auth_method: "cookie"` reads `cookie: { li_at }` plus a top-level `user_agent`. Omit `account_id` to connect a NEW account into an empty `seat_id` (list your seats with GET /v1/accounts/seats, or copy a seat id from the seat table on your dashboard); include `account_id` (in the body) to re-authenticate an EXISTING account in place. Returns the account on success (201 new / 200 reconnect), or a checkpoint challenge (202) carrying the account_id when LinkedIn requires verification. Complete the challenge with POST /v1/auth/checkpoint/solve (codes) or POST /v1/auth/checkpoint/poll (mobile-app approval). Connection scope (which LinkedIn products are enabled) is not something you list: the connection asks for every product and LinkedIn activates the ones the account actually has. The recorded scope is readable as `requested_products` on the account. One LinkedIn account can hold only one of the two premium surfaces, and when both are asked for Sales Navigator takes precedence, so pass the optional `linkedin_premium` (`sales_navigator` or `recruiter`) if the account holds both and you want the other one. Omit it and nothing is narrowed. It applies per connection and is not remembered, so state it on every connect and reconnect where Recruiter must win. A reconnect that changes scope must use credentials (a saved cookie cannot change scope), which includes any reconnect of an account connected before the full product set became the default. Pin a managed proxy with the optional `country`/`ip` or supply a `proxy` to override it.
2413
2433
  */
2414
2434
  post: operations["postV1AuthIntent"];
2415
2435
  delete?: never;
@@ -2679,7 +2699,7 @@ interface paths {
2679
2699
  };
2680
2700
  /**
2681
2701
  * Read an account's safety policy
2682
- * @description Returns every configurable safety field for every budget row of one account, in a single response: the ceiling, the green and amber bands, the counting window, the enforcement posture and where it was inherited from, the activity window, warm-up state, the per-row character caps and search per-query cap, and how well calibrated each row's number is. Every value is seeded configuration and every one of them is settable. Where a configured value is above the Curviate default, the row carries an `over_default` entry naming the value, the default and the source class of that default. The response also carries `tenant_default_posture`, the workspace-wide default every account inherits, separately from this account's own effective `posture`, and `limit_profile`, which says which of the four Curviate default sets (`basic`, `premium`, `sales_navigator`, `recruiter`) every row below was resolved from, detected from the platform when the account connected.
2702
+ * @description Returns every configurable safety field for every budget row of one account, in a single response: the ceiling, the green and amber bands, the counting window, the enforcement posture and where it was inherited from, the activity window, warm-up state, the per-row character caps and search per-query cap, and how well calibrated each row's number is. Every value is seeded configuration and every one of them is settable. Each value is this account's own where it set one, otherwise the tenant default for its `limit_profile` (`GET /v1/safety-policy`), otherwise the Curviate default. Where a configured value is above the Curviate default, the row carries an `over_default` entry naming the value, the default and the source class of that default. The response also carries `tenant_default_posture`, the workspace-wide default every account inherits, separately from this account's own effective `posture`, and `limit_profile`, which says which of the four Curviate default sets (`basic`, `premium`, `sales_navigator`, `recruiter`) every row below was resolved from, detected from the platform when the account connected.
2683
2703
  */
2684
2704
  get: operations["getV1AccountIdSafetyPolicy"];
2685
2705
  put?: never;
@@ -2689,7 +2709,7 @@ interface paths {
2689
2709
  head?: never;
2690
2710
  /**
2691
2711
  * Update an account's safety policy
2692
- * @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. One field on this operation does not configure anything: `clear_halts` lifts the platform pause on the action types you name. When the platform refuses a call on an account, Curviate pauses that action type for the platform's own retry-after or a seeded cooldown, and every later call on it is refused locally without reaching the platform; the account resource reports the live pauses as `quotas[].halt`. Naming an action type here lifts its pause immediately, so the next call goes out. An action type with no active pause is accepted and does nothing, which makes it safe to send for a set you have not checked, and only the ones actually lifted are ledgered, each with the expiry it cut short, the actor and the time, readable afterwards on `GET /v1/{account_id}/safety-events` with `reason: "halt_cleared"`. Clearing disarms nothing: if the platform refuses the account again the pause returns, and a 429 or a refused write returns it for the full cooldown. Clear one when you have reason to believe the refusal was a transient upstream fault rather than the platform pushing back on this account.
2712
+ * @description The account-level safety-policy write (tenant-wide defaults are set on `PATCH /v1/safety-policy`). 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 tenant default where one is set, the Curviate default otherwise. 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. One field on this operation does not configure anything: `clear_halts` lifts the platform pause on the action types you name. When the platform refuses a call on an account, Curviate pauses that action type for the platform's own retry-after or a seeded cooldown, and every later call on it is refused locally without reaching the platform; the account resource reports the live pauses as `quotas[].halt`. Naming an action type here lifts its pause immediately, so the next call goes out. An action type with no active pause is accepted and does nothing, which makes it safe to send for a set you have not checked, and only the ones actually lifted are ledgered, each with the expiry it cut short, the actor and the time, readable afterwards on `GET /v1/{account_id}/safety-events` with `reason: "halt_cleared"`. Clearing disarms nothing: if the platform refuses the account again the pause returns, and a 429 or a refused write returns it for the full cooldown. Clear one when you have reason to believe the refusal was a transient upstream fault rather than the platform pushing back on this account.
2693
2713
  */
2694
2714
  patch: operations["patchV1AccountIdSafetyPolicy"];
2695
2715
  trace?: never;
@@ -2714,6 +2734,30 @@ interface paths {
2714
2734
  patch?: never;
2715
2735
  trace?: never;
2716
2736
  };
2737
+ "/v1/safety-policy": {
2738
+ parameters: {
2739
+ query?: never;
2740
+ header?: never;
2741
+ path?: never;
2742
+ cookie?: never;
2743
+ };
2744
+ /**
2745
+ * Read the tenant safety defaults
2746
+ * @description Returns the tenant-wide safety defaults, per limit profile and per budget row: the values every account on that profile resolves from unless it sets its own. A value nobody has set here is the Curviate default, and a value set above the Curviate default carries an `over_default` entry naming the value, the default and its source class. Also carries `tenant_default_posture`. Works with no accounts connected, so defaults can be in place before the first one is.
2747
+ */
2748
+ get: operations["getV1SafetyPolicy"];
2749
+ put?: never;
2750
+ post?: never;
2751
+ delete?: never;
2752
+ options?: never;
2753
+ head?: never;
2754
+ /**
2755
+ * Update the tenant safety defaults
2756
+ * @description The tenant-level safety-policy write. Sets defaults per limit profile and per budget row; every account on that profile resolves from them unless it overrides the same field itself, including accounts connected later. THIS CHANGES EVERY ACCOUNT IN THE TENANT THAT HAS NOT OVERRIDDEN THE FIELD, and it applies immediately: under `enforce` posture, lowering a default can start refusing actions across the tenant in one request. The response carries `impact`: how many accounts had a ceiling change, and how many moved into `over`, measured on those accounts before and after the write. Send only what you are changing; `null` clears a default back to the Curviate default. A value equal to the one already in force is not stored and not recorded. Any limit may be set to any value, and a value above the Curviate default is reported rather than refused. Every change is appended to the ledger with the previous value, the new value, the Curviate default, the actor and the time. Per-row posture is not a tenant default: use `tenant_default_posture` here, or `posture` on an account's own policy. Per-account values are set on `PATCH /v1/{account_id}/safety-policy`.
2757
+ */
2758
+ patch: operations["patchV1SafetyPolicy"];
2759
+ trace?: never;
2760
+ };
2717
2761
  }
2718
2762
  interface components {
2719
2763
  schemas: {
@@ -2841,7 +2885,7 @@ interface components {
2841
2885
  chat_id?: string;
2842
2886
  /** @description Identifier of the sender. */
2843
2887
  sender_id?: string;
2844
- /** @description Full message text (content pass-through, never stored). */
2888
+ /** @description Full message text. Curviate does not keep it on the way out; reading a conversation back stores its message bodies in your tenant's inbox records, with no expiry. */
2845
2889
  text?: string | null;
2846
2890
  /** @description Attachment descriptors (no bytes, use the attachment endpoint to download). */
2847
2891
  attachments?: {
@@ -2876,6 +2920,11 @@ interface components {
2876
2920
  reaction_count?: number;
2877
2921
  /** @description The platform this message originates from. */
2878
2922
  provider?: string;
2923
+ /** @description Platform-specific detail on the message. Carries `subject` for an InMail, which is set on the thread's opening message; absent or empty for an ordinary message. */
2924
+ specifics?: {
2925
+ /** @description The InMail subject line, when the platform carries one on this message. Ordinary messages have none. Reading a conversation back stores the subject in your tenant's inbox records alongside the body, with no expiry. */
2926
+ subject?: string | null;
2927
+ };
2879
2928
  /** @description The sender's profile, when the platform returned one alongside the message. sender_id always carries the identifier; this object carries the rest of what is known about that person. */
2880
2929
  sender?: {
2881
2930
  /** @description Identifier of the counterpart. */
@@ -10292,7 +10341,7 @@ interface operations {
10292
10341
  last_message_timestamp?: string;
10293
10342
  /** @description Identifier of the 1:1 counterpart. */
10294
10343
  user_id?: string;
10295
- /** @description The most recent message in the chat. */
10344
+ /** @description The most recent message in the chat. Subjects are not previewed here, read the chat's messages for one. */
10296
10345
  last_message?: {
10297
10346
  /**
10298
10347
  * @description Response type discriminator.
@@ -10308,7 +10357,7 @@ interface operations {
10308
10357
  chat_id?: string;
10309
10358
  /** @description Identifier of the sender. */
10310
10359
  sender_id?: string;
10311
- /** @description Full message text (content pass-through, never stored). */
10360
+ /** @description Full message text. Curviate does not keep it on the way out; reading a conversation back stores its message bodies in your tenant's inbox records, with no expiry. */
10312
10361
  text?: string | null;
10313
10362
  /** @description Attachment descriptors (no bytes, use the attachment endpoint to download). */
10314
10363
  attachments?: {
@@ -10717,7 +10766,7 @@ interface operations {
10717
10766
  last_message_timestamp?: string;
10718
10767
  /** @description Identifier of the 1:1 counterpart. */
10719
10768
  user_id?: string;
10720
- /** @description The most recent message in the chat. */
10769
+ /** @description The most recent message in the chat. Subjects are not previewed here, read the chat's messages for one. */
10721
10770
  last_message?: {
10722
10771
  /**
10723
10772
  * @description Response type discriminator.
@@ -10733,7 +10782,7 @@ interface operations {
10733
10782
  chat_id?: string;
10734
10783
  /** @description Identifier of the sender. */
10735
10784
  sender_id?: string;
10736
- /** @description Full message text (content pass-through, never stored). */
10785
+ /** @description Full message text. Curviate does not keep it on the way out; reading a conversation back stores its message bodies in your tenant's inbox records, with no expiry. */
10737
10786
  text?: string | null;
10738
10787
  /** @description Attachment descriptors (no bytes, use the attachment endpoint to download). */
10739
10788
  attachments?: {
@@ -11103,7 +11152,7 @@ interface operations {
11103
11152
  chat_id?: string;
11104
11153
  /** @description Identifier of the sender. */
11105
11154
  sender_id?: string;
11106
- /** @description Full message text (content pass-through, never stored). */
11155
+ /** @description Full message text. Curviate does not keep it on the way out; reading a conversation back stores its message bodies in your tenant's inbox records, with no expiry. */
11107
11156
  text?: string | null;
11108
11157
  /** @description Attachment descriptors (no bytes, use the attachment endpoint to download). */
11109
11158
  attachments?: {
@@ -11138,6 +11187,11 @@ interface operations {
11138
11187
  reaction_count?: number;
11139
11188
  /** @description The platform this message originates from. */
11140
11189
  provider?: string;
11190
+ /** @description Platform-specific detail on the message. Carries `subject` for an InMail, which is set on the thread's opening message; absent or empty for an ordinary message. */
11191
+ specifics?: {
11192
+ /** @description The InMail subject line, when the platform carries one on this message. Ordinary messages have none. Reading a conversation back stores the subject in your tenant's inbox records alongside the body, with no expiry. */
11193
+ subject?: string | null;
11194
+ };
11141
11195
  /** @description The sender's profile, when the platform returned one alongside the message. sender_id always carries the identifier; this object carries the rest of what is known about that person. */
11142
11196
  sender?: {
11143
11197
  /** @description Identifier of the counterpart. */
@@ -11482,7 +11536,7 @@ interface operations {
11482
11536
  chat_id?: string;
11483
11537
  /** @description Identifier of the sender. */
11484
11538
  sender_id?: string;
11485
- /** @description Full message text (content pass-through, never stored). */
11539
+ /** @description Full message text. Curviate does not keep it on the way out; reading a conversation back stores its message bodies in your tenant's inbox records, with no expiry. */
11486
11540
  text?: string | null;
11487
11541
  /** @description Attachment descriptors (no bytes, use the attachment endpoint to download). */
11488
11542
  attachments?: {
@@ -11517,6 +11571,11 @@ interface operations {
11517
11571
  reaction_count?: number;
11518
11572
  /** @description The platform this message originates from. */
11519
11573
  provider?: string;
11574
+ /** @description Platform-specific detail on the message. Carries `subject` for an InMail, which is set on the thread's opening message; absent or empty for an ordinary message. */
11575
+ specifics?: {
11576
+ /** @description The InMail subject line, when the platform carries one on this message. Ordinary messages have none. Reading a conversation back stores the subject in your tenant's inbox records alongside the body, with no expiry. */
11577
+ subject?: string | null;
11578
+ };
11520
11579
  /** @description The sender's profile, when the platform returned one alongside the message. sender_id always carries the identifier; this object carries the rest of what is known about that person. */
11521
11580
  sender?: {
11522
11581
  /** @description Identifier of the counterpart. */
@@ -12174,7 +12233,7 @@ interface operations {
12174
12233
  id?: string;
12175
12234
  /** @description Account id that owns this message. */
12176
12235
  account_id?: string;
12177
- /** @description Full message text (content pass-through, never stored). */
12236
+ /** @description Full message text. Curviate does not keep it on the way out; reading a conversation back stores its message bodies in your tenant's inbox records, with no expiry. */
12178
12237
  text?: string | null;
12179
12238
  /** @description Identifier of the sender. */
12180
12239
  sender_id?: string;
@@ -12313,7 +12372,7 @@ interface operations {
12313
12372
  recipient_urn: string;
12314
12373
  /** @description InMail subject line (1-200 chars). */
12315
12374
  subject: string;
12316
- /** @description InMail body text (1-8000 chars). */
12375
+ /** @description InMail body text (1-8000 chars). This call keeps nothing and logs nothing. Once sent it is a message in the account's InMail inbox, so reading that chat back through Curviate stores its body in your tenant's inbox records, with no expiry. */
12317
12376
  text: string;
12318
12377
  };
12319
12378
  };
@@ -12656,7 +12715,7 @@ interface operations {
12656
12715
  last_message_timestamp?: string;
12657
12716
  /** @description Identifier of the 1:1 counterpart. */
12658
12717
  user_id?: string;
12659
- /** @description The most recent message in the chat. */
12718
+ /** @description The most recent message in the chat. Subjects are not previewed here, read the chat's messages for one. */
12660
12719
  last_message?: {
12661
12720
  /**
12662
12721
  * @description Response type discriminator.
@@ -12672,7 +12731,7 @@ interface operations {
12672
12731
  chat_id?: string;
12673
12732
  /** @description Identifier of the sender. */
12674
12733
  sender_id?: string;
12675
- /** @description Full message text (content pass-through, never stored). */
12734
+ /** @description Full message text. Curviate does not keep it on the way out; reading a conversation back stores its message bodies in your tenant's inbox records, with no expiry. */
12676
12735
  text?: string | null;
12677
12736
  /** @description Attachment descriptors (no bytes, use the attachment endpoint to download). */
12678
12737
  attachments?: {
@@ -17930,7 +17989,7 @@ interface operations {
17930
17989
  "application/json": components["schemas"]["Error"];
17931
17990
  };
17932
17991
  };
17933
- /** @description The résumé is still being generated and was not ready in time. Retry the request shortly. */
17992
+ /** @description LINKEDIN_SERVICE_UNAVAILABLE, the résumé is still being generated and was not ready in time. Retry the request shortly. */
17934
17993
  503: {
17935
17994
  headers: {
17936
17995
  [name: string]: unknown;
@@ -20136,11 +20195,11 @@ interface operations {
20136
20195
  "application/json": {
20137
20196
  /** @description One or more Recruiter member IDs (AE... format) to include in the chat. */
20138
20197
  attendees_ids: string[];
20139
- /** @description Opening message text (1-8000 chars). Passed to the platform and discarded; never stored or logged. */
20198
+ /** @description Opening message text (1-8000 chars). This call keeps nothing and logs nothing. Once sent it is a message in the account's InMail inbox, so reading that chat back through Curviate stores its body in your tenant's inbox records, with no expiry. */
20140
20199
  text: string;
20141
20200
  /** @description Subject line; REQUIRED for Recruiter (InMail-based messaging), unlike the classic surface (<= 200 chars). */
20142
20201
  subject: string;
20143
- /** @description Sender signature; REQUIRED for Recruiter. Not stored or logged. */
20202
+ /** @description Sender signature; REQUIRED for Recruiter. Kept as a field by neither this call nor the log. The platform renders it into the sent message body, which is stored if that chat is later read back through Curviate. */
20144
20203
  signature: string;
20145
20204
  /**
20146
20205
  * @description Visibility of the recruiter chat.
@@ -20159,11 +20218,11 @@ interface operations {
20159
20218
  send_as?: "INMAIL" | "EMAIL";
20160
20219
  /** @description Sourcing channel for tracking purposes (e.g. CAREER_SITE, MANUAL_IMPORT, INTERNAL_CANDIDATES, RECRUITER_SEARCH, REFERRAL; the vendor's own vocabulary is broader than this illustrative set, so any non-empty value is accepted rather than a closed enum). */
20161
20220
  channel_type?: string;
20162
- /** @description Recruiter PRO only: schedule a follow-up message. subject/text are not stored or logged. */
20221
+ /** @description Recruiter PRO only: schedule a follow-up message. subject: This call keeps nothing and logs nothing, and unlike the message body the platform does not render it into what is sent. Once sent it is an InMail in the account's inbox: if a message read surfaces this subject, reading that chat back stores it in your tenant's inbox records like a body, with no expiry. text: This call keeps nothing and logs nothing. Once sent it is a message in the account's InMail inbox, so reading that chat back through Curviate stores its body in your tenant's inbox records, with no expiry. */
20163
20222
  follow_up?: {
20164
- /** @description Follow-up message subject. Not stored or logged. */
20223
+ /** @description Follow-up message subject. This call keeps nothing and logs nothing, and unlike the message body the platform does not render it into what is sent. Once sent it is an InMail in the account's inbox: if a message read surfaces this subject, reading that chat back stores it in your tenant's inbox records like a body, with no expiry. */
20165
20224
  subject: string;
20166
- /** @description Follow-up message body. Not stored or logged. */
20225
+ /** @description Follow-up message body. This call keeps nothing and logs nothing. Once sent it is a message in the account's InMail inbox, so reading that chat back through Curviate stores its body in your tenant's inbox records, with no expiry. */
20167
20226
  text: string;
20168
20227
  /** @description Optional follow-up attachments. */
20169
20228
  attachments?: {
@@ -24806,7 +24865,7 @@ interface operations {
24806
24865
  "application/json": {
24807
24866
  /** @description Sales Navigator member IDs for the chat recipients (>= 1, e.g. ACw...). */
24808
24867
  attendees_ids: string[];
24809
- /** @description Opening message text (1-8000 chars). Not stored or logged. */
24868
+ /** @description Opening message text (1-8000 chars). This call keeps nothing and logs nothing. Once sent it is a message in the account's InMail inbox, so reading that chat back through Curviate stores its body in your tenant's inbox records, with no expiry. */
24810
24869
  text: string;
24811
24870
  /** @description Subject line; REQUIRED for Sales Navigator (InMail-based messaging), unlike the classic surface where it is optional (<= 200 chars). Maps into the SN-only specifics branch. */
24812
24871
  subject: string;
@@ -24910,7 +24969,7 @@ interface operations {
24910
24969
  "application/json": components["schemas"]["Error"];
24911
24970
  };
24912
24971
  };
24913
- /** @description RECIPIENT_UNREACHABLE or ACCOUNT_RESTRICTED, the recipient cannot be messaged or the account is restricted. */
24972
+ /** @description ACCOUNT_RESTRICTED, the connected LinkedIn account cannot perform this operation. */
24914
24973
  422: {
24915
24974
  headers: {
24916
24975
  [name: string]: unknown;
@@ -28333,6 +28392,91 @@ interface operations {
28333
28392
  };
28334
28393
  };
28335
28394
  };
28395
+ getV1AccountsSeats: {
28396
+ parameters: {
28397
+ query?: never;
28398
+ header?: never;
28399
+ path?: never;
28400
+ cookie?: never;
28401
+ };
28402
+ requestBody?: never;
28403
+ responses: {
28404
+ /** @description Every live seat in the workspace with its occupancy. Empty list when the workspace has no seats. */
28405
+ 200: {
28406
+ headers: {
28407
+ "RateLimit-Policy": components["headers"]["RateLimit-Policy"];
28408
+ RateLimit: components["headers"]["RateLimit"];
28409
+ [name: string]: unknown;
28410
+ };
28411
+ content: {
28412
+ "application/json": {
28413
+ /**
28414
+ * @description Response type discriminator.
28415
+ * @enum {string}
28416
+ */
28417
+ object: "seat_list";
28418
+ items: {
28419
+ /** @description The seat ID (`seat_...`). Pass an unoccupied one as `seat_id` when connecting a new account. */
28420
+ seat_id: string;
28421
+ /** @description True when an account is connected on this seat. */
28422
+ occupied: boolean;
28423
+ /** @description The account on this seat, or null when unoccupied. */
28424
+ account_id: string | null;
28425
+ }[];
28426
+ safety_warning?: components["schemas"]["SafetyWarning"];
28427
+ };
28428
+ };
28429
+ };
28430
+ /** @description Missing or invalid API key. */
28431
+ 401: {
28432
+ headers: {
28433
+ [name: string]: unknown;
28434
+ };
28435
+ content: {
28436
+ "application/json": components["schemas"]["Error"];
28437
+ };
28438
+ };
28439
+ /** @description Rate limited, slow down and retry after the hinted delay. */
28440
+ 429: {
28441
+ headers: {
28442
+ "RateLimit-Policy": components["headers"]["RateLimit-Policy"];
28443
+ RateLimit: components["headers"]["RateLimit"];
28444
+ "Retry-After": components["headers"]["Retry-After"];
28445
+ [name: string]: unknown;
28446
+ };
28447
+ content: {
28448
+ "application/json": components["schemas"]["Error"];
28449
+ };
28450
+ };
28451
+ /** @description Internal error. */
28452
+ 500: {
28453
+ headers: {
28454
+ [name: string]: unknown;
28455
+ };
28456
+ content: {
28457
+ "application/json": components["schemas"]["Error"];
28458
+ };
28459
+ };
28460
+ /** @description Service unavailable. */
28461
+ 503: {
28462
+ headers: {
28463
+ [name: string]: unknown;
28464
+ };
28465
+ content: {
28466
+ "application/json": components["schemas"]["Error"];
28467
+ };
28468
+ };
28469
+ /** @description Gateway timeout. */
28470
+ 504: {
28471
+ headers: {
28472
+ [name: string]: unknown;
28473
+ };
28474
+ content: {
28475
+ "application/json": components["schemas"]["Error"];
28476
+ };
28477
+ };
28478
+ };
28479
+ };
28336
28480
  postV1AuthIntent: {
28337
28481
  parameters: {
28338
28482
  query?: never;
@@ -28343,7 +28487,7 @@ interface operations {
28343
28487
  requestBody: {
28344
28488
  content: {
28345
28489
  "application/json": {
28346
- /** @description The empty seat this NEW account will occupy. Required on a new connect; omit it and the call returns 400 INVALID_REQUEST with 'seat_id is required'. Seat ids look like seat_01H..., and every seat you own is listed with click-to-copy in the seat table on your dashboard; any seat showing no attached account is free to use. Ignored when account_id is present, because a reconnect keeps the account on its current seat. */
28490
+ /** @description The empty seat this NEW account will occupy. Required on a new connect; omit it and the call returns 400 INVALID_REQUEST with 'seat_id is required'. Seat ids look like seat_01H..., and every seat you own is listed by GET /v1/accounts/seats (any item with occupied false is free to use) and with click-to-copy in the seat table on your dashboard. Ignored when account_id is present, because a reconnect keeps the account on its current seat. */
28347
28491
  seat_id?: string;
28348
28492
  /**
28349
28493
  * @description How to authenticate. 'credentials' reads the nested `credentials` object (email + password). 'cookie' reads the nested `cookie` object (li_at) and also requires a top-level `user_agent`. Neither set of fields is accepted at the top level.
@@ -28513,7 +28657,7 @@ interface operations {
28513
28657
  "application/json": components["schemas"]["Error"];
28514
28658
  };
28515
28659
  };
28516
- /** @description Payment required, an active subscription / seat is needed. */
28660
+ /** @description Either PAYMENT_REQUIRED (an active subscription / seat is needed; update your payment method or purchase a seat) or ACCOUNT_DISPUTED (the tenant's account is under dispute review; contact support). The code field distinguishes the two. */
28517
28661
  402: {
28518
28662
  headers: {
28519
28663
  [name: string]: unknown;
@@ -30624,14 +30768,14 @@ interface operations {
30624
30768
  content: {
30625
30769
  "application/json": {
30626
30770
  /**
30627
- * @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, re-detects it on every reconnect and, at most once a day, on an account read; setting it here is an operator override of that result and holds until the next connect. To undo the override, send `limit_profile_source: "default"`: the pin is released, and Curviate re-reads the value from LinkedIn on the account's next read or connect. Sending the value the account already holds changes nothing and pins nothing. 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`.
30771
+ * @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, re-detects it on every reconnect and, at most once a day, on an account read; setting it here is an operator override of that result and holds until the next connect. To undo the override, send `limit_profile_source: "default"`: the pin is released, and Curviate re-reads the value from LinkedIn on the account's next read or connect. Sending the value the account already holds changes nothing and pins nothing. 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 Sales Navigator and 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`.
30628
30772
  * @enum {string}
30629
30773
  */
30630
30774
  limit_profile?: "basic" | "premium" | "sales_navigator" | "recruiter";
30631
30775
  /** @description The IANA zone this account's ACTIVITY window is read in, e.g. `Europe/Berlin`. Must be a real zone; anything else is a 400. Null clears it, which DISABLES the activity window for every row that has not set its own: a guessed zone inverts the window, which is worse than not having one. */
30632
30776
  timezone?: string | null;
30633
30777
  /**
30634
- * @description The tenant-wide posture default, which every account inherits unless it overrides it. Set it once for a whole workspace of personas. Null clears it back to `warn`.
30778
+ * @description The tenant-wide posture default, which every account inherits unless it overrides it. Set it once for a whole tenant of personas. Null clears it back to `warn`.
30635
30779
  * @enum {string|null}
30636
30780
  */
30637
30781
  tenant_default_posture?: "warn" | "enforce" | null;
@@ -30700,7 +30844,7 @@ interface operations {
30700
30844
  source_class?: "substrate" | "linkedin_official" | "practitioner" | "inferred" | "unseeded" | null;
30701
30845
  /** @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. */
30702
30846
  effective_ceiling?: unknown;
30703
- /** @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. */
30847
+ /** @description READ-ONLY. What a call through the matching elevated interface (the Sales Navigator and Recruiter operations) 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. */
30704
30848
  interface_ceiling?: unknown;
30705
30849
  /** @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. */
30706
30850
  effective_interface_ceiling?: unknown;
@@ -31030,10 +31174,342 @@ interface operations {
31030
31174
  };
31031
31175
  };
31032
31176
  };
31177
+ getV1SafetyPolicy: {
31178
+ parameters: {
31179
+ query?: never;
31180
+ header?: never;
31181
+ path?: never;
31182
+ cookie?: never;
31183
+ };
31184
+ requestBody?: never;
31185
+ responses: {
31186
+ /** @description The tenant safety defaults, every limit profile and every budget row. */
31187
+ 200: {
31188
+ headers: {
31189
+ "RateLimit-Policy": components["headers"]["RateLimit-Policy"];
31190
+ RateLimit: components["headers"]["RateLimit"];
31191
+ [name: string]: unknown;
31192
+ };
31193
+ content: {
31194
+ "application/json": {
31195
+ /**
31196
+ * @description Response type discriminator.
31197
+ * @enum {string}
31198
+ */
31199
+ object?: "tenant_safety_policy";
31200
+ /**
31201
+ * @description The workspace-wide posture default every account in the tenant inherits, or null when none is set. Always present, and separate from `posture` on purpose: when this account overrides the tenant default, a change to the tenant default does not move `posture`, and this field is how you can still see it took effect.
31202
+ * @enum {string|null}
31203
+ */
31204
+ tenant_default_posture?: "warn" | "enforce" | null;
31205
+ /** @description One entry per limit profile, always all of them. */
31206
+ profiles?: {
31207
+ /**
31208
+ * @description The limit profile these defaults apply to. An account resolves from its own profile's defaults.
31209
+ * @enum {string}
31210
+ */
31211
+ limit_profile?: "basic" | "premium" | "sales_navigator" | "recruiter";
31212
+ /** @description Every budget row, always: the tenant default where one is set, the Curviate default otherwise. */
31213
+ rows?: {
31214
+ /** @description The counted-action row this policy governs. */
31215
+ budget_row?: string;
31216
+ /** @description What `enforce` refuses at and `warn` reports at, in the row's own unit. Null means the row is uncalibrated: Curviate has no figure for it. */
31217
+ ceiling?: number | null;
31218
+ /** @description Routine band. */
31219
+ green?: number | null;
31220
+ /** @description Warn-louder band. */
31221
+ amber?: number | null;
31222
+ /**
31223
+ * @description The calendar grain this row is counted in.
31224
+ * @enum {string}
31225
+ */
31226
+ window_kind?: "day" | "week" | "month";
31227
+ /** @description How many grain units one counting window spans. */
31228
+ window_span?: number;
31229
+ /** @description IANA zone name the counting window is aligned to. Null counts in UTC. */
31230
+ window_timezone?: string | null;
31231
+ /** @description Local HH:MM the activity window opens. */
31232
+ activity_window_start?: string;
31233
+ /** @description Local HH:MM the activity window closes. */
31234
+ activity_window_end?: string;
31235
+ /** @description IANA zone name the activity window is read in. Null disables the window entirely. */
31236
+ activity_window_timezone?: string | null;
31237
+ /**
31238
+ * @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. One action set to `all` reaches the whole account's live reads that spend no budget of their own (notifications, profile analytics, SSI, profile visitors, the invitation and saved-list listings): those calls debit no action type, so they have none to read this setting from and take the account-wide answer instead. Reads that DO debit an action type read that action type's own setting.
31239
+ * @enum {string}
31240
+ */
31241
+ activity_window_applies_to?: "writes" | "all";
31242
+ /** @description The tenant default multiplier for this row, or null when none is set. Null means each account follows its own derived warm-up ramp; 1 pins every account on this profile out of it. */
31243
+ warm_up_factor?: number | null;
31244
+ /** @description Length cap on the row's free-text field, in characters. */
31245
+ character_cap?: number | null;
31246
+ /** @description Length cap on the row's subject line, in characters. */
31247
+ subject_character_cap?: number | null;
31248
+ /** @description Bound on a single query's result lines. Search rows only. */
31249
+ per_query_cap?: number | null;
31250
+ /**
31251
+ * @description How well calibrated this row's number is. `unseeded` means Curviate has no green, amber or ceiling figure for this row on this profile: the row is reported so nothing is silently missing, but nothing has calibrated it, so no value you set can be `over_default`.
31252
+ * @enum {string}
31253
+ */
31254
+ source_class?: "substrate" | "linkedin_official" | "practitioner" | "inferred" | "unseeded";
31255
+ /** @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. */
31256
+ interface_ceiling?: number | null;
31257
+ /** @description Empty when nothing on this row is above default. Computed against the STANDARD-interface default, like `band` and for the same reason. */
31258
+ over_default?: {
31259
+ /**
31260
+ * @description The field whose configured value is above default.
31261
+ * @enum {string}
31262
+ */
31263
+ field?: "ceiling" | "green" | "amber" | "character_cap" | "subject_character_cap" | "per_query_cap";
31264
+ /** @description The configured value. */
31265
+ value?: number;
31266
+ /** @description The Curviate default it exceeds. */
31267
+ default?: number;
31268
+ /**
31269
+ * @description How well calibrated the DEFAULT is. `substrate` and `linkedin_official` are published figures; `practitioner` is corroborated operator experience; `inferred` is our own reasoning; `unseeded` means we have no figure at all for that row, in which case there is nothing to be above and no entry appears. Read this before deciding whether being above default matters.
31270
+ * @enum {string}
31271
+ */
31272
+ source_class?: "substrate" | "linkedin_official" | "practitioner" | "inferred" | "unseeded";
31273
+ }[];
31274
+ }[];
31275
+ }[];
31276
+ safety_warning?: components["schemas"]["SafetyWarning"];
31277
+ };
31278
+ };
31279
+ };
31280
+ /** @description Rate limited, slow down and retry after the hinted delay. */
31281
+ 429: {
31282
+ headers: {
31283
+ "RateLimit-Policy": components["headers"]["RateLimit-Policy"];
31284
+ RateLimit: components["headers"]["RateLimit"];
31285
+ "Retry-After": components["headers"]["Retry-After"];
31286
+ [name: string]: unknown;
31287
+ };
31288
+ content: {
31289
+ "application/json": components["schemas"]["Error"];
31290
+ };
31291
+ };
31292
+ };
31293
+ };
31294
+ patchV1SafetyPolicy: {
31295
+ parameters: {
31296
+ query?: never;
31297
+ header?: never;
31298
+ path?: never;
31299
+ cookie?: never;
31300
+ };
31301
+ requestBody: {
31302
+ content: {
31303
+ "application/json": {
31304
+ /**
31305
+ * @description The tenant-wide posture default every account inherits unless it overrides it. Null clears it back to `warn`.
31306
+ * @enum {string|null}
31307
+ */
31308
+ tenant_default_posture?: "warn" | "enforce" | null;
31309
+ /** @description Tenant defaults, per limit profile. */
31310
+ profiles?: {
31311
+ /**
31312
+ * @description The limit profile these defaults apply to. An account resolves from the defaults of its own `limit_profile` only.
31313
+ * @enum {string}
31314
+ */
31315
+ limit_profile: "basic" | "premium" | "sales_navigator" | "recruiter";
31316
+ /** @description Per-row defaults for this profile. Omit a field to leave it; `null` clears the tenant default back to the Curviate default. A row read back from this document may be sent unchanged. */
31317
+ rows: {
31318
+ /**
31319
+ * @description The budget row this patch configures.
31320
+ * @enum {string}
31321
+ */
31322
+ 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";
31323
+ /** @description What `enforce` refuses at and `warn` reports at, in this row's own unit. Any value up to 9007199254740991 is accepted and stored verbatim; a value above the Curviate default is reported back, never clamped. */
31324
+ ceiling?: number | null;
31325
+ /** @description Routine band. Activity at or below it is unremarkable. */
31326
+ green?: number | null;
31327
+ /** @description Warn-louder band, between green and the ceiling. */
31328
+ amber?: number | null;
31329
+ /**
31330
+ * @description The calendar grain this row is counted in.
31331
+ * @enum {string|null}
31332
+ */
31333
+ window_kind?: "day" | "week" | "month" | null;
31334
+ /** @description How many `window_kind` units one counting window spans. */
31335
+ window_span?: number | null;
31336
+ /** @description IANA zone name the counting window is aligned to, e.g. `Europe/Berlin` or `UTC`. Must be a real zone; anything else is a 400. Null counts in UTC. */
31337
+ window_timezone?: string | null;
31338
+ /** @description Local time the activity window opens, HH:MM. Outside the window, live write operations are reported or refused per posture. */
31339
+ activity_window_start?: string | null;
31340
+ /** @description Local time the activity window closes, HH:MM. */
31341
+ activity_window_end?: string | null;
31342
+ /** @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. */
31343
+ activity_window_timezone?: string | null;
31344
+ /**
31345
+ * @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. One action set to `all` reaches the whole account's live reads that spend no budget of their own (notifications, profile analytics, SSI, profile visitors, the invitation and saved-list listings): those calls debit no action type, so they have none to read this setting from and take the account-wide answer instead. Reads that DO debit an action type read that action type's own setting.
31346
+ * @enum {string|null}
31347
+ */
31348
+ activity_window_applies_to?: "writes" | "all" | null;
31349
+ /** @description Multiplier applied to this row's ceiling while ramping. 1 is not ramping. */
31350
+ warm_up_factor?: number | null;
31351
+ /** @description Length cap on this row's free-text field, in characters (an invitation note, an InMail body). */
31352
+ character_cap?: number | null;
31353
+ /** @description Length cap on this row's subject line, in characters. */
31354
+ subject_character_cap?: number | null;
31355
+ /** @description Bound on a single query's result lines. Search rows only. */
31356
+ per_query_cap?: number | null;
31357
+ /**
31358
+ * @description How well calibrated this row's configured number is. Overriding it labels your own figure; the over-default warning always reports the class of the Curviate default.
31359
+ * @enum {string|null}
31360
+ */
31361
+ source_class?: "substrate" | "linkedin_official" | "practitioner" | "inferred" | "unseeded" | null;
31362
+ /** @description READ-ONLY. What a call through the matching elevated interface (the Sales Navigator and Recruiter operations) 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. */
31363
+ interface_ceiling?: unknown;
31364
+ /** @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. */
31365
+ over_default?: unknown;
31366
+ }[];
31367
+ }[];
31368
+ /** @description READ-ONLY. The document's type discriminator. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
31369
+ object?: unknown;
31370
+ /** @description READ-ONLY. What the last write changed across the tenant's accounts. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
31371
+ impact?: unknown;
31372
+ };
31373
+ };
31374
+ };
31375
+ responses: {
31376
+ /** @description The tenant safety defaults as they now read, plus the `impact` of this write. */
31377
+ 200: {
31378
+ headers: {
31379
+ "RateLimit-Policy": components["headers"]["RateLimit-Policy"];
31380
+ RateLimit: components["headers"]["RateLimit"];
31381
+ [name: string]: unknown;
31382
+ };
31383
+ content: {
31384
+ "application/json": {
31385
+ /**
31386
+ * @description Response type discriminator.
31387
+ * @enum {string}
31388
+ */
31389
+ object?: "tenant_safety_policy";
31390
+ /**
31391
+ * @description The workspace-wide posture default every account in the tenant inherits, or null when none is set. Always present, and separate from `posture` on purpose: when this account overrides the tenant default, a change to the tenant default does not move `posture`, and this field is how you can still see it took effect.
31392
+ * @enum {string|null}
31393
+ */
31394
+ tenant_default_posture?: "warn" | "enforce" | null;
31395
+ /** @description One entry per limit profile, always all of them. */
31396
+ profiles?: {
31397
+ /**
31398
+ * @description The limit profile these defaults apply to. An account resolves from its own profile's defaults.
31399
+ * @enum {string}
31400
+ */
31401
+ limit_profile?: "basic" | "premium" | "sales_navigator" | "recruiter";
31402
+ /** @description Every budget row, always: the tenant default where one is set, the Curviate default otherwise. */
31403
+ rows?: {
31404
+ /** @description The counted-action row this policy governs. */
31405
+ budget_row?: string;
31406
+ /** @description What `enforce` refuses at and `warn` reports at, in the row's own unit. Null means the row is uncalibrated: Curviate has no figure for it. */
31407
+ ceiling?: number | null;
31408
+ /** @description Routine band. */
31409
+ green?: number | null;
31410
+ /** @description Warn-louder band. */
31411
+ amber?: number | null;
31412
+ /**
31413
+ * @description The calendar grain this row is counted in.
31414
+ * @enum {string}
31415
+ */
31416
+ window_kind?: "day" | "week" | "month";
31417
+ /** @description How many grain units one counting window spans. */
31418
+ window_span?: number;
31419
+ /** @description IANA zone name the counting window is aligned to. Null counts in UTC. */
31420
+ window_timezone?: string | null;
31421
+ /** @description Local HH:MM the activity window opens. */
31422
+ activity_window_start?: string;
31423
+ /** @description Local HH:MM the activity window closes. */
31424
+ activity_window_end?: string;
31425
+ /** @description IANA zone name the activity window is read in. Null disables the window entirely. */
31426
+ activity_window_timezone?: string | null;
31427
+ /**
31428
+ * @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. One action set to `all` reaches the whole account's live reads that spend no budget of their own (notifications, profile analytics, SSI, profile visitors, the invitation and saved-list listings): those calls debit no action type, so they have none to read this setting from and take the account-wide answer instead. Reads that DO debit an action type read that action type's own setting.
31429
+ * @enum {string}
31430
+ */
31431
+ activity_window_applies_to?: "writes" | "all";
31432
+ /** @description The tenant default multiplier for this row, or null when none is set. Null means each account follows its own derived warm-up ramp; 1 pins every account on this profile out of it. */
31433
+ warm_up_factor?: number | null;
31434
+ /** @description Length cap on the row's free-text field, in characters. */
31435
+ character_cap?: number | null;
31436
+ /** @description Length cap on the row's subject line, in characters. */
31437
+ subject_character_cap?: number | null;
31438
+ /** @description Bound on a single query's result lines. Search rows only. */
31439
+ per_query_cap?: number | null;
31440
+ /**
31441
+ * @description How well calibrated this row's number is. `unseeded` means Curviate has no green, amber or ceiling figure for this row on this profile: the row is reported so nothing is silently missing, but nothing has calibrated it, so no value you set can be `over_default`.
31442
+ * @enum {string}
31443
+ */
31444
+ source_class?: "substrate" | "linkedin_official" | "practitioner" | "inferred" | "unseeded";
31445
+ /** @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. */
31446
+ interface_ceiling?: number | null;
31447
+ /** @description Empty when nothing on this row is above default. Computed against the STANDARD-interface default, like `band` and for the same reason. */
31448
+ over_default?: {
31449
+ /**
31450
+ * @description The field whose configured value is above default.
31451
+ * @enum {string}
31452
+ */
31453
+ field?: "ceiling" | "green" | "amber" | "character_cap" | "subject_character_cap" | "per_query_cap";
31454
+ /** @description The configured value. */
31455
+ value?: number;
31456
+ /** @description The Curviate default it exceeds. */
31457
+ default?: number;
31458
+ /**
31459
+ * @description How well calibrated the DEFAULT is. `substrate` and `linkedin_official` are published figures; `practitioner` is corroborated operator experience; `inferred` is our own reasoning; `unseeded` means we have no figure at all for that row, in which case there is nothing to be above and no entry appears. Read this before deciding whether being above default matters.
31460
+ * @enum {string}
31461
+ */
31462
+ source_class?: "substrate" | "linkedin_official" | "practitioner" | "inferred" | "unseeded";
31463
+ }[];
31464
+ }[];
31465
+ }[];
31466
+ /** @description What this write changed across the tenant's accounts, measured on them before and after it applied. */
31467
+ impact?: {
31468
+ /** @description Accounts on which at least one budget row's resolved ceiling changed. */
31469
+ accounts_affected?: number;
31470
+ /** @description Accounts on which at least one budget row moved into `band: "over"`. */
31471
+ accounts_moved_into_over?: number;
31472
+ };
31473
+ safety_warning?: components["schemas"]["SafetyWarning"];
31474
+ };
31475
+ };
31476
+ };
31477
+ /** @description INVALID_REQUEST. An unknown limit profile, row name or field, or a value that is not a value (a negative ceiling). A value is never rejected for being unsafe. */
31478
+ 400: {
31479
+ headers: {
31480
+ [name: string]: unknown;
31481
+ };
31482
+ content: {
31483
+ "application/json": components["schemas"]["Error"];
31484
+ };
31485
+ };
31486
+ /** @description Payload too large, the request body exceeds the size limit. */
31487
+ 413: {
31488
+ headers: {
31489
+ [name: string]: unknown;
31490
+ };
31491
+ content: {
31492
+ "application/json": components["schemas"]["Error"];
31493
+ };
31494
+ };
31495
+ /** @description Rate limited, slow down and retry after the hinted delay. */
31496
+ 429: {
31497
+ headers: {
31498
+ "RateLimit-Policy": components["headers"]["RateLimit-Policy"];
31499
+ RateLimit: components["headers"]["RateLimit"];
31500
+ "Retry-After": components["headers"]["Retry-After"];
31501
+ [name: string]: unknown;
31502
+ };
31503
+ content: {
31504
+ "application/json": components["schemas"]["Error"];
31505
+ };
31506
+ };
31507
+ };
31508
+ };
31033
31509
  }
31034
31510
 
31035
31511
  /**
31036
- * Accounts resource: connected-account management (4 methods, root-scoped).
31512
+ * Accounts resource: connected-account management (5 methods, root-scoped).
31037
31513
  *
31038
31514
  * Pattern followed by all resource namespaces:
31039
31515
  * - take a {@link RequestContext} in the constructor,
@@ -31055,6 +31531,8 @@ interface operations {
31055
31531
  type AccountListPage = paths["/v1/accounts"]["get"]["responses"]["200"]["content"]["application/json"];
31056
31532
  /** `GET /v1/accounts` query params. */
31057
31533
  type AccountListParams = NonNullable<paths["/v1/accounts"]["get"]["parameters"]["query"]>;
31534
+ /** `GET /v1/accounts/seats` 200 body, the workspace's live seats with their occupancy. */
31535
+ type SeatList = paths["/v1/accounts/seats"]["get"]["responses"]["200"]["content"]["application/json"];
31058
31536
  /** `GET /v1/accounts/{account_id}` 200 body. */
31059
31537
  type AccountDetail = paths["/v1/accounts/{account_id}"]["get"]["responses"]["200"]["content"]["application/json"];
31060
31538
  /** `PATCH /v1/accounts/{account_id}` request body. */
@@ -31082,6 +31560,26 @@ declare class AccountsResource {
31082
31560
  * for (const acc of page.items ?? []) console.log(acc.account_id);
31083
31561
  */
31084
31562
  list(params?: AccountListParams): Promise<AccountListPage>;
31563
+ /**
31564
+ * List the workspace's live seats: each `seat_id`, whether an account
31565
+ * `occupied` it, and that `account_id` (`null` when free). Not paginated.
31566
+ *
31567
+ * Only live seats are listed, and an empty seat is listed only when
31568
+ * connecting an account to it would be accepted right now. So an empty seat
31569
+ * that is provisional, cancelling, on an ended trial, or blocked by billing
31570
+ * does not appear, and `items` can be `[]` even though the workspace has
31571
+ * seats. Any seat with `occupied: false` is a valid `seat_id` for connecting
31572
+ * a new account with `auth.intent`. Carries no billing fields.
31573
+ *
31574
+ * @returns `{ object: "seat_list", items: { seat_id, occupied, account_id }[] }`.
31575
+ *
31576
+ * @example
31577
+ * const { items } = await curviate.accounts.listSeats();
31578
+ * const free = items.find((seat) => !seat.occupied);
31579
+ * if (!free) throw new Error("No seat is free to connect to right now (add a seat, or check billing).");
31580
+ * await curviate.auth.intent({ seat_id: free.seat_id, auth_method: "cookie", cookie: { li_at }, user_agent });
31581
+ */
31582
+ listSeats(): Promise<SeatList>;
31085
31583
  /**
31086
31584
  * Return metadata and current state for one connected account, including the
31087
31585
  * central `quotas[]` account-safety view, `account_states[]` and `seat_id`
@@ -31180,7 +31678,8 @@ declare class AuthResource {
31180
31678
  /**
31181
31679
  * Authenticate a LinkedIn account with credentials or a session cookie.
31182
31680
  *
31183
- * Omit `account_id` to connect a NEW account into an empty seat; include it
31681
+ * Omit `account_id` to connect a NEW account into an empty seat (find one
31682
+ * with `accounts.listSeats()`: any seat with `occupied: false`); include it
31184
31683
  * to re-authenticate an EXISTING account in place. Returns the account on
31185
31684
  * success (200 re-authenticated in place / 201 new), or a checkpoint
31186
31685
  * challenge (202) when LinkedIn requires verification; resolve it with
@@ -31349,6 +31848,19 @@ declare class MessagingResource {
31349
31848
  /**
31350
31849
  * List messages in a chat, cursor-paginated.
31351
31850
  * `GET /v1/{account_id}/chats/{chat_id}/messages`
31851
+ *
31852
+ * An InMail thread's subject line arrives on a MESSAGE, as
31853
+ * `message.specifics.subject`, carried by the thread's opening message. The
31854
+ * chat object has no subject of its own, and `chat.name` is the counterpart's
31855
+ * display name rather than a folded-in subject, so read the subject from the
31856
+ * first message rather than from the chat. Ordinary (non-InMail) messages
31857
+ * return `specifics: {}`.
31858
+ *
31859
+ * A CHAT READ CARRIES NO SUBJECT AT ALL, including on its embedded
31860
+ * `last_message`: the preview is deliberately narrower than a message read, so
31861
+ * that a chat read returns the same fields whether it was answered from
31862
+ * LinkedIn or from Curviate's stored copy. Getting a subject means reading the
31863
+ * chat's messages.
31352
31864
  */
31353
31865
  listMessages(chatId: string, params?: MessageListQuery): Promise<MessageListPage>;
31354
31866
  /**
@@ -31383,6 +31895,11 @@ declare class MessagingResource {
31383
31895
  /**
31384
31896
  * Get a single message by ID, re-homed under its chat.
31385
31897
  * `GET /v1/{account_id}/chats/{chat_id}/messages/{message_id}`
31898
+ *
31899
+ * `specifics` carries the InMail subject when the platform set one on this
31900
+ * message (`specifics.subject`), and is `{}` otherwise. It is narrowed to
31901
+ * that one field on purpose: the platform's other `specifics` keys are not
31902
+ * part of the published surface.
31386
31903
  */
31387
31904
  getMessage(chatId: string, messageId: string): Promise<MessageDetail>;
31388
31905
  /**
@@ -33831,4 +34348,4 @@ interface ConstructEventOptions {
33831
34348
  */
33832
34349
  declare function constructEvent(rawBody: string | Buffer, signatureHeader: string, secret: string, opts?: ConstructEventOptions): Promise<CurviateEvent>;
33833
34350
 
33834
- export { type AccountListPage, type AccountListParams, type AccountPayload, type AccountScopedNamespaces, type ConnectionPayload, type ConstructEventOptions, Curviate, type CurviateConfig, CurviateError, type CurviateErrorInit, type CurviateErrorJSON, type CurviateEvent, type CurviateEventEnvelope, ERROR_CODES, type ErrorCode, type EventPayloadBase, type MessagePayload, type ResolvedConfig, type ResourceNamespaces, type RetryHint, type SafetyHint, type SafetyReason, WebhookSignatureError, type components, constructEvent, isCurviateError, type operations, type paths };
34351
+ export { type AccountListPage, type AccountListParams, type AccountPayload, type AccountScopedNamespaces, type ConnectionPayload, type ConstructEventOptions, Curviate, type CurviateConfig, CurviateError, type CurviateErrorInit, type CurviateErrorJSON, type CurviateEvent, type CurviateEventEnvelope, ERROR_CODES, type ErrorCode, type EventPayloadBase, type MessagePayload, type ResolvedConfig, type ResourceNamespaces, type RetryHint, type SafetyHint, type SafetyReason, type SeatList, WebhookSignatureError, type components, constructEvent, isCurviateError, type operations, type paths };