# MakeLeaps API Documentation - Basics Section ## Navigation - [Back to index](/api/llms.txt) - [Current section](/api/llms/basics.md) ## Topics in this Section - MakeLeaps REST API - Notice regarding MakeLeaps API usage - Authentication - Money - Supported Currencies ## MakeLeaps REST API The MakeLeaps API allows you to easily access your data. You can use it to integrate with existing systems. Please read the Notice regarding MakeLeaps API usage section first. Environments ------------ We provide two endpoints for automated access to the MakeLeaps system: - api.makeleaps.com - Production data (JSON API) - app.makeleaps.com - Production data (User Browsable Web) Automated access to the main application server (app.makeleaps.com) should be avoided. Identifiers ----------- Top-level objects in MakeLeaps are given special unique id's that we refer to as a `mid` (MakeLeaps ID). These identifiers are not sequential and the scheme may change in the future. Most requests are keyed based on your partner ID. Requests will look like: GET https://api.makeleaps.com/api/partner/{ mid }/documents/ Our API uses the [HATEOAS design][hateoas_url]. When referencing an existing object (for example, if you wanted to say that a document is owned by an existing client), you should use the client's `url` in the JSON that you send to specify it. [hateoas_url]: http://en.wikipedia.org/wiki/HATEOAS Throttling ---------- Currently we allow 120 requests per minute but we may raise or lower the throttle depending on server load. You can look for the `Retry-After` header that is sent along with the responses: Retry-After: 53 If you are throttled, you will have to wait to make more requests. You can use the parameter to tell you how long you should `sleep()` to stay under the limit. There is also a daily limit to how many requests you may make. That is currently set to 5000/day but again, we reserve the right to change it depending on usage patterns and performance. Numeric Values -------------- Note that decimal numeric values should be submitted as quoted strings, not as literals. This prevents errors in rounding when parsing strings and maintains precision. Example JSON: { "quantity": "3", "tax_rate": "5.00", "unit_cost": "1.17" } Dates and Times --------------- Standard format for Date and Timestamp fields is ISO 8601. #### Dates and Timestamps in responses - Date fields: return only year, month, and day. - Timestamp fields: return using the `T` separator between date and time, generally in UTC (`Z` format) with up to microsecond precision. It is recommended to use a generic ISO 8601 parser. Example JSON: { "date_due": "2011-05-11", "date_paid": "2011-11-11T15:00:00Z" } #### Dates and Timestamps in requests - Date fields: specify year, month, and day. - Timestamp fields: Varying precision and timezone offsets can be used when sending timestamps, within the following format.
YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HH:MM|-HH:MM|Z]
Notes: - Any timestamp specified without timezone or `Z` specified will be assumed to be UTC. - Any timestamp specified with a timezone will still be stored in UTC and returned in Z format in subsequent GET requests. Errors ------ Error messages provided by the API are meant to be displayed to end-users. However, the text itself might change without notice, so avoid writing error-handling code that checks against the exact text of the error. When creating or updating data through the API, you should always confirm that your request was successful by checking the status of the response. You can confirm the status of the response via one of the following: - Check the HTTP response code (*recommended*) - Check the `"status_code"` property on the `"meta"` dictionary in the response (Some API endpoints include the `"status"` property for historical reasons, but this field nor its presence should not be relied upon) In the case of an error from user-behaviour (4xx response), the `"response"` dictionary will include error information to tell you of what mistake is being made. The following is an example of an error when attempting to create a document after forgetting a required field and having an invalid format for the date: { "meta": { "status_code": 400 }, "response": { "currency": [ "This field is required." ], "date": [ "Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]]." ] } } By default error messages from the API will be in English. However, if you pass in the `Accept-Language` header as `ja`, you can receive translated error message like what follows: { "meta": { "status_code": 400 }, "response": { "currency": [ "このフィールドは必須です" ], "date": [ "日付の形式が違います。以下のどれかの形式にしてください: YYYY[-MM[-DD]]。" ] } } Generally, errors will point to specific fields that caused the issue, but in certain situations the error will not be related to a specific field. In this case a special `"non_field_errors"` property will be included in the response, with an error message detailing the problem. { "meta": { "status_code": 400 }, "response": { "non_field_errors": [ "A document with type 'invoice' and number '011' already exists." ] } } (In Japanese) { "meta": { "status_code": 400 }, "response": { "non_field_errors": [ "書類番号011のinvoiceがすでにあります。別の書類番号をお選びください。" ] } } Error responses may also include a mix of field and non_field_errors: { "meta": { "status_code": 400 }, "response": { "currency": [ "This field is required." ], "non_field_errors": [ "A document with type 'invoice' and number '011' already exists." ] } } For 5xx errors, details of the error will be provided in the `'detail'` key. However, such a status code is likely an issue with MakeLeaps' systems. If you are persistently getting 5xx errors, please contact support with details of how you are using the API, so we can further investigate. Searching --------- Certain views support full text search on their resources. This can help you find resources through a fuzzy search in certain situations. This full text search is enabled via a `?search=` query parameter. For example, to do a search of documents containing the text `makeleaps`, you could search with: GET /api/partner//document?search=makeleaps Full text search is currently enabled for several list endpoints. See "Extra Fiters" table in each endpoint description. Please contact us if there are any endpoints you would like to see added. Filtering of List Views ---------- Certain resources have fields that are filterable. By adding a query string (e.g. `?date=2023-07-19`) to the URL, the list view of certain resources can be filtered based on the values of certain fields. Below are our different filtering options. Please contact us if there are any fields or filtering methods you would like added. #### Single parameter filtering In your query string, specify the field and the target value you want to filter by, and only objects that fulfill the "field=target" condition will be returned. The fields for which this is enabled are indicated in the standard field tables by the funnel icon. Fields listed in the "Extra filters" tables can also be used in the same way. Example: Documents are filterable by `document_type`, so you can filter your Document GET result to only Documents of type `invoice` using: GET /api/partner//document/?document_type=invoice #### Multiple parameter filtering In your query string, string together multiple field=target pairs using `&`. Any objects that fulfill ALL conditions will be returned (AND logic). Any filterable field can be included in a multi-parameter filter. Example: Documents are filterable by `document_type` and `date`, so using the following, you can filter your Document GET result to Documents of type `invoice` that ALSO have an issue date of July 19, 2023 by using the following: GET /api/partner//document/?document_type=invoice&date=2023-07-19 #### Filtering using multiple values for a single parameter (comma-separated) By using a single parameter in your query string and passing multiple values in a comma-separated list, you can filter to objects that have ANY ONE OF THOSE values (OR logic). The fields for which this is enabled are marked `Multi-value OR filter (comma-separated)` in the appropriate tables. Example: Documents are filterable in this way using the `tags` field, so you can filter your Document GET result to any Documents that have either `2021` or `2022` tag with the following: GET /api/partner//document/?tags=2021,2022 #### Filtering using multiple values for a single parameter (repeat parameter) By including certain parameters multiple times in your query string and passing different values each time, you can filter to objects that have ANY ONE OF THOSE values ("OR" logic). The fields for which this is enabled are marked `Multi-value OR filter (repeat parameter)` in the appropriate tables. Example: Documents are filterable in this way via the `document_number` field, so you can filter your Document GET result to Documents that have numbers `INV-1234` or `INV-5678` with the following: GET /api/partner//document/?document_number=INV-1234&document_number=INV-5678 #### Filtering Documents by dates or timestamps using before/after Supported filters on Document dates and timestamps are as follows, usable by appending to the field name. Note: for Date fields, use only the date part of ISO-8601 format (e.g. `2020-01-01`), but for Timestamp fields you need to include time through minutes (seconds and time zone are not required, e.g. `2020-01-01T00:00`). - `__lt`: Less than (strict) - `__lte`: Less than (inclusive) - `__gt`: Greater than (strict) - `__gte`: Greater than (inclusive) Examples: # documents with a date of June 20th 2017 GET /api/partner//document/?date=2017-06-20 # documents with a date less than or equal to June 20th 2017 GET /api/partner//document/?date__lte=2017-06-20 # documents with a date between June 20th 2017 and July 1st 2017 GET /api/partner//document/?date__gte=2017-06-20&date__lt=2017-07-01 Expansion --------- Certain views have fields that support expansion. When a field is expanded, its value will be the entire resource, instead of just a URL returning a resource. For example, the Document Instance View has a `client` field that can be expanded by passing the `?expand=client` query parameter to the request. If this parameter is passed, then the result will be: { "document_type": "invoice", "client": { "display_name": "Sample Company", [...] }, [...] } Multiple fields can be expanded within the same request. For example, to expand the `client` and `client_contact` fields at once, pass the `?expand=client,client_contact` parameter. Only top-level fields can be expanded, however. Please contact us if there are any fields that you would like to have expanded. Language --------- Most fields in MakeLeaps only have one value, so specifying a language in the request will not change the API's response, but some fields do have bilingual variants. If a field has bilingual variants, the default value returned by the API will be the English version. The Japanese version can be accessed by passing the `Accept-Language` request header as `ja`. Examples of values for different fields with different `Accept-Language` settings: - `name` field of Partner resource - no header: returns "English Name" value set in the My Company screen. - `ja`: returns "Japanese Name" value set in the My Company screen. - `display_name` field of Document, Received Document, and Accepted Order - no header: returns string containing English Document Type name, " #", and the Document Number, e.g. "Invoice #101". - `ja`: returns string containing Japanese Document Type name, "番号", and the Document Number, e.g. "請求書番号101". ## Notice regarding MakeLeaps API usage - MakeLeaps does not offer technical support for this API. We are not responsible for answering questions about implementations using this API. - At its discretion, MakeLeaps may provide information about the API. Doing so does not create an obligation to provide support for the API, nor liability for implementations making use of said information. - Please refer to MakeLeaps Help Center about MakeLeaps' functionality. ## Authentication Authentication -------------- All requests to the MakeLeaps API must be made with an access token and be TLS/SSL encrypted. The requests will be associated with an API key you can [create in the MakeLeaps API page][api_page]. [api_page]: https://app.makeleaps.com/integrations/makeleaps/api-users/ [team_page]: https://app.makeleaps.com/home/team/ To access the API, you will be using OAuth2 with a `client_credentials` grant. [Client credentials][client_credentials] is a simplified version of OAuth2 designed specifically for backend systems which avoids some of the more complex redirection that you may have seen when working with OAuth2 in the past. In this mode, you will be using your OAuth2 `client_id` and `client_secret` to authenticate and obtain a token. This token is what the API accepts for proof that you have access to your company. Both the `client_secret` and the token must be kept secret. Since you can always get a new token and they periodically expire you should never save them. You can simply request a new one when your program starts running. [client_credentials]: http://tools.ietf.org/html/rfc6749#section-4.4 Authentication Headers ---------------------- When authenticating to the oauth url you should send the following headers: POST /user/oauth2/token/ HTTP/1.1 Host: api.makeleaps.com Accept: application/json Authorization: Basic: < BASIC AUTH CREDENTIALS > As described in the [Basic Auth spec][basic_auth], the basic auth credentials should be the userid and password, separated by a single colon (":") character, as a base64 encoded string. Most libraries have basic auth built in. Only the first reqeust to get an access token requires basic auth. When making a request to the api endpoints, you should use the following headers: GET /api/ HTTP/1.1 Host: api.makeleaps.com Accept: application/json Authorization: Bearer: < ACCESS TOKEN > [basic_auth]: http://www.ietf.org/rfc/rfc2617.txt Authentication Example ---------------------- To demonstrate we will be using the `curl` command line utility. To get started, copy your API `client_id` and `client_secret` out of the application and make a request to the authentication url. You can add `--trace-ascii -` to any of the commands below to get better debugging output. The authentication request should use basic auth to pass the `client_id` and `client_secret` as the username and password. These are the values you have copied from the MakeLeaps application: $ curl -v https://api.makeleaps.com/user/oauth2/token/ \ -X POST \ -u "CLIENT_ID:CLIENT_SECRET" \ -d "grant_type=client_credentials" {"access_token": "0a1b2c3d4e5f6g7h8i9j0k", "token_type": "Bearer", "expires_in": 36000, "scope": "read write"} The authentication url will return an `access_token` (sometimes also called a 'Bearer Token' in the OAuth2 documentation) for you to use. This token can be used to make a request to any API url by setting it in the header of your requests. For example, let's try using it on the root url of the API: $ curl -v https://api.makeleaps.com/api/ \ -X GET \ -H 'Authorization: Bearer 0a1b2c3d4e5f6g7h8i9j0k' { "meta": {"status": 200}, "response": { "partners": [{ "url": "https://api.makeleaps.com/api/partner/{ mid }/", "name": "TEST COMPANY"}], "currencies": "https://api.makeleaps.com/api/currency/" } } If something is wrong with your credentials, you may get a response such as: {"status_code": 401, "detail": "Authentication credentials were not provided."} In this case, please check that your code is sending the headers as described above. Revoking Tokens --------------- If one of your tokens was compromised, you can revoke it using the `revoke-token` endpoint: $ curl https://api.makeleaps.com/user/oauth2/revoke-token/ \ -X POST \ -u "CLIENT_ID:CLIENT_SECRET " \ -d "token=0a1b2c3d4e5f6g7h8i9j0k" If your client_id or client_secret were comprimised, you can head to the [MakeLeaps API page][api_page] to revoke the API Key. [api_page]: https://app.makeleaps.com/integrations/makeleaps/api-users/ Creating Objects ---------------- If a URL endpoint reports that it supports POST, PATCH, PUT, or DELETE values, then you may use the API to modify your data. When objects are created, you should send in data as json by specifying the `Content-Type: application/json` header. For example: $ curl -v https://api.makeleaps.com/api/partner/{ mid }/contact/ \ -X POST \ -H 'Authorization: Bearer 0a1b2c3d4e5f6g7h8i9j0k' \ -H 'Content-Type: application/json' \ -d '{ ... }' { ... "url": "https://api.makeleaps.com/api/partner/{ mid }/contact/"} The response will usually be a status code of `201 CREATED` along with the json representation of the object created including a `url` value to request more details about the object that was created. Access Token Expiration ----------------------- The `access_token` used to access the API has a limited lifetime. After expiring, it will not longer be valid for making requests and you will have to reauthenticate to get a new one. You can either keep track of the token's expiration time using the `expires_in` value or simply wait until it expires and reauthenticate. ## Money Money fields are represented as strings (instead of numbers), in order to avoid floating-point related rounding errors. Money fields are often paired with currency fields. For example, on the document field, to represent a document with a 5000 Yen total, you would pass in: { ... "currency": "JPY", "total": "5000" } ## Supported Currencies ### Endpoints - `/api/currency/` - Name: Supported Currencies - Methods: OPTIONS Supported Currencies -------------------- [These currencies](https://app.makeleaps.com/api/currency/) are officially suported. Please contact support if a currency you would like to use is not yet supported.