@zoplio/sdk-js 0.2.0 → 0.3.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zoplio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,14 +1,24 @@
1
1
  # @zoplio/sdk-js
2
2
 
3
- Official Zoplio Node.js/TypeScript SDK for the [Zoplio API v1](../../docs/quickstart.md). MIT licensed.
3
+ Official Zoplio Node.js/TypeScript SDK for the [Zoplio API v1](https://github.com/Zoplio/zoplio-sdk/blob/main/docs/quickstart.md). MIT licensed.
4
4
 
5
- Zoplio schedules meetings for you: you say who and roughly when, Zoplio negotiates with every participant over WhatsApp/email and confirms a slot.
5
+ Zoplio schedules meetings for you: you say who to invite and roughly when, Zoplio negotiates with every invitee over WhatsApp/email and confirms a slot.
6
6
 
7
7
  Requires Node.js >= 18 (uses the global `fetch`).
8
8
 
9
9
  ## Install
10
10
 
11
- Not yet published to npm — consumed from this monorepo. Build with `npm run build` in this package.
11
+ ```bash
12
+ npm i @zoplio/sdk-js
13
+ ```
14
+
15
+ ## Roles
16
+
17
+ The account that owns the API key is the organizer. `participants` are the people Zoplio invites. To arrange a meeting for someone else, set `organizer`.
18
+
19
+ - You are a Zoplio user like anyone on WhatsApp: a meeting you create runs on your calendar, in your timezone and working hours, Zoplio tells you when the invitees answer, and it counts against your plan.
20
+ - Every participant (1-8) is invited; one is enough. Your own number or e-mail as a participant is rejected with `validation_failed`.
21
+ - `organizer` is the optional on-behalf mode (an agency booking for a client): that person is then the organizer, every participant is still invited, and the meeting still bills to your account.
12
22
 
13
23
  ## Usage
14
24
 
@@ -20,36 +30,49 @@ const zoplio = new ZoplioClient({
20
30
  // baseUrl: 'https://api.zoplio.com' (default)
21
31
  });
22
32
 
23
- // Create a meeting Zoplio reaches out to participants and negotiates.
33
+ // Create a meeting. You are the organizer; Zoplio invites Jana.
24
34
  const created = await zoplio.scheduleMeeting(
25
35
  {
26
36
  title: 'Intro call',
27
37
  durationMinutes: 30,
28
- participants: [
29
- { email: 'petr@example.com', name: 'Petr' },
30
- { phone: '+420777123456', name: 'Jana' },
31
- ],
32
- preferredDate: '2026-06-15',
38
+ participants: [{ phone: '+420777123456', name: 'Jana' }],
39
+ preferredDate: '2026-09-16',
33
40
  preferredTime: '14:00',
34
- timezone: 'Europe/Prague',
41
+ timezone: 'Europe/Prague', // always send it with preferredTime
35
42
  },
36
43
  { idempotencyKey: 'order-42-intro-call' }, // optional, safe retries
37
44
  );
38
45
  console.log(created.meetingId, created.status, created.proposedSlots);
39
46
 
40
- // Poll status (or use webhooks instead).
47
+ // Poll status (or use webhooks instead). Each entry of meeting.participants
48
+ // carries status, attending and role ('organizer' | 'participant').
41
49
  const meeting = await zoplio.getMeeting(created.meetingId);
42
50
 
43
51
  // List / reschedule / cancel.
44
52
  await zoplio.listMeetings({ status: 'confirmed', limit: 10 });
45
- await zoplio.rescheduleMeeting(created.meetingId, {
46
- preferredDate: '2026-06-16',
47
- preferredTime: '10:00',
53
+ await zoplio.rescheduleMeeting(
54
+ created.meetingId,
55
+ { preferredDate: '2026-09-17', preferredTime: '10:00', timezone: 'Europe/Prague' },
56
+ { idempotencyKey: 'order-42-intro-call-move-1' }, // a retry replays instead of opening another round
57
+ );
58
+ await zoplio.cancelMeeting(created.meetingId);
59
+ ```
60
+
61
+ On behalf of someone else: set `organizer`. Petr is then the organizer (his calendar and timezone; Zoplio tells him the meeting is being arranged and again once it confirms) and Jana is invited:
62
+
63
+ ```ts
64
+ await zoplio.scheduleMeeting({
65
+ title: 'Intro call',
66
+ organizer: { email: 'petr@example.com', name: 'Petr' },
67
+ participants: [{ phone: '+420777123456', name: 'Jana' }],
68
+ preferredDate: '2026-09-16',
69
+ preferredTime: '14:00',
48
70
  timezone: 'Europe/Prague',
49
71
  });
50
- await zoplio.cancelMeeting(created.meetingId);
51
72
  ```
52
73
 
74
+ Scheduling mode is picked by the date fields you send: exact (`preferredDate` + `preferredTime` + `timezone`), day (`preferredDate` only), range (`earliestDate` + `latestDate`) or open ask (`openAsk: true` plus the window). With no date fields Zoplio proposes one slot per working day over the next seven days at the start of the organizer's working hours (09:00 by default), rendered in each invitee's own timezone.
75
+
53
76
  ## Errors
54
77
 
55
78
  Every non-2xx response throws `ZoplioApiError` with the contract envelope:
@@ -60,20 +83,24 @@ try {
60
83
  } catch (err) {
61
84
  if (err instanceof ZoplioApiError) {
62
85
  err.status; // 404
63
- err.code; // 'not_found' | 'unauthorized' | 'rate_limited' | 'validation_failed' | 'conflict' | 'upstream_error'
86
+ err.code; // 'not_found' | 'unauthorized' | 'rate_limited' | 'validation_failed' | 'conflict' | 'quota_exceeded' | 'upstream_error'
64
87
  err.message; // human-readable
65
88
  err.details; // [{ field, message }] on validation_failed
66
89
  }
67
90
  }
68
91
  ```
69
92
 
93
+ `quota_exceeded` (HTTP 402) means your account's free-plan limit was reached this calendar month, the same limits as for any Zoplio user: 3 confirmed meetings and 15 meeting requests per calendar month (UTC). Meetings still being arranged count against the 3 until they confirm or fall through; `err.message` says which limit it was.
94
+
70
95
  ## Webhooks
71
96
 
72
97
  ```ts
73
- // Subscribe the secret is returned exactly once.
98
+ // Subscribe. The secret is returned exactly once.
74
99
  const hook = await zoplio.createWebhook({
75
100
  url: 'https://example.com/zoplio-hook',
76
- events: ['meeting.confirmed', 'meeting.cancelled'],
101
+ events: ['meeting.confirmed', 'meeting.rescheduled', 'meeting.cancelled'],
102
+ // omit `events` for all five: meeting.created, meeting.confirmed,
103
+ // meeting.cancelled, meeting.rescheduled, negotiation.failed
77
104
  });
78
105
  saveSecret(hook.secret); // whsec_...
79
106
 
@@ -81,7 +108,9 @@ await zoplio.listWebhooks();
81
108
  await zoplio.deleteWebhook(hook.id);
82
109
  ```
83
110
 
84
- Verify deliveries with the static helper pass the RAW request body:
111
+ `meeting.rescheduled` fires the moment a confirmed meeting re-opens to move; its payload carries `previousSlot`, and a fresh `meeting.confirmed` (or a cancellation) follows when the renegotiation resolves.
112
+
113
+ Verify deliveries with the static helper. Pass the RAW request body:
85
114
 
86
115
  ```ts
87
116
  import express from 'express';
@@ -103,5 +132,6 @@ app.post('/zoplio-hook', express.raw({ type: 'application/json' }), (req, res) =
103
132
 
104
133
  ```bash
105
134
  npm run typecheck # tsc --noEmit
135
+ npm test # unit tests (node:test via tsx)
106
136
  npm run build # emit dist/
107
137
  ```
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ApiErrorCode, CancelMeetingResult, CreateWebhookParams, DeleteWebhookResult, FieldDetail, ListMeetingsParams, ListMeetingsResult, ListWebhooksResult, MeetingDetail, RescheduleMeetingParams, RescheduleMeetingResult, ScheduleMeetingOptions, ScheduleMeetingParams, ScheduleMeetingResult, WebhookCreated, ZoplioConfig } from './types';
1
+ import { ApiErrorCode, CancelMeetingResult, CreateWebhookParams, DeleteWebhookResult, FieldDetail, ListMeetingsParams, ListMeetingsResult, ListWebhooksResult, MeetingDetail, RescheduleMeetingOptions, RescheduleMeetingParams, RescheduleMeetingResult, ScheduleMeetingOptions, ScheduleMeetingParams, ScheduleMeetingResult, WebhookCreated, ZoplioConfig } from './types';
2
2
  /**
3
3
  * Error thrown for every non-2xx API response. Carries the contract error
4
4
  * envelope: `{ error: { code, message, details? } }`.
@@ -19,10 +19,17 @@ export declare class ZoplioApiError extends Error {
19
19
  * const zoplio = new ZoplioClient({ apiKey: process.env.ZOPLIO_API_KEY! });
20
20
  * const { meetingId } = await zoplio.scheduleMeeting({
21
21
  * title: 'Intro call',
22
- * participants: [{ email: 'petr@example.com' }],
22
+ * participants: [{ phone: '+420777123456', name: 'Jana' }],
23
+ * preferredDate: '2026-09-16',
24
+ * preferredTime: '14:00',
25
+ * timezone: 'Europe/Prague',
23
26
  * });
24
27
  * ```
25
28
  *
29
+ * The account that owns the API key is the organizer: the meeting runs on
30
+ * your calendar and Zoplio invites `participants`. To arrange a meeting for
31
+ * someone else, set `organizer`.
32
+ *
26
33
  * Requires a `fetch` global (Node.js >= 18).
27
34
  */
28
35
  export declare class ZoplioClient {
@@ -33,20 +40,30 @@ export declare class ZoplioClient {
33
40
  /**
34
41
  * Create a meeting and start negotiating with the participants.
35
42
  * `POST /v1/meetings`
43
+ *
44
+ * You (the account that owns the API key) are the organizer: the meeting
45
+ * runs on your calendar and Zoplio messages every entry of
46
+ * `params.participants` (one is enough). Set `params.organizer` to arrange
47
+ * a meeting for someone else: they are then the organizer (their calendar
48
+ * and timezone; not invited, told that the meeting is being arranged and
49
+ * again once it confirms). A participant equal to your own number or
50
+ * e-mail throws `ZoplioApiError` with code `validation_failed`.
51
+ * Always send `timezone` with `preferredTime`.
36
52
  */
37
53
  scheduleMeeting(params: ScheduleMeetingParams, options?: ScheduleMeetingOptions): Promise<ScheduleMeetingResult>;
38
54
  /**
39
- * Fetch one meeting you organize, with per-participant status.
55
+ * Fetch one meeting you created with this key, with each person's status
56
+ * and role (`organizer` or `participant`).
40
57
  * `GET /v1/meetings/:id`
41
58
  */
42
59
  getMeeting(meetingId: string): Promise<MeetingDetail>;
43
60
  /**
44
- * List meetings you organize, newest first.
61
+ * List meetings you created with this key (on-behalf ones included), newest first.
45
62
  * `GET /v1/meetings?status=&limit=`
46
63
  */
47
64
  listMeetings(params?: ListMeetingsParams): Promise<ListMeetingsResult>;
48
65
  /**
49
- * Cancel a meeting (idempotent cancelling twice still returns `cancelled`).
66
+ * Cancel a meeting (idempotent: cancelling twice still returns `cancelled`).
50
67
  * `POST /v1/meetings/:id/cancel`
51
68
  */
52
69
  cancelMeeting(meetingId: string): Promise<CancelMeetingResult>;
@@ -54,17 +71,23 @@ export declare class ZoplioClient {
54
71
  * Propose a new exact date+time to all participants.
55
72
  * `POST /v1/meetings/:id/reschedule`
56
73
  *
74
+ * Pass `options.idempotencyKey` so a retry replays the original proposal
75
+ * instead of opening another negotiation round: every un-keyed call
76
+ * consumes a round, and exhausting the round limit cancels the meeting.
77
+ *
57
78
  * Throws `ZoplioApiError` with code `conflict` when the requested time
58
79
  * collides with a participant's availability, when the negotiation state
59
- * does not allow re-proposing, or when the negotiation ran out of rounds -
80
+ * does not allow re-proposing, or when the negotiation ran out of rounds:
60
81
  * in that last case the meeting has been cancelled and every participant
61
82
  * told. Throws code `validation_failed` when the requested time is already
62
83
  * in the past; nothing changed and nobody was contacted.
63
84
  */
64
- rescheduleMeeting(meetingId: string, params: RescheduleMeetingParams): Promise<RescheduleMeetingResult>;
85
+ rescheduleMeeting(meetingId: string, params: RescheduleMeetingParams, options?: RescheduleMeetingOptions): Promise<RescheduleMeetingResult>;
65
86
  /**
66
- * Subscribe a URL to meeting lifecycle events. The returned `secret`
67
- * (whsec_...) is shown exactly once store it to verify deliveries.
87
+ * Subscribe a public https URL to meeting lifecycle events (all five when
88
+ * `events` is omitted). The host is DNS-resolved and validated at
89
+ * subscribe time. The returned `secret` (whsec_...) is shown exactly once:
90
+ * store it to verify deliveries.
68
91
  * `POST /v1/webhooks`
69
92
  */
70
93
  createWebhook(params: CreateWebhookParams): Promise<WebhookCreated>;
@@ -81,9 +104,9 @@ export declare class ZoplioClient {
81
104
  /**
82
105
  * Verify a webhook delivery: constant-time comparison of the
83
106
  * `X-Zoplio-Signature` header against HMAC-SHA256(secret, rawBody),
84
- * hex-encoded exactly how Zoplio signs deliveries.
107
+ * hex-encoded, exactly how Zoplio signs deliveries.
85
108
  *
86
- * Pass the RAW request body bytes/string (before any JSON parsing
109
+ * Pass the RAW request body bytes/string (before any JSON parsing:
87
110
  * re-serializing the parsed body may not be byte-identical).
88
111
  */
89
112
  static verifyWebhookSignature(rawBody: string | Uint8Array, signatureHeader: string, secret: string): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,mCAAmC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;gBAErB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE;CAOzF;AAMD;;;;;;;;;;;;GAYG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,YAAY;YAQlB,OAAO;IAqCrB;;;OAGG;IACG,eAAe,CACnB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,qBAAqB,CAAC;IAOjC;;;OAGG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAI3D;;;OAGG;IACG,YAAY,CAAC,MAAM,GAAE,kBAAuB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAQhF;;;OAGG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIpE;;;;;;;;;;OAUG;IACG,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,uBAAuB,CAAC;IAMnC;;;;OAIG;IACG,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IAIzE;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAIjD;;;OAGG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIpE;;;;;;;OAOG;IACH,MAAM,CAAC,sBAAsB,CAC3B,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,GACb,OAAO;CASX"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,mCAAmC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;gBAErB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE;CAOzF;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,YAAY;YAQlB,OAAO;IAqCrB;;;;;;;;;;;;OAYG;IACG,eAAe,CACnB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,qBAAqB,CAAC;IAOjC;;;;OAIG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAI3D;;;OAGG;IACG,YAAY,CAAC,MAAM,GAAE,kBAAuB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAQhF;;;OAGG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIpE;;;;;;;;;;;;;;OAcG;IACG,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,uBAAuB,EAC/B,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,uBAAuB,CAAC;IAcnC;;;;;;OAMG;IACG,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IAIzE;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAIjD;;;OAGG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIpE;;;;;;;OAOG;IACH,MAAM,CAAC,sBAAsB,CAC3B,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,GACb,OAAO;CASX"}
package/dist/client.js CHANGED
@@ -29,10 +29,17 @@ exports.ZoplioApiError = ZoplioApiError;
29
29
  * const zoplio = new ZoplioClient({ apiKey: process.env.ZOPLIO_API_KEY! });
30
30
  * const { meetingId } = await zoplio.scheduleMeeting({
31
31
  * title: 'Intro call',
32
- * participants: [{ email: 'petr@example.com' }],
32
+ * participants: [{ phone: '+420777123456', name: 'Jana' }],
33
+ * preferredDate: '2026-09-16',
34
+ * preferredTime: '14:00',
35
+ * timezone: 'Europe/Prague',
33
36
  * });
34
37
  * ```
35
38
  *
39
+ * The account that owns the API key is the organizer: the meeting runs on
40
+ * your calendar and Zoplio invites `participants`. To arrange a meeting for
41
+ * someone else, set `organizer`.
42
+ *
36
43
  * Requires a `fetch` global (Node.js >= 18).
37
44
  */
38
45
  class ZoplioClient {
@@ -72,6 +79,15 @@ class ZoplioClient {
72
79
  /**
73
80
  * Create a meeting and start negotiating with the participants.
74
81
  * `POST /v1/meetings`
82
+ *
83
+ * You (the account that owns the API key) are the organizer: the meeting
84
+ * runs on your calendar and Zoplio messages every entry of
85
+ * `params.participants` (one is enough). Set `params.organizer` to arrange
86
+ * a meeting for someone else: they are then the organizer (their calendar
87
+ * and timezone; not invited, told that the meeting is being arranged and
88
+ * again once it confirms). A participant equal to your own number or
89
+ * e-mail throws `ZoplioApiError` with code `validation_failed`.
90
+ * Always send `timezone` with `preferredTime`.
75
91
  */
76
92
  async scheduleMeeting(params, options) {
77
93
  const headers = options?.idempotencyKey
@@ -80,14 +96,15 @@ class ZoplioClient {
80
96
  return this.request('POST', '/v1/meetings', params, headers);
81
97
  }
82
98
  /**
83
- * Fetch one meeting you organize, with per-participant status.
99
+ * Fetch one meeting you created with this key, with each person's status
100
+ * and role (`organizer` or `participant`).
84
101
  * `GET /v1/meetings/:id`
85
102
  */
86
103
  async getMeeting(meetingId) {
87
104
  return this.request('GET', `/v1/meetings/${encodeURIComponent(meetingId)}`);
88
105
  }
89
106
  /**
90
- * List meetings you organize, newest first.
107
+ * List meetings you created with this key (on-behalf ones included), newest first.
91
108
  * `GET /v1/meetings?status=&limit=`
92
109
  */
93
110
  async listMeetings(params = {}) {
@@ -100,7 +117,7 @@ class ZoplioClient {
100
117
  return this.request('GET', `/v1/meetings${qs ? `?${qs}` : ''}`);
101
118
  }
102
119
  /**
103
- * Cancel a meeting (idempotent cancelling twice still returns `cancelled`).
120
+ * Cancel a meeting (idempotent: cancelling twice still returns `cancelled`).
104
121
  * `POST /v1/meetings/:id/cancel`
105
122
  */
106
123
  async cancelMeeting(meetingId) {
@@ -110,20 +127,29 @@ class ZoplioClient {
110
127
  * Propose a new exact date+time to all participants.
111
128
  * `POST /v1/meetings/:id/reschedule`
112
129
  *
130
+ * Pass `options.idempotencyKey` so a retry replays the original proposal
131
+ * instead of opening another negotiation round: every un-keyed call
132
+ * consumes a round, and exhausting the round limit cancels the meeting.
133
+ *
113
134
  * Throws `ZoplioApiError` with code `conflict` when the requested time
114
135
  * collides with a participant's availability, when the negotiation state
115
- * does not allow re-proposing, or when the negotiation ran out of rounds -
136
+ * does not allow re-proposing, or when the negotiation ran out of rounds:
116
137
  * in that last case the meeting has been cancelled and every participant
117
138
  * told. Throws code `validation_failed` when the requested time is already
118
139
  * in the past; nothing changed and nobody was contacted.
119
140
  */
120
- async rescheduleMeeting(meetingId, params) {
121
- return this.request('POST', `/v1/meetings/${encodeURIComponent(meetingId)}/reschedule`, params);
141
+ async rescheduleMeeting(meetingId, params, options) {
142
+ const headers = options?.idempotencyKey
143
+ ? { 'X-Idempotency-Key': options.idempotencyKey }
144
+ : undefined;
145
+ return this.request('POST', `/v1/meetings/${encodeURIComponent(meetingId)}/reschedule`, params, headers);
122
146
  }
123
147
  // ── Webhooks ───────────────────────────────────────────────────────
124
148
  /**
125
- * Subscribe a URL to meeting lifecycle events. The returned `secret`
126
- * (whsec_...) is shown exactly once store it to verify deliveries.
149
+ * Subscribe a public https URL to meeting lifecycle events (all five when
150
+ * `events` is omitted). The host is DNS-resolved and validated at
151
+ * subscribe time. The returned `secret` (whsec_...) is shown exactly once:
152
+ * store it to verify deliveries.
127
153
  * `POST /v1/webhooks`
128
154
  */
129
155
  async createWebhook(params) {
@@ -146,9 +172,9 @@ class ZoplioClient {
146
172
  /**
147
173
  * Verify a webhook delivery: constant-time comparison of the
148
174
  * `X-Zoplio-Signature` header against HMAC-SHA256(secret, rawBody),
149
- * hex-encoded exactly how Zoplio signs deliveries.
175
+ * hex-encoded, exactly how Zoplio signs deliveries.
150
176
  *
151
- * Pass the RAW request body bytes/string (before any JSON parsing
177
+ * Pass the RAW request body bytes/string (before any JSON parsing:
152
178
  * re-serializing the parsed body may not be byte-identical).
153
179
  */
154
180
  static verifyWebhookSignature(rawBody, signatureHeader, secret) {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Wire types for the Zoplio public API v1 (served by api-gateway under /v1).
3
- * Shapes mirror apps/api-gateway/src these are the exact JSON bodies on the
3
+ * Shapes mirror apps/api-gateway/src: these are the exact JSON bodies on the
4
4
  * wire, not internal models.
5
5
  */
6
6
  export interface ZoplioConfig {
@@ -17,14 +17,14 @@ export interface FieldDetail {
17
17
  message: string;
18
18
  }
19
19
  export type MeetingStatus = 'draft' | 'negotiating' | 'confirmed' | 'cancelled' | 'rescheduling';
20
- /** Public webhook event names the only events delivered to subscribers. */
21
- export type WebhookEvent = 'meeting.created' | 'meeting.confirmed' | 'meeting.cancelled' | 'negotiation.failed';
20
+ /** Public webhook event names: the only events delivered to subscribers. */
21
+ export type WebhookEvent = 'meeting.created' | 'meeting.confirmed' | 'meeting.cancelled' | 'meeting.rescheduled' | 'negotiation.failed';
22
22
  /** A concrete time slot. ISO 8601 datetimes (UTC). */
23
23
  export interface Slot {
24
24
  start: string;
25
25
  end: string;
26
26
  }
27
- /** Meeting participant input each entry needs `phone` (E.164) or `email`. */
27
+ /** A person (organizer or participant): needs `phone` (E.164) or `email`. */
28
28
  export interface ParticipantInput {
29
29
  /** E.164 phone number, e.g. `+420777123456`. */
30
30
  phone?: string;
@@ -32,28 +32,59 @@ export interface ParticipantInput {
32
32
  /** Display name, max 200 chars. */
33
33
  name?: string;
34
34
  }
35
+ /**
36
+ * Body of `POST /v1/meetings`. The account that owns the API key is the
37
+ * organizer; `participants` are the people Zoplio invites. To arrange a
38
+ * meeting for someone else, set `organizer`.
39
+ *
40
+ * Scheduling mode is picked by the date fields you send: exact
41
+ * (`preferredDate` + `preferredTime` + `timezone`), day (`preferredDate`
42
+ * only), range (`earliestDate` + `latestDate`) or open ask (`openAsk: true`
43
+ * plus the window). With no date fields Zoplio proposes one slot per working
44
+ * day over the next seven days at the start of the organizer's working hours.
45
+ */
35
46
  export interface ScheduleMeetingParams {
36
47
  /** Max 300 chars. Defaults to "Meeting" server-side. */
37
48
  title?: string;
38
49
  /** Integer 5..1440. Defaults to 30 server-side. */
39
50
  durationMinutes?: number;
40
- /** 1..8 participants, each with a phone or an email. */
51
+ /**
52
+ * On-behalf mode: the person the meeting is for when it is not you. Zoplio
53
+ * uses their calendar and timezone, does not invite them and tells them the
54
+ * meeting is being arranged. When omitted, you (the account that owns the
55
+ * API key) are the organizer.
56
+ */
57
+ organizer?: ParticipantInput;
58
+ /**
59
+ * The people Zoplio invites (1..8), each with a phone or an email; one is
60
+ * enough. Your own number or e-mail is rejected with `validation_failed`.
61
+ */
41
62
  participants: ParticipantInput[];
42
63
  /** YYYY-MM-DD. Required when `preferredTime` is set. */
43
64
  preferredDate?: string;
44
65
  /** HH:MM (24h). */
45
66
  preferredTime?: string;
46
- /** IANA timezone the preferredDate/preferredTime are expressed in. */
67
+ /**
68
+ * IANA timezone the preferredDate/preferredTime are expressed in. Always
69
+ * send it with `preferredTime`: without it the time is read in the
70
+ * organizer's stored timezone (your account's zone, UTC for an account
71
+ * Zoplio has only seen by e-mail; for an on-behalf organizer the phone's
72
+ * country zone, or UTC for an e-mail contact).
73
+ */
47
74
  timezone?: string;
48
- /** YYYY-MM-DD. */
75
+ /** YYYY-MM-DD. Start of the window for range and open-ask scheduling. */
49
76
  earliestDate?: string;
50
- /** YYYY-MM-DD. */
77
+ /** YYYY-MM-DD. End of the window for range and open-ask scheduling. */
51
78
  latestDate?: string;
52
79
  /** Ask participants for their availability instead of proposing slots. */
53
80
  openAsk?: boolean;
54
81
  /** Max 500 chars. Omitting it makes the meeting virtual. */
55
82
  location?: string;
56
- /** Set `false` for meetings the organizer does not attend. */
83
+ /**
84
+ * Set `false` when the organizer (you, or the on-behalf `organizer`) only
85
+ * arranges the meeting and will not attend; the invitees then meet among
86
+ * themselves, so list at least two of them.
87
+ */
57
88
  organizerAttending?: boolean;
58
89
  }
59
90
  export interface ScheduleMeetingOptions {
@@ -77,6 +108,11 @@ export interface MeetingParticipant {
77
108
  /** e.g. `pending`, `accepted`, `declined`, `counter-proposed`. */
78
109
  status: string;
79
110
  attending: boolean;
111
+ /**
112
+ * `organizer` is the person the meeting is for (you, or the on-behalf
113
+ * `organizer`); `participant` is an invitee.
114
+ */
115
+ role: 'organizer' | 'participant';
80
116
  }
81
117
  export interface MeetingDetail {
82
118
  id: string;
@@ -108,25 +144,41 @@ export interface RescheduleMeetingParams {
108
144
  preferredDate: string;
109
145
  /** HH:MM (24h). Required. */
110
146
  preferredTime: string;
111
- /** IANA timezone the date/time are expressed in. */
147
+ /**
148
+ * IANA timezone the date/time are expressed in. Always send it; without it
149
+ * the time is read in a stored timezone rather than yours.
150
+ */
112
151
  timezone?: string;
113
152
  }
153
+ export interface RescheduleMeetingOptions {
154
+ /**
155
+ * Sent as `X-Idempotency-Key` (1-128 chars). Replaying the same key returns
156
+ * the original proposal instead of opening another negotiation round, so a
157
+ * retry cannot walk the meeting into the round-limit cancellation. Send a
158
+ * new key when you genuinely want to move the meeting again.
159
+ */
160
+ idempotencyKey?: string;
161
+ }
114
162
  export interface RescheduleMeetingResult {
115
163
  meetingId: string;
116
164
  status: 'negotiating';
117
165
  proposedSlots: Slot[];
118
166
  }
119
167
  export interface CreateWebhookParams {
120
- /** Public http(s) endpoint. Private/internal hosts are rejected. */
168
+ /**
169
+ * Public https endpoint. The host is DNS-resolved and validated at
170
+ * subscribe time: http URLs, hosts that do not resolve, and hosts
171
+ * resolving to private/internal addresses are rejected.
172
+ */
121
173
  url: string;
122
- /** Defaults to all four events when omitted. */
174
+ /** Defaults to all five events when omitted. */
123
175
  events?: WebhookEvent[];
124
176
  }
125
177
  export interface WebhookCreated {
126
178
  id: string;
127
179
  url: string;
128
180
  events: WebhookEvent[];
129
- /** `whsec_` signing secret returned exactly once, at creation. */
181
+ /** `whsec_` signing secret, returned exactly once, at creation. */
130
182
  secret: string;
131
183
  }
132
184
  export interface WebhookSummary {
@@ -152,12 +204,19 @@ export interface WebhookDeliveryBody {
152
204
  payload: {
153
205
  meetingId?: string;
154
206
  organizerUserId?: string;
207
+ /**
208
+ * The account that owns the API key; equals organizerUserId unless the
209
+ * meeting was arranged on behalf of someone else.
210
+ */
211
+ billingAccountId?: string;
155
212
  title?: string;
156
213
  /** Present on confirmed/cancelled/failed events. */
157
214
  negotiationId?: string;
158
215
  participantEmails?: string[];
159
216
  /** Present on meeting.confirmed. */
160
217
  confirmedSlot?: Slot;
218
+ /** Present on meeting.rescheduled: the slot the meeting left. */
219
+ previousSlot?: Slot;
161
220
  [key: string]: unknown;
162
221
  };
163
222
  /** ISO 8601 delivery timestamp. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Wire types for the Zoplio public API v1 (served by api-gateway under /v1).
4
- * Shapes mirror apps/api-gateway/src these are the exact JSON bodies on the
4
+ * Shapes mirror apps/api-gateway/src: these are the exact JSON bodies on the
5
5
  * wire, not internal models.
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zoplio/sdk-js",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Official Zoplio Node.js/TypeScript SDK for the Zoplio API v1 (MIT)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -21,7 +21,7 @@
21
21
  "scripts": {
22
22
  "build": "tsc",
23
23
  "typecheck": "tsc --noEmit",
24
- "test": "npx --yes tsx@4.19.2 --test \"src/**/__tests__/*.test.ts\"",
24
+ "test": "npx --yes tsx@4.19.2 --test src/__tests__/*.test.ts",
25
25
  "prepublishOnly": "npm run build"
26
26
  },
27
27
  "license": "MIT",