vPlan is the easiest way to plan and track your work. Get insight and results. This API is available on: https://api.vplan.com/v1
Additional resources:
Look at the playlist below for technical videos about our API.
This API reference contains the documentation for all supported third-party vPlan objects. There are also undocumented endpoints, that are accessible with the API token, these endpoints are used by the application itself. Undocumented endpoints are unsupported for third-party use. These endpoints are subject to change without prior warning.
For every object a data structure table is given, the field description can end with:
The examples below show default requirements and options. This information applies to all endpoints unless explicitly stated otherwise.
The vPlan API supports pagination via the query parameters limit
and offset
.
Example: ?limit=50&offset=150
Limit is the maximum number of records given in a resulting dataset.
Default: 0
Offset is the number of records to be skipped for the resulting dataset
Default: 0
If an offset is larger than the possible items that can be returned for the request, an empty data array will be returned.
The count
property of a resultset can be used to determine how many calls must be made to retrieve all objects.
warning
Currently there is no default for limit, this will change to 100 with a maximum of 1000
For sorting the resulting dataset use the query parameter sort
with the format:
field
:direction
,field
:direction
Example: ?sort=updated_at:desc,name
Colon :
is the separator between the field and the optional sorting order.
Default sorting order is ascending.
Comma ,
can be used to add multiple fields for sorting the dataset
warning
Will only work on main fields of the object and not on fields from included objects
On the list endpoints it is possible to filter the result set given.
To apply a filter use the filter
query parameter with the format:
field
:operator
:value
Example: ?filter=created_at:gt:2020-09-26,and,(id:not:starts_with:0000,or,id:contains:FFFF)
Colon :
is the separator between the field, operator(s) and value.
Comma ,
can be used to combine filter statements by using ,and,
or ,or,
.
Braces (
...)
can be used to group filter statements.
The following operators are supported
operator | description |
---|---|
eq | equal to the given value |
gt | greater than the given value |
gte | greater than or equal to the given value |
lt | lesser than the given value |
lte | lesser than or equal to the given value |
not | negation of the operator that follows it |
contains | has occurrence of the given value |
starts_with | starts with the given value |
end_with | ends with the given value |
warning
Currently the comma , and colon : are not supported within the filter value
The query parameters show
and hide
allow clients to requests a limited set of properties.
In addition to reducing the amount of data transferred, this can be helpful in reducing errors caused by additional features added in a release update.
show
specifies which properties the client will receive.hide
specifies which properties will be removed from the reponse.
Both must contain a comma separated list of properties.
For the properties of the main object this is pretty straigth forward. Subobjects added via eager loading come in 2 flavors:
related object
.property
related objects
.*.property
or related objects
.item #
.property
Please note that * can be used to show or hide all properties of a subobject.
Examples:
As shown in the last example show and hide can be combined this is primarily usefull if you want specific properties from the main object and hide properties from related objects.
When retrieving a List or Single object, the with
query parameter allows to eager load
and retrieve related objects with one call.
It consists of a comma separated list of objects, using the dot . as separator for subobjects.
Example: ?with=attachments,cards.resources
If this example with was performed on the Collection List, It would retrieve every collection, and with every collection its attachments, it would also retrieve all the cards of every collection, and finally it would return every resource from every card of every collection.
The first layer of possible with options are stated with every object in this documentation.
The vPlan API is constantly improving, which means that today's endpoints and features could be replaced or removed in the future.
Within this documentation endpoints, parameters or fields can be flagged as Deprecated.
Newly created integrations should not use anything marked as deprecated.
Existing integrations that use anything marked as deprecated, should alter that part of the integration in the near future, in order to prevent possible future errors.
For deprecated endpoints the API will send a Deprecated
header with a description.
Example: GET v1/collection/detail is deprecated and will be removed in future versions
Integrations are expected to look out for this header, and act accordingly.
Another option is retrieving the API messages.
Almost every object relevant for integrations has a property named external_ref
.
In principal this is not a field vPlan uses it self. However if it has a value the vPlan frontend will block certain manually changes for a user.
The main goal for this property is to provide integrations with a location to store the unique identifier of the source object.
The external_ref has the requirement that it must be unique, within that object. If you try to create an object with an already existing external_ref the vPlan API give an error "HTTP 422 Unprocessable entity", with a description stating "Duplicate entry".
For Orders the unique key is external_ref combined with type and sub_type.
note
Objects that have the archive feature will per default not return archived objects.
Archived objects are not separate from unarchived objects, as such unique constraints still apply, i.e. an "active" or unarchived object cannot have the same value for a unique constraint as an archived object
warning
If in an order type or sub_type is given the value
null
the unique constraint will not be triggered. Use the valuenone
instead.
The RateLimit headers are sent in responses to all the Api-Key or OAuth requests, they contain information about the amount of requests that can be made within the specified time window.
Header | Description |
---|---|
RateLimit-Limit | Maximum number of requests you're permitted to make per time window |
RateLimit-Remaining | Number of requests remaining in the current rate limit window. |
RateLimit-Reset | Time at which the current rate limit window resets in seconds. |
Tips for optimizing an integration:
In the event the request results in an error of any kind, the API will respond with an json error. If you receive any other kind of error there must be a connection issue somewhere down the line.
An error will always be in the following format:
reference required | string <uuid> Error reference, used for support requests |
required | Array of objects (Error) [ items ] |
{- "reference": "6ad5af82-69bb-4e90-892e-45ec76d34954",
- "errors": [
- {
- "code": 10001,
- "message": "string",
- "reference": "6ad5af82-69bb-4e90-892e-45ec76d34954",
- "timestamp": "2020-01-02T11:24:35Z",
- "description": "A description of the error can be found here"
}
]
}
The API will use different HTTP status codes if suitable. The status codes commonly seen within this API, are in the table down below. Please note that this is not a complete list.
HTTP Code | Description | Example occurrences |
---|---|---|
400 | BAD REQUEST | Invalid request given, e.g. limit=-15 as query parameter given |
401 | UNAUTHORIZED | Accesstoken is expired |
403 | FORBIDDEN | Endpoint or action is not permitted |
404 | NOT FOUND | Invalid endpoint, or an object id in request does not exist |
405 | METHOD NOT ALLOWED | Requested method (GET, POST, PUT, DELETE) is not allowed for the the endpoint |
422 | UNPROCESSABLE ENTITY | Validation on the request has failed |
429 | TOO MANY REQUESTS | For more info look at Rate Limits |
500 | INTERNAL SERVER ERROR | An internal error occurred |
Look at Service Unavailable for responses given during maintenance.
The HTTP Status code gives an indication of the kind of error. More detailed information is available in the error message. The error message should be enough to correct the request accordingly.
An error message stating Unknown, indicates an error that is currently not forseen within our API.
Scenario: you try to create an object and receive a 200 Ok response, but the object values are empty or using the default values.
Solution: your request is probably missing or having an invalid Content-Type
header, make sure you provide it accordingly to your request e.g. application/json
A request can result in a 10005 Memory exhausted error.
It is likely that this request has worked in the past, but due to a growing amount of data now results in this error. Our API is unable to handle the large dataset resulting from your request.
The best way to prevent this error is ensure you use a combination of paging, filtering or reducing the amount of included data.
Most of our errors should be self explanatory, in the event of an Unknown error you can send a support request.
On creating an support request please provide the following information:
errors[].reference
from the error responseWhile most of our maintenance is being performed without any downtime. An integration should take in account the following 2 responses:
Code | Description | Note |
---|---|---|
303 | See Other | vPlan Services are not available |
503 | Service Unavailable | A release or maintenance is being performed |
warning
The 303 See Other is a last resort redirect to give a proper unavailable notice page
The location that is given will end up in a HTTP 200 response with normal webpage content instead of json.
An integration should:
- not follow the redirect
- view the request as failed
- and try again later.
{- "errors": [
- {
- "code": 503,
- "message": "Service unavailable",
- "description": "Database is under maintenance",
- "timestamp": "2020-01-02T11:24:35.000Z"
}
]
}
The vPlan API is constantly improving, which means that today's endpoints and features could be replaced or removed in the future.
Where possible and appropriate, the API adds a deprecated header to the response. The API also offers this endpoint to retrieve any messages or warnings recorded during third party requests.
Integrators are expected to review these messages regularly and act accordingly.
sort | |
limit | integer >= 0 Default: 0 Example: limit=50 maximum number of records given, see pagination for more info |
offset | |
filter | string Example: filter=created_at:gt:2020-09-26,and,(id:not:starts_with:0000,or,id:contains:FFFF) used to filter the dataset, see filtering for more info |
show | string Example: show=id,updated_at limit the response to show only specific properties, see slimmed down result for more info |
hide | string Example: hide=created_at,updated_at hide properties from the response, see slimmed down result for more info |
ETag | string <md5> Example: "62a232916ac3a2f395791c108c295e8d" Entity Tag, used for caching |
X-REFERENCE | string <uuid> Example: "05cad843-4214-4537-9010-90a7c3ba91f1" Reference Tag, used for internal tracing and debugging of the request |
id required | string <uuid> /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[8... Unique identifier |
log_level | string Enum: "info" "warning" "error" |
method | string Enum: "GET" "POST" "PUT" "DELETE" used method that caused the message |
endpoint | string used endpoint that caused the message |
query_params | string used query parameters that caused the message |
message_code | string code to categorize the message |
message | string full message with details |
created_at | string <date-time> Creation date / time |
updated_at | string <date-time> Update date / time |
{- "id": "68e5bf7b-c525-4865-a50b-ad7654b8fd12",
- "log_level": "warning",
- "method": "GET",
- "endpoint": "v1/order",
- "query_params": {
- "limit": 2000,
- "with": "item,order_rows"
}, - "message_code": "RESULT_GT_100",
- "message": "limit=2000, greater than max (1000), count 610",
- "created_at": "2020-01-02T11:24:35Z",
- "updated_at": "2020-01-02T11:24:35Z"
}
Within vPlan we divide our objects in basically 3 sections:
The configuration section are objects that are generaly setup at the start and should not change that often. Integrations will probably create a lot of these objects, or otherwise retrieve these objects to use the id's later on.
The third party data section are objects that are pure informational for the front end users. It exists primarily to facilitate integrations to update their data, and give the front end users the option to change values like the title, without losing the original information on screen. Most integrations use these objects to push there plannable objects to vPlan.
The base data section consists of object used in the normal day to day usage of vPlan: Most integrations use these objects to retreive information about the planning and send it back to the original system.
The vPlan API allows for three means of authentication, JWT Token, oAuth 2 or API Key.
API Keys are great for rapid prototyping and easy access.
For increased security, integrations should strive to use OAuth 2, especially if designed for multiple customers.
warning
An API Key is static and gives unsupervised access to an account, to improve security we recommend to replace API Keys at least every 6 months.
Customers will receive reminders advising to replace their API Key.
As stated OAuth does not have this security risk.
In this document the headers are included in the examples, the credentials that need to be filled in this header are replaced with a placeholder {token}
.
A JWT token consists of three parts, a header, a payload and a signature. The signature is created on the server with a specific secret, a user cannot construct a token on its own.
The header contains information about the token (type, signature algorithm). The payload contains information about the user and the validity of the token (username, expiration date, issuer). The signature is a hash created with the defined algorithm in the header, signing the information in the token.
Security Scheme Type | HTTP |
---|---|
HTTP Authorization Scheme | bearer |
Bearer format | "JWT" |
The Api-Key is to be used in combination with X-Api-Env.
The two headers combined can be used as authentication.
Perform the following steps:
Security Scheme Type | API Key |
---|---|
Header parameter name: | X-Api-Key |
Api-Env is to be used in combination with Api-Key
Security Scheme Type | API Key |
---|---|
Header parameter name: | X-Api-Env |
Resources on oAuth:
OAuth 2 Role | Application |
---|---|
Client | Application using this API |
Resource Server | The vPlan API service |
Authorization Server | Most Wanted OAuth 2 Authorization Server |
Resource Owner | The user of the vPlan environment |
To create an app, that users can connect to their vPlan environment, go to https://developer.vplan.com/
Registration of the app provides a client id
and client secret
. This information is specific to the app.
The client secret should never be shared publicly.
Registration requires a redirect URI, this should be the base URI to which all callbacks will be performed, this URI should be publicly accessible.
Security Scheme Type | OAuth2 |
---|---|
authorizationCode OAuth Flow | Authorization URL: https://developer.mostwanted.io/api/v1/oauth/authorize Token URL: https://developer.mostwanted.io/api/v1/oauth/token Scopes: |