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

@elvenvtt/api

v0.7.2

Published

Typed REST client for the Elven creator API. The shared core consumed by @elvenvtt/cli, @elvenvtt/mcp-account, and any third-party tooling.

Downloads

104

Readme

@elvenvtt/api

Typed REST client for the Elven creator API. Zero runtime dependencies — works in Node, Bun, Deno, browsers, and edge runtimes (Workers, Vercel Edge).

Full docs: docs.elvenvtt.com/docs/agent-platform

npm install @elvenvtt/api
import { createClient } from '@elvenvtt/api';

const elven = createClient();
await elven.setTokens({ accessToken: process.env.ELVEN_TOKEN!, kind: 'pat' });

const me = await elven.whoami();
const mine = await elven.listings.mine();

This is the shared core that powers @elvenvtt/cli and @elvenvtt/mcp-account. Use it directly when you want to script Elven from your own code without the CLI binary or MCP server.

What's in the client

All methods are typed; full types ship in dist/index.d.ts.

elven.whoami()                              // → { userId, email, slug, claims }
elven.setTokens({ accessToken, kind })
elven.logout()

elven.listings.create(input)
elven.listings.list({ type, search, ... })
elven.listings.mine()
elven.listings.get(idOrSlug)
elven.listings.update(id, input)
elven.listings.delete(id)

elven.publish.uploadFile({ listingId, slug, path, content })
elven.publish.manifestUrl(listingId, slug)  // utility — builds the public URL

elven.posts.create({ title, bodyText, status, visibility })
elven.posts.get(id)
elven.posts.byUser(userId)
elven.posts.update(id, input)
elven.posts.delete(id)

elven.drops.create({ name, openAt, closeAt, eligibility, claimContents })
elven.drops.get(id)
elven.drops.byUser(userId)
elven.drops.update(id, input)
elven.drops.delete(id)
elven.drops.claim(id)
elven.drops.feed()                          // open drops from creators you follow
elven.drops.claims()                        // drops you've claimed

elven.followers.count(userId)
elven.followers.following()
elven.followers.state(creatorIds)           // map: creatorId → bool
elven.followers.follow({ creatorSlug })
elven.followers.unfollow(creatorId)

elven.analytics.overview()                  // dashboard (one round-trip)
elven.analytics.sales()                     // seller sales rollup

elven.tokens.create({ label, expiresInDays })
elven.tokens.list()
elven.tokens.revoke(id)

Tokens & refresh

The client takes a TokenStore (default: in-memory). Pass your own to persist across processes.

import { createClient, type TokenStore } from '@elvenvtt/api';

const myStore: TokenStore = {
  async read(profile = 'default') { /* ... */ },
  async write(tokens, profile = 'default') { /* ... */ },
  async clear(profile = 'default') { /* ... */ },
};

const elven = createClient({ tokenStore: myStore });

Two credential kinds:

  • JWT session (kind: 'jwt') — short-lived (~1 hour), auto-refreshed when there's less than 60s of life left. Rotated tokens are written back to the store automatically. This is what elven login obtains through the browser OAuth flow.
  • Personal access token (kind: 'pat') — long-lived opaque token starting with el_pat_. No refresh. Generate from the Elven Studio (Developer → CLI Tokens) or via elven tokens create.

Errors

The client maps server responses to four classes — catch by instanceof:

| Class | When | Suggested handling | |---|---|---| | AuthError | 401/403, no token, refresh failed | Prompt re-login. CLI exit code 60. | | ApiError | 4xx/5xx with a JSON body | Show e.status + e.body. CLI exit code 70. | | UsageError | Client-side: missing required input | Fix the call site. CLI exit code 80. | | NetworkError | fetch() threw (DNS, offline, etc.) | Retry / surface. CLI exit code 90. |

All four extend ElvenError, which extends Error.

import { AuthError, ApiError } from '@elvenvtt/api';

try {
  await elven.listings.create({ ... });
} catch (e) {
  if (e instanceof AuthError) return promptLogin();
  if (e instanceof ApiError && e.status === 422) return showValidationErrors(e.body);
  throw e;
}

Public contract: /v1/*

The client only calls /v1/* endpoints on the Elven backend. These paths are locked — additive changes only, no breaking shape changes within a major version. The unversioned aliases (/api/listings, /posts, etc.) still exist for the SvelteKit web app but aren't part of the public contract.

The base URLs default to production and can be overridden for local dev / staging:

createClient({
  stripeUrl: 'https://stripe.example.com',
  syncUrl: 'https://sync.example.com',
  uploadUrl: 'https://api.example.com',
});

Security

Tokens passed to setTokens() are long-lived credentials. Store them via the TokenStore interface (the CLI uses keytar; your code can use any secure backing store) and never log them. Audit + revoke at Studio Developer → CLI Tokens. Full guidance at docs.elvenvtt.com/docs/agent-platform/security.

License

MIT.