UNPKG

openapi-directory

Version:

Building & bundling https://github.com/APIs-guru/openapi-directory for easy use from JS

1 lines 369 kB
{"openapi":"3.0.1","servers":[{"url":"https://apis.e-conomic.com/api/v20.0.0/"}],"info":{"contact":{"email":"api@e-conomic.com","url":"https://www.e-conomic.com/"},"description":"# Changelog\r\n\r\n<details>\r\n <summary>Click to see changelog.</summary>\r\n\r\n| Version | Description |\r\n|---------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\r\n| 20.0.0 | Customer contacts and delivery locations endpoints deprecated. You can find the same enpoints in [`Customers API`](https://apis.e-conomic.com/#Customers) \r\n| 19.0.0 | Page-based endpoints were moved under /paged url and cursor-based endpoints dropped the /all.\r\n| 18.0.0 | Added isDeleted flag to [`customer-contacts`](#tag/Customer-contacts) and included deleted contacts in the response. <br> Deleted contacts can be used for history purposes, but cannot be set as reference persons on sales documents. <br> In previous versions only customer-contacts/id returns deleted contacts as well.\r\n| 17.0.2 | `TimeEntryEmployeeNumberCannotBeUpdated` and `MileageEmployeeNumberCannotBeUpdated` error codes removed. The change affects all versions, but we bumped the version for transparency.\r\n| 17.0.1 | New custom [`OpenAPI extension`](#section/Retrieving-data/Custom-extensions-in-OpenAPI-specification) added in the specification: `x-error-codes`. Existing `x-required-roles` extension converted to an array of strings.\r\n| 17.0.0 | Improved the error model. Added `code` and `property` fields to the model. `code` represents the error code. `property` is the field name on which the input validation failed.\r\n| 16.4.0 | [`customer-deliverylocations`](#tag/Customer-delivery-locations) endpoints added.\r\n| 16.3.0 | [`customer-contacts`](#tag/Customer-contacts) endpoints added. \r\n| 16.2.2 | Added input validations for required string properties, if a string property is required it can't be empty, it should contain at least 1 character.\r\n| 16.2.1 | Error codes extended for [`mileages`](#tag/Mileage-entries) and [`timeentries`](#tag/Time-entries). Affects all the exisiting versions.\r\n| 16.2.0 | - [`employeegroups`](#operation/DeleteEmployeeGroupById) DELETE endpoint added. <br>- [`employees`](#operation/DeleteEmployeeById) DELETE endpoint added. <br>- [`project-employeegroups`](#operation/DeleteProjectEmployeeGroupById) DELETE endpoint added. <br>- [`project-employees`](#operation/DeleteProjectEmployeeById) DELETE endpoint added.\r\n| 16.1.0 | [`Time entry prices`](#tag/Time-entry-prices) and [`Mileage entry prices`](#tag/Mileage-entry-prices) endpoints added.\r\n| 16.0.0 | Changed parameter schema for [`mileages`](#operation/ApproveMileageEntries) and [`timeentries`](#operation/ApproveTimeEntries) approve endpoints.\r\n| 15.0.0 | Added cost and sales accounts properties in [`activitygroups`](#tag/Activity-Groups) endpoints.\r\n| 14.1.3 | - Added new filter for `IsAccessible` in [`activities`](#tag/Activities) endpoints. <br>- Added new filter for `IsBarred` in [`costtypes`](#tag/Cost-Types) endpoints.\r\n| 14.1.2 | - Added input validations for [`activitygroups`](#tag/Activity-Groups). <br>- Updated description for [`projectgroups`](#operation/CreateProjectGroup) properties.\r\n| 14.1.1 | Added input validations for [`projectgroups`](#operation/CreateProjectGroup).\r\n| 14.1.0 | [`project-employees-count`](#operation/GetNumberOfProjectEmployees) endpoint added. \r\n| 14.0.0 | - [`project-activities`](#tag/Project-Activities) endpoints added. <br>- `projects/activities` have been deprecated.|\r\n| 13.2.0 | [`costtypegroups`](#tag/Cost-Type-Groups) endpoints added.|\r\n| 13.1.0 | [`costtypes`](#tag/Cost-Types) endpoints added.|\r\n| 13.0.0 | - [`projectgroups`](#operation/CreateProjectGroup) POST endpoint added, `Number` made non-required,<br>- [`activitygroups`](#operation/CreateActivityGroup) POST endpoint added, `Number` made non-required.|\r\n| 12.0.0 | [`projects`](#tag/Projects) `Number` made non-required. |\r\n| 11.0.0 | [`employees`](#tag/Employees) `Number` made required. |\r\n| 10.1.2 | API version number moved to the server URL. |\r\n| 10.1.1 | - [`activities`](#operation/GetAllowedActivities) `employeeNumber` maximum value changed to 999999. <br>- [`projects`](#operation/GetPagedListOfProjectUnderEmployee) `employeeNumber` maximum value changed to 999999. |\r\n| 10.1.0 | [`project-employees`](#operation/CreateProjectEmployee) POST endpoint added. |\r\n| 10.0.0 | - [`activities`](#tag/Activities) POST and PUT endpoints added. <br>- [`activitygroups`](#tag/Activity-Groups) GET endpoints added. <br>- Object version field added to `activities`, `projectstatuses` and `projectgroups` endpoints. |\r\n| 9.0.0 | `Project related settings for employee` resource renamed as `Project employee`. |\r\n| 8.1.0 | [`project-customers`](#tag/Project-Customers) endpoints added. |\r\n| 8.0.0 | - [`employeegroups`](#tag/Employee-groups) endpoints added: GET all paginated, GET count, POST and PUT. <br>- [`project-employeegroups`](#tag/Project-employee-groups) endpoints added: GET all paginated, GET all cursor-based, GET count, GET by number, POST and PUT. <br> - Object version field added to employee groups endpoints. | |\r\n| 7.0.0 | [Projects related settings for employee](#tag/Project-employees) extended with new fields for Name, GroupNumber and IsBarred. |\r\n| 6.0.0 | Readonly property `IsReconciled` added to `TimeEntries` endpoint. |\r\n| 5.1.0 | [Project delete](#operation/DeleteProjectById) endpoint added. |\r\n| 5.0.0 | - Project-related properties such as `isUser`, `userId`, `canApprove`, `canInvoice`, `employeeType` in `/employees` moved to `/project-employees`. <br>- Properties `lastUpdated`, `costPrice`, `salesPrice` and `invoicedtotal` in `/projects` changed to readonly.<br>- Property `date` in `/timeentries` changed to mandatory.<br>- Access permission to `/employees` changed to requiring access to `Sales`.<br>- PUT endpoints for `/timeentries/{number}`, `/employees/{number}`, `/employeeprojectrelatedsettings/{number}` have been deprecated and new ones without `{number}` in the URL have been added. |\r\n| 4.0.0 | `project.CustomerNumber` made non-required, range check introduced. |\r\n| 3.1.0 | Error messages of time entry approval improved, `timeEntry.IsApproved`, `mileage.IsApproved` and `mileage.IncludeApproval` made read-only. |\r\n| 3.0.0 | `mileage.Date` made required. Verification for `mileage.EmployeeNumber` and `mileage.Distance` added. |\r\n| 2.2.2 | Range check introduced in `projects.Number`, `employee.Number` and `employeeGroup.Number`. |\r\n| 2.2.1 | Employees PATCH endpoint deprecated. |\r\n| 2.2.0 | [`employeegroups/all`](#operation/GetAllEmployeeGroups) and [`employeegroups/{number}`](#operation/GetEmployeeGroupById) endpoints added. |\r\n| 2.1.0 | [`/activities/allowed`](#operation/GetAllowedActivities) endpoint added to get allowed activities for an employee and project. |\r\n| 2.0.0 | Open API released! Endpoints related to Projects module added. |\r\n\r\n</details>\r\n\n# TL;DR\r\n\r\n**Add these three headers to your requests.**\r\n\r\n| Header | Value | What is this? |\r\n| :-------------------- | :------------------------- | :----------------------------------------------------------- |\r\n| X-AppSecretToken | YOUR_PRIVATE_TOKEN | This identifies your app. This is your secret token. Try using the value `demo`. |\r\n| X-AgreementGrantToken | YOUR_AGREEMENT_GRANT_TOKEN | This identifies the grant issued by an agreement, to allow your app to access the agreements data. Try using the value `demo`. |\r\n| Content-Type | application/json | We’re a JSON based API. This tells us that you agree with us on using JSON. |\r\n\r\n### Examples\r\n\r\n#### jQuery\r\n\r\n```javascript/jQuery\r\n$.ajax({\r\n url: \"https://apis.e-conomic.com/api/v20.0.0/projects\",\r\n dataType: \"json\",\r\n headers: {\r\n 'X-AppSecretToken': \"demo\",\r\n 'X-AgreementGrantToken': \"demo\",\r\n 'Content-Type': \"application/json\"\r\n },\r\n type: \"GET\"\r\n})\r\n .always(function (data) {\r\n $(\"#output\").text(JSON.stringify(data, null, 4));\r\n});\r\n```\r\n\r\n#### cURL\r\n\r\n```curl\r\ncurl -H \"X-AppSecretToken: demo\" -H \"X-AgreementGrantToken: demo\" https://apis.e-conomic.com/api/v20.0.0/projects\r\n```\r\n\r\n\r\n\r\n# Introduction\r\n\r\nWelcome to the **Visma e-conomic OpenAPI** documentation!\r\n\r\nThe e-conomic API is a document-based JSON REST API. \r\n\r\nFor more in-depth information about e-conomic itself, please have a look at the e-copedia [http://wiki.e-conomic.dk](http://wiki.e-conomic.dk/).\r\n\r\n## Usage\r\n\r\n- **Generating a client** can easily be done using tools like [swagger-codegen](https://github.com/swagger-api/swagger-codegen) or others that work with [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification) specs.\r\n\r\n\r\n## Versioning\r\n\r\nAPI releases are versioned using a three-part versioning scheme: `{major version}.{minor version}.{patch version}`.\r\n\r\nWe broadly follow [Semantic Versioning](https://semver.org/) principles when versioning the API. The major version number is incremented when a breaking change occurs. \r\n\r\nThe format is:\r\n\r\n`/api/v{major version}.{minor version}.{patch version}/{resource-name}`\r\n\r\nEach value of the above are integers and you should configure the specific version in each API call. \r\n\r\nAn example could be: `/api/v2.2.1/projects`\r\n\r\nTo track the changes of versions, please see our [changelog](#section/Changelog).\r\n\r\nWe reserve the right to deprecate versions at intervals since this allows for moving into a friendly environment for you faster.\r\n\r\n## Demo authentication\r\n\r\nIf you wish to try out the API before registering a developer agreement, you can do this by using the demo agreement, which mimics the authentication flow you will have to use when you create your app. All you have to do is specify HTTP header tokens `X-AgreementGrantToken: demo` and `X-AppSecretToken: demo`. Note however that you can only do GET requests with the demo agreement. If you want full access to our API's, you will need to register.\r\n\r\n# Retrieving data\r\n\r\nOur data is exposed as collections of items. Each item has many properties, with one property as a unique identifier, usually called `number` or `id`. You can always get a single item if you already know the unique identifier. In case the unique identifier is not known, you can always search the collection and retrieve an array of items that satisfy the search criteria, or retrieve only the count of items that satisfy the search criteria. When you search for items in a collection, you can always use filtering, sorting and pagination. When it comes to pagination, we offer two distinct approaches available on separate endpoints. You can read more about filtering, sorting and pagination in the following sections. \r\n\r\n## Filtering\r\n\r\nFiltering is enabled on all collection endpoints but not on all properties.\r\n\r\nFiltering on collections can be done using the query string parameter `filter`. A filter is made up of a set of predicates and follows a syntax inspired by mongoDB. A predicate is made up of a property name, an operator, and a value.\r\n\r\nExample: `?filter=name$eq:Joe`\r\n\r\nThis matches all resources with the value Joe in the property name.\r\n\r\nPredicates can be chained using either of the logical operators AND and OR.\r\n\r\nExample: `?filter=name$eq:Joe$and:city$like:*port`\r\n\r\nFiltering on strings is case insensitive.\r\n\r\n#### Filterable properties\r\nInformation about what properties allow filtering and on what operators can be found in the property in the schema for the collection. Each property that allows filtering has the property `\"x-filterable\"` in combination with `operators` set. If you try to filter on something that isn’t allowed the server will respond with a status code 400.\r\n\r\n#### Specifying Operator affinity\r\nIf you want to control the operator affinity then you can use parentheses.\r\n\r\nAn example is: `?filter=name$eq:Joe$and:(city$like:*port$or:age$lt:40)`\r\n\r\n#### URL Encoding\r\nURL parameter values should always be URL compatible. Always URL encode filter strings.\r\n\r\n#### Filter Operators\r\nThe possible filtering operators are:\r\n\r\n| Operator | Syntax |\r\n| -------- | ------ |\r\n|Equals | $eq:|\r\n|Not equals | $ne:|\r\n|Greater than | $gt:|\r\n|Greater than or equal | $gte:|\r\n|Less than | $lt:|\r\n|Less than or equal | $lte:|\r\n|Substring match\t| $like:|\r\n|And also | $and:|\r\n|Or else | $or:|\r\n|In | $in:|\r\n|Not In | $nin:|\r\n\r\n#### Substring matching\r\n\r\nThe `$like:` operator supports both using wildcards (*) and not using wildcards. If no wildcards are used, the expression is considered a `contains` expression and effectively becomes a filter with a wildcard at the start of the string and one at the end of the string. This operator is only allowed on some properties.\r\n\r\n#### Escaping special characters in your filter\r\nTo not interfere with the parsing of the filter expression, certain escape sequences are necessary.\r\n\r\n- “$” is escaped with “$$”\r\n- “(” is escaped with “$(”\r\n- “)” is escaped with “$)”\r\n- “*” is escaped with “$*”\r\n- “,” is escaped with “$,”\r\n- “[” is escaped with “$[”\r\n- “]” is escaped with “$]”\r\n\r\n#### Using null values in your filter\r\nShould you want to filter for the nonexistence of a property (i.e. null value) you can use the null escape sequence.\r\n\r\n`$null:`\r\n\r\n#### Using in and not in operators\r\nTo determine whether a specified value matches any value in (or not in) a list you filter using the `$in:` or `$nin:` operator. The list to filter by has to be enclosed in brackets and values separated by commas.\r\n\r\n`customerNumber$in:[2,5,7,22,45]`\r\n\r\n\r\nIt is possible to also use the `$null:` keyword if you wish to include that in the filter. The max supported length of an array using the `$in:` or `$nin:` operator is 200.\r\n\r\n\r\n## Sorting\r\n\r\nSorting on strings is case insensitive.\r\n\r\n### Sort ascending\r\n\r\nSorting on collections can be done using the query string parameter ‘sort’.\r\n\r\n```\r\n?sort=name\r\n```\r\n\r\n### Sort descending\r\n\r\nThe default sort direction is ascending, but this can be turned by prepending a minus (-).\r\n\r\n```\r\n?sort=-name\r\n```\r\n\r\n### Sort by multiple properties\r\n\r\nIf you need to sort by multiple properties these can just be separated by commas. Mixing of directions is allowed.\r\n\r\n```\r\n?sort=-name,age\r\n```\r\n\r\n### Sort alphabetically\r\n\r\nIn certain cases, you might want to enforce that even numeric values are sorted alphabetically, so 1000 is less than 30. In those cases, you can prepend the sort property with a tilde (~).\r\n\r\n```\r\n?sort=~name\r\n```\r\n\r\n#### Sortable properties\r\nInformation about what properties are sortable can be found in the schema for the collection. Each property that allows sorting has the property `\"x-sortable\": true` set.\r\n\r\n\r\n## Pagination\r\n\r\nWhen it comes to retrieving a collection of items, you can use two distinct approaches:\r\n\r\n* **Cursor-based pagination** (continued loading of items using a `cursor` as a query parameter to get the next page of items)\r\n * This is the recommended approach, and the one you should use by default.\r\n * The endpoint naming scheme is **\"Retrieve all `Items`\"**. (Usage: `/{ITEM}?cursor={CURSOR_VALUE}`)\r\n\r\n\r\n* **Classic pagination** (limited functionality*. Specify `skippages` and `pagesize ` as query parameters to get a specific page of items)\r\n * You should only consider using classic pagination, if you rely on loading pages (i.e. for list views or table/grid-based UI's).\r\n * The endpoint naming scheme is **\"Retrieve a page of `Items`\"**. (Usage: `/{ITEM}/paged?skippages=0&pagesize=20`) \r\n \\* It's important to note that there is a limit of 10.000 items using this approach. Any items outside of the first 10.000 items will not be loaded.\r\n\r\nPlease bear in mind that the two approaches are supported by **separate endpoints**. To use classic pagination, add `/paged` to your request URL.\r\n\r\nIf you need to know the total count of items that you can expect to get from your search, you can use a separate endpoint called **\"Retrieve the number of `Items`\"**. \r\nYou can also use the result of this endpoint to calculate the pagination navigation buttons for a table/grid-based UI.\r\n\r\n\r\n### Which approach should you use?\r\nWe highly recommend that you use cursor-based pagination because:\r\n- It is more performant and offers much faster retrieval of items;\r\n- It can be used for very large collections of many thousands or millions of items, whereas classic pagination is limited to only returning 10.000 results, everything else is ignored; \r\n Classic pagination is only appropriate when you have an app with a table/grid-based UI.\r\n\r\n### Cursor-based pagination\r\n\r\n#### How it works\r\n\r\nWhen you search for items in a large collection, the response will contain the first 1.000 items and a `cursor` that you can use in a subsequent request to get the next series of items. This way you can retrieve the next set of items only when needed (if 1.000 items suffice, you don't need to send a second request).\r\n\r\nPlease note that the cursor is currently the `id` of the first `item` on the next set and it should not be mistaken for the number of items which are yet to be displayed.\r\nAlso, if the cursor is not present in the response, it means that there are no more items in the results.\r\n\r\n##### Real world example\r\n\r\nI want to retrieve all projects.\r\n\r\n1) I send a request to `https://apis.e-conomic.com/api/v20.0.0/projects`\r\n and get back an array of 1.000 projects, and a `cursor` with value `34781`\r\n\r\n\r\n2) I send a request for the next items in the resulting collection: \r\n `https://apis.e-conomic.com/api/v20.0.0/projects?cursor=34781` \r\n and get back an array of 1.000 projects and a cursor with value `87695`\r\n\r\n\r\n3) I send a request for the next items in the result: \r\n `https://apis.e-conomic.com/api/v20.0.0/projects?cursor=87695` \r\n and get back an array of 56 items and no cursor. \r\n No cursor means I have retrieved all the projects, i.e. I have reached the end of the list.\r\n\r\n\r\n### Classic pagination\r\n\r\nIf no parameters are used, the collection endpoint returns 20 items at a time. URL parameters allow you to increase this to up to 100 items or to skip pages if necessary.\r\n\r\n##### Real world example\r\n\r\nI want to show a grid with page size of 50 and pagination navigation buttons.\r\n\r\n1) I send a request to see how many projects there are in the collection: \r\n `https://apis.e-conomic.com/api/v20.0.0/projects/count` \r\n I get the number of projects in the collection, `2056`, and I can calculate the number of pages to be 2056 divided by 50 = 40 with 6 as remainder, meaning I have 41 pages total. I can then use this to present the user the navigation buttons.\r\n\r\n\r\n2) I send a request to retrieve the first page of projects that my user will see: \r\n `https://apis.e-conomic.com/api/v20.0.0/projects/paged?pagesize=50&sort=name` \r\n with this I get back an array of 50 projects, sorted alphabetically by the project name.\r\n\r\n\r\n3) Now if the user wants to see page number 6, I'll send a new request, skipping the first 5 pages to get the projects from page number 6: \r\n `https://apis.e-conomic.com/api/v20.0.0/projects/paged?pagesize=50&skippages=5&sort=name` \r\n I get back an array of 50 projects, that belong to page number 6 when sorting alphabetically by the project name.\r\n\r\n\r\n\r\n### Number of items in a collection\r\n\r\nAs mentioned before we offer endpoint to get the count of items in the collection. You can also use this info for calculation of pagination navigation in case of classic pagination.\r\n\r\nExample `https://apis.e-conomic.com/api/v20.0.0/projects/count`\r\n\r\n\r\n## HTTP Status Codes\r\n\r\nThe Open API returns these HTTP status codes.\r\n\r\n| Code | Text | Description |\r\n| :--- | :--------------------- | :----------------------------------------------------------- |\r\n| 200 | OK | Everything is OK |\r\n| 201 | Created | When you create resources, this is what you get. This will be accompanied by the created resource in the body and a location header with a link to the created resource. |\r\n| 204 | No Content | In certain cases there is nothing to return. So we will let you know by returning a 204. |\r\n| 400 | Bad Request | The request you made was somehow malformed. A malformed request could be failed validation on creation or updating. If you try to filter on something that isn’t filterable this is also what you’ll see. Whenever possible we will also try to include a developer hint to help you get around this issue. |\r\n| 401 | Unauthorized | The credentials you supplied us with weren’t correct, or perhaps you forgot them altogether. If an agreement has revoked the grant they gave your app, this is what you will see. |\r\n| 403 | Forbidden | You won’t necessarily have access to everything. So even though you were authorized we might still deny access to certain resources. This depends on the roles asked for when the grant was issued. |\r\n| 404 | Not Found | This is returned when you try to request something that doesn’t exist. This could be a resource that has been deleted or just a URL you tried to hack. If you see a lot of these, it could be an indication that you aren’t using the links provided by the API. You should never need to concatenate any URLs. The API should provide you with the links needed. |\r\n| 405 | Method Not Allowed | Not all endpoints support all HTTP methods. If you try issue a PUT request to a collection resource this is what you get. |\r\n| 415 | Unsupported Media Type | Our API is a JSON api. If you ask us to give you anything else, we give you this, and tell you why in the JSON body of the response. |\r\n| 500 | Internal Server Error | We don’t like to see these, and they are flagged in our logs. When you see this, something went wrong on our end. Either try again, or contact our support. |\r\n\r\n\r\n## Required and Readonly Properties\r\n\r\nSince OpenAPI allows client generation based on the specification, we decided to use the same model/schema in our for both read and write endpoints where possible.\r\n\r\nThis led us to chose not to have the Id/Number in the URL parameter for PUT requests, but to use the one from the body, so there is no confusion.\r\n\r\nWhen a property is marked as `required` it means you need to provide a value on each POST and PUT requests.\r\n\r\nWhen a property is marked as `readonly` it means you should provide the same value you get in the GET requests, or do not send the property in the JSON at all (skip it).\r\n\r\n## Custom resource encoding\r\n\r\nFor some resource ids (the direct URL path to a resource) the question of non-alphanumeric characters must be solved in REST APIs by either encoding or replacement to ensure URL compatibility.\r\n\r\nIn the e-conomic REST API a subset of non-alphanumeric characters are replaced using a custom scheme for resource URLs:\r\n\r\n| Character | Replacement |\r\n| :--------------- | :---------- |\r\n| “<” | *0* |\r\n| “>” | *1* |\r\n| “*” | *2* |\r\n| “%” | *3* |\r\n| “:” | *4* |\r\n| “&” | *5* |\r\n| “/” | *6* |\r\n| “\\” | *7* |\r\n| “_” | *8* |\r\n| “ ” (whitespace) | *9* |\r\n| “?” | *10* |\r\n| “.” | *11* |\r\n| “#” | *12* |\r\n| “+” | *13* |\r\n\r\nExample: Product “My Awesome Product_Discount5%” Resource URL (self): https://apis.e-conomic.com/products/My_9_Awesome_9_Product_8_Discount5_3_\r\n\r\nAll other non-alphanumeric characters in resource URLs are standard URL encoded. Please refer to standard URL encoding for characters not mentioned above.\r\n\r\n## Implementation specifics\r\n\r\nHelpful details to know when implementing e-conomic REST.\r\n\r\n### Booleans\r\n\r\nBooleans should only be expected to be represented in responses when true. A false boolean is omitted from response body. The same logic applies to write operations such as POST and PUT.\r\n\r\n### Null values\r\n\r\nNull values are omitted from the response body.\r\n\r\n### Nulling\r\n\r\nWe do not generally accept null as a value and a validation exception should be expected. To null a property you must exclude it from your JSON on the write operation.\r\n\r\n## Object version\r\n\r\nObjectVersion is the mechanism that enforces updates only on latest state of an object.\r\nObjectVersion property is mandatory in Put Requests.\r\nObjectVersion property is retrieved on Get Request and needs to be included in Put Request.\r\nIf object was modified between Get and Put requests, Put request will fail with error code `409 Conflict`\r\n\r\n```\r\n{\r\n \"message\": \"Update conflict. Version does not match.\",\r\n \"developerHint\": \"The resource has been updated by another user. Retrieve the resource/object and try the update again. This is needed in order to prevent you from rolling back another user's update.\",\r\n \"logId\": \"09580053-1141-4e7f-85e1-bed8600e0278\",\r\n \"logTimeUtc\": \"2021-11-04T09:07:56\",\r\n \"property\": \"version\"\r\n}\r\n```\r\n\r\n## Custom extensions in OpenAPI specification\r\n\r\nIn the specification file, there are some custom extensions that developers can make use of when consuming endpoints. \r\nThose extensions are always prefixed by `x-`.\r\n\r\n1) `x-required-roles`: The list of roles that are required for each group of endpoints.\r\n2) `x-error-codes`: The list of error codes that are potentially returned from each group of endpoints.\r\n","title":"Visma e-conomic OpenAPI","version":"v20.0.0","x-apisguru-categories":["ecommerce"],"x-logo":{"url":""},"x-origin":[{"format":"openapi","url":"https://apis.e-conomic.com/openapi/e-conomic.openapi.json","version":"3.0"}],"x-providerName":"e-conomic.com"},"security":[{"X-AgreementGrantToken":[],"X-AppSecretToken":[]}],"tags":[{"description":"<code>Projects</code> are indispensable within the Projects module, as any registration needs to be linked to a project.\r\nProjects are either:\r\n* Sub-projects or\r\n* Main projects\r\n\r\nSub-projects can be linked to a main project or used independently.\r\n\r\nBoth kinds of projects can be invoiced, but expenses, time entries and mileages can only be registered on sub-projects.\r\n\r\nMain projects are primarily used to group sub-projects.\r\n\r\nExternal projects are assigned a customer number, which means that the registration on projects can have an effect on accounting.\r\n\r\n\r\n#### Examples of use cases:\r\n\r\n* Create new projects;\r\n* Retrieve all projects which need to be delivered by a given date;\r\n\r\n\r\nRelated guide for users: [e-copedia](https://www.e-conomic.dk/support/artikler/opret-projekt) (Danish)\r\n<details>\n<summary><b>Click to see the list of possible error codes.</b></summary>\n\n| Error Code | Description |\n| ---------- | ----------- |\n|ProjectCannotBeCreatedUpdatedNumberIsInvalid|Project cannot be created or updated since the given number is invalid.\n|ProjectCannotBeCreatedUpdatedGroupNumberIsInvalid|Project cannot be created or updated since the given group number is invalid.\n|ProjectCannotBeCreatedUpdatedNumberAlreadyExists|Project cannot be created or updated since the given number already exists.\n|ProjectCannotBeCreatedAsClosed|Project cannot be created as closed.\n|ProjectCannotBeCreatedUpdatedGroupDoesNotExist|Project cannot be created or updated since the given project group does not exist.\n|ProjectCannotBeCreatedUpdatedCustomerNumberRequired|Project cannot be created or updated since customer number is required.\n|ProjectCannotBeCreatedUpdatedMainProjectNumberCannotBeSet|Project cannot be created or updated, main project number can only be set when creating subprojects.\n|ProjectCannotBeCreatedUpdatedMainProjectNumberDoesNotExistOrInvalid|Project cannot be created or updated, provided main project number doesn't exist or is not a main project.\n|ProjectCannotBeCreatedUpdatedInvalidCustomerNumber|Project cannot be created or updated, customer number is invalid.\n|ProjectCannotBeCreatedUpdatedCustomerNotFound|Project cannot be created or updated, customer was not found.\n|ProjectCannotBeMadeMainHasTimeEntries|Project cannot be made main project, it has time entries.\n|ProjectCannotBeMadeMainHasMileageEntries|Project cannot be made main project, it has mileage entries.\n|ProjectCannotBeMadeSubprojectHasSubProjects|Project cannot be made subproject, it already has subprojects.\n|ProjectCannotBeDeletedHasSubProjects|Project cannot be deleted since it has subprojects.\n|ProjectCannotBeDeletedHasTimeEntries|Project cannot be deleted since it has time entries.\n|ProjectCannotBeDeletedHasDraftEntries|Project cannot be deleted since it has draft daybook entries.\n|ProjectCannotBeDeletedHasBookedEntries|Project cannot be deleted since it has booked daybook entries.\n|ProjectCannotBeDeletedHasInvoices|Project cannot be deleted since it has invoices.\n|ProjectCannotBeDeletedHasSalesDocuments|Project cannot be deleted since it has sales documents.\n|ProjectCannotBeDeletedHasExpenses|Project cannot be deleted since it has expenses.\n|ProjectCannotBeDeletedHasMileages|Project cannot be deleted since it has mileage entries.\n</details>\n\n**Required application roles:** ProjectEmployee or SuperUser [[More info]](https://www.e-conomic.com/developer/permissions)\n","name":"Projects","x-error-codes":["ProjectCannotBeCreatedUpdatedNumberIsInvalid","ProjectCannotBeCreatedUpdatedGroupNumberIsInvalid","ProjectCannotBeCreatedUpdatedNumberAlreadyExists","ProjectCannotBeCreatedAsClosed","ProjectCannotBeCreatedUpdatedGroupDoesNotExist","ProjectCannotBeCreatedUpdatedCustomerNumberRequired","ProjectCannotBeCreatedUpdatedMainProjectNumberCannotBeSet","ProjectCannotBeCreatedUpdatedMainProjectNumberDoesNotExistOrInvalid","ProjectCannotBeCreatedUpdatedInvalidCustomerNumber","ProjectCannotBeCreatedUpdatedCustomerNotFound","ProjectCannotBeMadeMainHasTimeEntries","ProjectCannotBeMadeMainHasMileageEntries","ProjectCannotBeMadeSubprojectHasSubProjects","ProjectCannotBeDeletedHasSubProjects","ProjectCannotBeDeletedHasTimeEntries","ProjectCannotBeDeletedHasDraftEntries","ProjectCannotBeDeletedHasBookedEntries","ProjectCannotBeDeletedHasInvoices","ProjectCannotBeDeletedHasSalesDocuments","ProjectCannotBeDeletedHasExpenses","ProjectCannotBeDeletedHasMileages"],"x-required-roles":["ProjectEmployee","SuperUser"]},{"description":"<code>Project Statuses</code> help distinguish between two types of statuses:\r\n* Quote sent\r\n* Realised\r\n\r\nHowever, having a status is not mandatory, so there may be projects without one.\r\n\r\n#### Examples of use cases:\r\n\r\n- Retrieve all projects which have the status set to Realised.\r\n\r\n\r\nRelated guide for users: [e-copedia](https://www.e-conomic.dk/support/artikler/opret-projektstatus) (Danish)\r\n\n**Required application roles:** ProjectEmployee or SuperUser [[More info]](https://www.e-conomic.com/developer/permissions)\n","name":"Project Statuses","x-required-roles":["ProjectEmployee","SuperUser"]},{"description":"<code>Project Groups</code> allow projects to be classified as:\r\n\r\n- Internal\r\n- External, invoiceable or\r\n- External, non-invoiceable\r\n\r\nInternal projects are only for internal use, whereas external projects are for other companies and therefore need to be assigned a customer.\r\n\r\nThe distinction between invoiceable and non-invoiceable is whether the costs registered on a project are to be considered billable to the user's customer or not.\r\n\r\nAdditionally, project groups determine whether registrations on a project should have an impact on the financial accounting or not.\r\n\r\n\r\n#### Examples of use cases:\r\n\r\n* Retrieve all project groups;\r\n* Display the available project groups when creating a new project.\r\n\r\n\r\nRelated guide for users: [e-copedia](https://www.e-conomic.dk/support/artikler/opret-en-projektgruppe) (Danish)<details>\n<summary><b>Click to see the list of possible error codes.</b></summary>\n\n| Error Code | Description |\n| ---------- | ----------- |\n|ProjectGroupCannotBeCreatedUpdatedNumberAlreadyExists|Project group cannot be created since the given number already exists.\n|ProjectGroupCannotBeCreatedUpdatedCostDataInvalid|Project group cannot be created or updated. If includeCostPriceInFinance is true, then costAccountOngoingType, costAccountOngoing, costContraAccountOngoing and costAccountClosed are required, otherwise they should be ommited.\n|ProjectGroupCannotBeCreatedUpdatedSalesDataInvalid|Project group cannot be created or updated. If includeSalesPriceInFinance is true, then salesAccountOngoingType, salesAccountOngoing, salesContraAccountOngoing and salesAccountClosed are required, otherwise they should be ommited.\n|ProjectGroupCannotBeCreatedUpdatedAccountDoesNotExist|Project group cannot be created or updated. The account does not exist.\n|ProjectGroupCannotBeCreatedUpdatedAccountIsBarred|Project group cannot be created or updated. The account is barred.\n|ProjectGroupCannotBeCreatedUpdatedAccountIsOfWrongType|Project group cannot be created or updated. The type of the account needs to be either `Balance` or `Profit & Loss`.\n</details>\n\n**Required application roles:** ProjectEmployee or SuperUser [[More info]](https://www.e-conomic.com/developer/permissions)\n","name":"Project Groups","x-error-codes":["ProjectGroupCannotBeCreatedUpdatedNumberAlreadyExists","ProjectGroupCannotBeCreatedUpdatedCostDataInvalid","ProjectGroupCannotBeCreatedUpdatedSalesDataInvalid","ProjectGroupCannotBeCreatedUpdatedAccountDoesNotExist","ProjectGroupCannotBeCreatedUpdatedAccountIsBarred","ProjectGroupCannotBeCreatedUpdatedAccountIsOfWrongType"],"x-required-roles":["ProjectEmployee","SuperUser"]},{"description":"<code>Time entries</code> endpoints allow for the registration of time spent working on a certain activity on a given project.<br>\r\nUntil they are approved, time entries are only considered drafts and can be edited or deleted.\r\n\r\n#### Examples of use cases:\r\n\r\n* Retrieve all time entries registered on a project;\r\n* Create new time entries;\r\n* Approve the time entries that meet all requirements (e.g. date is within a valid accounting year and there is no recording rule to prevent registration on the selected activity or project).\r\n\r\n\r\nRelated guide for users: [e-copedia](https://www.e-conomic.dk/support/artikler/tidsregistrering) (Danish)\r\n<details>\n<summary><b>Click to see the list of possible error codes.</b></summary>\n\n| Error Code | Description |\n| ---------- | ----------- |\n|TimeEntryIsApproved|Time entry is already approved.\n|TimeEntryOnBarredProjectCannotBeApproved|Time entry cannot be approved since the project has been barred.\n|CannotCreateUpdateActivityNotFound|Time entry cannot be created or updated since the provided activity was not found.\n|CannotCreateUpdateActivityIsBarred|Time entry cannot be created or updated since the provided activity is barred.\n|CannotCreateUpdateActivityNotPartOfProject|Time entry cannot be created or updated since the provided activity is not part of the provided project.\n|TimeEntryIsNotInAccountingPeriod|Time entry is not in a valid accounting period.\n|TimeEntryCannotBeCreatedUpdatedOrApprovedAccountingPeriodIsBarredOrClosed|Time entry cannot be created, updated or approved, it is in an accounting period that is either barred or closed.\n|TimeEntryCannotBeCreatedUpdatedOrApprovedAccountingPeriodIsClosed|Time entry cannot be created, updated or approved, it is in a closed accounting period.\n|TimeEntryCannotBeApprovedNotFound|Time entry cannot be approved since it was not found.\n|TimeEntryCannotBeUpdatedAlreadyApproved|Time entry cannot be updated or deleted since it is approved.\n|TimeEntryCannotBeCreatedUpdatedDateIsNotSet|Time entry cannot be created or updated, date must be set and be greater than minimum date.\n|TimeEntryNumberListCannotBeEmpty|List of time entries cannot be empty.\n|TimeEntryApprovalFailedBaseCurrencyIsNotSet|Time entry cannot be approved since the company base currency has not been set.\n|TimeEntryCannotBeCreatedUpdatedForCompletedActivity|Time entry cannot be created or updated since the activity is completed.\n|TimeEntryCannotBeCreatedUpdatedForActivityThatHasntStarted|Time entry cannot be created or updated since the activity has not started yet.\n|EmployeeHasNoAccessToProject|Employee has no access to the provided project.\n|EmployeeHasNoAccessToActivity|Employee has no access to the provided activity.\n|EntriesNotAllowedProjectNotFound|Entries not allowed on an inexistent project.\n|EntriesNotAllowedProjectIsMain|Entries not allowed on a main project.\n|EntriesNotAllowedProjectIsClosed|Entries not allowed on a closed project.\n|EntriesNotAllowedProjectIsBarred|Entries not allowed on a barred project.\n|EntriesNotAllowedEmployeeNotFound|Entries not allowed because the given employee was not found.\n|EntriesNotAllowedEmployeeIsBarred|Entries not allowed because the given employee is barred.\n|CannotBeApprovedEmployeeNotFound|Entry cannot be approved since employee was not found.\n|CannotBeApprovedEmployeeIsBarred|Entry cannot be approved since employee is barred.\n|CannotBeApprovedActivityNotFound|Entry cannot be approved since activity was not found.\n|CannotBeApprovedActivityIsBarred|Entry cannot be approved since activity is barred.\n|CannotBeApprovedForCompletedActivity|Entry cannot be approve