A fully-typed TypeScript client library for the PocketSmith API, automatically generated from their official OpenAPI specification.
- ✅ Fully typed - Complete TypeScript definitions for all API endpoints
- ✅ Auto-generated - Built directly from PocketSmith's official OpenAPI spec
- ✅ Zero boilerplate - Minimal configuration required
- ✅ Modern - Built with
openapi-fetchfor excellent performance - ✅ Authentication - Supports both API keys and OAuth2
npm install pocketsmith-tsimport { createPocketSmithClient } from 'pocketsmith-ts';
const client = createPocketSmithClient({
apiKey: 'your-api-key-here'
});
// Get current user
const { data: user } = await client.GET('/me');
console.log(user);
// Get user's accounts
const { data: accounts } = await client.GET('/users/{id}/accounts', {
params: { path: { id: user.id } }
});const client = createPocketSmithClient({
accessToken: 'your-oauth-token-here'
});
const { data: user } = await client.GET('/me');const client = createPocketSmithClient({
// API base URL (optional, defaults to https://api.pocketsmith.com/v2)
baseUrl: 'https://api.pocketsmith.com/v2',
// For personal use - get from https://my.pocketsmith.com/api_keys
apiKey: 'your-developer-key',
// For OAuth apps - obtained through OAuth flow
accessToken: 'your-oauth-token',
});PocketSmith has two types of account endpoints that serve different purposes:
High-level account groupings that represent conceptual account containers. These are used for organizing and categorizing your financial structure.
// Fetch all accounts for a user
const { data: accounts } = await client.GET('/users/{id}/accounts', {
params: { path: { id: userId } }
});
// Get specific account details
const { data: account } = await client.GET('/accounts/{id}', {
params: { path: { id: accountId } }
});Individual accounts where transactions are actually posted. These represent the actual bank accounts, credit cards, etc. where money moves in and out.
// Fetch transaction accounts for an account
const { data: transactionAccounts } = await client.GET('/accounts/{id}/transaction_accounts', {
params: { path: { id: accountId } }
});
// Get transactions for a specific transaction account
const { data: transactions } = await client.GET('/transaction_accounts/{id}/transactions', {
params: {
path: { id: transactionAccountId },
query: {
start_date: '2024-01-01',
end_date: '2024-12-31'
}
}
});
// Create a transaction in a specific transaction account
const { data: transaction } = await client.POST('/transaction_accounts/{id}/transactions', {
params: { path: { id: transactionAccountId } },
body: {
payee: 'Coffee Shop',
amount: -4.50,
date: '2024-01-15'
}
});const { data: transactions } = await client.GET('/users/{id}/transactions', {
params: {
path: { id: userId },
query: {
start_date: '2024-01-01',
end_date: '2024-12-31',
search: 'coffee',
type: 'debit'
}
}
});// Get transactions for a high-level account grouping
const { data: accountTransactions } = await client.transactions.getByAccount(123, {
start_date: '2024-01-01',
end_date: '2024-12-31',
search: 'coffee'
});
// Get transactions for a specific transaction account (where transactions are posted)
const { data: transactionAccountTransactions } = await client.transactions.getByTransactionAccount(456, {
start_date: '2024-01-01',
end_date: '2024-12-31',
type: 'debit'
});const { data: transaction } = await client.POST('/transaction_accounts/{id}/transactions', {
params: {
path: { id: transactionAccountId }
},
body: {
payee: 'Coffee Shop',
amount: -4.50,
date: '2024-01-15',
category_id: categoryId,
note: 'Morning coffee'
}
});// Create a category
const { data: category } = await client.POST('/users/{id}/categories', {
params: { path: { id: userId } },
body: {
title: 'Coffee & Drinks',
colour: '#8B4513',
is_bill: false
}
});
// Update a category
const { data: updated } = await client.PUT('/categories/{id}', {
params: { path: { id: category.id } },
body: {
title: 'Coffee & Beverages',
colour: '#654321'
}
});The client returns a { data, error } object for each request. For better error debugging, use the serializeError utility:
import { createPocketSmithClient, serializeError } from 'pocketsmith-ts';
const client = createPocketSmithClient({ apiKey: 'your-key' });
const { data, error } = await client.GET('/me');
if (error) {
// Use serializeError to properly format errors (no more [object Object])
console.error('API Error:', serializeError(error));
console.error('Full error object:', error);
// Handle error case
return;
}
// Use data safely here
console.log(data.name);All API responses and request bodies are fully typed:
// user is typed as components["schemas"]["User"]
const { data: user } = await client.GET('/me');
// TypeScript knows about all user properties
console.log(user.id, user.name, user.email);
// Request body is also typed
await client.POST('/users/{id}/categories', {
params: { path: { id: userId } },
body: {
title: 'Required field',
colour: '#FF0000', // Optional but typed
// TypeScript will error if you use invalid properties
}
});# Run all tests
npm test
# Run only integration tests (requires API key)
npm run test:integration
# Run with coverage
npm test -- --coverageIntegration tests require a valid PocketSmith API key. Set it as an environment variable:
export POCKETSMITH_API_KEY=your_api_key_here
npm run test:integrationOr create a .env file (copy from .env.example):
cp .env.example .env
# Edit .env with your API keyNote: Integration tests make real API calls to PocketSmith and may count against your API rate limits.
The client is automatically generated from PocketSmith's official OpenAPI specification. To update:
npm run generateThis will:
- Download the latest OpenAPI spec from PocketSmith's GitHub repo
- Generate TypeScript types and interfaces
- Update the client accordingly
npm run buildnpm run devFor personal use or simple integrations, you can generate a developer key:
- Log into PocketSmith
- Go to Settings → Security & Integrations
- Create a new developer key
- Use it with the
apiKeyoption
For applications that other users will use:
- Contact PocketSmith at api@pocketsmith.com to register your app
- Implement the OAuth2 flow to get access tokens
- Use tokens with the
accessTokenoption
See PocketSmith's OAuth documentation for details.
MIT
- Fork the repository
- Create your feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
John Barton - @joho