Introduction

Hello Developers Welcome to the YNAB API! (If you aren't a developer or you have no idea what an "API" is and you just want to sign in to your YNAB account, you can do that here.) The YNAB API is REST based, uses the JSON data format and is secured with HTTPS. You can use it to build a personal application to interact with your own budget or build an application that any other YNABer can authorize and use. Be sure to check out what other YNABers have built in the Works with YNAB section and let us know when you build something yourself! You can check our Release Notes to find out about updates and improvements to the API. If you need support, please send an email to api@youneedabudget.com or head over to the API Community Forum. Quick Start If you're the type of person who just wants to get up and running as quickly as possible and then circle back to fill in the gaps, these steps are for you: Sign in to the YNAB web app and go to the "Account Settings" page and then to the "Developer Settings" page. Under the "Personal Access Tokens" section, click "New Token", enter your password and click "Generate" to get an access token. Open a terminal window and run this:

curl -H "Authorization: Bearer <ACCESS_TOKEN>" https://api.youneedabudget.com/v1/budgets You should get a response that looks something like this: HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 {"data": { "budgets": [ { "id":"6ee704d9-ee24-4c36-b1a6-cb8ccf6a216c", "name":"My Budget", "last_modified_on":"2017-12-01T12:40:37.867Z", "first_month":"2017-11-01", "last_month":"2017-11-01" } ] } } That's it! You just received a list of your budgets in JSON format through the YNAB API. Horray! If you want to start working with the API to build something more substantial, you might want to check out our YNAB API Starter Kit which is a simple, but functional web application that uses the API.

Authentication

Overview All API resources require a valid access token for authentication. There are two ways to obtain access tokens: Personal Access Tokens and OAuth Applications. Personal Access Tokens Personal Access Tokens are access tokens created by an account owner and are intended to be used only by that same account owner. They should not be shared and are intended for individual usage scenarios. They are a convenient way to obtain an access token without having to use a full OAuth authentication flow. If you are an individual developer and want to simply access your own account through the API, Personal Access Tokens are the best choice. Obtaining a Personal Access Token To obtain a Personal Access Token, sign in to your account, go to "Account Settings", scroll down and navigate to "Developer Settings" section. From the Developer Settings page, click "New Token" under the Personal Access Tokens section, enter your password and you will be presented with a new Personal Access Token. You will not be able to retrieve the token later so you should store it in a safe place. This new token will not expire but can be revoked at any time from this same screen. You should not share this access token with anyone or ask for anyone else's access token. It should be treated with as much care as your main account password. OAuth Applications OAuth is a secure way for a third-party application to obtain delegated but limited permissions to a user account and is appropriate for use in applications that need to gain limited authorized permissions to accounts they do not own. If you are developing an application that uses the API and want other users to be able to use your application, OAuth is the only option for obtaining access tokens for other users. All OAuth Application integrations must abide by the API Terms of Service and the OAuth Application Requirements. Failure to do so will result in disabling of the application. Restricted Mode When an OAuth application is created, it will be placed in Restricted Mode initially. This means the application will be limited to obtaining 25 access tokens for users other than the OAuth application owner. Once this limit is reached, a message will be placed on the Authorization screen and new authorizations will be prohibited. To have Restricted Mode removed, you must send a request to api@youneedabudget.com. We will review your OAuth application to ensure it abides by the API Terms of Service and the OAuth Application Requirements. Once we review the application and confirm adherence to our policies, we will remove Restricted Mode. Creating an OAuth Application To create an OAuth Application, sign in to your account, go to "Account Settings", scroll down and navigate to "Developer Settings" section. From the Developer Settings page, click "New Application" under the OAuth Applications section. Here, you specify the details of your application and save it. After saving, you will see the details of the new application, including the Client ID and the Client Secret which are referenced in the instructions below. After creating the application, you are then able to use one of the supported grant types to obtain a valid access token. The YNAB API supports two OAuth grant types: Implict Grant and Authorization Code Grant. Implicit Grant Flow The Implict Grant type, also informally known as the "client-side flow", should be used in scenarios where the application Secret cannot be kept private. The application Secret should never be visible or accessible by a client! If you are requesting an access token directly from a browser or other client that is not secure (i.e. mobile app) this is the flow you should use. This grant type does not support refresh tokens so once the access token expires 2 hours after it was granted, the user must be prompted again to authorize your application. Here is the flow to obtain an access token: Send user to the authorization URL: https://app.youneedabudget.com/oauth/authorize?client_id=[CLIENT_ID]&redirect_uri=[REDIRECT_URI]&response_type=token , replacing [CLIENT_ID] and [REDIRECT_URI] with the values configured when creating the OAuth Application. The user will be given the option to approve your request for access: Upon approval, the user's browser will be redirected to the [REDIRECT_URI] with a new access token sent as a fragment (hash) identifier named access_token. For example, if your Redirect URI is configured as https://myawesomeapp.com, upon the user authorizing your application, they would be redirected to https://myawesomeapp.com/#access_token=8bc63e42-1105-11e8-b642-0ed5f89f718b . This access token can then be used to authenticate through the API. Authorization Code Grant Flow The Authorization Code Grant type, also informally known as the "server-side flow", is intended for server-side applications, where the application Secret can be protected. If you are requesting an access token from a server application that is private and under your control, this grant type can be used. This grant type supports refresh tokens so once the access token expires 2 hours after it was granted, the application can request a new access token without having to prompt the user to authorize again. Here is the flow to obtain an access token: Send user to the authorization URL: https://app.youneedabudget.com/oauth/authorize?client_id=[CLIENT_ID]&redirect_uri=[REDIRECT_URI]&response_type=code , replacing [CLIENT_ID] and [REDIRECT_URI] with the values configured when creating the OAuth Application. The user will be given the option to approve your request for access: Upon approval, the user's browser will be redirected to the [REDIRECT_URI] with a new authorization code sent as a query parameter named code. For example, if your Redirect URI is configured as https://myawesomeapp.com, upon the user authorizing your application, they would be redirected to https://myawesomeapp.com/?code=8bc63e42-1105-11e8-b642-0ed5f89f718b . Now that your application has an authorization code, you need to request an access token by sending a POST request to https://app.youneedabudget.com/oauth/token?client_id=[CLIENT_ID]&client_secret=[CLIENT_SECRET]&redirect_uri=[REDIRECT_URI]&grant_type=authorization_code&code=[AUTHORIZATION_CODE] . Here are the values that should be passed as form data fields: client_id - The same [CLIENT_ID] sent with the original authorization code in Step 1 above and provided when setting up the OAuth Application.

- The same [CLIENT_ID] sent with the original authorization code in Step 1 above and provided when setting up the OAuth Application. client_secret - The client secret provided when setting up the OAuth Application.

- The client secret provided when setting up the OAuth Application. redirect_uri - The same [REDIRECT_URI] sent with the original authorization code request in Step 1 above and specified when setting up the OAuth Application.

- The same [REDIRECT_URI] sent with the original authorization code request in Step 1 above and specified when setting up the OAuth Application. grant_type - The value authorization_code should be provided for this field, which will indicate that you are supplying an authorization code and requesting an access token.

- The value should be provided for this field, which will indicate that you are supplying an authorization code and requesting an access token. code - The authorization code received as code query param in Step 2 above. The access_token, which can be used to authenticate through the API, will be included in the token response which will look like this: { "access_token": "0cd3d1c4-1107-11e8-b642-0ed5f89f718b", "token_type": "bearer", "expires_in": 7200, "refresh_token": "13ae9632-1107-11e8-b642-0ed5f89f718b" } The access token has an expiration, indicated by the "expires_in" value. To obtain a new access token without requiring the user to manually authorize again, you should store the "refresh_token" and then send a POST request to https://app.youneedabudget.com/oauth/token?client_id=[CLIENT_ID]&client_secret=[CLIENT_SECRET]&grant_type=refresh_token&refresh_token=[REFRESH_TOKEN] . If successful, the response will contain a new access token and a new refresh token in the original token response format. A refresh token can only be used once to obtain a new access token, and will be revoked the first time you use the new access token. Authorization Parameters read-only Scope When an OAuth application is requesting authorization, a scope parameter with a value of read-only can be passed to request read-only access to a budget. For example: https://app.youneedabudget.com/oauth/authorize?client_id=[CLIENT_ID]&redirect_uri=[REDIRECT_URI]&response_type=token&scope=read-only . If an access token issued with the read-only scope is used when requesting an endpoint that modifies the budget (POST, PATCH, etc.) a 403 Forbidden response will be issued. If you do not need write access to a budget, please use the read-only scope. state parameter An optional, but recommended, state parameter can also be supplied to prevent Cross Site Request Forgery (XRSF) attacks. If specified, the same value will be returned to the [REDIRECT_URI] as a state parameter. For example: if you included parameter state=4cac8f43 in the authorization URI, when the user is redirected to [REDIRECT_URI], the URL would contain that same value in a state parameter. The value of state should be unique for each request. Default Budget Selection An OAuth application can optionally have 'default budget selection' enabled. When default budget selection is enabled, a user will be asked to select a default budget when authorizating your application: You can then pass in the value 'default' in lieu of a budget_id in endpoint calls. For example, to get a list of accounts on the default budget you could use this endpoint: https://api.youneedabudget.com/v1/budgets/default/accounts . Access Token Usage Once you have obtained an access token, you must use HTTP Bearer Authentication, as defined in RFC6750, to authenticate when sending requests to the API. We support Authorization Request Header and URI Query Parameter as means to pass an access token. Authorization Request Header The recommended method for sending an access token is by using an Authorization Request Header where the access token is sent in the HTTP request header. curl -H "Authorization: Bearer <ACCESS_TOKEN>" https://api.youneedabudget.com/v1/budgets URI Query Parameter An access token can also be passed as a URI query parameter named "access_token": curl https://api.youneedabudget.com/v1/budgets?access_token=<ACCESS_TOKEN>

Usage

Overview Our API uses a REST based design, leverages the JSON data format, and relies upon HTTPS for transport. We respond with meaningful HTTP response codes and if an error occurs, we include error details in the response body. We support Cross-Origin Resource Sharing (CORS) which allows you to use the API directly from a web application. Mostly read-only The current version of the API ("v1") is mostly read-only, supporting GET requests. However, creating (POST) and updating (PUT, PATCH) transactions at /budgets/{budget_id}/transactions and updating (PATCH) monthly budgeted amounts at /budgets/{budget_id}/months/{month}/categories/{category_id} is supported. Security TLS (a.k.a. SSL or HTTPS) is enforced on all requests to ensure communication from your client to our endpoint is encrypted, end-to-end. You must obtain an access token and provide it with each request. An access token is tied directly to a YNAB account but can be independently revoked. Best Practices Caching Please cache data received from the API when possible to avoid unnecessary traffic. Delta Requests Some endpoints support Delta Requests, where you can request to receive only what has changed since the last response. It is highly recommended to use this feature as it reduces load on our servers as well as makes processing responses more efficient. Fault Tolerance Errors and exceptions will sometimes happen. You might experience a connection problem between your app and the YNAB API or a complete outage. You should always anticipate that errors or exceptions may occur and build in accommodations for them in your application. Specific Requests You should use the most specific request possible to avoid large responses which are taxing on the API server and slower for your app to consume and process. For example, if you want to retrieve the balance for a particular category, you should request that single category from /budgets/{budget_id}/categories/{category_id} rather than requesting all categories. Endpoints The base URL is: https://api.youneedabudget.com/v1 . To see a list of all available endpoints, please refer to our API Endpoints page. The documentation also lets you "try it out" on each endpoint directly within the page. Response Format All responses from the API will come with a response wrapper object to make them predictable and easier to parse. Successful Responses Successful responses will return wrapper object with a data property that will contain the resource data. The name of the object inside of the data property will correspond to the requested resource. For example, if you request /budgets , the response will look like: { "data": { "budgets ": [ {"id": "cee64af3-a3df-425e-a18a-980e7ec10dc2", ...}, {"id": "55697d98-b942-4f29-97d8-f870edd001d6", ...} ] } If you request a single account from /accounts/{account_id} : { "data": { "account": {"id": "16da87a0-66c7-442f-8216-a3daf9cb82a8", ...} } Empty data Response data properties that have no data will be specified as null rather than being omitted. For example, a transaction that does not have a payee would have a body that looks like this: { "data": { "transaction": { "id": "16da87a0-66c7-442f-8216-a3daf9cb82a8", "date": "2017-12-01", "payee_id": null, // This transaction does not have a payee ... } } Error Responses For error responses, the HTTP Status Code will be specified as something other than 20X and the body of the response will contain an error object. The format of an error response is : { "error": { "id": "123" "name": "error_name" "detail": "Error detail" } } The Errors section lists the possible errors. Errors Errors from the API are indicated by the HTTP response status code and also included in the body of the response, according to the response format. The following errors are possible: HTTP Status Error ID Name Description 400 400 bad_request The request could not be understood by the API due to malformed syntax or validation errors. 401 401 not_authorized This error will be returned in any of the following cases: Missing access token

Invalid access token

Revoked access token

Expired access token 403 403.1 subscription_lapsed The subscription for this account has lapsed 403.2 trial_expired The trial for this account has expired 403.3 unauthorized_scope The supplied access token has a scope which does not allow access. 404 404.1 not_found The specified URI does not exist 404.2 resource_not_found This error will be returned when requesting a resource that is not found. For example, if you requested /budgets/123 and a budget with the id '123' does not exist, this error would be returned. 409 409 conflict If resource cannot be saved during a PUT or POST request because it conflicts with an existing resource, this error will be returned. 429 429 too_many_requests This error is returned if you make too many requests to the API in a short amount of time. Please see the Rate Limiting section. Wait a while and try again. 500 500 internal_server_error This error will be returned if the API experiences an unexpected error. 503 503 service_unavailable This error will be returned if we have temporarily disabled access to the API. This can happen when we are experiencing heavy load or need to perform maintenance. Data Formats Numbers Currency amounts returned from the API—such as account balance, category balance, and transaction amounts— use a format we call "milliunits". Most currencies don't have three decimal places, but you can think of it as the number of thousandths of a unit in the currency: 1,000 milliunits equals "one" unit of a currency (one Dollar, one Euro, one Pound, etc.). Here are some concrete examples: Currency Milliunits Amount USD ($) 123930 $123.93 USD ($) -220 -$0.22 Euro (€) 4924340 €4.924,34 Euro (€) -2990 -€2,99 Jordanian dinar -395032 -395.032 Dates All dates returned in response calls use ISO 8601 (RFC 3339 "full-date") format. For example, December 30, 2015 is formatted as 2015-12-30 . Timezone All dates use UTC as the timezone. Delta Requests The following API resources support "delta requests", where you ask for only those entities that have changed since your last request: budgets/{budget_id}

budgets/{budget_id}/accounts

budgets/{budget_id}/categories

budgets/{budget_id}/months

budgets/{budget_id}/payees

budgets/{budget_id}/transactions

budgets/{budget_id}/scheduled_transactions We recommend using delta requests as they allow API consumers to parse less data and make updates more efficient, and decreases server load on our end. Resources supporting delta requests return a server_knowledge number in the response. This number can then be passed in as the last_knowledge_of_server query parameter. Then, only the data that has changed since the last request will be included in the response. For example, if you request a budget's contents from /budgets/{budget_id} , it will include the server_knowledge like so: { "data": { "server_knowledge": 100, "budget": { "id": "16da87a0-66c7-442f-8216-a3daf9cb82a8", ... } } } On a subsequent request, you can pass that same server_knowledge in as a query parameter named last_knowledge_of_server ( /budgets/{budget_id}?last_knowledge_of_server=100 ) and get back only the entities that have changed since your last request. For example, if a single account had its name changed since your last request, the response would look something like: { "data":{ "server_knowledge":101, "budget":{ ... "accounts":[ { "id":"ea0c0ace-1a8c-4692-9e1d-0a21fe67f10a", "name":"Renamed Checking Account", "type":"Checking", "on_budget":true, "closed":false, "note":null, "balance":20000 } ], ... } } } Rate Limiting An access token may be used for up to 200 requests per hour. The limit is reset every clock hour. So, if an access token is used at 12:30 PM and for 199 more requests up to 12:45 PM and then hits the limit, any additional requests will be forbidden until 1:00 PM. At 1:00 PM you would have the full 200 requests allowed again, until 2:00 PM. You can check how many requests you have remaining by referencing the X-Rate-Limit response header. The value of this header is in the format: X/200 , X being the number of requests already made and 200 being the limit. For example, if your application has already made 35 requests, the next response will look like this: HTTP/1.1 200 OK X-Rate-Limit: 36/200 ... If you exceed the rate limit, an error response returns a 429 error: HTTP/1.1 429 Too Many Requests Content-Type: application/json; charset=utf-8 "error": { "id": "429" "name": "too_many_requests" "detail": "Too many requests" } Support If you need API support, please send an email to api@youneedabudget.com. We also have an API Community Forum available.

Libraries

Works with YNAB

Legal