@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/sdkQuick 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[]withid,slug,title,status,excerpt,coverImageUrl,publishedAt,updatedAtpageInfo.nextCursorpageInfo.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
htmlfor rendered blog contentseo.metaTitleseo.metaDescriptionseo.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:
400invalid request401missing or invalid API key404blog not found429rate 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.
