vPlan API (v1)

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.

General

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:

  • for informational purposes only
    • this field is not used by vPlan but can be used freely to store extra information, e.g. for filtering
  • reserved for future use
    • this field is not used by vPlan at this moment but can be limited in possible values in the future
  • internally maintained
    • the value is calculated within vPlan and is read-only, the calculation could be async or triggered by an action

The examples below show default requirements and options. This information applies to all endpoints unless explicitly stated otherwise.

Pagination

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

Sorting

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

Filtering

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

Slimmed down result

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:

  1. single subobject, e.g. collection or address for an order
    format: related object.property
  2. list of subobjects, e.g. order_rows
    format: related objects.*.property or related objects.item #.property

Please note that * can be used to show or hide all properties of a subobject.

Examples:

  • v1/order?show=code,type
  • v1/order?hide=created_at,updated_at
  • v1/order?with=collection,order_rows&show=code,type,collection.id,collection.source_type,order_rows.*.id
  • v1/order?with=collection,order_rows&hide=collection.id,collection.source_type,order_rows.*.id
  • v1/order?with=collection,order_rows&show=code,type,collection.id,collection.source_type,order_rows.0.id,order_rows.1.description
  • v1/order?with=collection&show=collection.*&hide=collection.id,collection.source_type
  • v1/order?with=order_rows&show=order_rows.*&hide=order_rows.*.id,order_rows.*.updated_at

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.

Eager loading

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.

Deprecated

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.

External Reference

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.

Unique constraint

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 value none instead.

Rate Limits

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:

  • Use webhooks to be signaled when a certain event is triggered, instead of synchronizing every X minutes
  • Increase the interval between synchronizations, for example every 30 minutes instead of every 10 minutes
  • Create an Order with OrderRows in 1 request instead of separate requests per OrderRow
  • Use Eager loading, for example the Relation or Project info can be included when getting an Order in 1 request
  • Reduce retrieval of data. When an objects needs to be updated or referenced in another call having the information available without having to retrieve it every time can drastically reduce request counts Possible options are:
    • Store vPlan ids
    • Store entire vPlan objects
    • Cache vPlan ids
    • Cache entire vPlan objects

Errors

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": [
    • {
      }
    ]
}

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.

Empty values in created object

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

Memory exhausted

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.

Report an issue

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:

  • value of the errors[].reference from the error response
  • the endpoint of the request
  • the request body
  • the expected result
  • the actual result

Service Unavailable

While 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.

Responses

Response samples

Content type
application/json
{
  • "errors": [
    • {
      }
    ]
}

Retrieve Api Messages

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.

query Parameters
sort
string
Example: sort=updated_at:desc,id

field(s) for sorting the dataset, see sorting for more info

limit
integer >= 0
Default: 0
Example: limit=50

maximum number of records given, see pagination for more info

offset
integer >= 0
Default: 0

the number of records to be skipped, see pagination for more info

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

Responses

Response Headers
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

Response Schema: application/json
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

Response samples

Content type
application/json
{
  • "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"
}

Structure

Within vPlan we divide our objects in basically 3 sections:

  • configuration
  • third party data
  • base data

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.

Authentication

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}.

JwtToken

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"

Api-Key

The Api-Key is to be used in combination with X-Api-Env.

The two headers combined can be used as authentication.

Creating an Api-Key

Perform the following steps:

  • log into vPlan
  • in the menu click on Settings
  • in the menu click on API Keys
  • Click on the ADD KEY button
Security Scheme Type API Key
Header parameter name: X-Api-Key

Api-Env

Api-Env is to be used in combination with Api-Key

Security Scheme Type API Key
Header parameter name: X-Api-Env

Oauth2

Resources on oAuth:

Roles

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

Creating an app

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:

    Get authorization

    In order to create access tokens for a specific vPlan environment, the Resource Owner has to authorize the app to access their vPlan environment.

    To request authorization, the Resource Owner should be redirected to https://developer.mostwanted.io/api/v1/oauth/authorize

    The Resource Owner will be asked to log in to vPlan and allow this app to access the data in his vPlan environment.

    query Parameters
    client_id
    required
    string
    Example: client_id=176b8c0c-be44-4b0a-805f-28252932b48e

    Client ID of the app

    redirect_uri
    required
    string
    Example: redirect_uri=https://example.com/callback

    A valid, TLS secured, redirect URI

    response_type
    required
    string
    Value: "code"

    Response type for the request

    state
    string
    Example: state=33cab0a8-ea0c-48e4-a090-71e9b95ab831

    Unique state, to prevent man-in-the-middle attacks

    Responses

    Response samples

    Content type
    application/json
    {
    • "errors": [
      • {
        }
      ]