Our API uses a REST based design, leverages the JSON data format, and relies upon HTTPS for transport.
Bring your own key. This API needs your own YNAB API Endpoints key - get one from the provider, add it once below, and the proxy injects it on every call. Your OmniStream plan covers the unified SDK, key storage, and proxy - the provider's own rate limits still apply to your key.
This is a community listing. If you own this API, you can request ownership.
npm install omnistream-sdkimport { OmniClient } from "omnistream-sdk";
const omni = new OmniClient({ token: process.env.OMNI_KEY! });
// One key reaches every API on the marketplace.
const data = await omni.call("youneedabudget/getBudgets");One install, one key - the same client calls every API on the marketplace.
Whether to include the list of budget accounts
List budgets
Single budget
Account list
Create a new account
Single account
List account transactions
/**
* YNABAPIEndpoints - generated by OmniStream from YNAB API Endpoints's OpenAPI spec.
* One typed method per endpoint. A single Omni key reaches the API.
*/
const DEFAULT_BASE = "https://grid.skinvaults.online/v1/proxy/youneedabudget";
export class YNABAPIEndpointsError extends Error {
status: number;
code?: string;
constructor(status: number, code: string | undefined, message?: string) {
super(message || `YNABAPIEndpoints error ${status}`);
this.name = "YNABAPIEndpointsError";
this.status = status;
this.code = code;
}
}
export interface YNABAPIEndpointsOptions {
baseUrl?: string;
fetch?: typeof fetch;
timeoutMs?: number;
}
export class YNABAPIEndpoints {
/** @param token Your OmniStream key (one key for every API). */
constructor(private token: string, private opts: YNABAPIEndpointsOptions = {}) {
if (!token) throw new Error("YNABAPIEndpoints: token is required");
}
rateLimit: { remainingMinute?: number; remainingDay?: number } | null = null;
private async _request(method: string, path: string, { params, body }: { params?: Record<string, unknown>; body?: unknown } = {}): Promise<any> {
const f = this.opts.fetch ?? globalThis.fetch;
const url = new URL((this.opts.baseUrl ?? DEFAULT_BASE).replace(/\/+$/, "") + path);
if (params) for (const [k, v] of Object.entries(params)) if (v != null) url.searchParams.set(k, String(v));
const headers: Record<string, string> = { "x-omni-key": this.token };
if (body !== undefined) headers["content-type"] = "application/json";
const res = await f(url, { method, headers, body: body !== undefined ? JSON.stringify(body) : undefined });
this.rateLimit = {
remainingMinute: Number(res.headers.get("x-ratelimit-remaining-minute")) || undefined,
remainingDay: Number(res.headers.get("x-ratelimit-remaining-day")) || undefined,
};
const data = await res.json().catch(() => ({}));
if (!res.ok) throw new YNABAPIEndpointsError(res.status, data?.error?.code, data?.error?.message);
return data.data ?? data;
}
/** List budgets */
getBudgets(params: { "include_accounts"?: boolean }): Promise<any> {
return this._request("GET", "/budgets", { params });
}
/** Single budget */
getBudgetById(params: { "budget_id": string; "last_knowledge_of_server"?: number }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}", { params });
}
/** Account list */
getAccounts(params: { "budget_id": string; "last_knowledge_of_server"?: number }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/accounts", { params });
}
/** Create a new account */
createAccount(body: unknown, params: { "budget_id": string }): Promise<any> {
return this._request("POST", "/budgets/{budget_id}/accounts", { body, params });
}
/** Single account */
getAccountById(params: { "budget_id": string; "account_id": string }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/accounts/{account_id}", { params });
}
/** List account transactions */
getTransactionsByAccount(params: { "budget_id": string; "account_id": string; "since_date"?: string; "type"?: string; "last_knowledge_of_server"?: number }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/accounts/{account_id}/transactions", { params });
}
/** List categories */
getCategories(params: { "budget_id": string; "last_knowledge_of_server"?: number }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/categories", { params });
}
/** Single category */
getCategoryById(params: { "budget_id": string; "category_id": string }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/categories/{category_id}", { params });
}
/** List category transactions */
getTransactionsByCategory(params: { "budget_id": string; "category_id": string; "since_date"?: string; "type"?: string; "last_knowledge_of_server"?: number }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/categories/{category_id}/transactions", { params });
}
/** List budget months */
getBudgetMonths(params: { "budget_id": string; "last_knowledge_of_server"?: number }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/months", { params });
}
/** Single budget month */
getBudgetMonth(params: { "budget_id": string; "month": string }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/months/{month}", { params });
}
/** Single category for a specific budget month */
getMonthCategoryById(params: { "budget_id": string; "month": string; "category_id": string }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/months/{month}/categories/{category_id}", { params });
}
/** Update a category for a specific month */
updateMonthCategory(body: unknown, params: { "budget_id": string; "month": string; "category_id": string }): Promise<any> {
return this._request("PATCH", "/budgets/{budget_id}/months/{month}/categories/{category_id}", { body, params });
}
/** List payee locations */
getPayeeLocations(params: { "budget_id": string }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/payee_locations", { params });
}
/** Single payee location */
getPayeeLocationById(params: { "budget_id": string; "payee_location_id": string }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/payee_locations/{payee_location_id}", { params });
}
/** List payees */
getPayees(params: { "budget_id": string; "last_knowledge_of_server"?: number }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/payees", { params });
}
/** Single payee */
getPayeeById(params: { "budget_id": string; "payee_id": string }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/payees/{payee_id}", { params });
}
/** List locations for a payee */
getPayeeLocationsByPayee(params: { "budget_id": string; "payee_id": string }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/payees/{payee_id}/payee_locations", { params });
}
/** List payee transactions */
getTransactionsByPayee(params: { "budget_id": string; "payee_id": string; "since_date"?: string; "type"?: string; "last_knowledge_of_server"?: number }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/payees/{payee_id}/transactions", { params });
}
/** List scheduled transactions */
getScheduledTransactions(params: { "budget_id": string; "last_knowledge_of_server"?: number }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/scheduled_transactions", { params });
}
/** Single scheduled transaction */
getScheduledTransactionById(params: { "budget_id": string; "scheduled_transaction_id": string }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/scheduled_transactions/{scheduled_transaction_id}", { params });
}
/** Budget Settings */
getBudgetSettingsById(params: { "budget_id": string }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/settings", { params });
}
/** List transactions */
getTransactions(params: { "budget_id": string; "since_date"?: string; "type"?: string; "last_knowledge_of_server"?: number }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/transactions", { params });
}
/** Create a single transaction or multiple transactions */
createTransaction(body: unknown, params: { "budget_id": string }): Promise<any> {
return this._request("POST", "/budgets/{budget_id}/transactions", { body, params });
}
/** Update multiple transactions */
updateTransactions(body: unknown, params: { "budget_id": string }): Promise<any> {
return this._request("PATCH", "/budgets/{budget_id}/transactions", { body, params });
}
/** Bulk create transactions */
bulkCreateTransactions(body: unknown, params: { "budget_id": string }): Promise<any> {
return this._request("POST", "/budgets/{budget_id}/transactions/bulk", { body, params });
}
/** Import transactions */
importTransactions(params: { "budget_id": string }): Promise<any> {
return this._request("POST", "/budgets/{budget_id}/transactions/import", { params });
}
/** Single transaction */
getTransactionById(params: { "budget_id": string; "transaction_id": string }): Promise<any> {
return this._request("GET", "/budgets/{budget_id}/transactions/{transaction_id}", { params });
}
/** Updates an existing transaction */
updateTransaction(body: unknown, params: { "budget_id": string; "transaction_id": string }): Promise<any> {
return this._request("PUT", "/budgets/{budget_id}/transactions/{transaction_id}", { body, params });
}
/** Deletes an existing transaction */
deleteTransaction(params: { "budget_id": string; "transaction_id": string }): Promise<any> {
return this._request("DELETE", "/budgets/{budget_id}/transactions/{transaction_id}", { params });
}
/** User info */
getUser(): Promise<any> {
return this._request("GET", "/user", {});
}
}
export default YNABAPIEndpoints;
No reviews yet. Be the first to rate this API.
Yes. YNAB API Endpoints uses apiKey authentication, so you bring your own key from the provider. You store it once on OmniStream and the proxy injects it into every call, so your code only ever sends your Omni key.
Our API uses a REST based design, leverages the JSON data format, and relies upon HTTPS for transport. It exposes 31 endpoints over GET, POST, PATCH, PUT, DELETE, including GET /budgets, GET /budgets/{budget_id}, GET /budgets/{budget_id}/accounts.
Install the OmniStream SDK for your language and call YNAB API Endpoints through it. The client is generated from this API's OpenAPI spec, so parameters and responses are fully typed, and the same client also calls every other API in the marketplace.
You can start on the free plan. OmniStream charges for the unified SDK, key storage and proxy rather than for YNAB API Endpoints itself, and YNAB API Endpoints's own rate limits still apply to your provider key.
ExchangeRate-API: Fetch the latest currency exchange rates via API. ExchangeRate-API is free and unlimited.
List categories
Single category
List category transactions
List budget months
Single budget month
Single category for a specific budget month
Update a category for a specific month
List payee locations
Single payee location
List payees
Single payee
List locations for a payee
List payee transactions
List scheduled transactions
Single scheduled transaction
Budget Settings
List transactions
Create a single transaction or multiple transactions
Update multiple transactions
Bulk create transactions
Import transactions
Single transaction
Updates an existing transaction
Deletes an existing transaction
User info