Skip to content

TypeScript SDK

The SDK does two things. guard and hold put a limit around your code in one call. And every API operation is a typed method, so your editor knows each field and answer.

Terminal window
npm install @limitry/sdk

Set LIMITRY_API_KEY to a key from API keys in the app. Use a test key (lim_test_…) while you build.

guard checks the limit, then runs your code only if it’s allowed. Here it counts one AI call against a limit such as 100 a day:

import { createClient, LimitExceeded } from "@limitry/sdk";
const limitry = createClient(); // reads LIMITRY_API_KEY
try {
const reply = await limitry.guard(
{ subject: { kind: "user", id: "usr_123" }, action: "ai-call" },
() => callModel(prompt),
);
} catch (error) {
if (error instanceof LimitExceeded) {
console.log(`Try again in ${error.retryAfterSeconds} seconds`);
}
}

When you only know the cost afterwards, such as an AI reply your product pays for by the token, hold reserves an estimate (5 cents here), runs your code and charges what it actually used. If your code throws, the hold is released:

import { createClient } from "@limitry/sdk";
const limitry = createClient();
const answer = await limitry.hold(
{ subject: { kind: "user", id: "usr_123" }, action: "ai-call", estimate: 5 },
async (held) => {
const response = await callModel(prompt);
held.cost(priceCents(response.usage)); // your prices, in cents
return response;
},
);

If Limitry can’t be reached, each limit’s fail mode decides: open lets the work run, closed refuses it. See Add Limitry with your agent for more.

Each API operation is a method, named like its command in the CLI: limitry limits create is limitry.limits.create().

import { createClient } from "@limitry/sdk";
const limitry = createClient();
await limitry.limits.create({
name: "AI replies per day",
subjectKind: "user",
action: "ai-call",
amount: 100,
window: "day",
});
const { items } = await limitry.limits.list();
  • Ids in the path are arguments, and everything else is one object: limitry.limits.get(limitId).
  • A method returns the response’s data. A failure throws an ApiError with the error’s code, message, status and requestId.
  • Every write sends an idempotency key, and a failed attempt (a network error, a 5xx, a 429) is retried with the same key, so it happens once. To make your own retry safe too, pass your key as the last argument: limitry.checks.create(check, { idempotencyKey: id }).

Every method, linked to its fields and a full example under Endpoints:

Checks

MethodWhat it does
limitry.checks.create()Check whether a subject may act

Reservations

MethodWhat it does
limitry.reservations.commit()Commit a reservation
limitry.reservations.extend()Extend a reservation
limitry.reservations.release()Release a reservation

Limits

MethodWhat it does
limitry.limits.archive()Archive a limit
limitry.limits.create()Create a limit
limitry.limits.get()Get a limit
limitry.limits.grants.create()Add credits to a balance
limitry.limits.grants.list()List a balance's grants
limitry.limits.list()List limits
limitry.limits.restore()Restore an archived limit
limitry.limits.sync()Sync limits from a list
limitry.limits.update()Change a limit

Subjects

MethodWhat it does
limitry.subjects.get()Get a subject
limitry.subjects.reset()Reset a subject's limits
limitry.subjects.update()Set a subject's anchor

Usage

MethodWhat it does
limitry.usage.query()Get a limit's usage over time
limitry.usage.standing()Get where a subject stands
limitry.usage.subjects()List who is using a limit now

Workspace

MethodWhat it does
limitry.workspace.get()Get the current workspace
limitry.workspace.invitations.list()List pending invitations
limitry.workspace.members.list()List workspace members
limitry.workspace.teams.list()List teams
limitry.workspace.usage()Get your plan's usage this period

Webhooks

MethodWhat it does
limitry.workspace.eventTypes.list()List event types
limitry.workspace.webhookDeliveries.list()List an endpoint's deliveries
limitry.workspace.webhookDeliveries.redeliver()Redeliver an event
limitry.workspace.webhookEndpoints.create()Add a webhook endpoint
limitry.workspace.webhookEndpoints.delete()Remove a webhook endpoint
limitry.workspace.webhookEndpoints.enable()Re-enable a webhook endpoint
limitry.workspace.webhookEndpoints.get()Get a webhook endpoint
limitry.workspace.webhookEndpoints.list()List webhook endpoints
limitry.workspace.webhookEndpoints.test()Send a test event

Approvals

MethodWhat it does
limitry.workspace.approvalActions.list()List the actions you can ask approval for
limitry.workspace.approvalRequests.create()Ask a person to approve an action
limitry.workspace.approvalRequests.get()Check an approval request
limitry.workspace.approvalRequests.redeem()Redeem an approved request

Audit events

MethodWhat it does
limitry.workspace.auditEvents.list()List workspace audit events

Personal access tokens

MethodWhat it does
limitry.user.me()Get the current user
limitry.user.revokeToken()Revoke the token making this request
  • createClient() reads your key from the LIMITRY_API_KEY environment variable. Without it, it throws an error naming the variable. Where there’s no process.env, such as a browser or a Cloudflare Worker, pass the key: createClient({ token: env.LIMITRY_API_KEY }).
  • A test key (lim_test_…) acts in test, and a live key (lim_live_…) in live. See Test and live.
  • A personal access token names the workspace, and acts in test unless you name live: createClient({ token, workspace: "acme", environment: "live" }).

createLimits(client, options) gives you guard and hold with a different wait for a decision (timeoutMs, 1500 ms by default) or a fixed fail mode:

import { createClient, createLimits } from "@limitry/sdk";
const limits = createLimits(createClient(), { timeoutMs: 500 });

limitry.GET, limitry.POST and the other HTTP methods call any path, with the same types. They return { data, error, response } instead of throwing, and unwrap turns that into the data or an ApiError.