@curviate/sdk 0.40.1 → 0.42.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 CHANGED
@@ -9,6 +9,87 @@ Versioning: semantic. Minor for additive changes, patch for bug fixes; no stabil
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.42.0] - 2026-10-07
13
+
14
+ Fixture and types regenerated from the server integration branch (134 paths,
15
+ server `b1c443c6a3a0e1c2a09944be39f01c6921fca46c`), **not** from a deployed
16
+ document: regenerate from deployed staging and confirm an empty diff before
17
+ publishing.
18
+
19
+ ### Added
20
+
21
+ - **`drafts` resource** (root-scoped, 7 methods): `create`, `list`, `get`,
22
+ `update`, `delete`, `publish`, `uploadAttachment`. A Draft is a stored,
23
+ editable post that Curviate publishes at `scheduled_at` (ISO 8601 with
24
+ offset, passed through unchanged). `list` takes `status` as an array and
25
+ sends it as the API's comma list; `status: ["published"]` returns publish
26
+ records. `uploadAttachment(id, data, { filename, contentType })` sends a
27
+ file (an MP4 video or PDF up to 50 MiB; an image is capped at 5 MiB) as the raw request body.
28
+ `delete` resolves with `undefined` (204). (`posts.delete` and `comments.delete`
29
+ still hand back the transport's empty buffer under a `void` type; unchanged here.)
30
+ - **Six new error codes** decode to themselves instead of `INTERNAL`:
31
+ `DRAFT_LIMIT_REACHED`, `MEDIA_QUOTA_EXCEEDED`, `ACCOUNT_REQUIRED`,
32
+ `DRAFT_NOT_PUBLISHABLE`, `SCHEDULE_CONFLICT`, `DRAFT_PUBLISHING`.
33
+ - **`post.published` and `post.publish_failed` webhook events** join
34
+ `CurviateEvent` (`PostPublishedPayload`, `PostPublishFailedPayload`).
35
+ Payloads carry ids and times, never post text or media.
36
+ - `Draft*` request and result types are exported.
37
+
38
+ ### Changed
39
+
40
+ - The webhook `source` enum includes `post`, from the regenerated types.
41
+
42
+ ## [0.41.0] - 2026-10-03
43
+
44
+ Fixture and types regenerated against the deployed staging document
45
+ (`https://api.staging.curviate.com`, 130 paths, server
46
+ `df3c133205721a75786001d51b3ee4491b4fe697`).
47
+
48
+ ### Breaking
49
+
50
+ - **A new connect must name its connection location.** `auth.intent()`
51
+ without `account_id` needs exactly one of `country` (a supported ISO 3166-1
52
+ alpha-2 code, e.g. `"US"`), `ip` (a public IPv4) or your own `proxy`. The
53
+ API refuses a connect without one with `400 CONNECTION_LOCATION_REQUIRED`,
54
+ and `AuthIntentBody` now refuses it at compile time, along with two sources
55
+ at once and `allow_country_fallback` with `proxy`. A reconnect (`account_id`
56
+ present) may still omit it to keep the account's configured location.
57
+ `country` is typed as the served 56-code enum (`ConnectionCountry`).
58
+ - **`accounts.update()` returns the account.** It used to return
59
+ `{ object, account_id }`; it now returns the account as `get` does, without
60
+ `quotas` and `event_log`, with `connection_location` re-read after a
61
+ location change.
62
+ - **`proxy: null` on `accounts.update()` requires a `country`** in the same
63
+ call. Clearing your own proxy alone used to fall back to an automatic
64
+ location; it is now `CONNECTION_LOCATION_REQUIRED`.
65
+ - **Post engagement counts can be `null`.** On `search.posts`, `search.fromUrl`,
66
+ `companies.posts` and `feed.home` items, `likes`, `comments`
67
+ and `shares` are `number | null`, as the served document now declares.
68
+
69
+ ### Added
70
+
71
+ - **Connection location.** `country` and `allow_country_fallback` on
72
+ `accounts.update()` move an account's location (strict unless
73
+ `allow_country_fallback: true`). Every account read and connect result
74
+ carries `connection_location: { country, current_country, mode, strict }`,
75
+ plus `previous_country` when a connect moved an account you already had.
76
+ The `proxy.protocol` enum gains `socks4`.
77
+ - **`CONNECTION_LOCATION_REQUIRED` and `CONNECTION_LOCATION_UNAVAILABLE`** are
78
+ in `ERROR_CODES`; before this release both decoded to `INTERNAL`.
79
+ `CurviateError.connectionLocation` carries where the account connects from
80
+ now when a `CONNECTION_LOCATION_UNAVAILABLE` followed an applied change.
81
+ - Search and feed post items carry `created_at`, and the author carries
82
+ `display_name` and `type` on the shape without `name`.
83
+ - `AuthIntentBody`, `ConnectionCountry`, `ConnectionLocationSource`,
84
+ `ConnectionLocation`, `AccountDetail`, `AccountUpdateBody` and
85
+ `AccountUpdateResult` are exported.
86
+
87
+ ### Documentation
88
+
89
+ - `posts.get` JSDoc: a post search result's `id` and `share-` post URLs are
90
+ accepted post ids, and `listComments` and the reaction operations take the
91
+ same forms (the old note said they took the opaque `id` only).
92
+
12
93
  ## [0.40.1] - 2026-10-01
13
94
 
14
95
  ### Fixed
package/README.md CHANGED
@@ -37,10 +37,16 @@ const curviate = new Curviate({
37
37
 
38
38
  ## Account-scoped accessor
39
39
 
40
- Every LinkedIn operation (messages, member profiles, invites, posts) is tied to a **managed account**, a LinkedIn session you have connected via the connect flow (`curviate.auth.intent()`). The `curviate.account(id)` accessor fixes the `account_id` on every call so you do not have to thread it manually:
40
+ Every LinkedIn operation (messages, member profiles, invites, posts) is tied to a **managed account**, a LinkedIn session you have connected via the connect flow (`curviate.auth.intent()`). A new connect names where LinkedIn sees the account connecting from, with exactly one of `country` (e.g. `"US"`), `ip` or your own `proxy`:
41
41
 
42
42
  ```ts
43
- // Root-level: tenant-wide operations (accounts, auth, webhooks)
43
+ await curviate.auth.intent({ seat_id, auth_method: "credentials", credentials: { email, password }, country: "US" });
44
+ ```
45
+
46
+ The `curviate.account(id)` accessor fixes the `account_id` on every call so you do not have to thread it manually:
47
+
48
+ ```ts
49
+ // Root-level: tenant-wide operations (accounts, auth, webhooks, drafts)
44
50
  const { items: accounts } = await curviate.accounts.list();
45
51
 
46
52
  // Account-scoped: all LinkedIn ops under a specific account
@@ -52,6 +58,30 @@ const me = await acc.users.get("me"); // your own profile
52
58
  const profile = await acc.users.get("some-user-id"); // someone else's
53
59
  ```
54
60
 
61
+ ## Drafts and scheduled posts
62
+
63
+ A Draft is a stored, editable, unpublished post. Give it an account and a `scheduled_at` and Curviate publishes it at that time. Drafts are tenant-wide, so `drafts` hangs off the root client (a Draft's `account_id` is a field, and optional). `acc.posts.create()` still publishes immediately and does not schedule.
64
+
65
+ ```ts
66
+ const draft = await curviate.drafts.create({
67
+ account_id: "acc_...",
68
+ text: "Three things we learned shipping our first agent integration.",
69
+ scheduled_at: "2026-10-12T09:00:00+02:00", // ISO 8601 with offset; 5 min to 365 days ahead
70
+ });
71
+
72
+ // A video or PDF (up to 50 MiB) goes up as the raw body; images (up to 5 MiB) can ride inline as base64.
73
+ await curviate.drafts.uploadAttachment(draft.id, await readFile("clip.mp4"), {
74
+ filename: "clip.mp4",
75
+ contentType: "video/mp4",
76
+ });
77
+
78
+ await curviate.drafts.update(draft.id, { scheduled_at: null }); // unschedule
79
+ const { id: postId } = await curviate.drafts.publish(draft.id); // or publish now
80
+ const { items } = await curviate.drafts.list({ status: ["scheduled", "published"] });
81
+ ```
82
+
83
+ Refusals carry their own codes: `DRAFT_LIMIT_REACHED`, `MEDIA_QUOTA_EXCEEDED`, `ACCOUNT_REQUIRED`, `DRAFT_NOT_PUBLISHABLE`, `SCHEDULE_CONFLICT` and `DRAFT_PUBLISHING`. A scheduled publish that fails raises the `post.publish_failed` webhook (`post.published` on success); a `failure_code` of `outcome_unknown` means the post may be live, so check the account's posts before retrying.
84
+
55
85
  ---
56
86
 
57
87
  ## First end-to-end call