@curviate/sdk 0.18.1 → 0.20.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 +405 -230
- package/README.md +50 -17
- package/dist/index.d.ts +1578 -1364
- package/dist/index.js +127 -104
- package/package.json +6 -4
- package/src/generated/types.ts +1277 -1128
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# @curviate/sdk
|
|
2
2
|
|
|
3
|
-
The official TypeScript SDK for the [Curviate API](https://docs.curviate.com)
|
|
3
|
+
The official TypeScript SDK for the [Curviate API](https://docs.curviate.com). Agent-native
|
|
4
4
|
LinkedIn infrastructure for AI engineers and agent builders.
|
|
5
5
|
|
|
6
|
-
> **Status:**
|
|
6
|
+
> **Status:** pre-1.0. Full v2 API parity; the surface is public but not yet stability-promised.
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -17,7 +17,7 @@ Requires Node 18+. Works in Cloudflare Workers and Vercel Edge.
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
## Auth
|
|
20
|
+
## Auth: construct the client
|
|
21
21
|
|
|
22
22
|
Get your API key from the Curviate dashboard. Store it as an environment variable.
|
|
23
23
|
|
|
@@ -37,7 +37,7 @@ 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
|
|
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:
|
|
41
41
|
|
|
42
42
|
```ts
|
|
43
43
|
// Root-level: tenant-wide operations (accounts, auth, webhooks)
|
|
@@ -56,7 +56,7 @@ const profile = await acc.users.get("some-user-id"); // someone else's
|
|
|
56
56
|
|
|
57
57
|
## First end-to-end call
|
|
58
58
|
|
|
59
|
-
This snippet lists your connected accounts, picks the first one, and sends a message
|
|
59
|
+
This snippet lists your connected accounts, picks the first one, and sends a message, something an agent might do to automate outreach:
|
|
60
60
|
|
|
61
61
|
```ts
|
|
62
62
|
import { Curviate, isCurviateError } from "@curviate/sdk";
|
|
@@ -78,7 +78,7 @@ async function sendFirstMessage() {
|
|
|
78
78
|
// 3. Send a message to the first chat
|
|
79
79
|
const chat = chats[0]!;
|
|
80
80
|
await acc.messaging.sendMessage(chat.id ?? "", {
|
|
81
|
-
text: "Hi
|
|
81
|
+
text: "Hi, following up from our conversation.",
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
console.log("Message sent.");
|
|
@@ -114,20 +114,22 @@ try {
|
|
|
114
114
|
break;
|
|
115
115
|
default:
|
|
116
116
|
if (err.retryLikelyToSucceed) {
|
|
117
|
-
// Safe to retry
|
|
117
|
+
// Safe to retry: server-side transient error
|
|
118
118
|
await retry();
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
Every error code is documented in the [API reference](https://docs.curviate.com). The
|
|
125
|
+
exported `ErrorCode` type is the complete set, so `tsc` tells you when a `switch` over
|
|
126
|
+
`err.code` has missed one.
|
|
125
127
|
|
|
126
128
|
---
|
|
127
129
|
|
|
128
130
|
## Cursor pagination
|
|
129
131
|
|
|
130
|
-
Resources that return lists support cursor pagination. `curviate.paginate()` is an async iterator that follows the `cursor` field automatically
|
|
132
|
+
Resources that return lists support cursor pagination. `curviate.paginate()` is an async iterator that follows the `cursor` field automatically, so you pull items one at a time without managing cursors:
|
|
131
133
|
|
|
132
134
|
```ts
|
|
133
135
|
// Iterate over every chat across all pages
|
|
@@ -163,27 +165,28 @@ app.post("/webhook", express.raw({ type: "application/json" }), async (req, res)
|
|
|
163
165
|
event = await constructEvent(req.body, sig, secret);
|
|
164
166
|
} catch (err) {
|
|
165
167
|
if (err instanceof WebhookSignatureError) {
|
|
166
|
-
|
|
168
|
+
// 'invalid_signature' | 'replay_detected' | 'malformed_header' | 'malformed_payload'
|
|
169
|
+
console.warn("Bad webhook:", err.reason);
|
|
167
170
|
return res.sendStatus(400);
|
|
168
171
|
}
|
|
169
172
|
throw err;
|
|
170
173
|
}
|
|
171
174
|
|
|
172
|
-
switch (event.
|
|
175
|
+
switch (event.event) {
|
|
173
176
|
case "message.received":
|
|
174
|
-
// event.data is MessagePayload
|
|
177
|
+
// event.data is MessagePayload: account_id, message_id, and so on.
|
|
175
178
|
handleNewMessage(event.data);
|
|
176
179
|
break;
|
|
177
180
|
case "account.connected":
|
|
178
181
|
handleAccountConnected(event.data);
|
|
179
182
|
break;
|
|
180
|
-
//
|
|
183
|
+
// Every other event type is a case in the CurviateEvent union.
|
|
181
184
|
}
|
|
182
185
|
|
|
183
186
|
res.sendStatus(200);
|
|
184
187
|
});
|
|
185
188
|
|
|
186
|
-
// Hono / Vercel Edge
|
|
189
|
+
// Hono / Vercel Edge. Always await; Web Crypto is async.
|
|
187
190
|
app.post("/webhook", async (c) => {
|
|
188
191
|
const rawBody = await c.req.text();
|
|
189
192
|
const event = await constructEvent(rawBody, c.req.header("curviate-signature")!, secret);
|
|
@@ -191,16 +194,46 @@ app.post("/webhook", async (c) => {
|
|
|
191
194
|
});
|
|
192
195
|
```
|
|
193
196
|
|
|
194
|
-
`constructEvent` always returns a `Promise<CurviateEvent
|
|
197
|
+
`constructEvent` always returns a `Promise<CurviateEvent>`. Always `await` it.
|
|
195
198
|
|
|
196
|
-
|
|
199
|
+
Each event also carries its delivery metadata: `event.id`, `event.webhook_id`, and
|
|
200
|
+
`event.delivered_at`.
|
|
201
|
+
|
|
202
|
+
### De-duplicating retries
|
|
203
|
+
|
|
204
|
+
Delivery is at-least-once, so your handler can see the same logical event more than
|
|
205
|
+
once. The key that survives a retry is the payload composite `event.event` plus
|
|
206
|
+
`event.data.account_id` plus `event.data.occurred_at`, which the platform re-sends
|
|
207
|
+
byte-identical on every attempt:
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
const key = `${event.event}:${event.data.account_id}:${event.data.occurred_at}`;
|
|
211
|
+
if (await alreadyProcessed(key)) return res.sendStatus(200);
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Do not key on `event.id`.** That is a `wdl_` id minted per delivery *attempt*, so a
|
|
215
|
+
retry arrives with a different one and storing it would record the same event twice,
|
|
216
|
+
missing exactly the duplicates you were guarding against. It is still worth logging:
|
|
217
|
+
`event.id` is how you match one attempt to one line in your delivery logs, keyed
|
|
218
|
+
alongside the stable `occurred_at` composite above.
|
|
219
|
+
|
|
220
|
+
`WebhookSignatureError` is NOT a `CurviateError`. Narrow with `instanceof WebhookSignatureError`.
|
|
221
|
+
Its `reason` tells you where to look: `malformed_header` means the signature header could not be
|
|
222
|
+
read, `invalid_signature` means the HMAC did not match (check the secret, and check that you passed
|
|
223
|
+
the raw request bytes), `replay_detected` means the event is outside the replay window, and
|
|
224
|
+
`malformed_payload` means the signature was **valid** but the body was not a Curviate event, so
|
|
225
|
+
your secret and header are both fine.
|
|
226
|
+
|
|
227
|
+
> **Upgrading from 0.18.x or earlier?** The event discriminant is `event.event`, not `event.type`.
|
|
228
|
+
> See the 0.19.0 entry in [CHANGELOG.md](./CHANGELOG.md); the change is a one-word edit and it
|
|
229
|
+
> breaks no working code, because `constructEvent` never returned successfully before 0.19.0.
|
|
197
230
|
|
|
198
231
|
---
|
|
199
232
|
|
|
200
233
|
## Links
|
|
201
234
|
|
|
202
235
|
- API reference: https://docs.curviate.com
|
|
203
|
-
- Issues: https://github.com/curviate/sdk/issues
|
|
236
|
+
- Issues: https://github.com/curviate/curviate-sdk/issues
|
|
204
237
|
- Changelog: [CHANGELOG.md](./CHANGELOG.md)
|
|
205
238
|
|
|
206
239
|
## License
|