Finance — entry 046 of 47

YNAB

Verified Jul 2026

YNAB's REST API exposes the same budgets, accounts, transactions, categories, and payees that power its own apps, with read/write access scoped to the signed-in user. Auth is either a self-service Personal Access Token generated from account settings or a full OAuth 2.0 application flow, and a live OPTIONS preflight against api.ynab.com/v1 confirms open CORS support. The API itself carries no separate fee, but YNAB has no permanent free tier for the underlying budgeting subscription — only a time-limited trial ahead of its paid plans.

budgetingpersonal-financeoauthtransactionsaccounts
AuthenticationOAuthRequires an OAuth flow; expect app registration.
HTTPSSupportedTraffic is encrypted in transit.
CORSEnabledCallable directly from browser JavaScript.
PricingPaidSubscription required — no meaningful free tier.
FormatsJSONResponses can be requested as JSON.

GreatAPIs Score

Score66out of 100
Authentication8/25OAuth flow required
Pricing9/20Paid API
Docs20/20Machine-readable spec file bundled
Formats9/15Single response format
Freshness20/20Verified within 6 months

Embed this badge

Scored 66 on greatapis.com
<a href="https://greatapis.com/api/ynab/"><img src="https://greatapis.com/badge/ynab.svg" alt="Scored 66 on greatapis.com"></a>

Auth quickstart

  1. Register an app / run the OAuth flow to obtain a bearer token.
  2. Send it as an Authorization headerAuthorization: Bearer <token>
Stored keyNo key stored

Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.

Endpoints

Servers
https://api.ynab.com/v1
Auth
bearer
User1

The currently authenticated user

GET/userGet user
Responses
StatusDescriptionSchema
200The user infoUserResponse
Plans3

Plans are the top-level container for your YNAB data; accounts, categories, payees, and transactions all belong to a plan. Most endpoints require a plan_id, which can be obtained from "Get all plans". Alternatively, "last-used" can be used in place of a plan_id to specify the most recently used plan, and "default" can be used if [default plan selection](https://api.ynab.com/#oauth-default-plan) is enabled.

GET/plansGet all plans
Parameters
NameInRequiredType
include_accountsquerynoboolean
Responses
StatusDescriptionSchema
200The list of plansPlanSummaryResponse
404No plans were foundErrorResponse
GET/plans/{plan_id}Get a plan
Parameters
NameInRequiredType
plan_idpathyesstring
last_knowledge_of_serverquerynointeger
Responses
StatusDescriptionSchema
200The requested planPlanDetailResponse
404The specified plan was not foundErrorResponse
GET/plans/{plan_id}/settingsGet plan settings
Parameters
NameInRequiredType
plan_idpathyesstring
Responses
StatusDescriptionSchema
200The requested plan settingsPlanSettingsResponse
404The specified plan was not foundErrorResponse
Accounts3

The accounts for a plan. Every transaction belongs to an account, and an account is either "on budget", where its activity is categorized and planned, or a tracking account, where only its balance is tracked (see the on_budget flag).

GET/plans/{plan_id}/accountsGet all accounts
Parameters
NameInRequiredType
plan_idpathyesstring
last_knowledge_of_serverquerynointeger
Responses
StatusDescriptionSchema
200The list of requested accountsAccountsResponse
404No accounts were foundErrorResponse
POST/plans/{plan_id}/accountsCreate an account
Parameters
NameInRequiredType
plan_idpathyesstring
Request body

application/jsonPostAccountWrapper (required)

Responses
StatusDescriptionSchema
201The account was successfully createdAccountResponse
400The request could not be understood due to malformed syntax or validation error(s).ErrorResponse
GET/plans/{plan_id}/accounts/{account_id}Get an account
Parameters
NameInRequiredType
plan_idpathyesstring
account_idpathyesstring
Responses
StatusDescriptionSchema
200The requested accountAccountResponse
404The requested account was not foundErrorResponse
Categories8

The categories for a plan, organized into category groups. Category amounts (assigned, activity, available) are specific to a month, and can be read and updated through the month-scoped category endpoints.

GET/plans/{plan_id}/categoriesGet all categories
Parameters
NameInRequiredType
plan_idpathyesstring
last_knowledge_of_serverquerynointeger
Responses
StatusDescriptionSchema
200The categories grouped by category groupCategoriesResponse
404No categories were foundErrorResponse
POST/plans/{plan_id}/categoriesCreate a category
Parameters
NameInRequiredType
plan_idpathyesstring
Request body

application/jsonPostCategoryWrapper (required)

Responses
StatusDescriptionSchema
201The category was successfully createdSaveCategoryResponse
400The request could not be understood due to malformed syntax or validation error(s).ErrorResponse
GET/plans/{plan_id}/categories/{category_id}Get a category
Parameters
NameInRequiredType
plan_idpathyesstring
category_idpathyesstring
Responses
StatusDescriptionSchema
200The requested categoryCategoryResponse
404The category was not foundErrorResponse
PATCH/plans/{plan_id}/categories/{category_id}Update a category
Parameters
NameInRequiredType
plan_idpathyesstring
category_idpathyesstring
Request body

application/jsonPatchCategoryWrapper (required)

Responses
StatusDescriptionSchema
200The category was successfully updatedSaveCategoryResponse
400The request could not be understood due to malformed syntax or validation error(s)ErrorResponse
POST/plans/{plan_id}/category_groupsCreate a category group
Parameters
NameInRequiredType
plan_idpathyesstring
Request body

application/jsonPostCategoryGroupWrapper (required)

Responses
StatusDescriptionSchema
201The category group was successfully createdSaveCategoryGroupResponse
400The request could not be understood due to malformed syntax or validation error(s).ErrorResponse
PATCH/plans/{plan_id}/category_groups/{category_group_id}Update a category group
Parameters
NameInRequiredType
plan_idpathyesstring
category_group_idpathyesstring
Request body

application/jsonPatchCategoryGroupWrapper (required)

Responses
StatusDescriptionSchema
200The category group was successfully updatedSaveCategoryGroupResponse
400The request could not be understood due to malformed syntax or validation error(s)ErrorResponse
GET/plans/{plan_id}/months/{month}/categories/{category_id}Get a category for a specific plan month
Parameters
NameInRequiredType
plan_idpathyesstring
monthpathyesstring
category_idpathyesstring
Responses
StatusDescriptionSchema
200The requested month categoryCategoryResponse
404The month category was not was foundErrorResponse
PATCH/plans/{plan_id}/months/{month}/categories/{category_id}Update a category for a specific month
Parameters
NameInRequiredType
plan_idpathyesstring
monthpathyesstring
category_idpathyesstring
Request body

application/jsonPatchMonthCategoryWrapper (required)

Responses
StatusDescriptionSchema
200The month category was successfully updatedSaveCategoryResponse
400The request could not be understood due to malformed syntax or validation error(s)ErrorResponse
Payees4

The payees for a plan. Transfers between accounts are represented with special transfer payees; a payee with transfer_account_id set is the transfer payee for that account.

GET/plans/{plan_id}/payeesGet all payees
Parameters
NameInRequiredType
plan_idpathyesstring
last_knowledge_of_serverquerynointeger
Responses
StatusDescriptionSchema
200The requested list of payeesPayeesResponse
404No payees were foundErrorResponse
POST/plans/{plan_id}/payeesCreate a payee
Parameters
NameInRequiredType
plan_idpathyesstring
Request body

application/jsonPostPayeeWrapper (required)

Responses
StatusDescriptionSchema
201The payee was successfully createdSavePayeeResponse
400The request could not be understood due to malformed syntax or validation error(s)ErrorResponse
GET/plans/{plan_id}/payees/{payee_id}Get a payee
Parameters
NameInRequiredType
plan_idpathyesstring
payee_idpathyesstring
Responses
StatusDescriptionSchema
200The requested payeePayeeResponse
404The payee was not foundErrorResponse
PATCH/plans/{plan_id}/payees/{payee_id}Update a payee
Parameters
NameInRequiredType
plan_idpathyesstring
payee_idpathyesstring
Request body

application/jsonPatchPayeeWrapper (required)

Responses
StatusDescriptionSchema
200The payee was successfully updatedSavePayeeResponse
400The request could not be understood due to malformed syntax or validation error(s)ErrorResponse
Payee Locations3

When you enter a transaction and specify a payee on the YNAB mobile apps, the GPS coordinates for that location are stored, with your permission, so that the next time you are in the same place (like the Grocery store) we can pre-populate nearby payees for you! It’s handy and saves you time. This resource makes these locations available. Locations will not be available for all payees.

GET/plans/{plan_id}/payee_locationsGet all payee locations
Parameters
NameInRequiredType
plan_idpathyesstring
Responses
StatusDescriptionSchema
200The list of payee locationsPayeeLocationsResponse
404No payees locations were foundErrorResponse
GET/plans/{plan_id}/payee_locations/{payee_location_id}Get a payee location
Parameters
NameInRequiredType
plan_idpathyesstring
payee_location_idpathyesstring
Responses
StatusDescriptionSchema
200The payee locationPayeeLocationResponse
404The payee location was not foundErrorResponse
GET/plans/{plan_id}/payees/{payee_id}/payee_locationsGet all locations for a payee
Parameters
NameInRequiredType
plan_idpathyesstring
payee_idpathyesstring
Responses
StatusDescriptionSchema
200The list of requested payee locationsPayeeLocationsResponse
404No payees locations were foundErrorResponse
Months2

Each plan contains one or more months, which is where Ready to Assign, Age of Money and category (assigned / activity / available) amounts are available.

GET/plans/{plan_id}/monthsGet all plan months
Parameters
NameInRequiredType
plan_idpathyesstring
last_knowledge_of_serverquerynointeger
Responses
StatusDescriptionSchema
200The list of plan monthsMonthSummariesResponse
404No plan months were foundErrorResponse
GET/plans/{plan_id}/months/{month}Get a plan month
Parameters
NameInRequiredType
plan_idpathyesstring
monthpathyesstring
Responses
StatusDescriptionSchema
200The plan month detailMonthDetailResponse
404The plan month was not foundErrorResponse
Money Movements4

Money movements record money moved between two categories, or between a category and Ready to Assign, within a plan month. Movements performed together as a single action are linked by a money movement group.

GET/plans/{plan_id}/money_movement_groupsGet all money movement groups
Parameters
NameInRequiredType
plan_idpathyesstring
Responses
StatusDescriptionSchema
200The list of requested money movement groupsMoneyMovementGroupsResponse
404No money movement groups were foundErrorResponse
GET/plans/{plan_id}/money_movementsGet all money movements
Parameters
NameInRequiredType
plan_idpathyesstring
Responses
StatusDescriptionSchema
200The list of requested money movementsMoneyMovementsResponse
404No money movements were foundErrorResponse
GET/plans/{plan_id}/months/{month}/money_movement_groupsGet money movement groups for a plan month
Parameters
NameInRequiredType
plan_idpathyesstring
monthpathyesstring
Responses
StatusDescriptionSchema
200The list of requested money movement groupsMoneyMovementGroupsResponse
404No money movement groups were foundErrorResponse
GET/plans/{plan_id}/months/{month}/money_movementsGet money movements for a plan month
Parameters
NameInRequiredType
plan_idpathyesstring
monthpathyesstring
Responses
StatusDescriptionSchema
200The list of requested money movementsMoneyMovementsResponse
404No money movements were foundErrorResponse
Transactions11

The transactions for a plan. Transaction amounts are specified in [milliunits format](https://api.ynab.com/#formats). Split transactions are represented with subtransactions, and transfers between accounts are represented with transfer payees.

GET/plans/{plan_id}/accounts/{account_id}/transactionsGet account transactions
Parameters
NameInRequiredType
plan_idpathyesstring
account_idpathyesstring
since_datequerynostring
until_datequerynostring
typequerynostring
last_knowledge_of_serverquerynointeger
Responses
StatusDescriptionSchema
200The list of requested transactionsTransactionsResponse
404No transactions were foundErrorResponse
GET/plans/{plan_id}/categories/{category_id}/transactionsGet category transactions
Parameters
NameInRequiredType
plan_idpathyesstring
category_idpathyesstring
since_datequerynostring
until_datequerynostring
typequerynostring
last_knowledge_of_serverquerynointeger
Responses
StatusDescriptionSchema
200The list of requested transactionsHybridTransactionsResponse
404No transactions were foundErrorResponse
GET/plans/{plan_id}/months/{month}/transactionsGet plan month transactions
Parameters
NameInRequiredType
plan_idpathyesstring
monthpathyesstring
since_datequerynostring
until_datequerynostring
typequerynostring
last_knowledge_of_serverquerynointeger
Responses
StatusDescriptionSchema
200The list of requested transactionsTransactionsResponse
404No transactions were foundErrorResponse
GET/plans/{plan_id}/payees/{payee_id}/transactionsGet payee transactions
Parameters
NameInRequiredType
plan_idpathyesstring
payee_idpathyesstring
since_datequerynostring
until_datequerynostring
typequerynostring
last_knowledge_of_serverquerynointeger
Responses
StatusDescriptionSchema
200The list of requested transactionsHybridTransactionsResponse
404No transactions were foundErrorResponse
GET/plans/{plan_id}/transactionsGet transactions
Parameters
NameInRequiredType
plan_idpathyesstring
since_datequerynostring
until_datequerynostring
typequerynostring
last_knowledge_of_serverquerynointeger
Responses
StatusDescriptionSchema
200The list of requested transactionsTransactionsResponse
400An error occurredErrorResponse
404No transactions were foundErrorResponse
POST/plans/{plan_id}/transactionsCreate a single transaction or multiple transactions
Parameters
NameInRequiredType
plan_idpathyesstring
Request body

application/jsonPostTransactionsWrapper (required)

Responses
StatusDescriptionSchema
201The transaction or transactions were successfully createdSaveTransactionsResponse
400The request could not be understood due to malformed syntax or validation error(s).ErrorResponse
409A transaction on the same account with the same `import_id` already exists.ErrorResponse
PATCH/plans/{plan_id}/transactionsUpdate multiple transactions
Parameters
NameInRequiredType
plan_idpathyesstring
Request body

application/jsonPatchTransactionsWrapper (required)

Responses
StatusDescriptionSchema
200The transactions were successfully updatedSaveTransactionsResponse
400The request could not be understood due to malformed syntax or validation error(s).ErrorResponse
POST/plans/{plan_id}/transactions/importImport transactions
Parameters
NameInRequiredType
plan_idpathyesstring
Responses
StatusDescriptionSchema
200The request was successful but there were no transactions to importTransactionsImportResponse
201One or more transactions were imported successfullyTransactionsImportResponse
400The request could not be understood due to malformed syntax or validation error(s)ErrorResponse
GET/plans/{plan_id}/transactions/{transaction_id}Get a transaction
Parameters
NameInRequiredType
plan_idpathyesstring
transaction_idpathyesstring
Responses
StatusDescriptionSchema
200The requested transactionTransactionResponse
404The transaction was not foundErrorResponse
PUT/plans/{plan_id}/transactions/{transaction_id}Update a transaction
Parameters
NameInRequiredType
plan_idpathyesstring
transaction_idpathyesstring
Request body

application/jsonPutTransactionWrapper (required)

Responses
StatusDescriptionSchema
200The transaction was successfully updatedTransactionResponse
400The request could not be understood due to malformed syntax or validation error(s)ErrorResponse
DELETE/plans/{plan_id}/transactions/{transaction_id}Delete a transaction
Parameters
NameInRequiredType
plan_idpathyesstring
transaction_idpathyesstring
Responses
StatusDescriptionSchema
200The transaction was successfully deletedTransactionResponse
404The transaction was not foundErrorResponse
Scheduled Transactions5

The scheduled transactions for a plan; upcoming and recurring transactions that have not yet been entered into an account. Each has a frequency along with the first and next dates it will occur (date_first and date_next).

GET/plans/{plan_id}/scheduled_transactionsGet all scheduled transactions
Parameters
NameInRequiredType
plan_idpathyesstring
last_knowledge_of_serverquerynointeger
Responses
StatusDescriptionSchema
200The list of requested scheduled transactionsScheduledTransactionsResponse
404No scheduled transactions were foundErrorResponse
POST/plans/{plan_id}/scheduled_transactionsCreate a scheduled transaction
Parameters
NameInRequiredType
plan_idpathyesstring
Request body

application/jsonPostScheduledTransactionWrapper (required)

Responses
StatusDescriptionSchema
201The scheduled transaction was successfully createdScheduledTransactionResponse
400The request could not be understood due to malformed syntax or validation error(s).ErrorResponse
GET/plans/{plan_id}/scheduled_transactions/{scheduled_transaction_id}Get a scheduled transaction
Parameters
NameInRequiredType
plan_idpathyesstring
scheduled_transaction_idpathyesstring
Responses
StatusDescriptionSchema
200The requested Scheduled TransactionScheduledTransactionResponse
404The scheduled transaction was not foundErrorResponse
PUT/plans/{plan_id}/scheduled_transactions/{scheduled_transaction_id}Update a scheduled transaction
Parameters
NameInRequiredType
plan_idpathyesstring
scheduled_transaction_idpathyesstring
Request body

application/jsonPutScheduledTransactionWrapper (required)

Responses
StatusDescriptionSchema
200The scheduled transaction was successfully updatedScheduledTransactionResponse
400The request could not be understood due to malformed syntax or validation error(s)ErrorResponse
DELETE/plans/{plan_id}/scheduled_transactions/{scheduled_transaction_id}Delete a scheduled transaction
Parameters
NameInRequiredType
plan_idpathyesstring
scheduled_transaction_idpathyesstring
Responses
StatusDescriptionSchema
200The scheduled transaction was successfully deletedScheduledTransactionResponse
404The scheduled transaction was not foundErrorResponse

Try it

Developer reference

Base URLhttps://api.ynab.com/v1
Rate limit

YNAB's own docs (api.ynab.com/#rate-limiting) cap each access token at 200 requests per hour, enforced with a rolling one-hour window; exceeding it returns HTTP 429.

Key endpoints
  • GET/user
  • GET/plans
  • GET/plans/{plan_id}/accounts
  • GET/plans/{plan_id}/categories
  • GET/plans/{plan_id}/transactions