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

@flamel-ai/yext-api

v0.1.6

Published

Clean, fully-typed TypeScript SDK for the Yext API, generated from the official OpenAPI specs with zod validation. Covers all 11 Yext APIs.

Readme

@flamel-ai/yext-api

CI

A clean, fully-typed TypeScript SDK for the Yext API, generated from Yext's official OpenAPI specs with @hey-api/openapi-ts and zod validation.

  • All 11 Yext APIs, one tree-shakeable sub-module each.
  • Typed fetch SDK — every operation is a typed function.
  • zod schemas for every model, plus automatic response validation.
  • Auth handled for you — set a credential + API version once.

Install

pnpm add @flamel-ai/yext-api
# or: npm install @flamel-ai/yext-api

Requires Node 20+. zod is a dependency (no peer-install needed).

Modules

Each Yext API is its own subpath import:

| Import | API | Yext docs | |---|---|---| | @flamel-ai/yext-api/admin | Admin | Management APIs | | @flamel-ai/yext-api/answers | Search | Search | | @flamel-ai/yext-api/chat | Chat | Chat | | @flamel-ai/yext-api/events | Analytics Events | Events APIs | | @flamel-ai/yext-api/knowledge | Knowledge Graph (entities) | Knowledge Graph | | @flamel-ai/yext-api/live | Live (content delivery) | Content Delivery APIs | | @flamel-ai/yext-api/listings | Publisher Listings | Publisher Listings API | | @flamel-ai/yext-api/publisher-ecl | Publisher ECL | Publisher ECL API | | @flamel-ai/yext-api/publisher-notify-review | Publisher Notify Review | Publisher Notify Review API | | @flamel-ai/yext-api/publisher-tracking-pixel | Publisher Tracking Pixel | Publisher Tracking Pixel API | | @flamel-ai/yext-api/webhooks | Webhooks | Webhooks |

The package root (@flamel-ai/yext-api) re-exports every module namespaced (knowledge, listings, …) plus all the auth helpers. Prefer subpath imports for the smallest bundle.

Authentication

Yext accepts three credential shapes, and every request also needs a v API-version date (YYYYMMDD). @flamel-ai/yext-api injects both for you at the fetch layer, so you configure once and never thread them through individual calls. See Yext's Management APIs docs for how credentials and the v parameter work.

| Credential | Sent as | |---|---| | { type: "apiKey", value } | api_key query parameter | | { type: "apiKeyHeader", value } | api-key request header | | { type: "accessToken", value } | access_token query parameter (OAuth) |

Configure one API's client

import { client, listEntities } from "@flamel-ai/yext-api/knowledge";
import { configureYextClient } from "@flamel-ai/yext-api";

configureYextClient(client, {
  credential: { type: "apiKey", value: process.env.YEXT_API_KEY! },
  version: "20250401",
});

const { data, error } = await listEntities({ path: { accountId: "me" }, query: {} });
//      ^ fully typed + response-validated; `api_key` and `v` were injected automatically

Configure every API at once

import { configureYext } from "@flamel-ai/yext-api";

configureYext({
  credential: { type: "accessToken", value: oauthAccessToken },
  version: "20250401",
});

Multi-tenant servers (per-request credentials)

configureYext / configureYextClient mutate a shared singleton client — great for a single-tenant app or script, but unsafe on a server where concurrent requests each carry a different Yext token (one request would clobber another's credential mid-flight).

For that case, pass the credential per call with withYextAuth — no shared state, safe under concurrency:

import { withYextAuth } from "@flamel-ai/yext-api";
import { getEntity } from "@flamel-ai/yext-api/knowledge";

// inside a request handler — token resolved for THIS tenant/workspace
const { data } = await getEntity({
  path: { accountId: "me", entityId: id },
  query: {},
  ...withYextAuth({ credential: { type: "accessToken", value: req.workspaceYextToken } }),
});

Each call gets its own fetch closure carrying that request's token (and version), so two concurrent requests with different tokens never cross over.

OAuth (authorization-code flow)

import { buildYextAuthorizeUrl, requestYextOAuthToken } from "@flamel-ai/yext-api";

// 1. Send the user here to authorize your app:
const authUrl = buildYextAuthorizeUrl({
  clientId: process.env.YEXT_CLIENT_ID!,
  redirectUri: "https://app.example.com/yext/callback",
  scope: "read_entities write_entities",
});

// 2. In your redirect handler, exchange the `?code=...`:
const token = await requestYextOAuthToken({
  clientId: process.env.YEXT_CLIENT_ID!,
  clientSecret: process.env.YEXT_CLIENT_SECRET!,
  code: codeFromCallback,
  redirectUri: "https://app.example.com/yext/callback",
});

configureYext({ credential: { type: "accessToken", value: token.access_token } });

Use environment: "sandbox" on any of these helpers to target Yext's sandbox OAuth hosts.

zod schemas

Every model has a generated zod schema, exposed under each module's schemas namespace:

import { schemas } from "@flamel-ai/yext-api/knowledge";

const result = schemas.zEntityWrite.safeParse(payload);
if (!result.success) console.error(result.error);

Response bodies are validated against these schemas automatically. Request bodies are not validated client-side (the API validates them), which is what lets auth + version inject transparently.

Error handling

Yext doesn't signal every problem with the HTTP status. Each response carries a meta envelope, and problems are listed in meta.errors[], each tagged with a type (docs):

| type | HTTP | Meaning | |---|---|---| | WARNING | 200 | Accepted, but didn't follow best practices | | NON_FATAL_ERROR | 207 | Some item/field rejected, others succeeded | | FATAL_ERROR | 400 / 401 / 403 / 409 / 5xx | The whole request was rejected |

So a warning rides along on a 200 and a non-fatal error on a 207 — checking response.ok alone misses both. SDK calls return { data, error, response } (no throw by default); these helpers read meta.errors from either body:

import { getYextErrors, getYextWarnings, hasYextErrors, assertYextOk, YextApiError } from "@flamel-ai/yext-api";
import { createEntity } from "@flamel-ai/yext-api/knowledge";

const result = await createEntity({ path: { accountId: "me" }, query: {}, body: { /* ... */ } });

for (const w of getYextWarnings(result)) console.warn(`Yext warning ${w.code}: ${w.message}`);

if (hasYextErrors(result)) {
  // FATAL_ERROR, NON_FATAL_ERROR (207), a >= 400 status, or a populated `error` body
  const errors = getYextErrors(result);
  // handle...
}

Prefer throwing? assertYextOk returns the result on success (warnings don't throw) and throws a YextApiError — carrying status, uuid, and the parsed issues[] — otherwise:

try {
  const { data } = assertYextOk(await getEntity({ path: { accountId: "me", entityId: "loc-1" }, query: {} }));
  // data is the validated success body
} catch (err) {
  if (err instanceof YextApiError) {
    console.error(err.status, err.uuid, err.issues); // 404, "uuid…", [{ code, type, message }]
  }
}

Success-response bodies are validated against the generated zod schemas automatically; if Yext returns a body that doesn't match the spec, the SDK surfaces a zod error in result.error.

Per-call overrides

Anything you pass on a call wins over the injected defaults — e.g. pass query: { v: "20240101" } to pin a different version for one request, or auth/baseUrl via the client config.

Development

pnpm install
pnpm fetch-specs   # vendor the 11 specs from github.com/yext/openapi into specs/
pnpm generate      # normalize specs + regenerate src/<module>/*.gen.ts
pnpm typecheck
pnpm test
pnpm build         # emit dist/ (ESM + .d.ts)

The generated src/**/*.gen.ts is committed so the SDK is reviewable and usable straight from source. scripts/normalize-spec.ts fixes a few upstream spec quirks (wrong-typed defaults, an invalid query style: "simple", and makes the auto-injected v param optional for callers) before generation; the vendored specs/ stay as the untouched upstream copies.

Continuous integration & live verification

.github/workflows/ci.yml runs on every push and PR:

  • verify (always) — pnpm install --frozen-lockfiletypechecktestbuild. No secrets required.
  • integration (pushes to main only) — a real round-trip against the Yext API via pnpm test:integration.

The live test (test/integration.test.ts) lists one entity and asserts the response validates against the generated zod schema. It self-skips unless a credential is present, so CI stays green until you opt in.

Enabling the live test without leaking anything (public repo): add a credential as an encrypted repository secret — repo Settings → Secrets and variables → Actions → New repository secret:

  • YEXT_API_KEY (a static API key) or YEXT_ACCESS_TOKEN (an OAuth token)
  • optionally set YEXT_API_VERSION / YEXT_ACCOUNT_ID as Variables

GitHub secrets are encrypted at rest, masked in logs (any echo shows ***), and never exposed to pull requests from forks — so the credential stays private even though the code is public. Run it locally the same way: YEXT_API_KEY=… pnpm test:integration.

Publishing

.github/workflows/release.yml publishes to npm (with provenance) when you publish a GitHub Release. One-time setup: add an NPM_TOKEN automation token as a repository secret. Then:

pnpm version patch       # or minor / major — bumps + tags
git push --follow-tags
gh release create v0.1.1 --generate-notes

The workflow re-runs typecheck + test + build as a gate before pnpm publish.

License

BSD-3-Clause. The vendored OpenAPI specs under specs/ are from yext/openapi (BSD-3-Clause, © 2021 Yext, Inc.); the SDK code is © 2026 Flamel AI, Inc. Per Yext, only the spec files are covered by this license — use of the Yext API is governed by separate Yext agreements. See LICENSE.