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

@keytomic/sdk

v0.4.4

Published

Official TypeScript SDK for the Keytomic External Blogs API.

Downloads

351

Readme

@keytomic/sdk

When a TypeScript app needs external blog data without hand-rolled API glue, @keytomic/sdk is the direct path. It is the official TypeScript SDK for the Keytomic External Blogs API and gives developers typed access to health checks, blog listings, and blog detail fetches by ID or slug.

If you are evaluating content infrastructure or building editorial tooling, Keytomic is the platform behind this SDK. This package is built for developers who want a thin, typed, production-friendly layer over the Keytomic API.

What Is Keytomic?

Keytomic exposes external blog content through an API so developers can pull blog metadata and full blog documents into apps, sync jobs, internal dashboards, content pipelines, and publishing workflows. This SDK wraps that API in a small TypeScript-first interface.

Why Use This SDK?

  • Official TypeScript SDK for the Keytomic External Blogs API
  • Typed request and response models generated from the API schema
  • Small ergonomic wrappers that default to throwOnError: true
  • Raw generated methods still exported for lower-level control
  • Default API base URL already configured as https://api.keytomic.com

Install

npm install @keytomic/sdk

Quick Start

import { getBlogById, getBlogBySlug, getHealth, listBlogs } from "@keytomic/sdk";

/**
 * Demo: read blog data from Keytomic.
 */
async function main(): Promise<void> {
  const apiKey = process.env.KEYTOMIC_API_KEY;

  if (!apiKey) {
    throw new Error("Missing KEYTOMIC_API_KEY");
  }

  const auth = {
    headers: {
      Authorization: `Bearer ${apiKey}`,
    },
  };

  const health = await getHealth();
  console.log(health.data.status, health.data.timestamp);

  const blogs = await listBlogs({
    ...auth,
    query: { limit: 10 },
  });

  for (const blog of blogs.data.data) {
    console.log(blog.id, blog.slug, blog.title);
  }

  const firstBlogId = blogs.data.data[0]?.id;

  if (!firstBlogId) {
    return;
  }

  const blog = await getBlogById({
    ...auth,
    path: { id: firstBlogId },
  });

  console.log(blog.data.data.title);
  console.log(blog.data.data.seo.canonicalUrl);

  const sameBlogBySlug = await getBlogBySlug({
    ...auth,
    query: { slug: blog.data.data.slug },
  });

  console.log(sameBlogBySlug.data.data.id);
}

void main();

Authentication

listBlogs, getBlogById, and getBlogBySlug require Bearer auth. getHealth does not.

const auth = {
  headers: {
    Authorization: `Bearer ${process.env.KEYTOMIC_API_KEY}`,
  },
};

Environment variable:

  • KEYTOMIC_API_KEY: your Keytomic External Blogs API key

API Surface

| Export | Purpose | | ------------------------------------------------ | -------------------------------------------- | | getHealth(options?) | Checks API health at /health | | listBlogs(options?) | Lists blogs from /v1/blogs | | getBlogById({ path: { id } }) | Fetches a single blog from /v1/blogs/{id} | | getBlogBySlug({ query: { slug } }) | Fetches a single blog by slug | | client | Underlying generated client instance | | DEFAULT_KEYTOMIC_API_BASE_URL | Default base URL: https://api.keytomic.com | | getHealthRaw, listBlogsRaw, getBlogByIdRaw | Raw generated methods | | Options and generated types | Request and response typing helpers |

Response Details

listBlogs returns:

  • data[] with id, slug, title, status, excerpt, coverImageUrl, publishedAt, updatedAt
  • pageInfo.nextCursor
  • pageInfo.hasMore

You can filter listBlogs by slug:

const filtered = await listBlogs({
  ...auth,
  query: { slug: "my-blog-slug" },
});

getBlogById and getBlogBySlug return:

  • Blog identity and metadata fields
  • html for rendered blog content
  • seo.metaTitle
  • seo.metaDescription
  • seo.canonicalUrl

Pagination

Use query.limit and query.cursor with listBlogs.

const firstPage = await listBlogs({
  ...auth,
  query: { limit: 20 },
});

const nextCursor = firstPage.data.pageInfo.nextCursor;

if (nextCursor) {
  const secondPage = await listBlogs({
    ...auth,
    query: {
      limit: 20,
      cursor: nextCursor,
    },
  });

  console.log(secondPage.data.pageInfo.hasMore);
}

Base URL Override

If you need a proxy, staging target, or custom host, reconfigure the shared client.

import { client } from "@keytomic/sdk";

client.setConfig({
  baseUrl: "https://api.keytomic.com",
});

Error Handling

The top-level helpers in src/index.ts force throwOnError: true, so non-2xx responses throw by default.

getBlogBySlug also throws if the slug filter returns no matching blog.

If you want manual error inspection, use the raw exports:

import { listBlogsRaw } from "@keytomic/sdk";

const result = await listBlogsRaw({
  ...auth,
  throwOnError: false,
  query: { limit: 10 },
});

if (result.error) {
  console.error(result.response.status, result.error.error.message);
} else {
  console.log(result.data.data.length);
}

Common error statuses for protected endpoints:

  • 400 invalid request
  • 401 missing or invalid API key
  • 404 blog not found
  • 429 rate limited

Developer Notes

  • The SDK is generated from the Keytomic OpenAPI schema via @hey-api/openapi-ts
  • The package exports a small handwritten entrypoint on top of generated client code
  • Publish flow runs pnpm generate && pnpm build

Security Note

Never hardcode API keys in client-side or browser bundles. Keep KEYTOMIC_API_KEY on the server, in backend jobs, edge functions, or behind infrastructure you control.

About Keytomic

Keytomic is the product behind this SDK and API. If you want to understand the platform, evaluate the broader workflow, or see where this package fits, start here: Keytomic.

License

This package is UNLICENSED and no license is granted by default.