> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ninjatrader.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ninjatrader.com/_mcp/server.

# Change Plugin Permission

POST https://demo.tradovateapi.com/v1/userPlugin/changepluginpermission
Content-Type: application/json

### Grant or revoke a user's permission for a plugin.

**Available to:** All authenticated users

**Environments:** Live

**[Rate Limit](/api/authentication#request-rate-limits-and-time-penalties):** No endpoint-specific limit

Grants or revokes a user's approval for a named plugin entitlement. Identify the plugin with `pluginName` and set `approval` to `true` to grant the permission or `false` to revoke it. Provide `userId` to change the permission for a specific user; if omitted, the change applies to the calling user.

This is a Live-only endpoint; calling it on Demo returns an environment error directing you to the Live host. The request is forwarded to the licensing service, which applies the change and returns the result.

On success, the response returns with `ok` set to `true` and an empty `errorText`. On a handled failure, `ok` is `false` and `errorText` describes the problem.

**Common Failure Scenarios**

- The endpoint is called on Demo rather than Live (returns an environment error).
- The `userId` doesn't exist or isn't accessible to the caller.
- The licensing service is unavailable or returns an error while applying the change.
- The access token is missing or invalid (returns `HTTP 401`).

**Error Messages**

| `errorText` | Trigger |
|-------------|---------|
| `"This endpoint should be called on live.tradovateapi.com"` | The request was sent to the Demo host. |
| Non-empty `errorText` | The request failed; `ok` is `false` and the field describes the reason. |

Reference: https://docs.ninjatrader.com/api/rest-api-endpoints/users/change-plugin-permission

## OpenAPI Specification

```yaml
openapi: 3.1.0
info:
  title: public
  version: 1.0.0
paths:
  /userPlugin/changepluginpermission:
    post:
      operationId: changePluginPermission
      summary: Change Plugin Permission
      description: >-
        ### Grant or revoke a user's permission for a plugin.


        **Available to:** All authenticated users


        **Environments:** Live


        **[Rate
        Limit](/api/authentication#request-rate-limits-and-time-penalties):** No
        endpoint-specific limit


        Grants or revokes a user's approval for a named plugin entitlement.
        Identify the plugin with `pluginName` and set `approval` to `true` to
        grant the permission or `false` to revoke it. Provide `userId` to change
        the permission for a specific user; if omitted, the change applies to
        the calling user.


        This is a Live-only endpoint; calling it on Demo returns an environment
        error directing you to the Live host. The request is forwarded to the
        licensing service, which applies the change and returns the result.


        On success, the response returns with `ok` set to `true` and an empty
        `errorText`. On a handled failure, `ok` is `false` and `errorText`
        describes the problem.


        **Common Failure Scenarios**


        - The endpoint is called on Demo rather than Live (returns an
        environment error).

        - The `userId` doesn't exist or isn't accessible to the caller.

        - The licensing service is unavailable or returns an error while
        applying the change.

        - The access token is missing or invalid (returns `HTTP 401`).


        **Error Messages**


        | `errorText` | Trigger |

        |-------------|---------|

        | `"This endpoint should be called on live.tradovateapi.com"` | The
        request was sent to the Demo host. |

        | Non-empty `errorText` | The request failed; `ok` is `false` and the
        field describes the reason. |
      tags:
        - Users
      parameters:
        - name: Authorization
          in: header
          description: Bearer authentication
          required: true
          schema:
            type: string
      responses:
        '200':
          description: SimpleResponse
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SimpleResponse'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChangePluginPermission'
servers:
  - url: https://demo.tradovateapi.com/v1
    description: Demo
  - url: https://live.tradovateapi.com/v1
    description: Live
components:
  schemas:
    ChangePluginPermission:
      type: object
      properties:
        userId:
          type: integer
          format: int64
        pluginName:
          type: string
        approval:
          type: boolean
      required:
        - pluginName
        - approval
      title: ChangePluginPermission
    SimpleResponse:
      type: object
      properties:
        errorText:
          type: string
          description: Non-empty if the request failed
        ok:
          type: boolean
      required:
        - ok
      title: SimpleResponse
  securitySchemes:
    bearer_access_token:
      type: http
      scheme: bearer

```

## Examples



**Request**

```json
{
  "pluginName": "string",
  "approval": true
}
```

**Response**

```json
{
  "ok": true,
  "errorText": "string"
}
```

**SDK Code**

```python
import requests

url = "https://demo.tradovateapi.com/v1/userPlugin/changepluginpermission"

payload = {
    "pluginName": "string",
    "approval": True
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://demo.tradovateapi.com/v1/userPlugin/changepluginpermission';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"pluginName":"string","approval":true}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://demo.tradovateapi.com/v1/userPlugin/changepluginpermission"

	payload := strings.NewReader("{\n  \"pluginName\": \"string\",\n  \"approval\": true\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://demo.tradovateapi.com/v1/userPlugin/changepluginpermission")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"pluginName\": \"string\",\n  \"approval\": true\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://demo.tradovateapi.com/v1/userPlugin/changepluginpermission")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"pluginName\": \"string\",\n  \"approval\": true\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://demo.tradovateapi.com/v1/userPlugin/changepluginpermission', [
  'body' => '{
  "pluginName": "string",
  "approval": true
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://demo.tradovateapi.com/v1/userPlugin/changepluginpermission");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"pluginName\": \"string\",\n  \"approval\": true\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "pluginName": "string",
  "approval": true
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://demo.tradovateapi.com/v1/userPlugin/changepluginpermission")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```