## Input/Output

All requests take JSON as input, and return JSON in the response.

All requests return a status code of 200 on success. On most errors, the server will return a 403, with an error structure in the response body. The error structure looks like:

{
code: < @@#error code#errors@@ >,
message: < brief informative message >
}

An additional info or reason attribute might provide more context. None of this information is intended for direct display to the user.

If authentication (see below) is required, but missing or invalid, the server returns a 401. In rare cases, a 500 might be returned for an internal server error of some sort.

## Authentication

All requests require authentication unless the path starts with /no-auth. Authentication is performed by providing an "Authorization" header with the request. The value of the header should be "Bearer <accessToken>", where accessToken is an access token returned by either a response to the @@#confirm#confirm@@ request or the @@#login#login@@ request.

If a 401 is returned with a request, then the credentials provided are invalid and will never work. A new access token must be obtained by performing a @@#login#login@@ request.

## Headers and Versioning

In addition to the Authorization header for requests requiring authentication, all requests should provide the following custom headers on every request:

X-CS-Plugin-IDE: < the IDE issuing the request (eg. "atom", "vscode", etc.) >
X-CS-Plugin-IDE-DETAIL: < Details of the IDE issuing the request (eg. "IntelliJ Idea Ultimate", "Visual Studio 2019 Community", etc.) >
X-CS-Plugin-Version: < the version of the plugin >
X-CS-IDE-Version: < the version of the IDE >

The server will use these values to determine if the plugin version is out-of-date, deprecated, or no longer supported. It will return the following headers in the response:

X-CS-Version-Disposition: < a disposition value, see below >
X-CS-Current-Version: < the current release version for the IDE plugin >
X-CS-Supported-Version: < the earliest supported release version for the IDE plugin; requests from versions earlier than this will not be honored >
X-CS-Preferred-Version: < the minimum preferred release version for the IDE plugin; versions earlier than this are likely to be deprecated in the future >
X-CS-Supported-Agent: < the minimum supported release version of the agent; if the installation has an agent earlier than this, it MUST download an upgrade >
X-CS-Preferred-Agent: < the preferred release version of the agent; if the installation has an agent earlier than this, it SHOULD download an upgrade as soon as possible >

The value of X-CS-Version-Disposition can be one of the following:

unknown - no IDE plugin header was sent with the request, so version information can be determined
unknownIDE - the IDE plugin is not recognized, so no version information is available
unknownVersion - the IDE plugin is recognized, but no version information was found, so no agent compatibility information can be returned
incompatible - if the IDE plugin version is older than X-CS-Supported-Version, requests can not be served until the plugin is upgraded
deprecated - if the IDE plugin version is older than X-CS-Preferred-Version but newer than X-CS-Supported-Version, the plugin version is expected to be deprecated in the future and should be upgraded as soon as possible
outdated - if the IDE plugin version is older than X-CS-Current-Versionn but newer than X-CS-Preferred-Version, the plugin version is not the most recent, but is fully supported
ok - the IDE plugin version matches X-CS-Current-Version, so the plugin is up-to-date

## Directives

When receiving real-time messages through PubNub, or responses to requests, client applications should be prepared to process either full data models, or directives. Directives are transformations to be applied to existing models, rather than a full model. A client application will never see a full model and a transformation to be applied in the same object.
The directives to apply are:
// Set the indicated attributes to the indicated values
$set: {
<attribute1>: <value1>,
<attribute2>: <value2>,
...
}
// Unset (delete) the indicated attributes
$unset: {
<attribute1>: true,
<attribute2>: true,
...
}
// Assuming an attribute is of array type, push the indicated values onto the array; create the array if it doesn't exist; don't add the element if it is already present in the array
$addToSet: {
<arrayAttribute>: [ elem1, elem2, ... ],
<arrayAttribute>: [ elem1, elem2, ... ],
...
}
// Assuming an attribute is of array type, pull the indicated values from the array
$pull: {
<arrayAttribute>: [ elem1, elem2, ... ],
<arrayAttribute>: [ elem1, elem2, ... ],
...
}
Note that all models have a version attribute, which is a numeric value that increments every time there is a transformation on that model. All transformations will have a least a directive to set the model's version number to some value, as indicated by a $set directive. In addition, all transformations will have a $version directive, which looks like:
// Indicates the version of the model before the transformation, and the version of the model after the transformation
$version: {
before: <version before transformation>,
after: <version after transformation>
}
If the version value indicated in $version.before does not match the model the client application currently has, the client application should fetch the model from the server rather than apply the transformation, to ensure transformations are not applied to models mistakenly. Ideally, the fetched version will match the value in $version.after, but might be greater if another transformation has taken place.
Generally, after should usually be greater than before by 1, but in rare cases where two different client applications have modified a model at the same time, this might not be the case.