@curviate/sdk 0.30.0 → 0.31.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/CHANGELOG.md +53 -0
- package/dist/index.d.ts +7 -19
- package/dist/index.js +8 -26
- package/package.json +1 -1
- package/src/generated/types.ts +4 -16
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,59 @@ Versioning: semantic. Minor for additive changes, patch for bug fixes; no stabil
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [0.31.0] - 2026-09-11
|
|
11
|
+
|
|
12
|
+
Step two of the tier retirement, plus one billing refusal this SDK was about to
|
|
13
|
+
erase to `INTERNAL`. **Breaking** for any caller still branching on the two
|
|
14
|
+
retired codes; additive otherwise.
|
|
15
|
+
|
|
16
|
+
The trigger 0.30.0 named for the removal is met: every deployment now carries
|
|
17
|
+
the seat-based entitlement contract, so neither retired code can arrive.
|
|
18
|
+
|
|
19
|
+
Fixture and types regenerated against the deployed staging document
|
|
20
|
+
(`https://api.staging.curviate.com`, 125 paths); the exact source commit is
|
|
21
|
+
recorded in `fixtures/PROVENANCE.json`.
|
|
22
|
+
|
|
23
|
+
### Removed
|
|
24
|
+
|
|
25
|
+
- **`TIER_NOT_ACTIVE` and `PREMIUM_CONFLICT` are gone from `ErrorCode`,
|
|
26
|
+
`ERROR_CODES` and `KNOWN_ERROR_CODES`.** Deprecated in 0.30.0; no deployment
|
|
27
|
+
emits either any more. A `case "TIER_NOT_ACTIVE"` or
|
|
28
|
+
`case "PREMIUM_CONFLICT"` now fails to type-check, which is the point: it was
|
|
29
|
+
a branch that could never be taken. Handle `NO_ACTIVE_SEAT` for the seat
|
|
30
|
+
refusal; `PREMIUM_CONFLICT` has no replacement, because the current connect
|
|
31
|
+
input cannot express the conflict it reported.
|
|
32
|
+
|
|
33
|
+
Should a wire body ever carry either code, it decodes to `INTERNAL` like any
|
|
34
|
+
unknown code.
|
|
35
|
+
|
|
36
|
+
- **`seat_tier_mismatch` is gone from the safety-policy types**, on the read
|
|
37
|
+
response, the write response and the write body. Seats no longer carry a
|
|
38
|
+
tier, so there is nothing for it to disagree with, and the API has stopped
|
|
39
|
+
returning it. Read `limit_profile` for what LinkedIn grants the account.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- Two regenerated descriptions: job search `paging.total_count` now says it
|
|
44
|
+
counts matching job postings and is `0` on an empty page, and the connect
|
|
45
|
+
body's `recruiter_contract_id` is described by the LinkedIn Recruiter
|
|
46
|
+
subscription rather than a Curviate tier. Documentation only; no type moved.
|
|
47
|
+
|
|
48
|
+
### Added
|
|
49
|
+
|
|
50
|
+
- **`STRIPE_DRIFT_DETECTED` (503).** Checkout refuses closed when Curviate's
|
|
51
|
+
own seat-price configuration disagrees with the price it displays, so no one
|
|
52
|
+
is charged an amount they were never shown. It is a Curviate-side
|
|
53
|
+
misconfiguration: `userFixable` is `false`, a retry fails the same way until
|
|
54
|
+
Curviate corrects the price, and nothing was charged. Surface it to a human
|
|
55
|
+
or to support instead of backing off. Not in the transport's retryable set,
|
|
56
|
+
so a GET carrying it is fetched once.
|
|
57
|
+
|
|
58
|
+
Without this entry the refusal would have decoded to `INTERNAL`, reading as
|
|
59
|
+
a generic server fault and being retried as one.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
10
63
|
## [0.30.0] - 2026-09-09
|
|
11
64
|
|
|
12
65
|
Fixture and types regenerated against the deployed staging document
|
package/dist/index.d.ts
CHANGED
|
@@ -2679,7 +2679,7 @@ interface paths {
|
|
|
2679
2679
|
};
|
|
2680
2680
|
/**
|
|
2681
2681
|
* 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.
|
|
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.
|
|
2683
2683
|
*/
|
|
2684
2684
|
get: operations["getV1AccountIdSafetyPolicy"];
|
|
2685
2685
|
put?: never;
|
|
@@ -2689,7 +2689,7 @@ interface paths {
|
|
|
2689
2689
|
head?: never;
|
|
2690
2690
|
/**
|
|
2691
2691
|
* 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.
|
|
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.
|
|
2693
2693
|
*/
|
|
2694
2694
|
patch: operations["patchV1AccountIdSafetyPolicy"];
|
|
2695
2695
|
trace?: never;
|
|
@@ -9319,7 +9319,7 @@ interface operations {
|
|
|
9319
9319
|
}[];
|
|
9320
9320
|
/** @description Paging metadata. */
|
|
9321
9321
|
paging: {
|
|
9322
|
-
/** @description Total matching
|
|
9322
|
+
/** @description Total number of matching job postings, including 0 on an empty page. */
|
|
9323
9323
|
total_count: number | null;
|
|
9324
9324
|
};
|
|
9325
9325
|
/** @description Opaque next-page cursor; null on the last page. */
|
|
@@ -28400,7 +28400,7 @@ interface operations {
|
|
|
28400
28400
|
/** @description Maximum number of messages to sync per chat. */
|
|
28401
28401
|
messages?: number;
|
|
28402
28402
|
};
|
|
28403
|
-
/** @description Which Recruiter contract to bind this account to
|
|
28403
|
+
/** @description Which Recruiter contract to bind this account to. Only meaningful when the LinkedIn account holds a Recruiter subscription. */
|
|
28404
28404
|
recruiter_contract_id?: string;
|
|
28405
28405
|
};
|
|
28406
28406
|
};
|
|
@@ -30453,11 +30453,6 @@ interface operations {
|
|
|
30453
30453
|
* @enum {string}
|
|
30454
30454
|
*/
|
|
30455
30455
|
limit_profile?: "basic" | "premium" | "sales_navigator" | "recruiter";
|
|
30456
|
-
/**
|
|
30457
|
-
* @description The Curviate seat tier attached to this account when it disagrees with `limit_profile`, and null when the two agree or the account holds no seat. A seat records what you bought from Curviate; `limit_profile` records what LinkedIn currently grants, and a lapsed subscription moves one and not the other. The detected product always wins the numbers, so this is a report, not a refusal: a `recruiter` seat here means you are paying for Recruiter on an account LinkedIn does not currently grant it to. `core` alongside `basic` or `premium` is agreement, not a mismatch: Premium is a LinkedIn product, not a Curviate tier. A free-trial seat never reports here, because a trial is not a purchase, and neither does a seat whose entitlement has not started yet or has already lapsed.
|
|
30458
|
-
* @enum {string|null}
|
|
30459
|
-
*/
|
|
30460
|
-
seat_tier_mismatch?: "core" | "sn" | "recruiter" | null;
|
|
30461
30456
|
/**
|
|
30462
30457
|
* @description Where `limit_profile` came from. `detected`: Curviate read it from LinkedIn, at `limit_profile_detected_at`. `operator`: it was set through this operation and holds until the account next connects, or until you send `limit_profile_source: "default"` on this operation, which releases it. `default`: it has never been observed, so the value is the seeded `basic` and says nothing about the account; Curviate detects it on the account's next read or connect.
|
|
30463
30458
|
* @enum {string}
|
|
@@ -30718,8 +30713,6 @@ interface operations {
|
|
|
30718
30713
|
object?: unknown;
|
|
30719
30714
|
/** @description READ-ONLY. The account this document describes; the path names it. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
|
|
30720
30715
|
account_id?: unknown;
|
|
30721
|
-
/** @description READ-ONLY. The Curviate seat tier that disagrees with `limit_profile`. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
|
|
30722
|
-
seat_tier_mismatch?: unknown;
|
|
30723
30716
|
/**
|
|
30724
30717
|
* @description Where `limit_profile` came from: `default` (never observed), `detected` (read from LinkedIn) or `operator` (set through this operation). Sending `default` releases an operator override: the value is re-read from LinkedIn on the account's next read or connect. Sending `detected` or `operator` is accepted and ignored, so the whole document round-trips.
|
|
30725
30718
|
* @enum {string}
|
|
@@ -30758,11 +30751,6 @@ interface operations {
|
|
|
30758
30751
|
* @enum {string}
|
|
30759
30752
|
*/
|
|
30760
30753
|
limit_profile?: "basic" | "premium" | "sales_navigator" | "recruiter";
|
|
30761
|
-
/**
|
|
30762
|
-
* @description The Curviate seat tier attached to this account when it disagrees with `limit_profile`, and null when the two agree or the account holds no seat. A seat records what you bought from Curviate; `limit_profile` records what LinkedIn currently grants, and a lapsed subscription moves one and not the other. The detected product always wins the numbers, so this is a report, not a refusal: a `recruiter` seat here means you are paying for Recruiter on an account LinkedIn does not currently grant it to. `core` alongside `basic` or `premium` is agreement, not a mismatch: Premium is a LinkedIn product, not a Curviate tier. A free-trial seat never reports here, because a trial is not a purchase, and neither does a seat whose entitlement has not started yet or has already lapsed.
|
|
30763
|
-
* @enum {string|null}
|
|
30764
|
-
*/
|
|
30765
|
-
seat_tier_mismatch?: "core" | "sn" | "recruiter" | null;
|
|
30766
30754
|
/**
|
|
30767
30755
|
* @description Where `limit_profile` came from. `detected`: Curviate read it from LinkedIn, at `limit_profile_detected_at`. `operator`: it was set through this operation and holds until the account next connects, or until you send `limit_profile_source: "default"` on this operation, which releases it. `default`: it has never been observed, so the value is the seeded `basic` and says nothing about the account; Curviate detects it on the account's next read or connect.
|
|
30768
30756
|
* @enum {string}
|
|
@@ -33381,13 +33369,13 @@ declare class Curviate {
|
|
|
33381
33369
|
*
|
|
33382
33370
|
* So a retirement is two steps. First `@deprecated`, kept exported, with the
|
|
33383
33371
|
* replacement named. Then removed, in the first release after every deployment
|
|
33384
|
-
* carries the new contract. `TIER_NOT_ACTIVE` and `PREMIUM_CONFLICT`
|
|
33385
|
-
*
|
|
33372
|
+
* carries the new contract. `TIER_NOT_ACTIVE` and `PREMIUM_CONFLICT` took step
|
|
33373
|
+
* one in 0.30.0 and step two in 0.31.0.
|
|
33386
33374
|
*
|
|
33387
33375
|
* A code the API NEVER emitted is a different case and goes immediately, since
|
|
33388
33376
|
* no deployment can be sending it: `RATE_LIMITED` went that way in 0.30.0.
|
|
33389
33377
|
*/
|
|
33390
|
-
declare const ERROR_CODES: readonly ["UNAUTHORIZED", "INVALID_REQUEST", "UNSUPPORTED_MEDIA_TYPE", "PAYLOAD_TOO_LARGE", "ACCOUNT_NOT_FOUND", "ACCOUNT_RESTRICTED", "ACCOUNT_ALREADY_LINKED", "RESOURCE_NOT_FOUND", "NOT_STORED", "RESOURCE_ACCESS_RESTRICTED", "FILTER_CANDIDATES_REQUIRED", "NO_ACTIVE_SEAT", "LINKEDIN_FEATURE_NOT_SUBSCRIBED", "BETA_NOT_ENABLED", "
|
|
33378
|
+
declare const ERROR_CODES: readonly ["UNAUTHORIZED", "INVALID_REQUEST", "UNSUPPORTED_MEDIA_TYPE", "PAYLOAD_TOO_LARGE", "ACCOUNT_NOT_FOUND", "ACCOUNT_RESTRICTED", "ACCOUNT_ALREADY_LINKED", "RESOURCE_NOT_FOUND", "NOT_STORED", "RESOURCE_ACCESS_RESTRICTED", "FILTER_CANDIDATES_REQUIRED", "NO_ACTIVE_SEAT", "LINKEDIN_FEATURE_NOT_SUBSCRIBED", "BETA_NOT_ENABLED", "RATE_LIMIT_ACCOUNT", "RATE_LIMIT_TENANT", "PLATFORM_RATE_LIMIT", "BUDGET_EXHAUSTED", "PLATFORM_ERROR", "PLATFORM_NOT_IMPLEMENTED", "LINKEDIN_OPERATION_NOT_SUPPORTED", "CHECKPOINT_NOT_FOUND", "CHECKPOINT_EXPIRED", "CHECKPOINT_INVALID_CODE", "CHECKPOINT_MAX_ATTEMPTS", "CHECKPOINT_ALREADY_RESOLVED", "CHECKPOINT_UNSUPPORTED", "CONNECTION_IN_PROGRESS", "REAUTH_REQUIRED", "LINKEDIN_AUTH_FAILED", "LINKEDIN_SESSION_EVICTED", "LINKEDIN_RATE_LIMITED", "LINKEDIN_COOKIE_INVALID", "LINKEDIN_SERVICE_UNAVAILABLE", "MESSAGE_WINDOW_EXPIRED", "RECIPIENT_UNREACHABLE", "CONNECTION_REQUEST_CONFLICT", "PAYMENT_REQUIRED", "PAYMENT_FAILED", "SUBSCRIPTION_BUSY", "SUBSCRIPTION_NOT_FOUND", "SEAT_NOT_FOUND", "SEAT_CANCELLED", "NOT_FOUND", "REACTION_NOT_FOUND", "SUBSTRATE_LINK_FAILED", "SUBSTRATE_CAP_REACHED", "BILLING_CHECKOUT_FAILED", "BILLING_PORTAL_UNAVAILABLE", "ACCOUNT_DISPUTED", "ACCOUNT_LINKING_DISABLED", "PERIOD_LOCKED", "SEAT_NOT_EMPTY", "SEAT_PROVISIONAL", "SUBSCRIPTION_ALREADY_EXISTS", "ALREADY_CANCELLED", "CANCELLATION_ALREADY_EFFECTIVE", "INVALID_CANCELLATION_SOURCE", "TRIAL_EXPIRED", "TRIAL_SEAT_LIMIT", "TRIAL_ACTIVE_SEAT_LIMIT", "TRIAL_IDENTITY_ALREADY_USED", "TRIAL_IDENTITY_UNRESOLVED", "ADMIN_BYPASS", "STRIPE_DRIFT_DETECTED", "INTERNAL"];
|
|
33391
33379
|
/**
|
|
33392
33380
|
* The complete set of error codes observable by API callers.
|
|
33393
33381
|
*
|
package/dist/index.js
CHANGED
|
@@ -49,21 +49,6 @@ var ERROR_CODES = [
|
|
|
49
49
|
"NO_ACTIVE_SEAT",
|
|
50
50
|
"LINKEDIN_FEATURE_NOT_SUBSCRIBED",
|
|
51
51
|
"BETA_NOT_ENABLED",
|
|
52
|
-
/**
|
|
53
|
-
* @deprecated Replaced by {@link NO_ACTIVE_SEAT}. Product tiers are retired,
|
|
54
|
-
* so no refusal names one any more.
|
|
55
|
-
*
|
|
56
|
-
* STILL EXPORTED ON PURPOSE, and this is not a courtesy: API deployments
|
|
57
|
-
* that predate the seat-based entitlement rollout still emit this code, and
|
|
58
|
-
* a client that stopped recognising it would decode it to `INTERNAL`: a
|
|
59
|
-
* fixable billing refusal arriving as a server fault, against the very
|
|
60
|
-
* deployments most likely to send it. It is withdrawn in the first release
|
|
61
|
-
* after every deployment carries the new contract.
|
|
62
|
-
*
|
|
63
|
-
* Handle both while that is true: `NO_ACTIVE_SEAT` from a current
|
|
64
|
-
* deployment, this from an older one. They mean the same thing to a caller.
|
|
65
|
-
*/
|
|
66
|
-
"TIER_NOT_ACTIVE",
|
|
67
52
|
// Rate limits
|
|
68
53
|
"RATE_LIMIT_ACCOUNT",
|
|
69
54
|
"RATE_LIMIT_TENANT",
|
|
@@ -91,17 +76,6 @@ var ERROR_CODES = [
|
|
|
91
76
|
"CHECKPOINT_ALREADY_RESOLVED",
|
|
92
77
|
"CHECKPOINT_UNSUPPORTED",
|
|
93
78
|
"CONNECTION_IN_PROGRESS",
|
|
94
|
-
/**
|
|
95
|
-
* @deprecated Withdrawn with no replacement. The one-premium conflict it
|
|
96
|
-
* reported cannot be expressed on the current input, because
|
|
97
|
-
* `linkedin_premium` is single-valued.
|
|
98
|
-
*
|
|
99
|
-
* STILL EXPORTED for the same reason as {@link TIER_NOT_ACTIVE}: deployments
|
|
100
|
-
* that predate the connect rework can still emit it, and dropping it early
|
|
101
|
-
* would turn a fixable refusal into `INTERNAL` on exactly those. Withdrawn
|
|
102
|
-
* in the first release after every deployment carries the new contract.
|
|
103
|
-
*/
|
|
104
|
-
"PREMIUM_CONFLICT",
|
|
105
79
|
// A reconnect whose seat-derived scope differs from the account's recorded
|
|
106
80
|
// scope was attempted with cookie auth; a cookie replay cannot change
|
|
107
81
|
// scope, so a full credentials re-authentication is required. user_fixable,
|
|
@@ -182,6 +156,14 @@ var ERROR_CODES = [
|
|
|
182
156
|
// returned by `/v1` billing routes at nine sites; it was previously cited
|
|
183
157
|
// in this file as a code that never reaches a caller, which was wrong.
|
|
184
158
|
"ADMIN_BYPASS",
|
|
159
|
+
// Checkout refused closed (503): Curviate's own seat-price configuration
|
|
160
|
+
// disagrees with the price it displays, so completing checkout would charge
|
|
161
|
+
// an amount you were never shown. A misconfiguration on Curviate's side, not
|
|
162
|
+
// a mistake in the request and not a transient fault: user_fixable false,
|
|
163
|
+
// and a retry fails the same way until Curviate corrects the price. Nothing
|
|
164
|
+
// was charged. Stop and surface it to a human (or support) rather than
|
|
165
|
+
// backing off.
|
|
166
|
+
"STRIPE_DRIFT_DETECTED",
|
|
185
167
|
// Generic
|
|
186
168
|
"INTERNAL"
|
|
187
169
|
];
|
package/package.json
CHANGED
package/src/generated/types.ts
CHANGED
|
@@ -2581,7 +2581,7 @@ export interface paths {
|
|
|
2581
2581
|
};
|
|
2582
2582
|
/**
|
|
2583
2583
|
* Read an account's safety policy
|
|
2584
|
-
* @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.
|
|
2584
|
+
* @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.
|
|
2585
2585
|
*/
|
|
2586
2586
|
get: operations["getV1AccountIdSafetyPolicy"];
|
|
2587
2587
|
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. 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.
|
|
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. 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.
|
|
2595
2595
|
*/
|
|
2596
2596
|
patch: operations["patchV1AccountIdSafetyPolicy"];
|
|
2597
2597
|
trace?: never;
|
|
@@ -9223,7 +9223,7 @@ export interface operations {
|
|
|
9223
9223
|
}[];
|
|
9224
9224
|
/** @description Paging metadata. */
|
|
9225
9225
|
paging: {
|
|
9226
|
-
/** @description Total matching
|
|
9226
|
+
/** @description Total number of matching job postings, including 0 on an empty page. */
|
|
9227
9227
|
total_count: number | null;
|
|
9228
9228
|
};
|
|
9229
9229
|
/** @description Opaque next-page cursor; null on the last page. */
|
|
@@ -28304,7 +28304,7 @@ export interface operations {
|
|
|
28304
28304
|
/** @description Maximum number of messages to sync per chat. */
|
|
28305
28305
|
messages?: number;
|
|
28306
28306
|
};
|
|
28307
|
-
/** @description Which Recruiter contract to bind this account to
|
|
28307
|
+
/** @description Which Recruiter contract to bind this account to. Only meaningful when the LinkedIn account holds a Recruiter subscription. */
|
|
28308
28308
|
recruiter_contract_id?: string;
|
|
28309
28309
|
};
|
|
28310
28310
|
};
|
|
@@ -30357,11 +30357,6 @@ export interface operations {
|
|
|
30357
30357
|
* @enum {string}
|
|
30358
30358
|
*/
|
|
30359
30359
|
limit_profile?: "basic" | "premium" | "sales_navigator" | "recruiter";
|
|
30360
|
-
/**
|
|
30361
|
-
* @description The Curviate seat tier attached to this account when it disagrees with `limit_profile`, and null when the two agree or the account holds no seat. A seat records what you bought from Curviate; `limit_profile` records what LinkedIn currently grants, and a lapsed subscription moves one and not the other. The detected product always wins the numbers, so this is a report, not a refusal: a `recruiter` seat here means you are paying for Recruiter on an account LinkedIn does not currently grant it to. `core` alongside `basic` or `premium` is agreement, not a mismatch: Premium is a LinkedIn product, not a Curviate tier. A free-trial seat never reports here, because a trial is not a purchase, and neither does a seat whose entitlement has not started yet or has already lapsed.
|
|
30362
|
-
* @enum {string|null}
|
|
30363
|
-
*/
|
|
30364
|
-
seat_tier_mismatch?: "core" | "sn" | "recruiter" | null;
|
|
30365
30360
|
/**
|
|
30366
30361
|
* @description Where `limit_profile` came from. `detected`: Curviate read it from LinkedIn, at `limit_profile_detected_at`. `operator`: it was set through this operation and holds until the account next connects, or until you send `limit_profile_source: "default"` on this operation, which releases it. `default`: it has never been observed, so the value is the seeded `basic` and says nothing about the account; Curviate detects it on the account's next read or connect.
|
|
30367
30362
|
* @enum {string}
|
|
@@ -30622,8 +30617,6 @@ export interface operations {
|
|
|
30622
30617
|
object?: unknown;
|
|
30623
30618
|
/** @description READ-ONLY. The account this document describes; the path names it. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
|
|
30624
30619
|
account_id?: unknown;
|
|
30625
|
-
/** @description READ-ONLY. The Curviate seat tier that disagrees with `limit_profile`. Sent back on a write it is accepted and ignored, so the whole document round-trips; it is never stored and never ledgered. */
|
|
30626
|
-
seat_tier_mismatch?: unknown;
|
|
30627
30620
|
/**
|
|
30628
30621
|
* @description Where `limit_profile` came from: `default` (never observed), `detected` (read from LinkedIn) or `operator` (set through this operation). Sending `default` releases an operator override: the value is re-read from LinkedIn on the account's next read or connect. Sending `detected` or `operator` is accepted and ignored, so the whole document round-trips.
|
|
30629
30622
|
* @enum {string}
|
|
@@ -30662,11 +30655,6 @@ export interface operations {
|
|
|
30662
30655
|
* @enum {string}
|
|
30663
30656
|
*/
|
|
30664
30657
|
limit_profile?: "basic" | "premium" | "sales_navigator" | "recruiter";
|
|
30665
|
-
/**
|
|
30666
|
-
* @description The Curviate seat tier attached to this account when it disagrees with `limit_profile`, and null when the two agree or the account holds no seat. A seat records what you bought from Curviate; `limit_profile` records what LinkedIn currently grants, and a lapsed subscription moves one and not the other. The detected product always wins the numbers, so this is a report, not a refusal: a `recruiter` seat here means you are paying for Recruiter on an account LinkedIn does not currently grant it to. `core` alongside `basic` or `premium` is agreement, not a mismatch: Premium is a LinkedIn product, not a Curviate tier. A free-trial seat never reports here, because a trial is not a purchase, and neither does a seat whose entitlement has not started yet or has already lapsed.
|
|
30667
|
-
* @enum {string|null}
|
|
30668
|
-
*/
|
|
30669
|
-
seat_tier_mismatch?: "core" | "sn" | "recruiter" | null;
|
|
30670
30658
|
/**
|
|
30671
30659
|
* @description Where `limit_profile` came from. `detected`: Curviate read it from LinkedIn, at `limit_profile_detected_at`. `operator`: it was set through this operation and holds until the account next connects, or until you send `limit_profile_source: "default"` on this operation, which releases it. `default`: it has never been observed, so the value is the seeded `basic` and says nothing about the account; Curviate detects it on the account's next read or connect.
|
|
30672
30660
|
* @enum {string}
|