TypeScript SDK
The official TypeScript SDK wraps the Trile API in typed clients. It’s built on the
native fetch API, so it runs in Node.js 18+, Deno, Bun, browsers, and edge
runtimes with zero runtime dependencies.
- npm:
@trilehq/sdk - Source: github.com/TrileHQ/trile-node
Install
Section titled “Install”npm install @trilehq/sdkQuickstart
Section titled “Quickstart”import { Configuration, CustomersApi } from '@trilehq/sdk'
const config = new Configuration({ apiKey: process.env.TRILE_KEY, // your nep_test_… or nep_live_… key})
const customers = new CustomersApi(config)
// Every response is wrapped in { success, data, meta } — your result is in `.data`.const { data: customer } = await customers.createCustomer({ createCustomer: { email: 'asha@example.com', name: 'Asha K.' },})
console.log(customer.id) // → "cus_…"Authentication
Section titled “Authentication”Pass a secret API key (see Authentication). Use a
nep_test_… key against test data and a nep_live_… key in production. The SDK
sends it as the x-api-key header, so keep it server-side — never ship it in
client-side code.
const config = new Configuration({ apiKey: 'nep_live_…' })Configuration
Section titled “Configuration”| Option | Type | Description |
|---|---|---|
apiKey | string | Your secret API key. Sent as the x-api-key header. |
basePath | string | API base URL. Defaults to https://api.trile.app. |
headers | Record<string, string> | Extra headers sent on every request. |
fetchApi | typeof fetch | Custom fetch implementation (e.g. for testing). |
middleware | Middleware[] | Hooks to run before/after each request. |
Responses
Section titled “Responses”Every successful response is wrapped in the standard { success, data, meta }
envelope — your result is always in data, and
meta.requestId is handy when contacting support. Destructure it:
const { data, meta } = await customers.getCustomer({ customerId: 'cus_…' })console.log(data.email, meta.requestId)Error handling
Section titled “Error handling”Any non-2xx response throws a ResponseError carrying the raw Response, so you
can read the status and the API’s error envelope.
import { ResponseError } from '@trilehq/sdk'
try { await customers.getCustomer({ customerId: 'cus_missing' })} catch (err) { if (err instanceof ResponseError) { console.error(err.response.status) // e.g. 404 console.error(await err.response.json()) // { success: false, error: { code, message }, meta } } else { throw err }}Pagination
Section titled “Pagination”List endpoints return { items, nextCursor } inside data. Pass nextCursor
back as cursor to page; it’s null on the last page. All filter arguments are
optional. See Pagination.
let cursor: string | undefined
do { const { data: page } = await customers.listCustomers({ limit: '50', cursor }) for (const customer of page.items) console.log(customer.id, customer.email) cursor = page.nextCursor ?? undefined} while (cursor)Idempotency
Section titled “Idempotency”Every create/mutating call accepts an optional idempotencyKey — sending the same
key retries safely. See Idempotency.
await customers.createCustomer({ idempotencyKey: crypto.randomUUID(), createCustomer: { email: 'asha@example.com' },})Resources
Section titled “Resources”Each resource has its own client class; construct it with your Configuration.
| Client | Methods |
|---|---|
CustomersApi | createCustomer, getCustomer, listCustomers, updateCustomer, archiveCustomer |
CatalogApi | createProduct, getProduct, listProducts, updateProduct, archiveProduct, uploadProductImage, createPrice, getPrice, listPrices, updatePrice, archivePrice |
SubscriptionsApi | createSubscription, getSubscription, listSubscriptions, updateSubscription, cancelSubscription |
InvoicesApi | createInvoice, getInvoice, listInvoices, updateInvoice, sendInvoice, listInvoiceEvents |
CheckoutApi | createCheckoutSession |
WebhooksApi | createWebhookEndpoint, getWebhookEndpoint, listWebhookEndpoints, updateWebhookEndpoint, deleteWebhookEndpoint, rotateWebhookSecret, sendTestWebhook, replayWebhookDeliveries, listWebhookDeliveries |
EventsApi | listEvents, getEvent |
Every request and response is fully typed — your editor autocompletes the exact fields. For endpoint-level detail, see the API Reference.