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

# Firmware update Trays

PATCH https://nico-rest-api.nico.svc.cluster.local/v2/org/{org}/nico/tray/firmware
Content-Type: application/json

Update firmware on Trays with optional filters. If no filter is specified, targets all trays in the Site.

**Filter constraints:**
- `rackId` and `rackName` are mutually exclusive
- `rackId`/`rackName` cannot be combined with `ids`/`componentIds` (rack-level vs component-level targeting)
- `componentIds` requires `type` to be specified

Org must have an Infrastructure Provider entity. User must have authorization role with `PROVIDER_ADMIN` suffix.

Reference: https://docs.nvidia.com/infra-controller/infra-controller/rest-api-reference/api-reference/tray/firmware-update-trays

## OpenAPI Specification

```yaml
openapi: 3.1.0
info:
  title: NVIDIA Infra Controller REST API
  version: 1.0.0
paths:
  /v2/org/{org}/nico/tray/firmware:
    patch:
      operationId: firmware-update-trays
      summary: Firmware update Trays
      description: >-
        Update firmware on Trays with optional filters. If no filter is
        specified, targets all trays in the Site.


        **Filter constraints:**

        - `rackId` and `rackName` are mutually exclusive

        - `rackId`/`rackName` cannot be combined with `ids`/`componentIds`
        (rack-level vs component-level targeting)

        - `componentIds` requires `type` to be specified


        Org must have an Infrastructure Provider entity. User must have
        authorization role with `PROVIDER_ADMIN` suffix.
      tags:
        - subpackage_tray
      parameters:
        - name: org
          in: path
          description: Name of the Org
          required: true
          schema:
            type: string
        - name: Authorization
          in: header
          description: >-
            ```

            export JWT_BEARER_TOKEN="<jwt-bearer-token>"


            # Example org name: "acme-inc

            export ORG_NAME=<org-name>


            # Use the JWT bearer token in your API request auth header:

            curl -v -X GET -H "Content-Type: application/json" -H
            "Authorization: Bearer $JWT_BEARER_TOKEN"
            https://nico-rest-api.nico.svc.cluster.local/v2/org/$ORG_NAME/nico/user/current

            ```
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FirmwareUpdateResponse'
        '400':
          description: Error response when request data cannot be validated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NICoAPIError'
        '403':
          description: >-
            Error response when user is not authorized to call an endpoint or
            retrieve/modify objects
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NICoAPIError'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchTrayFirmwareUpdateRequest'
servers:
  - url: https://nico-rest-api.nico.svc.cluster.local
    description: Kubernetes Cluster
components:
  schemas:
    TrayFilterType:
      type: string
      enum:
        - compute
        - switch
        - powershelf
      description: Filter by tray type
      title: TrayFilterType
    TrayFilter:
      type: object
      properties:
        rackId:
          type: string
          format: uuid
          description: Filter by Rack ID
        rackName:
          type: string
          description: Filter by Rack name
        type:
          $ref: '#/components/schemas/TrayFilterType'
          description: Filter by tray type
        componentIds:
          type: array
          items:
            type: string
          description: Filter by component ID. Requires 'type'.
        ids:
          type: array
          items:
            type: string
            format: uuid
          description: Filter by tray UUID
        slotId:
          type: integer
          description: >-
            Restrict to trays at this rack slot (matches `position.slotId`).
            Requires `rackId` or `rackName`. Composes with the rest of the
            filter via AND.
      description: >-
        Filter criteria for selecting trays in batch operations. If omitted or
        empty, all trays in the site are targeted.


        Constraints: `rackId` and `rackName` are mutually exclusive.
        `rackId`/`rackName` cannot be combined with `ids`/`componentIds`.
        `componentIds` requires `type`. `slotId` requires `rackId` or
        `rackName`, must be >= 0, and composes with the rest of the filter via
        AND.
      title: TrayFilter
    BatchTrayFirmwareUpdateRequestTargetsItems:
      type: string
      enum:
        - bmc
        - cpld
        - bios
        - nvos
        - pmc
        - psu
      title: BatchTrayFirmwareUpdateRequestTargetsItems
    BatchTrayFirmwareUpdateRequest:
      type: object
      properties:
        siteId:
          type: string
          format: uuid
          description: ID of the Site
        filter:
          $ref: '#/components/schemas/TrayFilter'
        version:
          type:
            - string
            - 'null'
          description: Target firmware version.
        targets:
          type: array
          items:
            $ref: '#/components/schemas/BatchTrayFirmwareUpdateRequestTargetsItems'
          description: >-
            Optional subset of firmware targets to update within each matched
            tray.

            Names are lowercase and select sub-parts of the tray

            (BMC, BIOS, etc.). The accepted set per tray type comes from

            the Flow service's NICo proto bindings (which mirror Core's

            per-tray-type enums in `NICo-core/crates/rpc/proto/forge.proto`),

            so the supported values track Core as new sub-parts are added:
              - switch trays (NvSwitchComponent): currently bmc, cpld, bios, nvos
              - powershelf trays (PowerShelfComponent): currently pmc, psu
              - compute trays (ComputeTrayComponent): currently bmc, bios
                (currently NOT honored end-to-end: the NICo compute-firmware
                path goes through SetFirmwareUpdateTimeWindow + auto-update,
                which has no per-target selection; the request is logged
                and the whole bundle is applied. Will be honored once
                compute moves to UpdateComponentFirmware.)
            Omitted or empty means "update everything in the bundle"

            (the historical default). Unknown names are rejected.

            Requires `version` to be set.
        ruleId:
          type: string
          format: uuid
          description: |-
            Optional Operation Rule UUID. When set, pins every task spawned by
            this batch to the named rule and overrides Flow's default rule
            resolution.
      required:
        - siteId
      description: Request body for batch tray firmware update operations
      title: BatchTrayFirmwareUpdateRequest
    FirmwareUpdateResponse:
      type: object
      properties:
        taskIds:
          type: array
          items:
            type: string
            format: uuid
          description: List of task IDs created for the firmware update operation
      description: Response for firmware update operations containing task IDs for tracking
      title: FirmwareUpdateResponse
    NiCoApiErrorSource:
      type: string
      enum:
        - nico
      description: Source of the error.
      title: NiCoApiErrorSource
    NiCoApiErrorData:
      type: object
      properties: {}
      description: Additional data about the error
      title: NiCoApiErrorData
    NICoAPIError:
      type: object
      properties:
        source:
          $ref: '#/components/schemas/NiCoApiErrorSource'
          description: Source of the error.
        message:
          type: string
          description: Message describing the error
        data:
          oneOf:
            - $ref: '#/components/schemas/NiCoApiErrorData'
            - type: 'null'
          description: Additional data about the error
      description: Describes the error response from NVIDIA Infra Controller REST API
      title: NICoAPIError
  securitySchemes:
    JWTBearerToken:
      type: http
      scheme: bearer
      description: >-
        ```

        export JWT_BEARER_TOKEN="<jwt-bearer-token>"


        # Example org name: "acme-inc

        export ORG_NAME=<org-name>


        # Use the JWT bearer token in your API request auth header:

        curl -v -X GET -H "Content-Type: application/json" -H "Authorization:
        Bearer $JWT_BEARER_TOKEN"
        https://nico-rest-api.nico.svc.cluster.local/v2/org/$ORG_NAME/nico/user/current

        ```

```

## Examples

### example-1



**Request**

```json
undefined
```

**Response**

```json
{
  "taskIds": [
    "550e8400-e29b-41d4-a716-446655440000"
  ]
}
```

**SDK Code**

```python example-1
import requests

url = "https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware"

headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.patch(url, headers=headers)

print(response.json())
```

```javascript example-1
const url = 'https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: undefined
};

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

```go example-1
package main

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

func main() {

	url := "https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware"

	req, _ := http.NewRequest("PATCH", url, nil)

	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 example-1
require 'uri'
require 'net/http'

url = URI("https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware")

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

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'

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

```java example-1
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp example-1
using RestSharp;

var client = new RestClient("https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
```

```swift example-1
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]

let request = NSMutableURLRequest(url: NSURL(string: "https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers

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()
```

### all-trays-latest



**Request**

```json
{
  "siteId": "550e8400-e29b-41d4-a716-446655440000"
}
```

**Response**

```json
{
  "taskIds": [
    "550e8400-e29b-41d4-a716-446655440000"
  ]
}
```

**SDK Code**

```python all-trays-latest
import requests

url = "https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware"

payload = { "siteId": "550e8400-e29b-41d4-a716-446655440000" }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript all-trays-latest
const url = 'https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"siteId":"550e8400-e29b-41d4-a716-446655440000"}'
};

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

```go all-trays-latest
package main

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

func main() {

	url := "https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware"

	payload := strings.NewReader("{\n  \"siteId\": \"550e8400-e29b-41d4-a716-446655440000\"\n}")

	req, _ := http.NewRequest("PATCH", 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 all-trays-latest
require 'uri'
require 'net/http'

url = URI("https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware")

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

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"siteId\": \"550e8400-e29b-41d4-a716-446655440000\"\n}"

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

```java all-trays-latest
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"siteId\": \"550e8400-e29b-41d4-a716-446655440000\"\n}")
  .asString();
```

```php all-trays-latest
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware', [
  'body' => '{
  "siteId": "550e8400-e29b-41d4-a716-446655440000"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp all-trays-latest
using RestSharp;

var client = new RestClient("https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"siteId\": \"550e8400-e29b-41d4-a716-446655440000\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift all-trays-latest
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["siteId": "550e8400-e29b-41d4-a716-446655440000"] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
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()
```

### filtered-with-version



**Request**

```json
{
  "siteId": "550e8400-e29b-41d4-a716-446655440000",
  "filter": {
    "rackId": "660e8400-e29b-41d4-a716-446655440001"
  },
  "version": "24.11.0"
}
```

**Response**

```json
{
  "taskIds": [
    "550e8400-e29b-41d4-a716-446655440000"
  ]
}
```

**SDK Code**

```python filtered-with-version
import requests

url = "https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware"

payload = {
    "siteId": "550e8400-e29b-41d4-a716-446655440000",
    "filter": { "rackId": "660e8400-e29b-41d4-a716-446655440001" },
    "version": "24.11.0"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript filtered-with-version
const url = 'https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"siteId":"550e8400-e29b-41d4-a716-446655440000","filter":{"rackId":"660e8400-e29b-41d4-a716-446655440001"},"version":"24.11.0"}'
};

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

```go filtered-with-version
package main

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

func main() {

	url := "https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware"

	payload := strings.NewReader("{\n  \"siteId\": \"550e8400-e29b-41d4-a716-446655440000\",\n  \"filter\": {\n    \"rackId\": \"660e8400-e29b-41d4-a716-446655440001\"\n  },\n  \"version\": \"24.11.0\"\n}")

	req, _ := http.NewRequest("PATCH", 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 filtered-with-version
require 'uri'
require 'net/http'

url = URI("https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware")

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

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"siteId\": \"550e8400-e29b-41d4-a716-446655440000\",\n  \"filter\": {\n    \"rackId\": \"660e8400-e29b-41d4-a716-446655440001\"\n  },\n  \"version\": \"24.11.0\"\n}"

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

```java filtered-with-version
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"siteId\": \"550e8400-e29b-41d4-a716-446655440000\",\n  \"filter\": {\n    \"rackId\": \"660e8400-e29b-41d4-a716-446655440001\"\n  },\n  \"version\": \"24.11.0\"\n}")
  .asString();
```

```php filtered-with-version
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware', [
  'body' => '{
  "siteId": "550e8400-e29b-41d4-a716-446655440000",
  "filter": {
    "rackId": "660e8400-e29b-41d4-a716-446655440001"
  },
  "version": "24.11.0"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp filtered-with-version
using RestSharp;

var client = new RestClient("https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"siteId\": \"550e8400-e29b-41d4-a716-446655440000\",\n  \"filter\": {\n    \"rackId\": \"660e8400-e29b-41d4-a716-446655440001\"\n  },\n  \"version\": \"24.11.0\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift filtered-with-version
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "siteId": "550e8400-e29b-41d4-a716-446655440000",
  "filter": ["rackId": "660e8400-e29b-41d4-a716-446655440001"],
  "version": "24.11.0"
] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://nico-rest-api.nico.svc.cluster.local/v2/org/org/nico/tray/firmware")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
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()
```