@chronary/sdk 0.1.3

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.
@@ -0,0 +1,1016 @@
1
+ /**
2
+ * APIPromise wraps a fetch call as a thenable so callers can `await` it
3
+ * for parsed data, or call `.withResponse()` to get both parsed data and the raw
4
+ * Response (headers, status, etc.).
5
+ *
6
+ * ```ts
7
+ * // Normal — just the data
8
+ * const agent = await client.agents.get('agt_1');
9
+ *
10
+ * // With response access
11
+ * const { data, response } = await client.agents.get('agt_1').withResponse();
12
+ * console.log(response.status);
13
+ * console.log(response.headers.get('x-request-id'));
14
+ * ```
15
+ */
16
+ /**
17
+ * Parsed quota snapshot from the IETF `RateLimit` / `RateLimit-Policy` headers
18
+ * (draft-ietf-httpapi-ratelimit-headers). Present on responses from endpoints
19
+ * that enforce quotas (most authenticated routes); absent on unauthenticated
20
+ * or unlimited-plan responses.
21
+ */
22
+ interface QuotaSnapshot {
23
+ /** Configured ceiling (e.g. `1_000_000` API calls/month). Parsed from `RateLimit-Policy`. */
24
+ limit: number;
25
+ /** Remaining quota in the current window. Parsed from `RateLimit`. */
26
+ remaining: number;
27
+ /** Wall-clock time when the window resets. Computed from the `t=` delta-seconds in `RateLimit`. */
28
+ resetAt: Date;
29
+ }
30
+ interface RawResponse {
31
+ status: number;
32
+ headers: Headers;
33
+ url: string;
34
+ /**
35
+ * Typed view of the IETF RateLimit headers when present. Use this instead of
36
+ * parsing `headers.get('ratelimit')` yourself. `undefined` for responses
37
+ * that don't emit quota headers (public endpoints, unlimited plans).
38
+ */
39
+ quota?: QuotaSnapshot;
40
+ }
41
+ interface WithResponse<T> {
42
+ data: T;
43
+ response: RawResponse;
44
+ }
45
+ /**
46
+ * APIPromise is a thenable that resolves to `T` when awaited, but also
47
+ * exposes `.withResponse()` to get both the data and raw HTTP response.
48
+ *
49
+ * Because it implements `.then()`, it can be awaited, used with `Promise.all()`,
50
+ * and chained with `.then()` / `.catch()` / `.finally()`.
51
+ */
52
+ declare class APIPromise<T> implements PromiseLike<T> {
53
+ private innerPromise;
54
+ constructor(responsePromise: Promise<{
55
+ data: T;
56
+ rawResponse: RawResponse;
57
+ }>);
58
+ /**
59
+ * Returns both the parsed data and the raw HTTP response.
60
+ */
61
+ withResponse(): Promise<WithResponse<T>>;
62
+ /**
63
+ * Implements the thenable interface. When awaited, resolves to just the parsed data `T`.
64
+ */
65
+ then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
66
+ /**
67
+ * Attaches a rejection handler.
68
+ */
69
+ catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<T | TResult>;
70
+ /**
71
+ * Attaches a handler that runs on both fulfillment and rejection.
72
+ */
73
+ finally(onfinally?: (() => void) | null): Promise<T>;
74
+ }
75
+
76
+ interface ChronaryConfig {
77
+ apiKey?: string;
78
+ baseUrl?: string;
79
+ timeout?: number;
80
+ maxRetries?: number;
81
+ logLevel?: LogLevel;
82
+ fetch?: typeof globalThis.fetch;
83
+ appInfo?: AppInfo;
84
+ /**
85
+ * Extra headers to attach to every request. Used by wrapper packages
86
+ * (e.g. `chronary-mcp`) to set `X-Chronary-Client` so the API can
87
+ * attribute the wrapper's traffic separately from the bare TS SDK's.
88
+ * Header keys here override the SDK defaults — choose wisely.
89
+ */
90
+ extraHeaders?: Record<string, string>;
91
+ }
92
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'off';
93
+ interface AppInfo {
94
+ name: string;
95
+ version?: string;
96
+ }
97
+ interface RequestOptions {
98
+ signal?: AbortSignal;
99
+ timeout?: number;
100
+ idempotencyKey?: string;
101
+ }
102
+ interface PageResponse<T> {
103
+ data: T[];
104
+ total: number;
105
+ limit: number;
106
+ offset: number;
107
+ }
108
+ interface Page<T> {
109
+ data: T[];
110
+ total: number;
111
+ limit: number;
112
+ offset: number;
113
+ hasMore: boolean;
114
+ }
115
+ interface Agent {
116
+ id: string;
117
+ orgId: string;
118
+ name: string;
119
+ type: 'ai' | 'human' | 'resource';
120
+ description: string | null;
121
+ status: 'active' | 'paused' | 'decommissioned';
122
+ metadata: Record<string, unknown>;
123
+ createdAt: string;
124
+ updatedAt: string;
125
+ }
126
+ interface CreateAgentParams {
127
+ name: string;
128
+ type: 'ai' | 'human' | 'resource';
129
+ description?: string;
130
+ metadata?: Record<string, unknown>;
131
+ }
132
+ interface UpdateAgentParams {
133
+ name?: string;
134
+ description?: string | null;
135
+ metadata?: Record<string, unknown>;
136
+ status?: 'active' | 'paused';
137
+ }
138
+ interface ListAgentsParams {
139
+ type?: 'ai' | 'human' | 'resource';
140
+ status?: 'active' | 'paused' | 'decommissioned';
141
+ limit?: number;
142
+ offset?: number;
143
+ }
144
+ interface Calendar {
145
+ id: string;
146
+ orgId: string;
147
+ agentId: string | null;
148
+ name: string;
149
+ timezone: string;
150
+ metadata: Record<string, unknown>;
151
+ ical_url: string;
152
+ deletedAt: string | null;
153
+ createdAt: string;
154
+ updatedAt: string;
155
+ }
156
+ interface CreateCalendarParams {
157
+ name: string;
158
+ timezone: string;
159
+ agent_status?: 'idle' | 'working' | 'waiting' | 'error';
160
+ metadata?: Record<string, unknown>;
161
+ }
162
+ interface UpdateCalendarParams {
163
+ name?: string;
164
+ timezone?: string;
165
+ agent_status?: 'idle' | 'working' | 'waiting' | 'error';
166
+ metadata?: Record<string, unknown>;
167
+ }
168
+ interface ListCalendarsParams {
169
+ agentId?: string;
170
+ include?: 'all';
171
+ limit?: number;
172
+ offset?: number;
173
+ }
174
+ type EventStatus = 'confirmed' | 'tentative' | 'cancelled' | 'hold';
175
+ interface CalendarEvent {
176
+ id: string;
177
+ calendarId: string;
178
+ orgId: string;
179
+ title: string;
180
+ description: string | null;
181
+ startTime: string;
182
+ endTime: string;
183
+ allDay: boolean;
184
+ status: EventStatus;
185
+ source: 'internal' | 'external_ical';
186
+ metadata: Record<string, unknown>;
187
+ holdExpiresAt: string | null;
188
+ holdPriority: number | null;
189
+ deletedAt: string | null;
190
+ createdAt: string;
191
+ updatedAt: string;
192
+ }
193
+ interface CreateEventParams {
194
+ title: string;
195
+ start_time: string;
196
+ end_time: string;
197
+ description?: string;
198
+ all_day?: boolean;
199
+ status?: EventStatus;
200
+ metadata?: Record<string, unknown>;
201
+ /** ISO 8601 timestamp. Required when status='hold'. Must be 30s-15min in the future. */
202
+ hold_expires_at?: string;
203
+ /** Priority for conflict resolution. Only valid with status='hold'. 0-100. */
204
+ hold_priority?: number;
205
+ }
206
+ interface UpdateEventParams {
207
+ title?: string;
208
+ description?: string | null;
209
+ start_time?: string;
210
+ end_time?: string;
211
+ all_day?: boolean;
212
+ /** Holds cannot be updated via PATCH — use /confirm or /release instead. */
213
+ status?: 'confirmed' | 'tentative' | 'cancelled';
214
+ metadata?: Record<string, unknown>;
215
+ }
216
+ interface ListEventsParams {
217
+ calendarId?: string;
218
+ agentId?: string;
219
+ start_after?: string;
220
+ start_before?: string;
221
+ status?: EventStatus;
222
+ source?: 'internal' | 'external_ical';
223
+ limit?: number;
224
+ offset?: number;
225
+ }
226
+ type SlotDuration = '15m' | '30m' | '45m' | '1h' | '2h';
227
+ interface AvailabilitySlot {
228
+ start: string;
229
+ end: string;
230
+ }
231
+ interface BusyBlock {
232
+ start: string;
233
+ end: string;
234
+ calendar_id?: string;
235
+ event_id?: string;
236
+ }
237
+ interface AvailabilityParams {
238
+ start: string;
239
+ end: string;
240
+ slot_duration?: SlotDuration;
241
+ include_busy?: boolean;
242
+ }
243
+ interface CrossAgentAvailabilityParams {
244
+ agents: string[];
245
+ start: string;
246
+ end: string;
247
+ slot_duration?: SlotDuration;
248
+ calendars?: string[];
249
+ include_busy?: boolean;
250
+ }
251
+ interface AvailabilityResponse {
252
+ agents: string[];
253
+ slots: AvailabilitySlot[];
254
+ per_agent_busy?: Record<string, BusyBlock[]>;
255
+ }
256
+ type AgentStatus = 'idle' | 'working' | 'waiting' | 'error';
257
+ interface CalendarContext {
258
+ calendar_id: string;
259
+ now: string;
260
+ agent_status: AgentStatus;
261
+ current_event: CalendarEvent | null;
262
+ next_event: CalendarEvent | null;
263
+ recent_events: CalendarEvent[];
264
+ upcoming: CalendarEvent[];
265
+ }
266
+ interface WorkingHoursDay {
267
+ start: string;
268
+ end: string;
269
+ }
270
+ interface WorkingHours {
271
+ mon?: WorkingHoursDay;
272
+ tue?: WorkingHoursDay;
273
+ wed?: WorkingHoursDay;
274
+ thu?: WorkingHoursDay;
275
+ fri?: WorkingHoursDay;
276
+ sat?: WorkingHoursDay;
277
+ sun?: WorkingHoursDay;
278
+ }
279
+ interface AvailabilityRules {
280
+ id: string;
281
+ calendar_id: string;
282
+ buffer_before_minutes: number;
283
+ buffer_after_minutes: number;
284
+ working_hours: WorkingHours | null;
285
+ timezone: string;
286
+ created_at: string;
287
+ updated_at: string;
288
+ }
289
+ interface SetAvailabilityRulesParams {
290
+ buffer_before_minutes?: number;
291
+ buffer_after_minutes?: number;
292
+ working_hours?: WorkingHours | null;
293
+ timezone?: string;
294
+ }
295
+ interface Webhook {
296
+ id: string;
297
+ orgId: string;
298
+ url: string;
299
+ secret?: string;
300
+ events: string[];
301
+ active: boolean;
302
+ createdAt: string;
303
+ }
304
+ interface CreateWebhookParams {
305
+ url: string;
306
+ events: string[];
307
+ }
308
+ interface UpdateWebhookParams {
309
+ url?: string;
310
+ events?: string[];
311
+ active?: boolean;
312
+ }
313
+ interface ListWebhooksParams {
314
+ limit?: number;
315
+ offset?: number;
316
+ }
317
+ interface WebhookDelivery {
318
+ id: string;
319
+ subscription_id: string;
320
+ event_type: string;
321
+ status: 'pending' | 'delivered' | 'failed';
322
+ attempts: number;
323
+ last_attempt_at: string | null;
324
+ next_retry_at: string | null;
325
+ created_at: string;
326
+ payload?: Record<string, unknown>;
327
+ }
328
+ interface WebhookDeliveryStats {
329
+ pending: number;
330
+ delivered: number;
331
+ failed: number;
332
+ }
333
+ interface WebhookDeliveryListResponse {
334
+ data: WebhookDelivery[];
335
+ total: number;
336
+ limit: number;
337
+ offset: number;
338
+ stats: WebhookDeliveryStats;
339
+ }
340
+ interface ListWebhookDeliveriesParams {
341
+ limit?: number;
342
+ offset?: number;
343
+ status?: 'pending' | 'delivered' | 'failed';
344
+ include_payload?: boolean;
345
+ }
346
+ interface ICalSubscription {
347
+ id: string;
348
+ orgId: string;
349
+ agentId: string;
350
+ calendarId: string;
351
+ url: string;
352
+ label: string | null;
353
+ status: 'active' | 'error' | 'paused';
354
+ lastSyncedAt: string | null;
355
+ lastError: string | null;
356
+ createdAt: string;
357
+ }
358
+ interface CreateICalSubscriptionParams {
359
+ calendar_id: string;
360
+ url: string;
361
+ label?: string;
362
+ }
363
+ interface UpdateICalSubscriptionParams {
364
+ label?: string;
365
+ url?: string;
366
+ }
367
+ interface ListICalSubscriptionsParams {
368
+ agentId?: string;
369
+ status?: 'active' | 'error' | 'paused';
370
+ limit?: number;
371
+ offset?: number;
372
+ }
373
+ type ProposalStatus = 'pending' | 'confirmed' | 'expired' | 'cancelled';
374
+ interface ProposalSlot {
375
+ id?: string;
376
+ start_time: string;
377
+ end_time: string;
378
+ weight?: number;
379
+ calendar_id?: string | null;
380
+ }
381
+ type ProposalResponseAction = 'accept' | 'decline' | 'counter';
382
+ interface ProposalResponse {
383
+ id: string;
384
+ agent_id: string;
385
+ response: ProposalResponseAction;
386
+ selected_slot_id: string | null;
387
+ counter_slots: ProposalSlot[] | null;
388
+ message: string | null;
389
+ created_at: string;
390
+ }
391
+ interface ProposalSummary {
392
+ id: string;
393
+ title: string;
394
+ description: string | null;
395
+ organizer_agent_id: string;
396
+ participant_agent_ids: string[];
397
+ calendar_id: string;
398
+ status: ProposalStatus;
399
+ expires_at: string | null;
400
+ resolved_slot: ProposalSlot | null;
401
+ created_event_id: string | null;
402
+ metadata: Record<string, unknown>;
403
+ created_at: string;
404
+ updated_at: string;
405
+ }
406
+ interface Proposal extends ProposalSummary {
407
+ slots: ProposalSlot[];
408
+ responses: ProposalResponse[];
409
+ }
410
+ interface CreateProposalParams {
411
+ title: string;
412
+ description?: string;
413
+ organizer_agent_id: string;
414
+ participant_agent_ids: string[];
415
+ calendar_id: string;
416
+ slots: ProposalSlot[];
417
+ expires_at?: string;
418
+ metadata?: Record<string, unknown>;
419
+ }
420
+ interface RespondToProposalParams {
421
+ agent_id: string;
422
+ response: ProposalResponseAction;
423
+ selected_slot_id?: string;
424
+ counter_slots?: ProposalSlot[];
425
+ message?: string;
426
+ }
427
+ interface ListProposalsParams {
428
+ status?: ProposalStatus;
429
+ organizer_agent_id?: string;
430
+ limit?: number;
431
+ offset?: number;
432
+ }
433
+ type ResolveProposalResponse = {
434
+ status: 'confirmed';
435
+ resolved_slot: ProposalSlot;
436
+ } | {
437
+ status: 'cancelled';
438
+ reason: string;
439
+ };
440
+ interface CancelProposalResponse {
441
+ status: 'cancelled';
442
+ }
443
+ interface ScopedApiKey {
444
+ id: string;
445
+ key_prefix: string;
446
+ agent_id: string;
447
+ label: string | null;
448
+ created_at: string;
449
+ }
450
+ interface CreatedScopedApiKey extends ScopedApiKey {
451
+ key: string;
452
+ }
453
+ interface CreateScopedApiKeyParams {
454
+ agent_id: string;
455
+ label?: string;
456
+ }
457
+ interface UsageMetric {
458
+ used: number;
459
+ limit: number | null;
460
+ }
461
+ /**
462
+ * Temporal-hold lifecycle counters for the current period. Informational —
463
+ * not gated by any plan limit. The funnel identity
464
+ * `created = confirmed + expired + active` holds, where `active` is derived
465
+ * (not stored). Counts cover all three end-of-hold paths: TTL expiry,
466
+ * manual release, and priority-bump.
467
+ */
468
+ interface HoldsUsage {
469
+ created: number;
470
+ confirmed: number;
471
+ expired: number;
472
+ }
473
+ /**
474
+ * Availability requests that touched more than one calendar in the current
475
+ * period. Informational — gated separately by the
476
+ * `cross_calendar_availability` capability, not by this counter.
477
+ */
478
+ interface CrossCalendarQueriesUsage {
479
+ used: number;
480
+ }
481
+ interface Usage {
482
+ period_start: string;
483
+ period_end: string;
484
+ plan: string;
485
+ agents: UsageMetric;
486
+ calendars: UsageMetric;
487
+ events: UsageMetric;
488
+ api_calls: UsageMetric;
489
+ webhooks: UsageMetric;
490
+ availability_queries: UsageMetric;
491
+ ical_subscriptions: UsageMetric;
492
+ proposals: UsageMetric;
493
+ holds: HoldsUsage;
494
+ cross_calendar_queries: CrossCalendarQueriesUsage;
495
+ }
496
+ interface AuditLogEntry {
497
+ id: string;
498
+ action: string;
499
+ /** First 20 chars of the actor API key. Never the full key. */
500
+ actor_key_prefix: string | null;
501
+ /** Scoped-key agent ID when the actor used a chr_ak_* key. */
502
+ agent_id: string | null;
503
+ /** Entity IDs extracted from the request path (e.g. "agt_1/cal_2"). */
504
+ resource: string | null;
505
+ ip: string | null;
506
+ status: number;
507
+ method: string;
508
+ /** Route template with entity IDs replaced by :id placeholders. */
509
+ path: string;
510
+ duration_ms: number;
511
+ request_id: string | null;
512
+ created_at: string;
513
+ }
514
+ interface ListAuditLogParams {
515
+ /** Lower bound (inclusive, ISO-8601). Clamped to the retention window. */
516
+ from?: string;
517
+ /** Upper bound (inclusive, ISO-8601). Defaults to now. */
518
+ to?: string;
519
+ /** Filter by exact action name, e.g. "agent.create". */
520
+ action?: string;
521
+ /** Filter by the first 20 chars of the actor API key. */
522
+ actor_key_prefix?: string;
523
+ /** Opaque cursor from a previous response for keyset pagination. */
524
+ cursor?: string;
525
+ /** Page size (1–200). Defaults to 50. */
526
+ limit?: number;
527
+ }
528
+ interface AuditLogResponse {
529
+ data: AuditLogEntry[];
530
+ pagination: {
531
+ /** Opaque cursor for the next page. Null if no more results. */
532
+ next_cursor: string | null;
533
+ };
534
+ /**
535
+ * Audit-log retention window for the caller's plan (days).
536
+ * Null = unlimited (Custom tier, per-contract).
537
+ */
538
+ retention_days: number | null;
539
+ /**
540
+ * True when the requested `from` was outside the retention window and
541
+ * was clamped. Display an upgrade hint when this is true.
542
+ */
543
+ range_clamped: boolean;
544
+ }
545
+ type PlanId = 'free' | 'pro' | 'custom';
546
+ interface PlanLimits {
547
+ agents: number | null;
548
+ calendars: number | null;
549
+ events: number | null;
550
+ api_calls: number | null;
551
+ webhook_deliveries: number | null;
552
+ availability_queries: number | null;
553
+ ical_subscriptions: number | null;
554
+ proposals: number | null;
555
+ }
556
+ interface Plan {
557
+ id: PlanId;
558
+ name: string;
559
+ tagline: string;
560
+ /** Recurring monthly amount in the smallest currency unit (USD cents). `null` for custom-priced tiers. */
561
+ price: number | null;
562
+ /** Lowercase ISO-4217 code. `null` for custom-priced tiers. */
563
+ currency: string | null;
564
+ /** Enforced caps. `null` for custom-priced tiers. */
565
+ limits: PlanLimits | null;
566
+ /** Marketing copy — not machine-readable. Use `limits` for capability checks. */
567
+ display_features: string[];
568
+ /** Hint for UIs to highlight a tier (currently `pro`). */
569
+ recommended: boolean;
570
+ /** Present and `true` for the enterprise tier. */
571
+ custom_pricing?: boolean;
572
+ /** Sales contact URL for custom-priced tiers. */
573
+ contact_url?: string;
574
+ }
575
+ interface PlansListResponse {
576
+ plans: Plan[];
577
+ }
578
+ interface AgentSignUpParams {
579
+ /** Email address to send the verification code to. */
580
+ email: string;
581
+ /** Display name of the signing-up agent (1–100 chars). */
582
+ agent_name: string;
583
+ /** Exact ToS version string the caller has accepted. */
584
+ tos_version: string;
585
+ }
586
+ /**
587
+ * Response when a new org was created. Includes credentials for the
588
+ * restricted "unverified" stage — use `api_key` to construct a second
589
+ * `Chronary` client and call `agentAuth.verify({ otp })`.
590
+ */
591
+ interface AgentSignUpNewOrgResponse {
592
+ org_id: string;
593
+ agent_id: string;
594
+ /** API key. Limited to the verify endpoint until OTP succeeds. */
595
+ api_key: string;
596
+ /** Opaque confirmation — always `"Verification code sent to email"`. */
597
+ message: string;
598
+ }
599
+ /**
600
+ * Response when the email matched an existing org. To prevent enumeration,
601
+ * only a generic confirmation message is returned; no credentials.
602
+ */
603
+ interface AgentSignUpExistingOrgResponse {
604
+ message: string;
605
+ }
606
+ type AgentSignUpResponse = AgentSignUpNewOrgResponse | AgentSignUpExistingOrgResponse;
607
+ interface AgentVerifyParams {
608
+ /** Six-digit numeric code from the verification email. */
609
+ otp: string;
610
+ }
611
+ interface AgentVerifyResponse {
612
+ verified: true;
613
+ /** Opaque confirmation — always `"Full access unlocked"`. */
614
+ message: string;
615
+ }
616
+ interface WaitlistJoinParams {
617
+ /** Email address to join the waitlist with. */
618
+ email: string;
619
+ /** Optional display name. Derived from the email's local-part if omitted. */
620
+ name?: string;
621
+ /** Optional ToS version string the caller has accepted. */
622
+ tos_version?: string;
623
+ }
624
+ interface WaitlistedOrg {
625
+ id: string;
626
+ name: string;
627
+ email: string;
628
+ is_waitlisted: true;
629
+ waitlisted_at: string;
630
+ signup_source: string;
631
+ }
632
+ interface WaitlistJoinResponse {
633
+ data: WaitlistedOrg;
634
+ message: string;
635
+ }
636
+ type FeedbackType = 'bug' | 'feature' | 'friction';
637
+ interface SubmitFeedbackParams {
638
+ type: FeedbackType;
639
+ /** Free-text description, 10–2000 characters. */
640
+ message: string;
641
+ /** Optional JSON metadata (SDK version, endpoint, error context, etc.). */
642
+ context?: Record<string, unknown>;
643
+ }
644
+ interface FeedbackAcceptedResponse {
645
+ status: 'accepted';
646
+ }
647
+ type WebhookEventType = 'agent.created' | 'agent.updated' | 'event.created' | 'event.updated' | 'event.deleted' | 'event.started' | 'event.ended' | 'event.hold_created' | 'event.hold_expired' | 'event.hold_released' | 'event.hold_confirmed' | 'proposal.created' | 'proposal.responded' | 'proposal.confirmed' | 'proposal.expired' | 'proposal.cancelled' | 'webhook.deactivated';
648
+ interface WebhookEvent {
649
+ type: WebhookEventType;
650
+ data: Record<string, unknown>;
651
+ }
652
+ interface VerifyOptions {
653
+ tolerance?: number;
654
+ }
655
+ /**
656
+ * Response shape for `GET /v1/auth/export` (GDPR Art. 15 + 20 portability).
657
+ * Encrypted fields (event titles/descriptions, iCal URLs, webhook secrets)
658
+ * are returned in plaintext. Sensitive fields (key hashes, password hashes,
659
+ * OTP hashes, claim revocation tokens, internal scheduling state) are omitted.
660
+ */
661
+ interface DataExport {
662
+ exported_at: string;
663
+ format_version: '1';
664
+ org: {
665
+ id: string;
666
+ name: string;
667
+ email: string;
668
+ plan: string;
669
+ signup_source: string;
670
+ status: string;
671
+ oauth_provider: string | null;
672
+ oauth_provider_id: string | null;
673
+ email_verified: boolean;
674
+ onboarding_completed_at: string | null;
675
+ accepted_terms_version: string | null;
676
+ accepted_terms_at: string | null;
677
+ created_at: string;
678
+ updated_at: string;
679
+ };
680
+ agents: unknown[];
681
+ calendars: unknown[];
682
+ events: unknown[];
683
+ availability_rules: unknown[];
684
+ ical_subscriptions: unknown[];
685
+ webhook_subscriptions: unknown[];
686
+ api_keys: unknown[];
687
+ scheduling_proposals: unknown[];
688
+ proposal_slots: unknown[];
689
+ proposal_responses: unknown[];
690
+ usage_records: unknown[];
691
+ quota_counters: unknown[];
692
+ tos_acceptances: unknown[];
693
+ account_claims_initiated: unknown[];
694
+ account_claims_targeting_this_org: unknown[];
695
+ feedback_submissions: unknown[];
696
+ }
697
+
698
+ declare class CoreClient {
699
+ readonly baseUrl: string;
700
+ private readonly apiKey;
701
+ private readonly timeout;
702
+ private readonly maxRetries;
703
+ private readonly logLevel;
704
+ private readonly fetchFn;
705
+ private readonly userAgent;
706
+ private readonly extraHeaders;
707
+ constructor(config?: ChronaryConfig);
708
+ private log;
709
+ request<T>(method: string, path: string, body?: unknown, query?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): APIPromise<T>;
710
+ private _request;
711
+ private buildUrl;
712
+ private buildError;
713
+ private retryDelay;
714
+ }
715
+
716
+ declare class PageIterator<T> implements AsyncIterable<T> {
717
+ private readonly fetchPage;
718
+ private readonly defaultLimit;
719
+ private readonly initialOffset;
720
+ constructor(fetchPage: (offset: number, limit: number) => PromiseLike<PageResponse<T>>, defaultLimit?: number, initialOffset?: number);
721
+ getPage(offset?: number, limit?: number): Promise<Page<T>>;
722
+ [Symbol.asyncIterator](): AsyncIterableIterator<T>;
723
+ }
724
+
725
+ declare class AgentsClient {
726
+ private readonly client;
727
+ constructor(client: CoreClient);
728
+ /**
729
+ * Register your agent with Chronary. Creates a Chronary identity for an agent
730
+ * that already exists in your system, so it can own calendars, events, and webhooks.
731
+ */
732
+ create(params: CreateAgentParams, options?: RequestOptions): Promise<Agent>;
733
+ get(id: string, options?: RequestOptions): Promise<Agent>;
734
+ list(params?: ListAgentsParams): PageIterator<Agent>;
735
+ update(id: string, params: UpdateAgentParams, options?: RequestOptions): Promise<Agent>;
736
+ delete(id: string, options?: RequestOptions): Promise<void>;
737
+ }
738
+
739
+ declare class CalendarsClient {
740
+ private readonly client;
741
+ constructor(client: CoreClient);
742
+ create(params: CreateCalendarParams & {
743
+ agentId?: string;
744
+ }, options?: RequestOptions): Promise<Calendar>;
745
+ get(id: string, options?: RequestOptions): Promise<Calendar>;
746
+ list(params?: ListCalendarsParams): PageIterator<Calendar>;
747
+ update(id: string, params: UpdateCalendarParams, options?: RequestOptions): Promise<Calendar>;
748
+ delete(id: string, options?: RequestOptions): Promise<void>;
749
+ getContext(id: string, options?: RequestOptions): Promise<CalendarContext>;
750
+ setAvailabilityRules(id: string, params: SetAvailabilityRulesParams, options?: RequestOptions): Promise<AvailabilityRules>;
751
+ getAvailabilityRules(id: string, options?: RequestOptions): Promise<AvailabilityRules>;
752
+ deleteAvailabilityRules(id: string, options?: RequestOptions): Promise<void>;
753
+ }
754
+
755
+ declare class EventsClient {
756
+ private readonly client;
757
+ constructor(client: CoreClient);
758
+ create(calendarId: string, params: CreateEventParams, options?: RequestOptions): Promise<CalendarEvent>;
759
+ get(calendarId: string, eventId: string, options?: RequestOptions): Promise<CalendarEvent>;
760
+ list(params?: ListEventsParams): PageIterator<CalendarEvent>;
761
+ update(calendarId: string, eventId: string, params: UpdateEventParams, options?: RequestOptions): Promise<CalendarEvent>;
762
+ delete(calendarId: string, eventId: string, options?: RequestOptions): Promise<void>;
763
+ /**
764
+ * Promote a held event (status='hold') to status='confirmed'. Fails with 409
765
+ * if the event is not a hold, or if the hold has already expired.
766
+ */
767
+ confirm(eventId: string, options?: RequestOptions): Promise<CalendarEvent>;
768
+ /**
769
+ * Manually release a held event before its TTL, freeing the slot. Fails with
770
+ * 409 if the event is not a hold.
771
+ */
772
+ release(eventId: string, options?: RequestOptions): Promise<CalendarEvent>;
773
+ }
774
+
775
+ declare class AvailabilityClient {
776
+ private readonly client;
777
+ constructor(client: CoreClient);
778
+ forAgent(agentId: string, params: AvailabilityParams, options?: RequestOptions): Promise<AvailabilityResponse>;
779
+ forCalendar(calendarId: string, params: AvailabilityParams, options?: RequestOptions): Promise<AvailabilityResponse>;
780
+ check(params: CrossAgentAvailabilityParams, options?: RequestOptions): Promise<AvailabilityResponse>;
781
+ }
782
+
783
+ declare class WebhooksClient {
784
+ private readonly client;
785
+ constructor(client: CoreClient);
786
+ create(params: CreateWebhookParams, options?: RequestOptions): Promise<Webhook>;
787
+ get(id: string, options?: RequestOptions): Promise<Webhook>;
788
+ list(params?: ListWebhooksParams): PageIterator<Webhook>;
789
+ update(id: string, params: UpdateWebhookParams, options?: RequestOptions): Promise<Webhook>;
790
+ delete(id: string, options?: RequestOptions): Promise<void>;
791
+ listDeliveries(webhookId: string, params?: ListWebhookDeliveriesParams, options?: RequestOptions): Promise<WebhookDeliveryListResponse>;
792
+ }
793
+
794
+ declare class ICalSubscriptionsClient {
795
+ private readonly client;
796
+ constructor(client: CoreClient);
797
+ create(agentId: string, params: CreateICalSubscriptionParams, options?: RequestOptions): Promise<ICalSubscription>;
798
+ get(id: string, options?: RequestOptions): Promise<ICalSubscription>;
799
+ list(params: ListICalSubscriptionsParams & {
800
+ agentId: string;
801
+ }): PageIterator<ICalSubscription>;
802
+ update(id: string, params: UpdateICalSubscriptionParams, options?: RequestOptions): Promise<ICalSubscription>;
803
+ delete(id: string, options?: RequestOptions): Promise<void>;
804
+ sync(id: string, options?: RequestOptions): Promise<{
805
+ status: string;
806
+ }>;
807
+ }
808
+
809
+ declare class SchedulingClient {
810
+ private readonly client;
811
+ constructor(client: CoreClient);
812
+ create(params: CreateProposalParams, options?: RequestOptions): Promise<ProposalSummary>;
813
+ list(params?: ListProposalsParams): PageIterator<ProposalSummary>;
814
+ get(id: string, options?: RequestOptions): Promise<Proposal>;
815
+ respond(id: string, params: RespondToProposalParams, options?: RequestOptions): Promise<ProposalResponse>;
816
+ resolve(id: string, options?: RequestOptions): Promise<ResolveProposalResponse>;
817
+ cancel(id: string, options?: RequestOptions): Promise<CancelProposalResponse>;
818
+ }
819
+
820
+ declare class UsageClient {
821
+ private readonly client;
822
+ constructor(client: CoreClient);
823
+ get(options?: RequestOptions): Promise<Usage>;
824
+ }
825
+
826
+ declare class AuditLogClient {
827
+ private readonly client;
828
+ constructor(client: CoreClient);
829
+ list(params?: ListAuditLogParams, options?: RequestOptions): Promise<AuditLogResponse>;
830
+ }
831
+
832
+ declare class KeysClient {
833
+ private readonly client;
834
+ constructor(client: CoreClient);
835
+ create(params: CreateScopedApiKeyParams, options?: RequestOptions): Promise<CreatedScopedApiKey>;
836
+ list(options?: RequestOptions): Promise<ScopedApiKey[]>;
837
+ delete(id: string, options?: RequestOptions): Promise<void>;
838
+ }
839
+
840
+ declare class AgentAuthClient {
841
+ private readonly client;
842
+ constructor(client: CoreClient);
843
+ /**
844
+ * Register a new agent + org. Sends an OTP to the provided email.
845
+ *
846
+ * No authentication required — callers may construct a `Chronary` client
847
+ * with no `apiKey` to invoke this method.
848
+ *
849
+ * The response is a discriminated union:
850
+ * - **New org path** — returns `org_id`, `agent_id`, and `api_key`.
851
+ * The `api_key` is restricted to the verify endpoint until the OTP
852
+ * is submitted successfully; after verification it unlocks the full API.
853
+ * - **Existing-org dedup** — returns only `message`. No credentials are
854
+ * leaked when the email matches an existing org (enumeration defense).
855
+ *
856
+ * Use `isAgentSignUpNewOrg()` to narrow the union before accessing keys.
857
+ *
858
+ * @throws ChronaryError (409 `tos_version_stale`) if `tos_version` is not
859
+ * the currently-published version — retry with the value from the
860
+ * `current_version` field on the error body.
861
+ */
862
+ signUp(params: AgentSignUpParams, options?: RequestOptions): Promise<AgentSignUpResponse>;
863
+ /**
864
+ * Submit the OTP sent during `signUp()` to unlock the API key.
865
+ *
866
+ * Must be invoked on a `Chronary` client constructed with the restricted
867
+ * `api_key` returned by `signUp()` — NOT on the client that issued
868
+ * `signUp()` itself (which had no key).
869
+ *
870
+ * @throws ChronaryError (status 400) when the OTP is wrong or expired.
871
+ * The SDK's `ValidationError` class is reserved for HTTP 422; the
872
+ * API returns 400 for invalid/expired OTPs, which surfaces as a
873
+ * generic `ChronaryError` with the original message.
874
+ */
875
+ verify(params: AgentVerifyParams, options?: RequestOptions): Promise<AgentVerifyResponse>;
876
+ }
877
+ /**
878
+ * Type guard — narrows an `AgentSignUpResponse` to the new-org branch.
879
+ * The existing-org dedup branch returns only `message`, so this is the
880
+ * caller's cue that credentials are present.
881
+ */
882
+ declare function isAgentSignUpNewOrg(response: AgentSignUpResponse): response is AgentSignUpNewOrgResponse;
883
+
884
+ declare class WaitlistClient {
885
+ private readonly client;
886
+ constructor(client: CoreClient);
887
+ /**
888
+ * Join the Chronary waitlist (#442). Used during private preview when open
889
+ * signup is gated. Creates a real organization row flagged as
890
+ * `is_waitlisted: true`; an admin flips the flag to activate the account.
891
+ *
892
+ * No authentication required — invoke on a `Chronary` client constructed
893
+ * with no `apiKey`.
894
+ *
895
+ * Idempotent on repeat hits: a second call with the same email returns
896
+ * the existing waitlisted org instead of erroring. An active (non-waitlisted)
897
+ * account at the same email returns 409 `email_taken`.
898
+ *
899
+ * @throws ChronaryError (409 `email_taken`) when an active account already
900
+ * exists for this email — direct the user to sign-in instead.
901
+ * @throws ChronaryError (409 `tos_version_stale`) when the supplied
902
+ * `tos_version` doesn't match the currently-published version.
903
+ * @throws ChronaryError (429 `rate_limit_error`) on the per-IP / per-email
904
+ * waitlist limiter.
905
+ */
906
+ join(params: WaitlistJoinParams, options?: RequestOptions): Promise<WaitlistJoinResponse>;
907
+ }
908
+
909
+ declare class FeedbackClient {
910
+ private readonly client;
911
+ constructor(client: CoreClient);
912
+ /**
913
+ * Submit structured feedback (bug, feature, or friction) to Chronary.
914
+ *
915
+ * Rate-limited to 25 submissions per day per organization (UTC day).
916
+ * Available on all plans, including free. The 26th submission returns
917
+ * HTTP 429 with a `Retry-After` header set to the seconds until the
918
+ * next UTC midnight.
919
+ */
920
+ submit(params: SubmitFeedbackParams, options?: RequestOptions): Promise<FeedbackAcceptedResponse>;
921
+ }
922
+
923
+ declare class PlansClient {
924
+ private readonly client;
925
+ constructor(client: CoreClient);
926
+ /**
927
+ * Fetch the public plan catalog (`GET /v1/plans`).
928
+ *
929
+ * Returns all sellable tiers (free, pro, scale) plus the enterprise
930
+ * tier with `custom_pricing: true`. No authentication required.
931
+ * Responses are cacheable for 5 minutes at the edge.
932
+ */
933
+ list(options?: RequestOptions): Promise<PlansListResponse>;
934
+ }
935
+
936
+ declare class AccountClient {
937
+ private readonly client;
938
+ constructor(client: CoreClient);
939
+ /**
940
+ * Export every row this org owns as a single JSON payload (GDPR Art. 15 + 20
941
+ * portability / CCPA right-to-know / EU Data Act interoperability).
942
+ *
943
+ * **Authentication:** This endpoint is JWT-only — it returns decrypted
944
+ * webhook secrets and iCal subscription URLs that aren't normally accessible
945
+ * via API-key endpoints. Configure the SDK with a console JWT (e.g. cookie
946
+ * value or Bearer token from the console session) as the `apiKey` config to
947
+ * call this. API keys (`chr_sk_*` / `chr_ak_*`) will return 401.
948
+ *
949
+ * In most cases, end users should download via the console UI at
950
+ * `console.chronary.ai/settings`. The SDK method exists for programmatic
951
+ * use cases (e.g. server-side compliance tooling holding a delegated JWT).
952
+ *
953
+ * **Rate limit:** 10 exports/hour/org.
954
+ */
955
+ export(options?: RequestOptions): Promise<DataExport>;
956
+ }
957
+
958
+ declare function verifySignature(rawBody: string, headers: Headers | Record<string, string>, secret: string, options?: VerifyOptions): Promise<void>;
959
+ declare function constructEvent(rawBody: string, headers: Headers | Record<string, string>, secret: string, options?: VerifyOptions): Promise<WebhookEvent>;
960
+
961
+ declare const VERSION = "0.1.3";
962
+
963
+ declare class ChronaryError extends Error {
964
+ readonly status: number;
965
+ readonly requestId: string | undefined;
966
+ readonly headers: Headers | undefined;
967
+ readonly errorType: string | undefined;
968
+ constructor(message: string, status: number, requestId?: string, headers?: Headers, errorType?: string);
969
+ }
970
+ declare class AuthenticationError extends ChronaryError {
971
+ constructor(message: string, requestId?: string, headers?: Headers);
972
+ }
973
+ declare class RateLimitError extends ChronaryError {
974
+ readonly retryAfter: number | undefined;
975
+ constructor(message: string, requestId?: string, headers?: Headers);
976
+ }
977
+ declare class NotFoundError extends ChronaryError {
978
+ constructor(message: string, requestId?: string, headers?: Headers);
979
+ }
980
+ declare class ValidationError extends ChronaryError {
981
+ constructor(message: string, status: number, requestId?: string, headers?: Headers);
982
+ }
983
+ declare class QuotaExceededError extends ChronaryError {
984
+ constructor(message: string, requestId?: string, headers?: Headers);
985
+ }
986
+ declare class TimeoutError extends ChronaryError {
987
+ constructor(message: string);
988
+ }
989
+ declare class ConnectionError extends ChronaryError {
990
+ constructor(message: string);
991
+ }
992
+
993
+ declare class Chronary {
994
+ readonly agents: AgentsClient;
995
+ readonly calendars: CalendarsClient;
996
+ readonly events: EventsClient;
997
+ readonly availability: AvailabilityClient;
998
+ readonly webhooks: WebhooksClient;
999
+ readonly icalSubscriptions: ICalSubscriptionsClient;
1000
+ readonly scheduling: SchedulingClient;
1001
+ readonly usage: UsageClient;
1002
+ readonly auditLog: AuditLogClient;
1003
+ readonly keys: KeysClient;
1004
+ readonly agentAuth: AgentAuthClient;
1005
+ readonly waitlist: WaitlistClient;
1006
+ readonly feedback: FeedbackClient;
1007
+ readonly plans: PlansClient;
1008
+ readonly account: AccountClient;
1009
+ constructor(config?: ChronaryConfig);
1010
+ static webhooks: {
1011
+ verifySignature: typeof verifySignature;
1012
+ constructEvent: typeof constructEvent;
1013
+ };
1014
+ }
1015
+
1016
+ export { APIPromise, type Agent, type AgentSignUpExistingOrgResponse, type AgentSignUpNewOrgResponse, type AgentSignUpParams, type AgentSignUpResponse, type AgentStatus, type AgentVerifyParams, type AgentVerifyResponse, type AppInfo, type AuditLogEntry, type AuditLogResponse, AuthenticationError, type AvailabilityParams, type AvailabilityResponse, type AvailabilityRules, type AvailabilitySlot, type BusyBlock, type Calendar, type CalendarContext, type CalendarEvent, type CancelProposalResponse, Chronary, type ChronaryConfig, ChronaryError, ConnectionError, CoreClient, type CreateAgentParams, type CreateCalendarParams, type CreateEventParams, type CreateICalSubscriptionParams, type CreateProposalParams, type CreateScopedApiKeyParams, type CreateWebhookParams, type CreatedScopedApiKey, type CrossAgentAvailabilityParams, type DataExport, type FeedbackAcceptedResponse, type FeedbackType, type ICalSubscription, type ListAgentsParams, type ListAuditLogParams, type ListCalendarsParams, type ListEventsParams, type ListICalSubscriptionsParams, type ListProposalsParams, type ListWebhookDeliveriesParams, type ListWebhooksParams, type LogLevel, NotFoundError, type Page, PageIterator, type PageResponse, type Plan, type PlanId, type PlanLimits, type PlansListResponse, type Proposal, type ProposalResponse, type ProposalResponseAction, type ProposalSlot, type ProposalStatus, type ProposalSummary, QuotaExceededError, type QuotaSnapshot, RateLimitError, type RawResponse, type RequestOptions, type ResolveProposalResponse, type RespondToProposalParams, type ScopedApiKey, type SetAvailabilityRulesParams, type SlotDuration, type SubmitFeedbackParams, TimeoutError, type UpdateAgentParams, type UpdateCalendarParams, type UpdateEventParams, type UpdateICalSubscriptionParams, type UpdateWebhookParams, type Usage, type UsageMetric, VERSION, ValidationError, type VerifyOptions, type WaitlistJoinParams, type WaitlistJoinResponse, type WaitlistedOrg, type Webhook, type WebhookDelivery, type WebhookDeliveryListResponse, type WebhookDeliveryStats, type WebhookEvent, type WebhookEventType, type WithResponse, type WorkingHours, type WorkingHoursDay, constructEvent, Chronary as default, isAgentSignUpNewOrg, verifySignature };