npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@chronary/schemas

v0.2.1

Published

Zod schemas and types for the Chronary calendar API, including webhook event payload validation

Readme

@chronary/schemas

Zod schemas and types for the Chronary calendar API — use them to validate incoming webhook payloads at runtime, or to share request/response shapes between your client and server code.

Installation

npm install @chronary/schemas zod
# pnpm add @chronary/schemas zod
# yarn add @chronary/schemas zod

zod is a peer of this package and is already a transitive dep of @chronary/sdk and @chronary/toolkit, so you likely have it installed.

Webhook payload validation

Chronary webhooks put the event type in the X-Chronary-Event-Type header and the payload in the body. Pass both to parseWebhookEvent to get a typed, discriminated result.

import { parseWebhookEvent } from '@chronary/schemas/events';
import { verifySignature } from '@chronary/sdk';

app.post('/webhook', async (req, res) => {
  const rawBody = await req.text();

  // 1. Authenticate with the HMAC signature before trusting anything.
  //    verifySignature reads X-Signature/X-Timestamp from the headers and
  //    throws on a bad/missing signature or a stale timestamp.
  try {
    await verifySignature(rawBody, req.headers, process.env.CHRONARY_WEBHOOK_SECRET!);
  } catch {
    return res.status(401).end();
  }

  // 2. Parse into a typed event (the event type comes from the header).
  const event = parseWebhookEvent(
    req.header('x-chronary-event-type'),
    JSON.parse(rawBody),
  );

  if (!event.success) {
    console.warn('webhook parse failed:', event.error);
    return res.status(400).json({ error: event.error });
  }

  // 3. Narrow by event.type.
  switch (event.event.type) {
    case 'event.created':
      //             ^ TypeScript narrows `event.event.data` to the created payload
      console.log('New event:', event.event.data.event);
      break;
    case 'event.deleted':
      console.log('Deleted:', event.event.data.event_id);
      break;
    case 'proposal.responded':
      console.log(
        `Agent ${event.event.data.agent_id} responded: ${event.event.data.response}`,
      );
      break;
    default:
      console.log('Unhandled event:', event.event.type);
  }

  res.status(200).end();
});

Wire format contract

  • HTTP method: POST to your webhook URL.
  • Headers:
    • X-Signature — HMAC-SHA256 signature of timestamp + "." + body (verify with @chronary/sdk's verifySignature).
    • X-Timestamp — Unix epoch seconds (decimal string, e.g. 1745784205) used in the signature.
    • X-Delivery-Id — unique delivery ID (useful for idempotency + debugging).
    • X-Chronary-Event-Type — one of the 18 event types in WEBHOOK_EVENT_TYPES.
  • Body: raw JSON payload (schema depends on the event type).

Forward compatibility

Every payload schema uses .passthrough(). Fields added server-side in the future won't cause existing consumer code to fail parsing — the unknown fields are preserved on the result so you can opt in to reading them.

Request / response schemas

The package re-exports the Zod schemas used by the REST API for creating and updating resources:

import { CreateEventSchema, CreateCalendarSchema } from '@chronary/schemas';

const parsed = CreateEventSchema.parse(req.body);
// parsed is typed as CreateEventInput

Available:

  • CreateCalendarSchema, UpdateCalendarSchema, ListCalendarsQuerySchema
  • CreateEventSchema, UpdateEventSchema, ListEventsQuerySchema
  • CreateAgentSchema, UpdateAgentSchema, ListAgentsQuerySchema
  • CreateWebhookSchema, UpdateWebhookSchema, ListWebhooksQuerySchema, ListDeliveriesQuerySchema
  • CreateICalSubscriptionSchema, UpdateICalSubscriptionSchema, ListICalSubscriptionsQuerySchema
  • CreateProposalSchema, RespondToProposalSchema
  • WorkingHoursSchema, UpdateAvailabilityRulesSchema, AvailabilityQuerySchema, CrossAgentAvailabilityQuerySchema

Plus type exports inferred from each schema, like CreateEventInput, CreateCalendarInput, etc.

Full docs

docs.chronary.ai

License

Apache-2.0. See LICENSE.