> This page is for Firmware, version 4.0 (default).
> For other versions, use one of these documentation indexes:
> - 4.0 (default): https://docs.ouster.com/sensor-docs/firmware/4.0/llms.txt
> - 3.2: https://docs.ouster.com/sensor-docs/firmware/3.2/llms.txt

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

# Set configuration parameters

POST http://os-992244000006.local/api/v1/sensor/config
Content-Type: application/json

Multiple configuration parameters can be set at one time using this command. All of the specified sensor configuration parameters must be set successfully for the POST request to succeed, otherwise none of the specified sensor configuration parameters will be configured, and an error will be returned.

To stage a custom profile, set `udp_profile_lidar` to `CUSTOM` and include `udp_profile_lidar_custom`. Use `POST /sensor/custom_profile/validation` for live validation before staging.

__Note:__ After `POST /api/v1/sensor/config` request is received successfully, the sensor will reinitialize automatically to make the new configuration active, and the config settings are persisted across power cycles.

Reference: https://docs.ouster.com/sensor-docs/firmware/api-reference/ouster-http-api/sensor-metadata/post-config

## Request

### Query parameters

- `target` (enum, optional, default: persisted) — Specifies which configuration target to set: * `staged`: Updates the configuration for incremental validation without committing the changes to hardware. The staged configuration will be committed when the `active` or `persisted` target is specified **Note:** Parameters will be range checked, but will not be validated for mutual compatibility until the configuration is made active * `active`: Commits the staged configuration to hardware * `persisted`: Equivalent to `active` but saves the configuration to non-volatile memory if it passes validation * `active_persisted`: Saves **only** the running configuration to non-volatile memory. Changes that were staged, but not made `active` or `persisted`, are lost.
  - Allowed values: `active`, `staged`, `persisted`, `active_persisted`

### Body (application/json)

This endpoint expects a Config.

- `accel_fsr` (enum, optional) — Refers to the Full Scale Range of the accelerometer
  - Allowed values: `NORMAL`, `EXTENDED`
- `azimuth_window` (list of integer, optional, default: [0,360000]) — Set the visible region of interest of the sensor in millidegrees. Only data from within the specified azimuth window bounds is sent. The value should be provisioned as: [__min_bound_millideg__, __max_bound_millideg__]
- `bloom_reduction_optimization` (enum, optional, default: BALANCED) — Configure the bloom reduction algorithm's optimization level. This parameter controls the tradeoff between false positives and false negatives in bloom reduction.
  - Allowed values: `BALANCED`, `MINIMIZE_FALSE_POSITIVES`
- `columns_per_packet` (integer, optional, default: 16) — Determines the columns per packet, this parameter is read-only.
- `gyro_fsr` (enum, optional) — Refers to the Full Scale Range of the gyro
  - Allowed values: `NORMAL`, `EXTENDED`
- `imu_packets_per_frame` (enum, optional, default: 8) — IMU packets per frame
  - Allowed values: `1`, `2`, `4`, `8`
- `lidar_frame_azimuth_offset` (integer, optional, default: 0) — Set the rotational offset of the lidar coordinate frame in millidegrees. This parameter allows for angular alignment shifts of the entire lidar coordinate frame, including the starting angle of the first column. As an example, setting lidar_frame_azimuth_offset to 90000 will result in a 90° counter-clockwise rotation of the lidar coordinate frame about the shared Y axis of the stationary sensor coordinate frame. This results in the measurement frame starting at sensor coordinate frame azimuth 270°. All other lidar coordinate frame parameters (such as azimuth_window and phase_lock_offset) are applied relative to this offset.
- `lidar_mode` (enum, optional, default: 1024x10) — The horizontal resolution and rotation rate of the sensor. The effective range of the sensor is increased by 15-20% for every halving of the number of points gathered e.g. `512x10` has 15-20% longer range than `512x20`.
  - Allowed values: `1024x10`, `512x10`, `2048x10`, `512x20`, `1024x20`
- `min_range_threshold_cm` (enum, optional, default: 50) — Set `0`, `30`, or `50` centimeters to change the sensor's minimum reported range. Points below the configured minimum range will not be reported. In Short Range mode, only `30` or `50` are permitted. __Note:__ When `min_range_threshold_cm` is set to 30 or less, Ouster recommends setting `return_order` to `FARTHEST_TO_NEAREST`.
  - Allowed values: `0`, `30`, `50`
- `multipurpose_io_mode` (enum, optional, default: OFF) — Configure the mode of the `MULTIPURPOSE_IO` pin. Refer to the Time Synchronization section in the Firmware user manual for a detailed description of each option.
  - Allowed values: `OFF`, `INPUT_NMEA_UART`, `OUTPUT_FROM_INTERNAL_OSC`, `OUTPUT_FROM_SYNC_PULSE_IN`, `OUTPUT_FROM_PTP_1588`, `OUTPUT_FROM_ENCODER_ANGLE`, `ZONE_MONITOR_OVER_OSSD`, `ZONE_MONITOR_OVER_GPIO`
- `ossd_restart_mode` (enum, optional, default: INTERLOCK) — Controls how OSSD recovers after the condition that tripped it (for example a Zone Monitor infringement) clears. * `INTERLOCK` - OSSD remains deasserted until a manual reset. * `AUTOMATIC` - after `ossd_restart_delay_s` of continuous clear, clear all OSSD fault latches and re-run startup / BIST. Persistent hardware faults re-trip; cleared faults allow return to operation.
  - Allowed values: `AUTOMATIC`, `INTERLOCK`
- `ossd_restart_delay_s` (integer, optional, default: 2) — Seconds that the OSSD trip source must remain clear before an automatic restart is attempted. Only used when `ossd_restart_mode` is `AUTOMATIC`.
- `nmea_baud_rate` (enum, optional, default: BAUD_9600) — Set the expected baud rate for NMEA UART input `$GPRMC` messages.
  - Allowed values: `BAUD_9600`, `BAUD_115200`
- `nmea_ignore_valid_char` (integer, optional, default: 0) — * `0` - NMEA UART input `$GPRMC` messages should be ignored if valid character is not set * `1` - messages should be used for time syncing regardless of the valid character.
- `nmea_in_polarity` (enum, optional) — Set the polarity of NMEA UART input `$GPRMC` messages. See Time Synchronization section in sensor user manual for NMEA use case. * `ACTIVE_HIGH` - UART is active high, idle low, and start bit is after a falling edge
  - Allowed values: `ACTIVE_HIGH`, `ACTIVE_LOW`
- `nmea_leap_seconds` (integer, optional, default: 0) — Set an integer number of leap seconds that will be added to the UDP timestamp when calculating seconds since 00:00:00 Thursday, 1 January 1970. For Unix Epoch time, this should be set to 0.
- `operating_mode` (enum, optional, default: NORMAL) — * `NORMAL` - put the sensor into a normal operating mode * `STANDBY` - put the sensor into a low power (5W) operating mode where the motor does not spin and lasers do not fire.
  - Allowed values: `NORMAL`, `STANDBY`
- `phase_lock_offset` (integer, optional, default: 0) — Set the angle in the lidar coordinate frame that the sensor locks to, in millidegrees. Angle is traversed at the top of the second. When external time sync is configured (i.e. `TIME_FROM_SYNC_PULSE_IN`, `TIME_FROM_PTP_1588`), the offset aligns motor phase to the external time source. When `timestamp_mode` is `TIME_FROM_INTERNAL_OSC`, this parameter is accepted but note that the sensor is not locked to an external reference.
- `phase_lock_alert_enable` (boolean, optional, default: false) — Enable runtime phase-lock lost alerts (`PHASE_LOCK_LOST`, `PHASE_LOCK_REACQUIRE_FAILED`). The reporting threshold is 36 degrees.
- `return_order` (enum, optional, default: STRONGEST_TO_WEAKEST) — This parameter configures how the lidar returns are ordered. The return order can be set by the user . This parameter applies regardless of the configured `udp_profile_lidar` and can be used to configure the only reported return in single return UDP profiles. __Note:__ When `min_range_threshold_cm` is set to 30 or less, Ouster recommends setting `return_order` to `FARTHEST_TO_NEAREST`.
  - Allowed values: `STRONGEST_TO_WEAKEST`, `NEAREST_TO_FARTHEST`, `FARTHEST_TO_NEAREST`
- `signal_multiplier` (enum, optional, default: 1) — The config parameter signal\_multiplier \<1/2/3> sets the signal multiplier value. For 2x and 3x multipliers, the azimuth\_window \[int, int] parameter sets the azimuth window that the lasers will be enabled in. The higher the signal multiplier value, the smaller the maximum azimuth window can be. | Signal Multiplier Value | Max Azimuth Window | | ----------------------- | ------------------ | | `1` (Default) | 360° | | `2` | 180° | | `3` | 120° | All sensors have equivalent power draw and thermal output when operating at the max azimuth window for a particular signal multiplier value. Therefore, using an azimuth window that is smaller than the maximum allowable azimuth window with a particular signal multiplier value (excluding 1x) can reduce the power draw and thermal output of the sensor. However, while this can increase the max operating temp of the sensor, it can also degrade the performance at low temps. This discrepancy will be resolved in a future firmware.
  - Allowed values: `0.25`, `0.5`, `1`, `2`, `3`
- `sync_pulse_in_polarity` (enum, optional) — Set the polarity of `SYNC_PULSE_IN` input, which controls polarity of `SYNC_PULSE_IN` pin when timestamp_mode is set in `TIME_FROM_SYNC_PULSE_IN`.
  - Allowed values: `ACTIVE_HIGH`, `ACTIVE_LOW`
- `sync_pulse_out_angle` (integer, optional, default: 360) — The angle in terms of degrees that the sensor traverses between each `SYNC_PULSE_OUT` pulse. E.g. a value of 180 means a sync pulse is sent out every 180° for a total of two pulses per revolution and angular frequency of 20 Hz if the sensor is 1024x10 Hz lidar mode. Valid inputs are integers between 0 and 360 inclusive but also limited by the criteria described in the Time Synchronization section of Firmware User Manual.
- `sync_pulse_out_frequency` (integer, optional, default: 1) — The output `SYNC_PULSE_OUT` pulse rate in Hz. Valid inputs are integers >0 Hz, but also limited by the criteria described in the Time Synchronization section of the Firmware User Manual.
- `sync_pulse_out_polarity` (enum, optional) — Set the polarity of polarity of `SYNC_PULSE_OUT` output, if the sensor is set as the master sensor used for time synchronization.
  - Allowed values: `ACTIVE_HIGH`, `ACTIVE_LOW`
- `sync_pulse_out_pulse_width` (integer, optional, default: 10) — Set output `SYNC_PULSE_OUT` pulse width in ms, in 1 ms increments. Valid inputs are integers greater than 0 ms, but also limited by the criteria described in the Time Synchronization section of Software User Manual.
- `timestamp_mode` (enum, optional, default: TIME_FROM_INTERNAL_OSC) — Set the timestamp mode of the sensor. See Time Synchronization section in sensor user manual for details on each mode.
  - Allowed values: `TIME_FROM_INTERNAL_OSC`, `TIME_FROM_SYNC_PULSE_IN`, `TIME_FROM_PTP_1588`
- `udp_dest` (string, optional, default: 192.0.2.133) — UDP destination address for lidar and IMU data. Can be a hostname or IP address. Use @auto to automatically set to the client's IP address.
- `udp_port_imu` (integer, optional, default: 7503) — UDP destination port for IMU data.
- `udp_port_lidar` (integer, optional, default: 7502) — UDP destination port for lidar data.
- `udp_multicast_ttl` (integer, optional, default: 1) — Multicast TTL (Time To Live) for lidar and IMU UDP packets. Valid range is 1-255.
- `udp_dest_zm` (string, optional, default: ) — UDP destination address for Zone Monitor data. Can be a hostname or IP address. Use @auto to automatically set to the client's IP address.
- `udp_port_zm` (integer, optional, default: 0) — UDP destination port for Zone Monitor data.
- `udp_multicast_ttl_zm` (any, optional) — Multicast TTL (Time To Live) for Zone Monitor UDP packets. Valid range is 1-255. type: integer minimum: 1 maximum: 255 default: 1 header_type: description: The configured UDP packet header type $ref:
- `udp_profile_imu` (enum, optional, default: ACCEL32_GYRO32_NMEA) — The configured UDP profile for IMU
  - Allowed values: `ACCEL32_GYRO32_NMEA`
- `udp_profile_lidar` (enum, optional, default: RNG19_RFL8_SIG16_NIR16) — Configure the lidar data profile. When set to `CUSTOM`, the pixel assembler layout is defined by `udp_profile_lidar_custom`. Use `GET /sensor/custom_profile/fields` for field metadata and `POST /sensor/custom_profile/validation` to check a profile before staging.
  - Allowed values: `RNG19_RFL8_SIG16_NIR16`, `RNG19_RFL8_SIG16_NIR16_ZONE16`, `RNG19_RFL8_SIG16_ZONE16_DUAL`, `RNG19_RFL8_SIG16_NIR16_DUAL`, `RNG15_RFL8_NIR8`, `RNG15_RFL8_NIR8_ZONE16`, `RNG15_RFL8_NIR8_DUAL`, `CUSTOM`
- `udp_profile_lidar_custom` (CustomProfile, optional, nullable) — Custom pixel assembler profile used when `udp_profile_lidar` is `CUSTOM`. Validated via `POST /sensor/custom_profile/validation`. Derived field properties are available from `GET /sensor/custom_profile/fields`. Returned as a parsed object (not a JSON string) on GET.
- `phase_lock_enable` (boolean, optional, default: false, deprecated) — Deprecated. Rev8 always uses phase control; this parameter has no effect. Use `phase_lock_alert_enable` to control runtime phase-lock lost alerts.

## Response

### 204

Command succeeded

## Errors

### 400 Bad Request Error

Server cannot or will not process the request due to something that is perceived to be a client error.

- `any`

## Types

### CustomProfile

Custom pixel assembler profile defining UDP lidar field layout.

- `n_words` (integer, required) — Number of 32-bit output words in the custom profile.
- `fields` (list of CustomProfileField, required) — Placed fields within the custom profile word layout.

### CustomProfileField

A single placed field in a custom profile. Allowed `view_id` and `variant_id` values are firmware-build-specific; use `GET /sensor/custom_profile/fields` for the authoritative list. `return_index` is required for multi-return data views.

- `view_id` (string, required)
- `offset` (integer, required) — Bit offset from the start of word 0.
- `variant_id` (string, optional)
- `return_index` (integer, optional)

## Examples

**Request**

```json
{}
```

**SDK Code**

```python
import requests

url = "http://os-992244000006.local/api/v1/sensor/config"

payload = {}
headers = {"Content-Type": "application/json"}

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

print(response.json())
```

```javascript
const url = 'http://os-992244000006.local/api/v1/sensor/config';
const options = {method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{}'};

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 := "http://os-992244000006.local/api/v1/sensor/config"

	payload := strings.NewReader("{}")

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

	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("http://os-992244000006.local/api/v1/sensor/config")

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

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{}"

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("http://os-992244000006.local/api/v1/sensor/config")
  .header("Content-Type", "application/json")
  .body("{}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'http://os-992244000006.local/api/v1/sensor/config', [
  'body' => '{}',
  'headers' => [
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp
using RestSharp;

var client = new RestClient("http://os-992244000006.local/api/v1/sensor/config");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Content-Type": "application/json"]
let parameters = [] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "http://os-992244000006.local/api/v1/sensor/config")! 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()
```