{
  "openapi": "3.0.1",
  "info": {
    "title": "Method REST API",
    "description": "# Getting Started\r\nMethod's REST API gives the ability to create, update, retrieve and delete data from a Method account. It's a simple yet powerful way for programmers to integrate their applications with Method. It has predictable resource URLs and returns HTTP response codes. It also accepts and returns JSON in the HTTP body. You can use your favorite HTTP/REST library for your programming language to use our API.\r\n\r\nNew to Method's data model? Read [Working with Contacts, Customers, and Leads](#section/Working-with-Contacts-Customers-and-Leads) first — how records fit together decides which table you write to, and getting it wrong is the most common early mistake.\r\n\r\nIf you would like to test the Method API before beginning your integration, we have made a Postman collection available.\r\n- [Postman Collection for Method REST API.](../assets/method-restapi.postman_collection.json)\r\n\r\n# Authentication\r\nAll requests to the Method API must include a valid credential in the `Authorization` header. **API Key is the standard way to authenticate** with Method's REST API — see [Best Practices](#section/Best-Practices) for guidance on issuing, rotating, and securing your key.\r\n\r\n## Generate an API Key\r\nCreation of an API Key can be done directly through your Method Account from the API Integration page\r\n\r\n1. **[Log in](https://signin.method.me \"Method\")** to the Method Account you wish to generate an API key for\r\n\r\n2. Click the upper-right **blue circle icon** and then select **Integrations**  \r\n    ![Integrations Preference Menu](../assets/PrefsIntegrations.png \"Integrations Preferences\")\r\n\r\n3. Click on **API** from the Integrations list\r\n\r\n4. Click on **New** next to the section titled **API keys**\r\n\r\n5. Enter a name for your API Key, and click on **Generate API Key**  \r\n    ![New APIKey Wizard](../assets/newAPIKey.png \"New API Key\")\r\n> 📌 __**Note**__ The Name you enter for your API Key is for display purposes only - To help you distinguish multiple API Keys from one another. It is not used in the Authentication process.  \r\n \r\n6. An API Key should now be visible for you on the screen. Make sure you Copy this key and keep it safe! **This is the only time it will ever be displayed to you**  \r\n    ![Generated APIKey](../assets/GeneratedAPIKey.jpg \"Generated API Key\")\r\n\r\n## Use your API Key\r\nInclude your API Key in the HTTP `Authorization` header as `APIKey <apikey>`.\r\n\r\n```http\r\nGET /api/v1/tables/Contacts HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey eyJhbGciOiJSUzI1NiIsImtpZCI\r\n```\r\n\r\nBuilding a third-party application where Method users need to grant your app access to their own data? See [OAuth2](#section/OAuth2) at the end of this guide.\r\n\r\n# HTTP Request Methods\r\n| Method | Description                              |\r\n|--------|------------------------------------------|\r\n| GET    | To retrieve data/resource from the resource server. |\r\n| POST   | To insert or upload any new resource to the server. |\r\n| PUT    | To update an existing resource. This replaces the target resource with the updated content. |\r\n| PATCH  | To update a specific detail of the resource. This method updates the target resource with the provided content without changing other data. |\r\n| DELETE | To delete a resource at a particular location. |\r\n\r\n# HTTP Status Codes\r\n\r\n| Status Codes | Meaning                  | Description                              |\r\n|--------------|--------------------------|------------------------------------------|\r\n| 200          | OK                       | The API request is successful.           |\r\n| 201          | CREATED                  | Resource created. Ex. Contact created. |\r\n| 204          | NO CONTENT               | There is no content available for the request. Usually, for DELETE, PUT, or PATCH methods. |\r\n| 400          | BAD REQUEST              | The request is invalid. Required fields are missing or related records exceeded the maximum limit. |\r\n| 401          | AUTHORIZATION ERROR      | Invalid API key or Access Token. e.g. Access Token expired.               |\r\n| 403          | FORBIDDEN                | No permission to do the operation. e.g. Token is valid but user does not have necessary permission.       |\r\n| 404          | NOT FOUND                | Invalid request. e.g. Record or Table not found.                         |\r\n| 405          | METHOD NOT ALLOWED       | The specified method is not allowed.     |\r\n| 413          | REQUEST ENTITY TOO LARGE | The server did not accept the request while uploading a file, since the limited file size has exceeded. |\r\n| 415          | UNSUPPORTED MEDIA TYPE   | The server did not accept the request while uploading a file, since the media/ file type is not supported. |\r\n| 429          | TOO MANY REQUESTS        | Number of API requests for the time period has exceeded. |\r\n| 500          | INTERNAL SERVER ERROR    | Generic error that is encountered due to an unexpected server error. |\r\n\r\n# API Limits\r\nFor fair usage of our API, we will be limiting requests on an account basis as follows.\r\n- 100 requests per minute per account. \r\n- 5000 + [1000 * Number of Active licenses] (or) 75000 requests per day per account, whichever is lower. \r\n\r\nExample - If an account has 15 active licenses, then the daily limit is 20000 requests, calculated as 5000 + [1000 * 15]. \r\nIf an account has 90 active licenses, then the daily limit is 75000 requests, \r\nas the calculated value of 5000 + [1000 * 90] is 95000, which is greater than our maximum daily limit of 75000.\r\n\r\nOnce this limit has been reached, calls will return an error with status code 429. \r\nThe response header will contain the number of seconds after which the limit will be reset. \r\nThis rate limit is evaluated on a rolling window basis. \r\nBelow is a sample response that indicates the per-day (24h) limit is breached and you should retry after 7200 seconds (2 hours).\r\n\r\n  ```http\r\n    HTTP/1.1 429 Too Many Requests\r\n    Content-Type: text/plain\r\n    Retry-After: 7200\r\n    Date: Tue, 02 Jun 2020 13:34:48 GMT\r\n    Content-Length: 56\r\n\r\n    API calls quota exceeded! maximum admitted 6000 per 1d.\r\n  ```\r\n\r\n# Working with Contacts, Customers, and Leads\r\nMethod's data model mirrors QuickBooks' \"entity\" concept, and the API surfaces it through several table views. **Which view you write to determines what kind of record you get** — and getting it wrong is the most common integration mistake, because the wrong table still returns `201`.\r\n\r\n## The data model: Entities and Contacts\r\nAn **entity** is a company-level record — a Customer, Vendor, Employee, or Other Name. A **contact** is a person-level record that belongs to an entity. So every customer, lead, and vendor is a *pair* of records: the entity carries `EntityType`, lead status, billing address, and balance; the contact carries `FirstName`, `LastName`, `Email`, and `Phone`, and links back to its entity through `Entity_RecordID`.\r\n\r\nThe entity is the record that syncs to your accounting system and drives most workflows; contacts hang off it. When you link history (activities, cases), link it to the **entity** — contacts come and go, but the company relationship persists. `Customer`, `Vendor`, and the other entity types are all filtered views over the same underlying `Entity` table (see [The Entity Table](https://help.method.me/en/articles/5359646-the-entity-table)).\r\n\r\n## Which table do I write to?\r\n| Table (URL path) | What an insert creates | In \"Customers & Leads\"? |\r\n|------------------|------------------------|-------------------------|\r\n| `tables/Customer` | A Customer — or a **Customer Lead** when `IsLeadStatusOnly` is `true`. Auto-creates the linked Contact. | **Yes** |\r\n| `tables/Vendor` | A Vendor (or Vendor Lead with `IsLeadStatusOnly: true`). | No (under Vendors) |\r\n| `tables/OtherName` | An **Other Name** entity (`EntityType: \"OtherName\"`). Cannot be a customer or lead. | No |\r\n| `tables/Contacts` | A standalone person. Use only to add *additional* contacts to an entity that already exists. | No |\r\n\r\n**Creating a lead? Use `tables/Customer`** with `IsLeadStatusOnly: true` (worked example below).\r\n\r\n- **Don't** POST a lead to `tables/Contacts` — it returns `201`, but the record never appears in Customers & Leads. And don't POST the abstract `tables/Entity` — it returns `400` asking for a concrete subtype. This is the most common integration mistake.\r\n- **Do** POST to `tables/Customer` with `IsLeadStatusOnly: true`.\r\n\r\nWrite to a concrete subtype view — most commonly `Customer` (leads included, via `IsLeadStatusOnly`) or `Vendor`. The full set of entity types, and how they vary by accounting integration, is covered in [The Entity Table](https://help.method.me/en/articles/5359646-the-entity-table).\r\n\r\n## EntityType is derived, not writable\r\nEvery entity exposes a read-only `EntityType` field (`Customer`, `Customer Lead`, `Vendor`, …). The Customers & Leads screen lists records whose `EntityType` is `Customer` or `Customer Lead`.\r\n\r\n`EntityType` **cannot be set or changed through the API** — it is read-only on both create and update. It is derived from:\r\n1. **Which table view created the record** — `tables/Customer` → customer types, `tables/Vendor` → vendor types.\r\n2. **The `IsLeadStatusOnly` flag** — a Customer with `IsLeadStatusOnly: true` reports `EntityType: \"Customer Lead\"`; set it to `false` (and let it sync) and it becomes `EntityType: \"Customer\"`.\r\n\r\n- **Don't** send `EntityType` in a `POST`/`PATCH` to set or change a record's type — it's silently ignored (no error; see [Common Pitfalls](#section/Best-Practices/Common-Pitfalls)), and a record created through the wrong view **can't be converted by patching**.\r\n- **Do** pick the type by writing to the correct view (`tables/Customer` for a customer or lead), then use `IsLeadStatusOnly` to flip lead ↔ customer.\r\n\r\n## Creating a Customer Lead\r\n```http\r\nPOST /api/v1/tables/Customer HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\nContent-Type: application/json\r\n\r\n{\r\n    \"Name\": \"Jane Smith\",\r\n    \"FirstName\": \"Jane\",\r\n    \"LastName\": \"Smith\",\r\n    \"Email\": \"jane.smith@example.com\",\r\n    \"Phone\": \"555-123-4567\",\r\n    \"IsLeadStatusOnly\": true,\r\n    \"LeadStatus\": \"Open\",\r\n    \"AssignedTo_RecordID\": 4,\r\n    \"IsActive\": true\r\n}\r\n```\r\nThe response is `201 Created` and the body is the new RecordID as a **bare integer**, not a JSON object:\r\n\r\n- **Don't** parse it as JSON (`response.RecordID`, `response.id`) — there's no object, so the parse fails or returns null.\r\n- **Do** read the response body as an integer:\r\n    ```\r\n    22\r\n    ```\r\n\r\n| Field | Notes |\r\n|-------|-------|\r\n| `Name` | **Required.** The entity's display name (\"Name in QuickBooks\"). For a person-lead with no company, use `\"First Last\"`. Omitting it returns `400` — \"The required field Name was either missing or invalid.\" |\r\n| `IsLeadStatusOnly` | `true` = lead. Leads do **not** sync to QuickBooks/Xero. `PATCH` it to `false` later to convert the lead into a full customer (which triggers the accounting sync). |\r\n| `LeadStatus`, `LeadRating` | Dropdown fields. Pass the display value (`\"Open\"`) or the `_RecordID` form. Values are account-defined. |\r\n| `AssignedTo_RecordID` | The Method user who owns the lead. List users via `GET /api/v1/tables/Users`, or take the id from `GET /api/v1/me`. |\r\n\r\nRequired fields are defined per account (admins can customize them), so your account may enforce more or fewer than shown. A missing required field always returns `400` naming the field.\r\n\r\n## The auto-created Contact\r\nCreating a Customer also creates its primary **Contact** server-side. The Contact has its **own `RecordID`** in the Contacts table and links back via `Entity_RecordID`. The create response returns only the *Customer's* RecordID — look the Contact up by filter (don't assume its id matches the Customer's):\r\n```http\r\nGET /api/v1/tables/Contacts?filter=Entity_RecordID eq 22&select=RecordID,FirstName,LastName,Email&top=1 HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n```\r\nUse this **Contact** RecordID — not the Customer's — when linking activities, cases, or other contact-scoped records. Don't POST a separate `Contact` for the entity's primary contact, or you'll create a duplicate.\r\n\r\n## Multi-type tables\r\nSome Method tables hold **more than one kind of record in the same table**, distinguished by a **discriminator field the screen filters on** — not a separate endpoint and not a code path. The valid discriminator values are **defined per account**, in that account's screen setup, so the table name alone doesn't tell you what you're creating.\r\n\r\n**The general rule:** before writing to a multi-type table, `GET` an existing record of the kind you want and copy its discriminator value (prefer the `_RecordID` form) — or inspect the account's schema. Don't hardcode a value from another account or from documentation.\r\n\r\n| Table | Holds | Type determined by |\r\n|-------|-------|--------------------|\r\n| Entity (`Customer`/`Vendor`/`OtherName`) | Customer, Customer Lead, Vendor, Vendor Lead, Other Name | Same account-defined pattern — but Method also provides dedicated **views** (`tables/Customer`, `tables/Vendor`) plus the `IsLeadStatusOnly` flag as a write-side convenience. Use those; `EntityType` is derived, not writable. |\r\n| `Activity` | Calls, emails, to-dos, custom types | The `ActivityType` field, account-defined. The type must already exist in the account; also set `Entity_RecordID` so it appears in entity history. |\r\n| `WorkOrder` | Account-defined work-order types | A discriminator field filtered by the WorkOrders screen, account-defined. No global list exists. |\r\n\r\n> **Text-vs-id trap.** A screen can filter its discriminator on the FK id (`ActivityType_RecordID`) *or* on the text caption (`ActivityType = \"Web Comment\"`). If it filters on text and your value matches zero or multiple options — or differs by case/whitespace — the field is **silently dropped** (see [Common Pitfalls](#section/Best-Practices/Common-Pitfalls)): the record is still created (`201`) but lands with the wrong/empty type and never shows on the intended screen. Write the `_RecordID` form, sourced from a `GET` on an existing record of that type — it's unambiguous regardless of how the screen filters.\r\n\r\n# Common Workflows\r\n\r\n## Web to Lead and Activity\r\nA \"Contact Us\" form submits a name, email, phone, and a message. Three calls turn that into a lead in Customers & Leads with the message logged as an activity. **Order matters** — each step produces an id the next one needs.\r\n\r\n```bash\r\nKEY=\"Authorization: APIKey {your_key}\"\r\nAPI=\"https://rest.method.me/api/v1\"\r\n\r\n# 1. Create the Customer Lead (entity-level). Response = new Customer RecordID, a bare integer.\r\nCUSTOMER_ID=$(curl -s -X POST \"$API/tables/Customer\" \\\r\n  -H \"$KEY\" -H \"Content-Type: application/json\" \\\r\n  -d '{\r\n    \"Name\": \"Jane Smith\",\r\n    \"FirstName\": \"Jane\", \"LastName\": \"Smith\",\r\n    \"Email\": \"jane.smith@example.com\", \"Phone\": \"555-123-4567\",\r\n    \"IsLeadStatusOnly\": true, \"LeadStatus\": \"Open\",\r\n    \"AssignedTo_RecordID\": 4, \"IsActive\": true\r\n  }')\r\n\r\n# 2. Look up the auto-created Contact for that Customer (and its Entity_RecordID).\r\nCONTACT_ID=$(curl -s \"$API/tables/Contacts?top=1&filter=Entity_RecordID%20eq%20$CUSTOMER_ID\" \\\r\n  -H \"$KEY\" | jq '.value[0].RecordID')\r\n\r\n# 3. Log the form message as an Activity, linked to BOTH the Contact and the Entity.\r\ncurl -s -X POST \"$API/tables/Activity\" \\\r\n  -H \"$KEY\" -H \"Content-Type: application/json\" \\\r\n  -d \"{\r\n    \\\"ActivityType\\\": \\\"Web Comment\\\",\r\n    \\\"Comments\\\": \\\"Interested in a quote for spring landscaping.\\\",\r\n    \\\"Contacts_RecordID\\\": $CONTACT_ID,\r\n    \\\"Entity_RecordID\\\": $CUSTOMER_ID,\r\n    \\\"AssignedTo_RecordID\\\": 4,\r\n    \\\"ActivityStatus_RecordID\\\": 1,\r\n    \\\"DueDateStart\\\": \\\"2026-06-17T14:30:00\\\"\r\n  }\"\r\n```\r\nThe lead now appears in **Customers & Leads** with `EntityType: \"Customer Lead\"`, and the message shows on the contact's timeline and the entity's history.\r\n\r\n**The three things that make this flow non-obvious** (and that an endpoint list won't tell you):\r\n1. **Which table** — leads are created on `tables/Customer`, not `tables/Contacts`.\r\n2. **The hidden lookup** — the Contact you need for step 3 isn't returned by step 1; you query for it.\r\n3. **The order + linking fields** — Customer first (it mints the Entity + Contact), then read the Contact, then the Activity links back to **both**.\r\n\r\n### Activity fields\r\n| Field | Notes |\r\n|-------|-------|\r\n| `ActivityType` | **Required.** Prefer the `ActivityType_RecordID` form (from a `GET` on an existing record of the intended type); the caption form can be silently dropped on a zero/multiple/case mismatch. See [Multi-type tables](#section/Working-with-Contacts-Customers-and-Leads/Multi-type-tables). |\r\n| `Contacts_RecordID` | The **Contact** RecordID (from the lookup above). |\r\n| `Entity_RecordID` | **Set this too.** The API does not reject an Activity without it, but the activity won't appear in the entity's history. Use the `Entity_RecordID` read off the Contact. |\r\n| `AssignedTo_RecordID` | **Required** on standard accounts. |\r\n| `ActivityStatus_RecordID` | Dropdown (status lifecycle, e.g. Not Started / Completed). Values are account-defined. |\r\n| `Comments` | The note body (HTML preserved). There is no `Subject`, `Description`, `Date`, or `Name` field — those names are silently dropped. |\r\n| `DueDateStart` | `YYYY-MM-DDTHH:mm:ss`. Recommended so the activity lands correctly on calendars and follow-up lists. |\r\n\r\n# Filter Reference\r\nYou must use the appropriate notation for different data types with filter expressions.\r\n- String values must be delimited by single quotation marks.\r\n- Date-Time values must be delimited by single quotation marks and follow the ISO-8601 date-time format. \r\n\r\n  Complete date plus hours, minutes and seconds:\r\n  \r\n  YYYY-MM-DDThh:mm[:ss][TZD] (e.g. 2020-03-29T10:05:45-06:00)\r\n  Where:\r\n\r\n    - YYYY = four-digit year\r\n    - MM = two-digit month (e.g. 03=March)\r\n    - DD = two-digit day of the month (01 through 31)\r\n    - T = a set character indicating the start of the time element\r\n    - hh = two digits of an hour (00 through 23, AM/PM not included)\r\n    - mm = two digits of a minute (00 through 59)\r\n    - ss = two digits of a second (00 through 59). Optional\r\n    - TZD = time zone designator (Z or +hh:mm or -hh:mm). The + or - values indicate how far ahead or behind a time zone is from the UTC (Coordinated Universal Time) zone.\r\n      The time zone designator is optional, and if left out, the date-time is assumed to be UTC.\r\n\r\n   Examples\r\n   \r\n   - To get all Invoices created on April 17, 2020, EDT (Eastern Daylight Time)  \r\n   \r\n    ```http\r\n    GET /api/v1/tables/Invoice?filter=TimeCreated ge '2020-04-17T00:00-04:00' and TimeCreated lt '2020-04-18T00:00-04:00' HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    \r\n    or\r\n    \r\n    GET /api/v1/tables/Invoice?filter=TimeCreated ge '2020-04-17T04:00' and TimeCreated lt '2020-04-18T04:00' HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n\r\n    or\r\n    \r\n    GET /api/v1/tables/Invoice?filter=TimeCreated ge '2020-04-17T04:00Z' and TimeCreated lt '2020-04-18T04:00Z' HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n    \r\n   - To get all Invoices created in April 2020 EDT (Eastern Daylight Time)\r\n\r\n    ```http\r\n    GET /api/v1/tables/Invoice?filter=TimeCreated ge '2020-04-01T00:00-04:00' and TimeCreated lt '2020-05-01T00:00-04:00' HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n\r\n- Numeric values require no delimiters.\r\n\r\nYou can use the following expressions to construct a filter in Method REST API.\r\n\r\n| Filter Operation | Example | Explanation | \r\n|------------------------------------------|------------------------------------------|------------------------------------------|\r\n| **Comparison Operators** |\r\n| `eq` Equal | filter=FirstName eq 'Bill' |  Query on Contacts table. Returns Contacts with FirstName equal to 'Bill' |\r\n| `lt` Less than | filter=TotalBalance lt 100 | Query on Contacts table. Returns all Contacts with a balance lower than 100. |\r\n| `gt` Greater than | filter=TotalBalance gt 100 | Query on Contacts table. Returns all Contacts with a balance greater than 100. |\r\n| `ge` Greater than or equal to | filter=TotalBalance ge 100 | Query on Contacts table. Returns all Contacts with a balance 100 and greater. |\r\n| `le` Less than or equal to | filter=TotalBalance le 100 | Query on Contacts table. Returns all Contacts with a balance 100 and lower. |\r\n| `ne` Different from (not equal) | filter=TotalBalance ne 0 | Query on Contacts table. Returns all Contacts with a non-zero balance. |\r\n| **Logical Operators** |\r\n| `and` And | filter=FirstName eq 'Bill' and LastName eq 'Wagner' | Query on Contacts table. Returns Contacts with FirstName equal to 'Bill' and LastName equal to 'Wagner' |\r\n| `or` Or | filter=BillAddressCountry eq 'Canada' or BillAddressCountry eq 'USA' | Query on Contacts table. Returns Contacts in Canada and the United States. |\r\n|`not` Not | filter=not (BillAddressCountry eq 'Canada' or BillAddressCountry eq 'USA') | Query on Contacts table. Returns Contacts outside of Canada and the United States. |\r\n| **String Functions** |\r\n|  `endswith` String ends with | filter=endswith(Name,'RT') | Query on Contacts table. Returns all Contacts with names ending with 'RT'. |\r\n| `startswith` String starts with | filter=startswith(Name, 'S') | Query on Contacts table. Returns all Contacts with names beginning with 'S'. |\r\n| `contains` String containing | filter=contains(Name, 'RT') | Query on Contacts table. Returns all Contacts with names containing 'RT' |\r\n| `()` Grouping | filter=(not (BillAddressCountry eq 'Canada' or BillAddressCountry eq 'USA')) and (TotalBalance ge 100) | Query on Contacts table. Returns all Contacts outside Canada and the United States with Balance 100 and greater |\r\n\r\n\r\n# Data Aggregation Queries\r\nUsing the `apply` parameter in your query opens up the possibility of using data aggregation to condense many rows of information into just a few summary rows. \r\nThe currently available data transformations are: \r\n- [**Aggregate**](#section/Data-Aggregation-Queries/Aggregate-Methods)\r\n- [**Group By**](#section/Data-Aggregation-Queries/Group-By)\r\n- [**Filter**(For filtering data pre-aggregation)](#section/Data-Aggregation-Queries/Pre-Aggregate-Filter)\r\n\r\n## Aggregate Methods\r\nThe `aggregate` transformation on the `apply` clause is the real workhorse of the Data aggregation queries. It allows you to condense many rows of data into just a few summary rows to prevent you from having to do this calculation in your own external application.\r\nThe currently available aggregation methods are `count`, `sum`, `average`, `min`, `max` and `countdistinct`.\r\n\r\nYou can specify as many aggregations in a single clause as you would like. Multiple Aggregations are separated with a comma `,`.\r\n\r\n- __Example__ - `apply=aggregate(Amount with sum as TotalOwed, BalanceRemaining with average as 'Average outstanding')`\r\n\r\n### Count\r\nReturns the Count of rows which match your query. The Count aggregate has slightly different syntax to the other aggregate methods, in that you don't need to specify a Column name or use the `with` keyword to specify an aggregation method.\r\n\r\n- __Syntax__ - `apply=aggregate($count as <Alias>)`\r\n- __Example__ - Return the total count of how many Invoices you have in your Method Account.\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=aggregate($count as 'Number of Invoices')' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse: \r\n{\r\n    \"count\": 1,\r\n    \"value\": [\r\n        {\r\n            \"Number of Invoices\": 567\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n### Sum\r\nReturns the Sum Total of the specified numerical field for all rows matching your query.\r\n\r\n- __Syntax__ - `apply=aggregate(<FieldName> with sum as <Alias>)`\r\n- __Example__ - Return the sum total of all outstanding Invoice Balances.\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=aggregate(BalanceRemaining with sum as 'Total Outstanding')' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse: \r\n{\r\n    \"count\": 1,\r\n    \"value\": [\r\n        {\r\n            \"Total Outstanding\": 230460.5600\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n### Average\r\nReturns the Mean Average of a numerical field for all rows matching you query.\r\n\r\n- __Syntax__ - `apply=aggregate(<FieldName> with average as <Alias>)`\r\n- __Example__ - Return the average Total of all invoices.\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=aggregate(Amount with average as 'Average Invoice Amount')' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse: \r\n{\r\n    \"count\": 1,\r\n    \"value\": [\r\n        {\r\n            \"Average Invoice Amount\": 31299.4447\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n### Min\r\nReturns the Minimum value contained in the specified text or numerical field for all rows matching your query.\r\n\r\n- __Syntax__ - `apply=aggregate(<FieldName> with min as <Alias>)`\r\n- __Example__ - Return the Invoice with the smallest amount paid against it.\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=aggregate(AppliedAmount with min as SmallestAmountPaid)' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse: \r\n{\r\n    \"count\": 1,\r\n    \"value\": [\r\n        {\r\n            \"SmallestAmountPaid\": 0.0000\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n### Max\r\nReturns the Maximum value contained in the specified text or numerical field for all rows matching your query.\r\n\r\n- __Syntax__ - `apply=aggregate(<FieldName> with max as <Alias>)`\r\n- __Example__ - Return the Invoice with the largest outstanding balance.\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=aggregate(BalanceRemaining with max as LargestOutstanding)' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse: \r\n{\r\n    \"count\": 1,\r\n    \"value\": [\r\n        {\r\n            \"LargestOutstanding\": 510600.0000\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n\r\n### Distinct Count\r\nReturns the count of all the unique elements in the specified field\r\n\r\n- __Syntax__ - `apply=aggregate(<FieldName> with countdistinct as <Alias>)`\r\n- __Example__ - Return number of unique customers who have invoices\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=aggregate(Customer with countdistinct as UniqueCustomers)' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse: \r\n{\r\n    \"count\": 1,\r\n    \"value\": [\r\n        {\r\n            \"UniqueCustomers\": 14\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n## Group By\r\nThe `groupby` transformation allows you group rows together based on identical values in a specified field. Typically a `groupby` is performed in conjunction with an [Aggregate Transformation](#section/Data-Aggregation-Queries/Aggregate-Methods), which this transformation accepts as an optional second parameter.\r\nA `groupby` performed **without** the second optional 'aggregate' method parameter will essentially just return a list of all the unique values in the field specified.\r\n\r\n**Group By - No Aggregation**\r\n- __Syntax__ - `apply=groupby((<FieldName>))`\r\n- __Example__ - Return the unique names of customers that have Invoices\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=groupby((Customer))' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n```\r\n\r\n**Group By - With Aggregation**\r\n- __Syntax__ - `apply=groupby((<FieldName>), aggregate(<Aggregate Clause>))`\r\n- __Example__ - Return how many Invoices each customer has\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=groupby((Customer), aggregate($count as InvoiceCount))' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse: \r\n{\r\n    \"count\": 5,\r\n    \"value\": [\r\n        {\r\n            \"InvoiceCount\": 25,\r\n            \"Customer\": \"Bob Crenshaw\"\r\n        },\r\n        {\r\n            \"InvoiceCount\": 21,\r\n            \"Customer\": \"Pets R Us\"\r\n        },\r\n        {\r\n            \"InvoiceCount\": 13,\r\n            \"Customer\": \"Bens Bagels\"\r\n        },\r\n        {\r\n            \"InvoiceCount\": 12,\r\n            \"Customer\": \"Bens Bagels:Toronto Location\"\r\n        },\r\n        {\r\n            \"InvoiceCount\": 6,\r\n            \"Customer\": \"Felix Kramer\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n## Pre Aggregate Filter\r\nThe `apply` parameter will accept a `filter` as part of the query string. A filter added as part of the `apply` parameter will be applied **Before** any aggregation takes place, and can be useful for things like omitting any rows you don't want aggregated.\r\nOtherwise, this Filter behaves practically identically to the [Filter Query](#section/Filter-Reference), and is capable of the same operations. The first example below is just to give you an idea of the syntax. If you were to perform the filter this way, it would behave in exactly the same way as it would if you used the [Filter Query](#section/Filter-Reference) instead. \r\nThe second example is a better indicator of its real usage.\r\n\r\n  > 📌 __**Note**__ - If you also specify a regular `filter` query parameter in the same request where grouping is present, this filter will be applied to the Grouped Aggregates similar to how a **HAVING** Clause would work in SQL. \r\nThis 'Post Aggregate' filter will have access to the names of any aliases you specified in your aggregate methods.\r\nIts possible to specify **both** a pre-aggregate filter using the `apply=filter(<Filter Clause>)` and post aggregate filter using `filter=<Filter Clause>` at the same time which you can see an example of in the [Advanced Examples section](#section/Data-Aggregation-Queries/Advanced-Examples)\r\n\r\n- __Syntax__ - `apply=filter(<Filter Clause>)`\r\n- __Example__ - Return all Invoice with and outstanding balance of more than 1000\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=filter(BalanceRemaining gt 1000)' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n```\r\n\r\nTo run a filter on your query before its aggregated, you need to separate the Filter query and your aggregate with a forward slash `/`.\r\n\r\n- __Syntax__ - `apply=filter(<filter Clause>)/aggregate(<Aggregate Clause>)`\r\n- __Example__ - Return The outstanding Balance for all invoices created before July 1 2020.\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=filter(TimeCreated le '2020-07-01T00:00Z')/aggregate(BalanceRemaining with sum as 'Pre Q3 outstanding Balance')' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n```\r\n\r\n## Advanced Examples\r\n\r\n> 📌 __**Note**__ - These example queries have been split into multiple lines to make them easier to read. You don't need to format your queries this way.\r\n\r\n- Return every Customers Total amount Invoiced, and their Average Invoice Amount\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=groupby((Customer), aggregate(Amount with sum as 'Total Spent', Amount with average as 'Average Spend'))' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse: \r\n{\r\n    \"count\": 5,\r\n    \"value\": [\r\n        {\r\n            \"Total Spent\": 30890.5000,\r\n            \"Average Spend\": 1020.0000,\r\n            \"Customer\": \"Bob Crenshaw\"\r\n        },\r\n        {\r\n            \"Total Spent\": 1155.6000,\r\n            \"Average Spend\": 1155.6000,\r\n            \"Customer\": \"Pets R Us\"\r\n        },\r\n        {\r\n            \"Total Spent\": 5707.7500,\r\n            \"Average Spend\": 1902.5833,\r\n            \"Customer\": \"Bens Bagels\"\r\n        },\r\n        {\r\n            \"Total Spent\": 500.0000,\r\n            \"Average Spend\": 150.0000,\r\n            \"Customer\": \"Bens Bagels:Toronto Location\"\r\n        },\r\n        {\r\n            \"Total Spent\": 1537.3300,\r\n            \"Average Spend\": 1537.3300,\r\n            \"Customer\": \"Felix Kramer\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n- Return the Amount owed by your all combined Canadian customers\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=filter(BillAddressCountry eq 'Canada')\r\n                                 /aggregate(Amount with sum as 'Amount Owed Canada'))' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse:\r\n\r\n{\r\n    \"count\": 1,\r\n    \"value\": [\r\n        {\r\n            \"Amount Owed Canada\": 110355.6000\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n- Return the outstanding balances of all US based customers grouped by State\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=filter(BillAddressCountry eq 'US')\r\n                                 /groupby((BillAddressState), aggregate(BalanceRemaining with sum as 'Total owed in Region'))' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse: \r\n{\r\n    \"count\": 5,\r\n    \"value\": [\r\n        {\r\n            \"Total owed in Region\": 527651.7100,\r\n            \"BillAddressState\": \"CA\"\r\n        },\r\n        {\r\n            \"Total owed in Region\": 440638.8500,\r\n            \"BillAddressState\": \"NY\"\r\n        },\r\n        {\r\n            \"Total owed in Region\": 230569.6000,\r\n            \"BillAddressState\": \"WA\"\r\n        },\r\n        {\r\n            \"Total owed in Region\": 17338.8500,\r\n            \"BillAddressState\": \"DC\"\r\n        },\r\n        {\r\n            \"Total owed in Region\": 5339.5000,\r\n            \"BillAddressState\": \"NV\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n- Return all Australian Customers who have a higher than $10,000 outstanding balance on Invoices created prior to 2020\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=filter(BillAddressCountry eq 'AU' and TimeCreated le '2020-01-01T00:00Z')\r\n                                 /groupby((Customer), aggregate(BalanceRemaining with sum as OldDebt))\r\n                           &filter=OldDebt ge 10000 HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse: \r\n{\r\n    \"count\": 5,\r\n    \"value\": [\r\n        {\r\n            \"OldDebt\": 813.0000,\r\n            \"Customer\": \"Billy Crenshaw\"\r\n        },\r\n        {\r\n            \"OldDebt\": 1155.6000,\r\n            \"Customer\": \"PetMart\"\r\n        },\r\n        {\r\n            \"OldDebt\": 1955.9400,\r\n            \"Customer\": \"Greggs Pool Service\"\r\n        },\r\n        {\r\n            \"OldDebt\": 1338.1200,\r\n            \"Customer\": \"The Burger Store\"\r\n        },\r\n        {\r\n            \"OldDebt\": 270.6300,\r\n            \"Customer\": \"Bens Bagels:Brisbane\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n- Same Query as above, but also order the results from highest outstanding balance to lowest\r\n\r\n```http\r\nGET /api/v1/tables/Invoice?apply=filter(BillAddressCountry eq 'AU' and TimeCreated le '2020-01-01T00:00Z')\r\n                                 /groupby((Customer), aggregate(BalanceRemaining with sum as OldDebt))\r\n                           &filter=OldDebt ge 10000\r\n                           &orderby=OldDebt desc HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n\r\nResponse: \r\n{\r\n    \"count\": 5,\r\n    \"value\": [\r\n        {\r\n            \"OldDebt\": 1955.9400,\r\n            \"Customer\": \"Greggs Pool Service\"\r\n        },\r\n        {\r\n            \"OldDebt\": 1338.1200,\r\n            \"Customer\": \"The Burger Store\"\r\n        },\r\n        {\r\n            \"OldDebt\": 1155.6000,\r\n            \"Customer\": \"PetMart\"\r\n        },\r\n\r\n        {\r\n            \"OldDebt\": 813.0000,\r\n            \"Customer\": \"Billy Crenshaw\"\r\n        },\r\n        {\r\n            \"OldDebt\": 270.6300,\r\n            \"Customer\": \"Bens Bagels:Brisbane\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n# Best Practices\r\nFollow these patterns to keep your integration fast, stable, and within rate limits.\r\n\r\n## AI Resources\r\n\r\n**Building with AI tools?** Two machine-readable resources are available:\r\n\r\n- The [OpenAPI specification](/specs/v1/spec.json) — every endpoint, request and response schema, and the full text of this documentation in a single file. Give your assistant this URL rather than the address of this page, which renders in the browser and appears empty to AI agents.\r\n- A [code review ruleset](/docs/skills/method-api-review/method-api-review.zip) (SKILL.md) — 30 rules with Bad / Good examples that your assistant can apply to your integration code. Also readable as a quick reference.\r\n\r\n## Authentication & API Keys\r\n\r\nUse an **API Key** for most integrations — server-to-server automation, scheduled jobs, and partner-owned applications. [OAuth2](#section/OAuth2) exists for the exceptional case where an end-user of Method needs to grant your application access to their data, but it should not be your default choice.\r\n\r\nAPI keys inherit the permissions of the user they belong to, and only users with the **Admin** role can generate them. There is no scoped or read-only API key. Treat keys as secrets: load them from a secrets manager or environment variable, rotate them regularly, and regenerate immediately if one is exposed.\r\n\r\nOAuth2 access tokens expire after one hour. A long-running job that fetches a token at the start will hit `401 Unauthorized` once the token expires mid-job. Use the refresh token to get a new access token before the old one expires, or fetch a fresh token at the start of each job. API keys do not expire.\r\n\r\n## Querying Records\r\n\r\nLarge queries will time out and burn your rate limit if you're not careful. The maximum `top` per request is 100 — for larger result sets, paginate with `skip` / `top` and follow `nextLink`. Three patterns make the difference:\r\n\r\n### Always use `select`\r\nBy default, a query returns every field on the record — including linked and dropdown fields. On wide tables like Contacts or Invoice, that means hundreds of columns per row and slow responses. Always pass a `select` parameter with only the fields you need.\r\n\r\n- **Don't:** request every field.\r\n    ```http\r\n    GET /api/v1/tables/Contacts?select=&top=100 HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n\r\n- **Do:** project the fields you actually use.\r\n    ```http\r\n    GET /api/v1/tables/Contacts?select=RecordID,FirstName,LastName,Email&top=100 HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n\r\n### Always pair `skip`/`top` with `orderby`, and follow `nextLink`\r\nWithout a sort order, rows shift between pages as records change — you'll skip some and see others twice. Always include `orderby` with a stable field (typically `RecordID`) when paginating, and follow the `nextLink` URL returned in each response rather than computing your own `skip` values. `nextLink` is `null` on the last page.\r\n\r\n```http\r\nGET /api/v1/tables/Contacts?select=RecordID,FirstName&orderby=RecordID asc&skip=100&top=100 HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n```\r\n\r\n**If pagination isn't behaving as expected:**\r\n- *Getting the same 100 records on every call* — you're not following `nextLink`, or `orderby` is missing.\r\n- *Rows missing across pages* — records were modified mid-iteration; sort by `RecordID` (immutable) rather than `LastModifiedDate`.\r\n\r\n### Filter first, fetch second\r\nUnfiltered queries on large tables are the number one cause of timeouts and blown rate limits. Push the work to the server:\r\n- Only fetch the records you need — see [Filter Reference](#section/Filter-Reference) for syntax. Don't fetch everything and trim client-side.\r\n- If you don't know how many rows match, call `/count` first. If the number is large, page through with a narrow `select` and `filter`.\r\n- To sum, count, or group data, use the `apply` parameter — see [Data Aggregation Queries](#section/Data-Aggregation-Queries). Don't pull thousands of rows just to aggregate them in your application.\r\n\r\n```http\r\nGET /api/v1/tables/Contacts/count?filter=LastModifiedDate ge '2026-05-26T00:00Z' HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n```\r\n\r\n## Multi-Entity\r\n\r\nMethod supports [multi-entity](https://help.method.me/en/articles/4317233-what-is-multi-entity) accounts — franchise networks, multi-company businesses, or any setup where several legal entities share one Method account. API keys and OAuth2 tokens are scoped to a **single entity**. A credential issued in entity A cannot touch entity B's data, even though they share the same backend. There is no cross-entity query.\r\n\r\nTo work across entities:\r\n\r\n- Create one API key per entity. Store them keyed by entity in your application.\r\n- When you need data from multiple entities, loop through them — one request per entity with its own key.\r\n- Each entity has its own rate-limit quota. Looping across entities doesn't amplify the per-entity limit, but doesn't share it either.\r\n\r\n```http\r\nGET /api/v1/tables/Contacts/count HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {key-for-entity-1}\r\n```\r\n\r\n```http\r\nGET /api/v1/tables/Contacts/count HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {key-for-entity-2}\r\n```\r\n\r\nPlan for this from the start. Retrofitting per-entity credentials into an existing integration is the most common source of multi-entity rework.\r\n\r\n## Aggregate Roots & Child Records\r\n\r\nCreate or update a parent record and its children in one transaction by prefixing the child table name with `__`. This is the single most effective way to stay under rate limits — **one request with 50 children = one rate-limit hit. The same 50 children as individual calls = 50 hits.**\r\n\r\n- **Don't:** insert lines one at a time in a loop. Each iteration is a separate rate-limit hit.\r\n    ```\r\n    for each line in order:\r\n        POST /api/v1/tables/InvoiceLine   # 50 lines → 50 requests\r\n    ```\r\n\r\n- **Do:** send the parent and all children in a single request.\r\n    ```http\r\n    POST /api/v1/tables/Invoice HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    Content-Type: application/json\r\n\r\n    {\r\n        \"Customer_RecordID\": 1234,\r\n        \"TxnDate\": \"2026-05-26T00:00Z\",\r\n        \"__InvoiceLine\": [\r\n            { \"Item_RecordID\": 88, \"Quantity\": 1, \"Rate\": 400 },\r\n            { \"Item_RecordID\": 88, \"Quantity\": 3, \"Rate\": 500 }\r\n        ]\r\n    }\r\n    ```\r\n\r\nTo **add or update children** on an existing record, PATCH the parent with up to 50 children at a time. The body must include at least one parent-level field alongside the `__` array — include a field you intend to update, or any field set to its current value. Existing children not in the array are left untouched:\r\n\r\n```http\r\nPATCH /api/v1/tables/Invoice/4553 HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\nContent-Type: application/json\r\n\r\n{\r\n    \"TxnDate\": \"2026-05-26T00:00Z\",\r\n    \"__InvoiceLine\": [\r\n        { \"Item_RecordID\": 91, \"Quantity\": 1, \"Rate\": 250 },\r\n        { \"Item_RecordID\": 92, \"Quantity\": 2, \"Rate\": 100 }\r\n    ]\r\n}\r\n```\r\n\r\n**Rules:**\r\n1. **Max 50 children per request**, counted across all `__ChildTable` arrays. This applies to both POST and PATCH. For more than 50, send multiple PATCH requests of up to 50 each.\r\n2. **Always include a parent field.** A PATCH body with only `__` arrays and no top-level parent field returns a 400.\r\n3. **PATCH is upsert, not replace.** Children with a `RecordID` are updated; those without are created. Children not in the array are left alone. To remove a child, DELETE it explicitly.\r\n\r\n## Rate Limiting & Throttling\r\n\r\nSee [API Limits](#section/API-Limits) for the exact numbers and the `429` response shape.\r\n\r\nThere is no dedicated endpoint to check your remaining quota. Instead, every response includes rate-limit headers you can monitor:\r\n\r\n| Header | Value |\r\n|--------|-------|\r\n| `X-Rate-Limit-Limit` | The rate-limit window (e.g. `1m`, `1d`) |\r\n| `X-Rate-Limit-Remaining` | Requests left in the current window |\r\n| `X-Rate-Limit-Reset` | UTC timestamp when the window resets |\r\n\r\nTo stay under the limits:\r\n\r\n- **Batch your writes.** Looping individual creates/updates over thousands of records burns your daily quota fast. Combine related writes with aggregate-root requests and pace them across the rate-limit window.\r\n- **Cache reference data.** Tables that rarely change (Item, Class, Account, Customer) can be fetched once at the start of a job and reused. Don't re-query them per record.\r\n- **Spread bursts.** If your job is naturally bursty (e.g. an end-of-day sync), spread requests across the window rather than firing them all at once.\r\n- **Remember per-entity quotas.** In a [multi-entity account](#section/Best-Practices/Multi-Entity), each entity has its own rate-limit budget. Looping across them doesn't amplify any single entity's limit.\r\n\r\n## Error Handling\r\n\r\nEvery error response includes a `traceId` field. Save it — it's the fastest way for Method's support team to find your request in the logs.\r\n\r\n**What to retry:**\r\n- `429 Too Many Requests` — read the `Retry-After` header and wait at least that long before trying again.\r\n- `5xx` — use exponential backoff: start at 1 second, double on each retry, cap at 60 seconds, give up after 5 attempts. If a specific query keeps returning `5xx`, include the `traceId` when you contact support.\r\n- `401` — refresh your OAuth2 token, or regenerate your API key, then retry once.\r\n\r\n**What not to retry:**\r\n- Any other `4xx` — the request is wrong; retrying won't fix it.\r\n\r\n## Common Pitfalls\r\n\r\n### Field names are case-sensitive — and silently ignored when wrong\r\n`FirstName` and `firstname` are different fields. A typo or case mismatch on a PATCH or POST is **silently ignored** — the request returns 2xx, but the misnamed field is not saved. Copy field names directly from the table schema; don't type them by hand. The same applies to **newly created custom fields**: a field added moments ago may not be visible to the API yet. If a write isn't sticking after schema changes, GET an existing record first to confirm the field appears in the response.\r\n\r\n### Dropdown fields: use the `_RecordID`, not the caption\r\nDropdown and linked fields have two columns: a read-only display caption (e.g. `Customer`) and a writable foreign-key field (e.g. `Customer_RecordID`). Always use the `_RecordID` field — it's unambiguous. The display string triggers a server-side lookup, and if it matches zero or multiple records, the field is silently dropped.\r\n\r\n```json\r\n{ \"Customer_RecordID\": 1234 }\r\n```\r\n\r\n### Creating a Customer also creates a Contact\r\nCreating a `Customer` also creates its primary `Contact` server-side, and the create response returns only the Customer's `RecordID`. See [The auto-created Contact](#section/Working-with-Contacts-Customers-and-Leads/The-auto-created-Contact) for how to find and use it.\r\n\r\n### Only call `/Sync` when you mean it\r\nThe `/Sync` endpoint forces an immediate push to your connected accounting system (QuickBooks or Xero). Routine creates and updates are synced automatically — calling `/Sync` on every write is unnecessary, eats your rate limit, and can flood the sync queue. Use it only when you need to override the automatic timing.\r\n\r\n### Always include a timezone in date filters\r\nThe API accepts several date formats: `2026-05-26T00:00-04:00` (explicit offset), `2026-05-26T04:00` (no zone), and `2026-05-26T04:00Z` (UTC). The middle one is a trap — it looks local, but the server treats it as UTC. A filter the developer reads as \"midnight in Toronto\" actually means \"8 PM Toronto time the previous day.\" Always use `Z` or an explicit offset so there's no ambiguity.\r\n\r\n### Don't rely on `LastModifiedDate` for incremental sync\r\nNot every write updates `LastModifiedDate`. If you poll with `filter=LastModifiedDate gt {last_seen}` to pull only changed records, you **will miss rows** — and you won't notice until a reconciliation catches them weeks later. For reliable incremental sync, periodically reconcile against `RecordID` ranges or whole-table counts rather than trusting `LastModifiedDate` alone.\r\n\r\n### Activity field names aren't what you'd expect\r\nTwo gotchas on the `Activity` table: (1) activities belong to an **Entity**, not a Contact — set **both** `Contacts_RecordID` and `Entity_RecordID`, or the activity won't appear in the entity's history; (2) there is no `Subject`, `Description`, `Date`, or `Name` field (those are silently dropped) — the body goes in `Comments`, the time in `DueDateStart`, and `ActivityType` + `AssignedTo` are required. See [Common Workflows](#section/Common-Workflows) for the full field reference.\r\n\r\n## Limitations\r\n\r\nThings the REST API does **not** support today. Don't design around them:\r\n\r\n- **No PDF rendering.** There's no endpoint to fetch or generate a PDF of a record (Estimate, Invoice, etc.). PDFs are produced by the Method UI only.\r\n- **No `JournalEntry` / `JournalEntryLines` on QBO-connected accounts.** The tables exist for compatibility with QuickBooks Desktop, but they will always be empty on accounts connected to QuickBooks Online.\r\n- **No credit-card capture or payment-gateway charges via the API.** Card data and payment-gateway transactions cannot be initiated through REST. Use the relevant in-product flows.\r\n- **No email engagement fields.** Open / click / bounce / reply tracking is not exposed as fields on Activity or related tables.\r\n- **No server-side date macros.** There is no `CURRENT_DATE` or `TODAY` token in filters. Compute the date in your application and pass an absolute value (e.g. `filter=TxnDate ge '2026-05-26T00:00Z'`).\r\n- **No batch import or export endpoint.** For high-volume work, use aggregate-root requests (up to 50 children per call) and pace your writes across the rate-limit window.\r\n\r\n**Accounting-integration specifics:**\r\n\r\n- On **Xero**-connected accounts, only `ItemInventory` and `ItemService` are writable item types. Other item categories are read-only.\r\n- On **Xero**, `SalesDesc` is not a writable field on items.\r\n- On **Xero**, payments can be applied to draft Invoices (this is intentional, but surprises some integrations).\r\n- Some payments sync through the UI but **not** through the API. This is intentional — if a write doesn't flow through as expected, check whether it falls into this category before filing a bug.\r\n\r\n## Example Flow\r\n\r\nA typical integration flow — list, fetch, update, confirm — looks like this:\r\n\r\n**1. List recently modified contacts**\r\n```http\r\nGET /api/v1/tables/Contacts?select=RecordID,FirstName,LastName,Email&filter=LastModifiedDate ge '2026-05-26T00:00Z'&orderby=RecordID asc&top=50 HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n```\r\n\r\n**2. Fetch a single contact, expanding the parent entity**\r\n```http\r\nGET /api/v1/tables/Contacts/1234?select=RecordID,FirstName,LastName,Email,Entity&expand=Entity HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n```\r\n\r\n**3. Update the contact**\r\n```http\r\nPATCH /api/v1/tables/Contacts/1234 HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\nContent-Type: application/json\r\n\r\n{ \"Email\": \"new@example.com\", \"IsActive\": true }\r\n```\r\n\r\n**4. Confirm the update persisted**\r\n```http\r\nGET /api/v1/tables/Contacts/1234?select=RecordID,Email,IsActive HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\n```\r\n\r\nStep 4 matters. A 2xx on step 3 does **not** guarantee every field was saved — see [Common Pitfalls](#section/Best-Practices/Common-Pitfalls) for why.\r\n\r\n# OAuth2\r\n\r\nAPI Key is the standard way to authenticate with Method's REST API — see [Authentication](#section/Authentication). Use OAuth2 instead only if:\r\n\r\n- *You are developing a third-party application:* You are building a server-side tool, service, or integration intended for use by other Method customers, where each user explicitly grants your application access to their own account.\r\n- *You need per-user consent and revocability:* You want short-lived access tokens and the ability for a user to revoke your application's access without changing their own password or API key.\r\n\r\nIf you would like to test OAuth2 before beginning your integration, we have made a Postman collection available.\r\n- [Postman Collection for OAuth2 Authentication.](../assets/method-identity-server.postman_collection.json)\r\n\r\n## Register an OAuth2 Client\r\nSetting up OAuth2 requires registering your client application with Method before you can request an access token. To register your OAuth2 client, send the following information to [api@method.me](mailto:api@method.me) with subject `REST API | OAuth2 Client Request`\r\n- Redirect Url. (Not required for [Client Credentials Flow](#section/OAuth2/OAuth2:-Client-Credentials-Flow))\r\n- Application Type.\r\n- Method Account Name.\r\n\r\nOnce registered, request an access token using the appropriate flow:\r\n- [Authorization Code Flow](#section/OAuth2/OAuth2:-Authorization-Code-Flow) - Best for third-party developers creating web or mobile apps for other Method users.\r\n- [Client Credentials Flow](#section/OAuth2/OAuth2:-Client-Credentials-Flow) - Best for internal applications performing back-end jobs requiring extra security.\r\n\r\n## Make Authenticated Requests with OAuth2\r\nInclude your OAuth2 access token in the HTTP `Authorization` header as `Bearer <access_token>`.\r\n\r\n```http\r\nGET /api/v1/tables/Contacts/5 HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: Bearer {access_token}\r\n```\r\n\r\n## OAuth2: Authorization Code Flow\r\nThe Authorization Code flow is used for server-side web applications capable of securely storing secrets. It is recommended for third-party development where users must explicitly grant permission.\r\nAt a high-level, this flow has the following steps:\r\n1. Your application directs the browser to the Method Sign-In page, where the user authenticates.\r\n\r\n    Example: URL generated by your application to direct a browser to Sign-In page\r\n\r\n    ```url\r\n    https://auth.method.me/connect/authorize\r\n    ?client_id={your_client_id}\r\n    &nonce=d1f3f984-db5d-443c-a883-36f06f252d96\r\n    &redirect_uri={your_redirect_url}\r\n    &response_type=code\r\n    &scope=openid profile email api offline_access\r\n    &state=\r\n    ```\r\n\r\n2. The browser receives an authorization code from Method Identity Server.\r\n\r\n    Example: URL with authorization code in `code` query parameter\r\n\r\n    ```url\r\n    {your_redirect_url}\r\n    ?code=7bfbe93c9712414f7c53766e2e6399\r\n    &scope=openid%20profile%20email%20api%20offline_access\r\n    &session_state=l0ckSo5h_GPR_2bicxnUaY_vRr5FRYDAzxQmkI2N2mI.97ac90c0b2eb3b44242aa75a8b3961fb\r\n    ```\r\n\r\n3. The authorization code is passed to your application.\r\n4. Your application sends this code to Method Identity Server, and Method Identity Server returns access token ID token, and optionally a refresh token.\r\n\r\n    Example: \r\n    \r\n    Request\r\n\r\n    ```http\r\n    POST /connect/token HTTP/1.1\r\n    Host: https://auth.method.me\r\n    Content-Type: application/x-www-form-urlencoded\r\n\r\n    code=7bfbe93c9712414f7c53766e2e6399\r\n    &redirect_uri={your_redirect_url}\r\n    &grant_type=authorization_code\r\n    &client_id={your_client_id}\r\n    &client_secret={your_client_secret}\r\n    ```\r\n    \r\n    Response\r\n\r\n    ```json\r\n    {\r\n        \"id_token\": \"eyJhbGciOiJSUzI1NiIsImtpZCI\",\r\n        \"access_token\": \"eyJhbGciOiJSUzI1NiIsImtpZCI6\",\r\n        \"expires_in\": 3600,\r\n        \"token_type\": \"Bearer\",\r\n        \"refresh_token\": \"b4f33ac42b668f00803305aa7f038\"\r\n    }\r\n    ```   \r\n\r\n5. Your application can now use the access token to call the Method REST API on behalf of the user.\r\n    ```http\r\n    GET /api/v1/tables/Contacts HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI\r\n    ```\r\n\r\n## OAuth2: Client Credentials Flow\r\nThe Client Credentials flow is recommended for use in machine-to-machine authentication. Your application will need to securely store its Client ID and Secret and pass those to Method Identity Server in exchange for an access token. \r\nAt a high-level, the flow only has two steps:\r\n1. Your application passes its client credentials to your Method Identity Server.\r\n    Example:\r\n    \r\n    Request    \r\n\r\n    ```http\r\n    POST /connect/token HTTP/1.1\r\n    Host: https://auth.method.me\r\n    Content-Type: application/x-www-form-urlencoded\r\n\r\n    grant_type=client_credentials\r\n    &client_id={your_client_id}\r\n    &client_secret={your_client_secret}\r\n    ```\r\n    \r\n    Response\r\n\r\n    ```json\r\n    {\r\n        \"access_token\": \"eyJhbGciOiJSUzI1NiIsImtpZCI\",\r\n        \"expires_in\": 3600,\r\n        \"token_type\": \"Bearer\"\r\n    }\r\n    ```\r\n\r\n2. Your application can now use the access token to call the Method API.\r\n    ```http\r\n    GET /api/v1/tables/Contacts HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI\r\n    ```\r\n\r\n## Core Concepts and Terminology\r\nUse this reference to understand the specific parameters and tokens used in Method's OAuth2 authentication flows.\r\n| Term | Definition                               |\r\n|------|------------------------------------------|\r\n| **Access Token** | A temporary credential used to authenticate requests to Method REST APIs. Each access token will be valid only for an hour and can be used only for the set of operations described in the scope. |\r\n| **Authentication Code** | A temporary token created by the authorization server and sent to the client via the browser. It is exchanged server-side for an Access Token and Refresh Token. |\r\n| **Client ID** | The consumer key generated from the connected application. |\r\n| **Client Secret** | The consumer secret generated from the connected application. |\r\n| **Method Identity Server** | The centralized server (auth.method.me) handling user logins and issuing OAuth2 tokens. |\r\n| **Refresh Token** | A long-lived credential used to automatically request a new Access Token without requiring the user to re-authenticate. |\r\n| **Resource Owner** | The end-user of the account who grants the application permission to access their protected data. |\r\n| **Resource Server** | The Method server hosting protected resources (e.g., Contacts, Invoices) that accepts and validates access tokens. |\r\n| **Scopes** | Specific permissions defining accessible data. |\r\n\r\n### Supported Scopes\r\n| Scope | Requirement | Function |\r\n|-------|-------------|----------|\r\n| `api` | Required | Grants access to Method REST API endpoints. |\r\n| `openid` | Required | Grants access to user's ID and token timing metadata. |\r\n| `offline_access` | Recommended | Required to receive a Refresh Token. |\r\n| `email` | Optional | Grants access to user's email address information. | \r\n| `profile` | Optional | Grants access to user's profile information. |",
    "termsOfService": "https://www.method.me/legal/terms-of-service/",
    "contact": {
      "name": "Method Support",
      "url": "https://www.method.me/contact-us/",
      "email": "support@method.me"
    },
    "version": "1.0",
    "x-logo": {
      "url": "assets/methodapi.svg"
    }
  },
  "servers": [
    {
      "url": "https://rest.method.me",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/v1/files": {
      "get": {
        "tags": [
          "Files"
        ],
        "summary": "Get File List",
        "description": "To request data about files attached to a record in a table. Specify `{table}` and `{recordId}` as query parameters. \r\n\r\n\r\n### Examples\r\nTo get all files linked to RecordId 4 of Contacts table.\r\n\r\n```http\r\n    GET /api/v1/files?table=Contacts&recordId=4 HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey NWYyZDhlZDJiYTBjOD\r\n```",
        "operationId": "files-list",
        "parameters": [
          {
            "name": "table",
            "in": "query",
            "description": "Table name",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "recordId",
            "in": "query",
            "description": "RecordId of the record",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "200": {
            "description": "File List",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FileMetadata"
                  }
                },
                "example": [
  {
    "id": "ca056f3e-df09-40bb-8b0d-0b2b9b4f5784",
    "filename": "report.pdf",
    "fileExtension": "pdf",
    "size": 216363,
    "createdBy": "MethodSupport MethodSupport",
    "modifiedBy": "MethodSupport MethodSupport",
    "createdDate": "2026-08-13T15:15:11.9154498Z",
    "lastModifiedDate": "2026-08-13T15:15:11.9154502Z",
    "tenantId": 1,
    "links": null
  },
  {
    "id": "4601832d-6452-4ad8-b7a5-f62efce87086",
    "filename": "profile.pdf",
    "fileExtension": "pdf",
    "size": 25000,
    "createdBy": "MethodSupport MethodSupport",
    "modifiedBy": "MethodSupport MethodSupport",
    "createdDate": "2026-08-13T15:15:11.9154522Z",
    "lastModifiedDate": "2026-08-13T15:15:11.9154523Z",
    "tenantId": 1,
    "links": null
  }
]
              }
            }
          }
        },
        "x-code-samples": [
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/files?table=Contacts&recordId=5\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"GET\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey NWYyZDhlZDJiY\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;\r\n"
          },
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/files?table=Contacts&recordId=5\"\r\n\r\npayload = {}\r\nheaders = {\r\n  'Authorization': 'APIKey NWYyZDhlZDJiY'\r\n}\r\n\r\nresponse = requests.request(\"GET\", url, headers=headers, data = payload)\r\n\r\nprint(response.text.encode('utf8'))"
          },
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar options = {\r\n  'method': 'GET',\r\n  'url': 'https://rest.method.me/api/v1/files?table=Contacts&recordId=5',\r\n  'headers': {\r\n    'Authorization': 'APIKey NWYyZDhlZDJiY'\r\n  }\r\n};\r\nrequest(options, function (error, response) {\r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});\r\n"
          }
        ]
      },
      "post": {
        "tags": [
          "Files"
        ],
        "summary": "Upload File",
        "description": "To upload a file and link it to a record in a table.\r\n> 📌 __**Note**__ The upload file size limit is 50MB and the total storage limit for your account is 10GB. If you upload a file with a size greater than 50 MB, the server will return a 413 response.\r\n\r\n### Examples\r\nTo upload and link a file to RecordId 4 of the Contacts table.\r\n\r\n```http\r\nPOST /api/v1/files HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey NWYyZDhlZDJiYTBj\r\n\r\n----WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"\"; filename=\"/D:/Desktop/report.pdf\"\r\nContent-Type: application/pdf\r\n\r\n(data)\r\n----WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"table\"\r\n\r\nContacts\r\n----WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"recordId\"\r\n\r\n4\r\n----WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"attachToEmail\"\r\n\r\ntrue\r\n----WebKitFormBoundary7MA4YWxkTrZu0gW\r\n```",
        "operationId": "file-upload",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string",
                    "nullable": true
                  },
                  "recordId": {
                    "type": "integer",
                    "format": "int32"
                  },
                  "attachToEmail": {
                    "type": "boolean"
                  }
                }
              },
              "example": "",
              "encoding": {
                "table": {
                  "style": "form"
                },
                "recordId": {
                  "style": "form"
                },
                "attachToEmail": {
                  "style": "form"
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string",
                    "nullable": true
                  },
                  "recordId": {
                    "type": "integer",
                    "format": "int32"
                  },
                  "attachToEmail": {
                    "type": "boolean"
                  }
                }
              },
              "example": "",
              "encoding": {
                "table": {
                  "style": "form"
                },
                "recordId": {
                  "style": "form"
                },
                "attachToEmail": {
                  "style": "form"
                }
              }
            }
          }
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "201": {
            "description": "File Details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileMetadata"
                },
                "example": {
  "id": "2b1b2255-3c61-46a9-b8fb-e0c494103b8a",
  "filename": "report.pdf",
  "fileExtension": "pdf",
  "size": 216363,
  "createdBy": "MethodSupport MethodSupport",
  "modifiedBy": "MethodSupport MethodSupport",
  "createdDate": "2026-08-13T15:15:11.9209368Z",
  "lastModifiedDate": "2026-08-13T15:15:11.9209375Z",
  "tenantId": 1,
  "links": null
}
              }
            }
          }
        },
        "x-code-samples": [
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar fs = require('fs');\r\nvar options = {\r\n  'method': 'POST',\r\n  'url': 'https://rest.method.me/api/v1/files',\r\n  'headers': {\r\n    'Authorization': 'APIKey NWYyZDhlZDJiY'\r\n  },\r\n  formData: {\r\n    '': {\r\n      'value': fs.createReadStream('/D:/Desktop/report.pdf'),\r\n      'options': {\r\n        'filename': 'report.pdf',\r\n        'contentType': null\r\n      }\r\n    },\r\n    'table': 'Contacts',\r\n    'recordId': '5',\r\n    'attachToEmail': 'true'\r\n  }\r\n};\r\nrequest(options, function (error, response) {\r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});\r\n"
          },
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/files\"\r\n\r\npayload = {'table': 'Contacts',\r\n'recordId': '5',\r\n'attachToEmail': 'true'}\r\nfiles = [\r\n  ('', open('/D:/Desktop/report.pdf','rb'))\r\n]\r\nheaders = {\r\n  'Authorization': 'APIKey NWYyZDhlZDJiY'\r\n}\r\n\r\nresponse = requests.request(\"POST\", url, headers=headers, data = payload, files = files)\r\n\r\nprint(response.text.encode('utf8'))"
          },
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/files\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"POST\",\r\n  CURLOPT_POSTFIELDS => array(''=> new CURLFILE('/D:/Desktop/report.pdf'),'table' => 'Contacts','recordId' => '5','attachToEmail' => 'true'),\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey NWYyZDhlZDJiY\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;"
          }
        ]
      }
    },
    "/api/v1/files/{Id}/download": {
      "get": {
        "tags": [
          "Files"
        ],
        "summary": "Download File",
        "description": "To download a file, specify the file `{id}` in the URL path.\r\n\r\n\r\n### Examples\r\nTo download a file with ID = 9a14f324-59df-44b5-af1e-c7689b891b54.\r\n\r\n```http\r\nGET /api/v1/files/9a14f324-59df-44b5-af1e-c7689b891b54/download HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey NWYyZDhlZDJiYTBj\r\n```",
        "operationId": "file-download",
        "parameters": [
          {
            "name": "Id",
            "in": "path",
            "description": "Id",
            "required": true,
            "schema": {
              "type": "string",
              "nullable": true
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "302": {
            "description": "File",
            "content": {
              "application/json": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-code-samples": [
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar fs      = require('fs');\r\n\r\nvar options = {\r\n  'method': 'GET',\r\n  'url': 'https://rest.method.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a/download',\r\n  'headers': {\r\n    'Authorization': 'APIKey NWYyZDhlZDJiY'\r\n  }\r\n};\r\n\r\nvar r = request(options, function (error, response) {\r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});\r\n\r\nr.pipe(fs.createWriteStream('/D:/Desktop/report.pdf'));"
          },
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a/download\"\r\n\r\npayload = {}\r\nheaders = {\r\n  'Authorization': 'APIKey NWYyZDhlZDJiY'\r\n}\r\n\r\nresponse = requests.request(\"GET\", url, headers=headers, data = payload, allow_redirects=True)\r\nwith open('/D:/Desktop/report.pdf') as Pypdf:\r\n    pypdf.write(response.content)\r\n\r\nprint(response.text.encode('utf8'))\r\n"
          },
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a/download\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"GET\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey NWYyZDhlZDJiY\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\nfile_put_contents(\r\n    '/D:/Desktop/report.pdf',\r\n    $response\r\n);\r\n\r\necho $response;"
          }
        ]
      }
    },
    "/api/v1/files/{Id}/url": {
      "get": {
        "tags": [
          "Files"
        ],
        "summary": "Get File URL",
        "description": "To get a download link for a file, specify the file `{id}` in the URL path.\r\n> 📌 __**Note**__ For better security of file data, this file URL will expire after 20 minutes and users have to generate a new URL.\r\n \r\n \r\n### Examples\r\nTo get a download link for a file with ID = 9a14f324-59df-44b5-af1e-c7689b891b54.\r\n \r\n```http\r\nGET /api/v1/files/9a14f324-59df-44b5-af1e-c7689b891b54/url HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey NWYyZDhlZDJiYTBj\r\n```",
        "operationId": "file-url",
        "parameters": [
          {
            "name": "Id",
            "in": "path",
            "description": "Id",
            "required": true,
            "schema": {
              "type": "string",
              "nullable": true
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "200": {
            "description": "File",
            "content": {
              "application/json": {
                "schema": {
                  "type": "string"
                },
                "example": ""
              }
            }
          }
        },
        "x-code-samples": [
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a/url\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"GET\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey NWYyZDhlZDJiY\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;\r\n"
          },
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a/url\"\r\n\r\npayload = {}\r\nheaders = {\r\n  'Authorization': 'APIKey NWYyZDhlZDJiY'\r\n}\r\n\r\nresponse = requests.request(\"GET\", url, headers=headers, data = payload)\r\n\r\nprint(response.text.encode('utf8'))"
          },
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar options = {\r\n  'method': 'GET',\r\n  'url': 'https://rest.method.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a/url',\r\n  'headers': {\r\n    'Authorization': 'APIKey NWYyZDhlZDJiY'\r\n  }\r\n};\r\nrequest(options, function (error, response) {\r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});"
          }
        ]
      }
    },
    "/api/v1/files/{Id}/link": {
      "put": {
        "tags": [
          "Files"
        ],
        "summary": "Update File Link Details",
        "description": "To update the linked details for a file, specify the file `{id}` in the URL path and the link details in the request body. Currently, we only support updating the `attachToEmail` field.\r\n \r\n \r\n### Examples\r\nTo update link details for a file with Id = \"2a5e1cbc-c9c7-4d72-b554-026e8467cd7f\".\r\n\r\n```http\r\nPUT /api/v1/files/2a5e1cbc-c9c7-4d72-b554-026e8467cd7f HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey NWYyZDhlZDJiYTB\r\nContent-Type: application/json\r\n\r\n{\r\n    \"tableName\": \"Contacts\",\r\n    \"recordId\": 4,\r\n    \"attachToEmail\" : false\r\n}\r\n```",
        "operationId": "file-link-update",
        "parameters": [
          {
            "name": "Id",
            "in": "path",
            "description": "Id",
            "required": true,
            "schema": {
              "type": "string",
              "nullable": true
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileLink"
              },
              "example": ""
            }
          }
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "204": {
            "description": "Success"
          }
        },
        "x-code-samples": [
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a/link\"\r\n\r\npayload = \"{\\r\\n    \\\"tableName\\\": \\\"Contacts\\\",\\r\\n    \\\"recordId\\\": 5,\\r\\n    \\\"attachToEmail\\\" : false\\r\\n}\"\r\nheaders = {\r\n  'Authorization': 'APIKey NWYyZDhlZDJiY',\r\n  'Content-Type': 'application/json'\r\n}\r\n\r\nresponse = requests.request(\"PUT\", url, headers=headers, data = payload)\r\n\r\nprint(response.text.encode('utf8'))\r\n"
          },
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a/link\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"PUT\",\r\n  CURLOPT_POSTFIELDS =>\"{\\r\\n    \\\"tableName\\\": \\\"Contacts\\\",\\r\\n    \\\"recordId\\\": 5,\\r\\n    \\\"attachToEmail\\\" : false\\r\\n}\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey NWYyZDhlZDJiY\",\r\n    \"Content-Type: application/json\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;"
          },
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar options = {\r\n  'method': 'PUT',\r\n  'url': 'https://rest.methodl.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a/link',\r\n  'headers': {\r\n    'Authorization': 'APIKey NWYyZDhlZDJiY',\r\n    'Content-Type': 'application/json'\r\n  },\r\n  body: JSON.stringify({\"tableName\":\"Contacts\",\"recordId\":5,\"attachToEmail\":false})\r\n\r\n};\r\nrequest(options, function (error, response) {\r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});"
          }
        ]
      }
    },
    "/api/v1/files/{Id}": {
      "delete": {
        "tags": [
          "Files"
        ],
        "summary": "Delete File",
        "description": "To delete a file, specify the file `{id}` in the URL path.\r\n\r\n### Examples\r\nTo delete a file with ID = 9a14f324-59df-44b5-af1e-c7689b891b54.\r\n\r\n```http\r\nDELETE /api/v1/files/9a14f324-59df-44b5-af1e-c7689b891b54 HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey NWYyZDhlZDJiYTBj\r\n```",
        "operationId": "file-delete",
        "parameters": [
          {
            "name": "Id",
            "in": "path",
            "description": "Id",
            "required": true,
            "schema": {
              "type": "string",
              "nullable": true
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "204": {
            "description": "Success"
          }
        },
        "x-code-samples": [
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"DELETE\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey NWYyZDhlZDJiY\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;\r\n"
          },
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a\"\r\n\r\npayload = {}\r\nheaders = {\r\n  'Authorization': 'APIKey NWYyZDhlZDJiY'\r\n}\r\n\r\nresponse = requests.request(\"DELETE\", url, headers=headers, data = payload)\r\n\r\nprint(response.text.encode('utf8'))"
          },
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar options = {\r\n  'method': 'DELETE',\r\n  'url': 'https://rest.method.me/api/v1/files/80588584-1e5b-4a0e-86b5-3db3f7a1cd1a',\r\n  'headers': {\r\n    'Authorization': 'APIKey NWYyZDhlZDJiY'\r\n  }\r\n};\r\nrequest(options, function (error, response) {\r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});"
          }
        ]
      }
    },
    "/api/v1/me": {
      "get": {
        "tags": [
          "Me"
        ],
        "responses": {
          "200": {
            "description": "Success"
          }
        },
        "x-code-samples": [ ]
      }
    },
    "/api/v1/tables/{table}/{recordId}": {
      "get": {
        "tags": [
          "Tables"
        ],
        "summary": "Get Record",
        "description": "To request data for a specific record in a table. Specify `{table}` and `{recordId}` in the URL path. \r\n\r\nBy default, the response contains all fields including linked and drop-down fields, but you can request specific fields by using the `select` query parameter. \r\n\r\nThe `expand` query parameter allows you to retrieve the fields of a related child table. To check if a table is related, go to Account Settings > Tables & Fields and navigate to the child's table page. If it contains a dropdown field to the parent table, then the table can be expanded. In the example below, the child table `InvoiceLine` contains a dropdown field to the parent table `Invoice`. If multiple dropdown fields exist for the parent table, the first field found is used.\r\n\r\n### Examples\r\n- To get all field values from Contacts table for RecordId 5\r\n\r\n    ```http\r\n    GET /api/v1/tables/Contacts/5 HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n\r\n- To get FirstName and LastName field values from Contacts table for RecordId 5\r\n\r\n    ```http\r\n    GET /api/v1/tables/Contacts/5?select=FirstName,LastName HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n\r\n- To get a record from Invoice table for RecordId 3 and expand the InvoiceLine table.\r\n\r\n    ```http\r\n    GET /api/v1/tables/Invoice/3?expand=InvoiceLine HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```",
        "operationId": "tables-get-record",
        "parameters": [
          {
            "name": "table",
            "in": "path",
            "description": "Table name",
            "required": true,
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "recordId",
            "in": "path",
            "description": "RecordId of the record",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "select",
            "in": "query",
            "description": "Comma separated list of fields to be returned in the response",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Child table to retrieve. Limited to 50 records.",
            "schema": {
              "type": "string",
              "nullable": true
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "200": {
            "description": "Record Data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "additionalProperties": false
                  }
                },
                "example": {
  "RecordID": 5,
  "Email": "david@landscaping.com",
  "FirstName": "David",
  "IsOptOutOfBilling": false,
  "IsOptOutOfMarketing": false,
  "LastName": "Henderson",
  "Name": "David Henderson",
  "Note": null,
  "Phone": "(111)111-1111",
  "PortalPassword": null,
  "PortalUserName": null,
  "SpecialType": "Contact",
  "Title": null,
  "Mobile": "",
  "FaceBookUserName": null,
  "LinkedInPublicUserName": null,
  "TwitterUserName": null,
  "Website": null,
  "AltPhone": "",
  "Pager": null,
  "TagList": "Personas",
  "InstagramUserName": null,
  "LastModifiedDate": "2019-04-20T19:29:11.877",
  "Entity": "Landscaping Services",
  "Entity_RecordID": 280,
  "AccountNumber": null,
  "Balance": 36000.0,
  "BillAddressAddr1": "Landscaping Services",
  "BillAddressAddr2": "12 N Jackson St",
  "BillAddressAddr3": null,
  "BillAddressAddr4": null,
  "BillAddressAddr5": null,
  "BillAddressCity": "San Jose",
  "BillAddressCountry": "USA",
  "BillAddressNote": null,
  "IsEntityActive": true,
  "TenantID": 1
}
              }
            }
          }
        },
        "x-code-samples": [
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar options = {\r\n  'method': 'GET',\r\n  'url': 'https://rest.method.me/api/v1/tables/Contacts/9',\r\n  'headers': {\r\n    'Authorization': 'APIKey {your_key}'\r\n  }\r\n};\r\nrequest(options, function (error, response) { \r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});\r\n"
          },
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/tables/Contacts/9\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"GET\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey {your_key}\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;\r\n"
          },
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/tables/Contacts/9\"\r\n\r\npayload = {}\r\nheaders = {\r\n  'Authorization': 'APIKey {your_key}'\r\n}\r\n\r\nresponse = requests.request(\"GET\", url, headers=headers, data = payload)\r\n\r\nprint(response.text.encode('utf8'))\r\n"
          }
        ]
      },
      "patch": {
        "tags": [
          "Tables"
        ],
        "summary": "Update Record",
        "description": "To update records in a table.  Specify `{table}` and `{recordId}` in URL path. \r\nInclude only the fields you want to modify. Linked fields cannot be modified directly and will be ignored. \r\n\r\n### Examples\r\n- To update LastName, Note and IsActive fields of a Contact with RecordID 5\r\n    ```http\r\n    PATCH /api/v1/tables/Contacts/5 HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    Content-Type: application/json\r\n    \r\n    {\r\n        \"LastName\": \"Anderson\",\r\n        \"Note\": \"LastName modified and set active\",\r\n        \"IsActive\": true,\r\n    }\r\n    ```\r\n\r\n- To update an Invoice + InvoiceLine(s) in a single request. \r\nUse `__` as a prefix before the related table name. This will update the invoice, create or update invoice line(s), and also sync the invoice.\r\n\r\n> 📌 __**Note**__ Maximum of 50 related records can be created or updated in a single request.\r\n\r\n```http\r\nPATCH /api/v1/tables/Invoice/4553 HTTP/1.1\r\nHost: https://rest.method.me\r\nAuthorization: APIKey {your_key}\r\nContent-Type: application/json\r\n\r\n{\r\n\r\n    \"TxnDate\": \"2020-06-01T16:00:00\",\r\n    \"BillAddressAddr1\": \"Blue Jet Airways\",\r\n    \"BillAddressAddr2\": \"213 E Washington St\",\r\n    \"BillAddressCity\": \"Ashland\",\r\n    \"BillAddressState\": \"OH\",\r\n    \"BillAddressPostalCode\": \"44805\",\r\n    \"BillAddressCountry\": \"USA\",\r\n    \"IsPending\": false,\r\n    \"IsFinanceCharge\": false,\r\n    \"DueDate\": \"2020-06-01T16:00:00\",\r\n    \"IsPaid\": false,\r\n    \"IsToBePrinted\": false,\r\n    \"IsToBeEmailed\": false,\r\n    \"IsTaxIncluded\": false,\r\n    \"IsWaitingForSyncApproval\": false,\r\n    \"TenantID\": 1,\r\n    \"ARAccount\": \"Accounts Receivable\",\r\n    \"Customer\": \"Blue Jet Airways\",\r\n    \"__InvoiceLine\":[\r\n        {\r\n            \"RecordID\": 4821,\r\n            \"Desc\": \"Plans and Permits\",\r\n            \"Quantity\": 1,\r\n            \"Rate\": 800,\r\n            \"IsRatePercent\": false,\r\n            \"ServiceDate\": \"2020-06-30T16:15:25\",\r\n            \"UnitOfMeasure\": \"\",\r\n            \"LineOrder\": 1,\r\n            \"LastModifiedDate\": \"2020-06-01T16:16:08.597\",\r\n            \"Item\": \"01 Plans and Permits\",\r\n            \"SalesTaxCode\": \"Non\",\r\n            \"TenantID\": 1\r\n        },\r\n        {\r\n                \"RecordID\": 4820,\r\n            \"Desc\": \"Plans and Permits\",\r\n            \"Quantity\": 3,\r\n            \"Rate\": 900.00000,\r\n            \"IsRatePercent\": false,\r\n            \"ServiceDate\": \"2020-06-30T16:15:25\",\r\n            \"UnitOfMeasure\": \"\",\r\n            \"LineOrder\": 2,\r\n            \"LastModifiedDate\": \"2020-06-01T16:16:08.597\",\r\n            \"Item\": \"01 Plans and Permits\",\r\n            \"SalesTaxCode\": \"Non\",\r\n            \"TenantID\": 1\r\n        },\r\n        {\r\n            \"Desc\": \"Plans and Permits\",\r\n            \"Quantity\": 6,\r\n            \"Rate\": 100.00000,\r\n            \"IsRatePercent\": false,\r\n            \"ServiceDate\": \"2020-06-30T16:15:25\",\r\n            \"UnitOfMeasure\": \"\",\r\n            \"LineOrder\": 3,\r\n            \"LastModifiedDate\": \"2020-06-01T16:16:08.597\",\r\n            \"Item\": \"01 Plans and Permits\",\r\n            \"SalesTaxCode\": \"Non\",\r\n            \"TenantID\": 1\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n",
        "operationId": "tables-patch-record",
        "parameters": [
          {
            "name": "table",
            "in": "path",
            "description": "Table name",
            "required": true,
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "recordId",
            "in": "path",
            "description": "RecordId of the record",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { },
              "example": ""
            }
          }
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "204": {
            "description": "Record updated successfully"
          }
        },
        "x-code-samples": [
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/tables/Contacts/5\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"PATCH\",\r\n  CURLOPT_POSTFIELDS =>\"{\\n    \\\"LastName\\\": \\\"Anderson\\\",\\n    \\\"Note\\\": \\\"LastName modified\\\"\\n}\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey {your_key}\",\r\n    \"Content-Type: application/json\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;\r\n"
          },
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/tables/Contacts/5\"\r\n\r\npayload = \"{\\n    \\\"LastName\\\": \\\"Anderson\\\",\\n    \\\"Note\\\": \\\"LastName modified\\\"\\n}\"\r\nheaders = {\r\n  'Authorization': 'APIKey {your_key}',\r\n  'Content-Type': 'application/json'\r\n}\r\n\r\nresponse = requests.request(\"PATCH\", url, headers=headers, data = payload)\r\n\r\nprint(response.text.encode('utf8'))\r\n"
          },
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar options = {\r\n  'method': 'PATCH',\r\n  'url': 'https://rest.method.me/api/v1/tables/Contacts/5',\r\n  'headers': {\r\n    'Authorization': 'APIKey {your_key}',\r\n    'Content-Type': 'application/json'\r\n  },\r\n  body: JSON.stringify({\"LastName\":\"Anderson\",\"Note\":\"LastName modified\"})\r\n\r\n};\r\nrequest(options, function (error, response) { \r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});\r\n"
          }
        ]
      },
      "delete": {
        "tags": [
          "Tables"
        ],
        "summary": "Delete Record",
        "description": "To delete records from a table. Specify `{table}` and `{recordId}` in the URL path. \r\n\r\n\r\n### Examples\r\n- To delete RecordId 5 from Contacts table\r\n\r\n    ```http\r\n    DELETE /api/v1/tables/Contacts/5 HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n",
        "operationId": "tables-delete-record",
        "parameters": [
          {
            "name": "table",
            "in": "path",
            "description": "Table name",
            "required": true,
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "recordId",
            "in": "path",
            "description": "RecordId of the record",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "204": {
            "description": "Record deleted successfully"
          }
        },
        "x-code-samples": [
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/tables/Contacts/3695\"\r\n\r\npayload = {}\r\nheaders = {\r\n  'Authorization': 'APIKey {your_key}'\r\n}\r\n\r\nresponse = requests.request(\"DELETE\", url, headers=headers, data = payload)\r\n\r\nprint(response.text.encode('utf8'))\r\n"
          },
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar options = {\r\n  'method': 'DELETE',\r\n  'url': 'https://rest.method.me/api/v1/tables/Contacts/3695',\r\n  'headers': {\r\n    'Authorization': 'APIKey {your_key}'\r\n  }\r\n};\r\nrequest(options, function (error, response) { \r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});\r\n"
          },
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/tables/Contacts/3695\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"DELETE\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey {your_key}\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;\r\n"
          }
        ]
      }
    },
    "/api/v1/tables/{table}": {
      "get": {
        "tags": [
          "Tables"
        ],
        "summary": "Query Records",
        "description": "To query records from a table. Specify `{table}` in the URL path. \r\n\r\n- The `apply` query parameter allows standard data aggregations on your query like `sum`, `count`, and `group by`.\r\nSee [Data Aggregation Queries](#section/Data-Aggregation-Queries) for all supported aggregations and some examples.\r\n- The `filter` query parameter allows filtering records in a table. You can filter on any table fields, linked fields, and system fields. \r\nSee [Filter Reference](#section/Filter-Reference) for more options and examples about this format.\r\n- The `skip` and `top` query parameters together allow paginating through the records. \r\nThe default value of `top` is 10 and the maximum allowed value of `top` is 100. \r\nThat is, a maximum of 100 records can be requested in a single request; use the `nextLink` to get the next 100 records. \r\n- By default, the query result contains all fields including linked and drop-down fields, but you can request specific fields by using a `select` query parameter. \r\n- The `orderby` query parameter allows you to request records in either ascending order using `asc` or descending order using `desc`. \r\nIf asc or desc is not specified, then the resources will be ordered in ascending order. \r\nBy default, records are ordered in descending order by `RecordID` field.\r\n\r\n### Examples\r\n- To get first 10 Contacts that have `BillAddressCountry` equal to `Canada`\r\n    ```http\r\n    GET /api/v1/tables/Contacts?filter=BillAddressCountry eq 'Canada' HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n- To get next 10 Contacts that have `BillAddressCountry` equal to `Canada`\r\n    ```http\r\n    GET /api/v1/tables/Contacts?skip=10&top=10&filter=BillAddressCountry eq 'Canada' HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n\r\n- To get Contacts ordered by `TotalBalance` descending, followed by `LastModifiedDate` ascending\r\n    ```http\r\n    GET /api/v1/tables/Contacts?skip=10&top=10&filter=BillAddressCountry eq 'Canada'&orderby=TotalBalance desc,LastModifiedDate HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n\r\n- To exclude all fields in result except `BillAddressCountry`,`FirstName`,`LastName` and `RecordID`\r\n    ```http\r\n    GET /api/v1/tables/Contacts?skip=10&top=10&filter=BillAddressCountry eq 'Canada'&select=BillAddressCountry,FirstName,LastName,RecordID&orderby=TotalBalance desc,LastModifiedDate HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```",
        "operationId": "tables-query-records",
        "parameters": [
          {
            "name": "table",
            "in": "path",
            "description": "Table name",
            "required": true,
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "apply",
            "in": "query",
            "description": "Apply aggregates to your query",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "select",
            "in": "query",
            "description": "List of fields to be returned in the response",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "filter",
            "in": "query",
            "description": "Filter criteria. e.g. Firstname eq 'Amy' <br/> <a href='#section/Filter-Reference'>Filter Reference</a>",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "orderby",
            "in": "query",
            "description": "Order by specified fields",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "top",
            "in": "query",
            "description": "Return only this amount of records",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 10
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "How many matched records to skip before the first return",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "200": {
            "description": "Records returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryRecordsResult"
                },
                "example": {
  "count": 5,
  "nextLink": "https://rest.method.me/v1/tables/Contacts?skip=2&top=2&select=RecordID,FirstName,LastName,Phone,Email&filter=FirstName eq 'Amy'&orderby=RecordID desc",
  "value": [
    {
      "recordId": 1,
      "firstName": "Amy",
      "lastName": "Crenshaw",
      "phone": "111-222-3333",
      "email": "amy.c@gmail.com"
    },
    {
      "recordId": 1,
      "firstName": "Amy",
      "lastName": "Shaw",
      "phone": "111-000-1234",
      "email": "amy_shaw@gmail.com"
    }
  ]
}
              }
            }
          }
        },
        "x-code-samples": [
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar options = {\r\n  'method': 'GET',\r\n  'url': 'https://rest.method.me/api/v1/tables/Contacts?skip=10&top=10&filter=(BillAddressCountry eq \\'Canada\\' or BillAddressCountry eq \\'USA\\') and TotalBalance gt 0&select=BillAddressCountry,FirstName,LastName,RecordID,TotalBalance&orderby=TotalBalance desc,LastModifiedDate',\r\n  'headers': {\r\n    'Authorization': 'APIKey {your_key}'\r\n  }\r\n};\r\nrequest(options, function (error, response) { \r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});\r\n"
          },
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/tables/Contacts?skip=10&top=10&filter=(BillAddressCountry%20eq%20'Canada'%20or%20BillAddressCountry%20eq%20'USA')%20and%20TotalBalance%20gt%200&select=BillAddressCountry,FirstName,LastName,RecordID,TotalBalance&orderby=TotalBalance%20desc,LastModifiedDate\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"GET\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey {your_key}\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;\r\n"
          },
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/tables/Contacts?skip=10&top=10&filter=(BillAddressCountry eq 'Canada' or BillAddressCountry eq 'USA') and TotalBalance gt 0&select=BillAddressCountry,FirstName,LastName,RecordID,TotalBalance&orderby=TotalBalance desc,LastModifiedDate\"\r\n\r\npayload = {}\r\nheaders = {\r\n  'Authorization': 'APIKey {your_key}'\r\n}\r\n\r\nresponse = requests.request(\"GET\", url, headers=headers, data = payload)\r\n\r\nprint(response.text.encode('utf8'))\r\n"
          }
        ]
      },
      "post": {
        "tags": [
          "Tables"
        ],
        "summary": "Create Record",
        "description": "To insert a record into a table. Specify `{table}` in the URL path. \r\n\r\nInclude all required fields. Linked fields are ignored. \r\n\r\n### Examples\r\n- To create a record in the Contacts table\r\n    ```http\r\n    POST /api/v1/tables/Contacts HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    Content-Type: application/json\r\n    \r\n    {\r\n        \"Email\": \"david@landscaping.com\",\r\n        \"FirstName\": \"David\",\r\n        \"LastName\": \"Henderson\",\r\n        \"Phone\": \"1112223333\"\r\n    }\r\n    ```\r\n\r\n- To create an Invoice + InvoiceLine(s) in a single request. \r\nUse `__` as a prefix before the related table name. \r\nThis will create the invoice, invoice line(s), and also sync the invoice.\r\n**Maximum of 50 related records can be created in a single request.**\r\n\r\n    ```http\r\n    POST /api/v1/tables/Invoice HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    Content-Type: application/json\r\n\r\n    {\r\n   \r\n        \"TxnDate\": \"2020-06-01T16:00:00\",\r\n        \"BillAddressAddr1\": \"Blue Jet Airways\",\r\n        \"BillAddressAddr2\": \"213 E Washington St\",\r\n        \"BillAddressCity\": \"Ashland\",\r\n        \"BillAddressState\": \"OH\",\r\n        \"BillAddressPostalCode\": \"44805\",\r\n        \"BillAddressCountry\": \"USA\",\r\n        \"IsPending\": false,\r\n        \"IsFinanceCharge\": false,\r\n        \"DueDate\": \"2020-06-01T16:00:00\",\r\n        \"IsPaid\": false,\r\n        \"IsToBePrinted\": false,\r\n        \"IsToBeEmailed\": false,\r\n        \"IsTaxIncluded\": false,\r\n        \"IsWaitingForSyncApproval\": false,\r\n        \"TenantID\": 1,\r\n        \"ARAccount\": \"Accounts Receivable\",\r\n        \"Customer\": \"Blue Jet Airways\",\r\n        \"__InvoiceLine\":[\r\n            {\r\n                \"Desc\": \"Plans and Permits\",\r\n                \"Quantity\": 1,\r\n                \"Rate\": 400,\r\n                \"IsRatePercent\": false,\r\n                \"ServiceDate\": \"2020-06-30T16:15:25\",\r\n                \"UnitOfMeasure\": \"\",\r\n                \"LineOrder\": 1,\r\n                \"LastModifiedDate\": \"2020-06-01T16:16:08.597\",\r\n                \"Item\": \"01 Plans and Permits\",\r\n                \"SalesTaxCode\": \"Non\",\r\n                \"TenantID\": 1\r\n            },\r\n            {\r\n                \"Desc\": \"Plans and Permits\",\r\n                \"Quantity\": 3,\r\n                \"Rate\": 500.00000,\r\n                \"IsRatePercent\": false,\r\n                \"ServiceDate\": \"2020-06-30T16:15:25\",\r\n                \"UnitOfMeasure\": \"\",\r\n                \"LineOrder\": 2,\r\n                \"LastModifiedDate\": \"2020-06-01T16:16:08.597\",\r\n                \"Item\": \"01 Plans and Permits\",\r\n                \"SalesTaxCode\": \"Non\",\r\n                \"TenantID\": 1\r\n            }\r\n        ]\r\n    }\r\n    ```    \r\n\r\n\r\n",
        "operationId": "tables-create-record",
        "parameters": [
          {
            "name": "table",
            "in": "path",
            "description": "Table name",
            "required": true,
            "schema": {
              "type": "string",
              "nullable": true
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { },
              "example": ""
            }
          }
        },
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "201": {
            "description": "RecordID. Location header contains link to created record",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          }
        },
        "x-code-samples": [
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/tables/Contacts\"\r\n\r\npayload = \"{\\r\\n    \\\"Email\\\": \\\"david@landscaping.com\\\",\\r\\n    \\\"FirstName\\\": \\\"David\\\",\\r\\n    \\\"LastName\\\": \\\"Henderson\\\",\\r\\n    \\\"Phone\\\": \\\"1112223333\\\"\\r\\n}\"\r\nheaders = {\r\n  'Content-Type': 'application/json',\r\n  'Authorization': 'APIKey {your_key}'\r\n}\r\n\r\nresponse = requests.request(\"POST\", url, headers=headers, data = payload)\r\n\r\nprint(response.text.encode('utf8'))\r\n"
          },
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/tables/Contacts\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"POST\",\r\n  CURLOPT_POSTFIELDS =>\"{\\r\\n    \\\"Email\\\": \\\"david@landscaping.com\\\",\\r\\n    \\\"FirstName\\\": \\\"David\\\",\\r\\n    \\\"LastName\\\": \\\"Henderson\\\",\\r\\n    \\\"Phone\\\": \\\"1112223333\\\"\\r\\n}\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Content-Type: application/json\",\r\n    \"Authorization: APIKey {your_key}\",\r\n    \"Content-Type: text/plain\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;\r\n"
          },
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar options = {\r\n  'method': 'POST',\r\n  'url': 'https://rest.method.me/api/v1/tables/Contacts',\r\n  'headers': {\r\n    'Content-Type': ['application/json', 'text/plain'],\r\n    'Authorization': 'APIKey {your_key}'\r\n  },\r\n  body: \"{\\r\\n    \\\"Email\\\": \\\"david@landscaping.com\\\",\\r\\n    \\\"FirstName\\\": \\\"David\\\",\\r\\n    \\\"LastName\\\": \\\"Henderson\\\",\\r\\n    \\\"Phone\\\": \\\"1112223333\\\"\\r\\n}\"\r\n\r\n};\r\nrequest(options, function (error, response) { \r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});\r\n"
          }
        ]
      }
    },
    "/api/v1/tables/{table}/count": {
      "get": {
        "tags": [
          "Tables"
        ],
        "summary": "Record Count",
        "description": "To get the count of records in a table. Specify `{table}` in the URL path.\r\n\r\n- The `filter` query parameter allows filtering records in a table. You can filter on any table fields, linked fields, and system fields. \r\nSee [Filter Reference](#section/Filter-Reference) for more options and examples about this format.\r\n\r\n\r\n### Examples\r\n- To get count of Contacts that have `BillAddressCountry` equal to `Canada`\r\n    ```http\r\n    GET /api/v1/tables/Contacts/count?filter=BillAddressCountry eq 'Canada' HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n- To get total count of Contacts \r\n    ```http\r\n    GET /api/v1/tables/Contacts/count HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    ```\r\n\r\n",
        "operationId": "tables-record-count",
        "parameters": [
          {
            "name": "table",
            "in": "path",
            "description": "Table name",
            "required": true,
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "filter",
            "in": "query",
            "description": "Filter criteria. e.g. Firstname eq 'Amy' <br/> <a href='#section/Filter-Reference'>Filter Reference</a>",
            "schema": {
              "type": "string",
              "nullable": true
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "200": {
            "description": "Count returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int32"
                }
              }
            }
          }
        },
        "x-code-samples": [
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar options = {\r\n  'method': 'GET',\r\n  'url': 'https://rest.method.me/api/v1/tables/Contacts/count?filter=(BillAddressCountry eq \\'Canada\\' or BillAddressCountry eq \\'USA\\')',\r\n  'headers': {\r\n    'Authorization': 'APIKey {your_key}'\r\n  }\r\n};\r\nrequest(options, function (error, response) { \r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});\r\n"
          },
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/tables/Contacts/count?filter=(BillAddressCountry%20eq%20'Canada'%20or%20BillAddressCountry%20eq%20'USA')\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"GET\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey {your_key}\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;\r\n"
          },
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/tables/Contacts/count?filter=(BillAddressCountry eq 'Canada' or BillAddressCountry eq 'USA')\"\r\n\r\npayload = {}\r\nheaders = {\r\n  'Authorization': 'APIKey {your_key}'\r\n}\r\n\r\nresponse = requests.request(\"GET\", url, headers=headers, data = payload)\r\n\r\nprint(response.text.encode('utf8'))\r\n"
          }
        ]
      }
    },
    "/api/v1/tables/{table}/{recordId}/Sync": {
      "post": {
        "tags": [
          "Tables"
        ],
        "summary": "Sync Record",
        "description": "To sync a record in a table with QuickBooks or Xero. Specify `{table}` and `{recordId}` in the URL path. \r\nThis endpoint works only with syncable tables. \r\nYou can find the list of syncable tables for [QuickBooks Desktop](https://help.method.me/en/articles/2589623-supported-tables-for-quickbooks-desktop) and [QuickBooks Online](https://help.method.me/en/articles/2589601-supported-tables-for-quickbooks-online) in our Help Center. \r\nFor accounting transactions like Estimates, Invoices, etc., this endpoint also calculates the total amount.\r\n\r\n### Examples\r\n- To trigger sync for an Invoice with RecordID 10\r\n\r\n    ```http\r\n    POST /api/v1/tables/Invoice/10/Sync HTTP/1.1\r\n    Host: https://rest.method.me\r\n    Authorization: APIKey {your_key}\r\n    Content-Type: application/json\r\n    ```\r\n",
        "operationId": "tables-sync-record",
        "parameters": [
          {
            "name": "table",
            "in": "path",
            "description": "TableName",
            "required": true,
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "recordId",
            "in": "path",
            "description": "RecordId of the record",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                },
                "example": {
  "errors": {},
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "detail": "The required field InvoiceRecordID was either missing or invalid.",
  "traceId": "|2384b787 - 4bedc2c24ff24869."
}
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
  "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
  "title": "An error occured while processing your request.",
  "status": 500,
  "traceId": "|d7002816-40853c28b0eb90cd."
}
              }
            }
          },
          "204": {
            "description": "Record synced successfully"
          }
        },
        "x-code-samples": [
          {
            "lang": "Node.js",
            "source": "var request = require('request');\r\nvar options = {\r\n  'method': 'POST',\r\n  'url': 'https://rest.method.me/api/v1/tables/Invoice/10/Sync',\r\n  'headers': {\r\n    'Authorization': 'APIKey {your_key}',\r\n    'Content-Type': 'application/json'\r\n  }\r\n};\r\nrequest(options, function (error, response) { \r\n  if (error) throw new Error(error);\r\n  console.log(response.body);\r\n});\r\n"
          },
          {
            "lang": "PHP",
            "source": "<?php\r\n\r\n$curl = curl_init();\r\n\r\ncurl_setopt_array($curl, array(\r\n  CURLOPT_URL => \"https://rest.method.me/api/v1/tables/Invoice/10/Sync\",\r\n  CURLOPT_RETURNTRANSFER => true,\r\n  CURLOPT_ENCODING => \"\",\r\n  CURLOPT_MAXREDIRS => 10,\r\n  CURLOPT_TIMEOUT => 0,\r\n  CURLOPT_FOLLOWLOCATION => true,\r\n  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\r\n  CURLOPT_CUSTOMREQUEST => \"POST\",\r\n  CURLOPT_HTTPHEADER => array(\r\n    \"Authorization: APIKey {your_key}\",\r\n    \"Content-Type: application/json\"\r\n  ),\r\n));\r\n\r\n$response = curl_exec($curl);\r\n\r\ncurl_close($curl);\r\necho $response;\r\n"
          },
          {
            "lang": "Python",
            "source": "import requests\r\n\r\nurl = \"https://rest.method.me/api/v1/tables/Invoice/10/Sync\"\r\n\r\nheaders = {\r\n  'Authorization': 'APIKey {your_key}',\r\n  'Content-Type': 'application/json'\r\n}\r\n\r\nresponse = requests.request(\"POST\", url, headers=headers)\r\n\r\nprint(response.text.encode('utf8'))\r\n"
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "ValidationProblemDetails": {
        "type": "object",
        "properties": {
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "nullable": true
          }
        },
        "additionalProperties": {
          "type": "object",
          "additionalProperties": false
        }
      },
      "ProblemDetails": {
        "type": "object",
        "additionalProperties": {
          "type": "object",
          "additionalProperties": false
        }
      },
      "FileLink": {
        "required": [
          "recordId",
          "tableName"
        ],
        "type": "object",
        "properties": {
          "tableName": {
            "type": "string"
          },
          "recordId": {
            "type": "integer",
            "format": "int32"
          },
          "attachToEmail": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "FileMetadata": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "filename": {
            "type": "string",
            "nullable": true
          },
          "fileExtension": {
            "type": "string",
            "nullable": true
          },
          "size": {
            "type": "integer",
            "format": "int64"
          },
          "createdBy": {
            "type": "string",
            "nullable": true
          },
          "modifiedBy": {
            "type": "string",
            "nullable": true
          },
          "createdDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastModifiedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "tenantId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "links": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FileLink"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "QueryRecordsResult": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "format": "int32"
          },
          "nextLink": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "description": "API key authentication. Provide the header value as `APIKey <your-api-key>`.",
        "name": "Authorization",
        "in": "header"
      },
      "OAuth2": {
        "type": "oauth2",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://auth.method.me/connect/authorize",
            "tokenUrl": "https://auth.method.me/connect/token",
            "refreshUrl": "https://auth.method.me/connect/token",
            "scopes": {
              "api": "Required scope to access Method Rest API",
              "openid": "System required",
              "profile": "System required",
              "email": "System required"
            }
          }
        }
      }
    }
  },
  "security": [
    {
      "ApiKey": [ ]
    },
    {
      "OAuth2": [
        "api"
      ]
    }
  ],
  "tags": [
    {
      "name": "Files",
      "description": "You can upload, download, delete, and get a list of files linked to a table record using the endpoints listed below."
    },
    {
      "name": "Tables",
      "description": "You can perform CRUD (Create, Read, Update, and Delete) operations on tables using the endpoints listed below. \r\nTo view a list of available tables, log in to your account in Method and navigate to Account Settings > Tables. \r\nYou can also perform a Sync operation to trigger a record to sync with your accounting software."
    }
  ],
  "x-tagGroups": [
    {
      "name": "Endpoints",
      "tags": [
        "Files",
        "Tables"
      ]
    }
  ]
}