> This page is for Gateway.

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

# Update DLP Rule

PATCH https://api-gateway.merge.dev/v1/dlp-rules/{rule_id}
Content-Type: application/json

Update the fields you send. Seeded rules accept only `enabled` and
`action`.

Reference: https://docs.merge.dev/merge-gateway/management-api/security-rules/update-dlp-rule

## Authentication

- `Authorization` header (bearer token, required) — A management key (`mgmt_...`), sent as `Authorization: Bearer <key>`. Reading /v1/routing-policies also accepts the organization's gateway API keys; writing there needs a management key.

## Request

### Path parameters

- `rule_id` (string, required) — The rule's `id`.

### Body (application/json)

This endpoint expects a DLPRuleV1Update.

- `action` (enum, optional, nullable) — `log` records a match and sends the prompt unchanged, `redact` replaces each match with a placeholder such as `<US_SSN>` before the prompt is sent, and `block` refuses the request with 422. Omit, or send null, to keep the current value.
  - Allowed values: `log`, `redact`, `block`
- `description` (string, optional, nullable) — Seeded rules accept only enabled and action. Omit, or send null, to keep the current value.
- `enabled` (boolean, optional, nullable) — Omit, or send null, to keep the current value.
- `entity_type` (string, optional, nullable) — The rule's name. Unique among the organization's custom rules. Seeded rules accept only enabled and action. Omit, or send null, to keep the current value. Renaming is refused (409) while project or customer overrides use the current name.
- `keywords` (list of string, optional, nullable) — Seeded rules accept only enabled and action. Send [] to clear them. Omit, or send null, to keep the current value. A custom rule keeps at least one of pattern and keywords.
- `pattern` (string, optional, nullable) — Seeded rules accept only enabled and action. Send "" to clear it. Omit, or send null, to keep the current value. A custom rule keeps at least one of pattern and keywords.

## Response

### 200

The updated DLP rule

- `action` (enum, required) — `log` records a match and sends the prompt unchanged, `redact` replaces each match with a placeholder such as `<US_SSN>` before the prompt is sent, and `block` refuses the request with 422.
  - Allowed values: `log`, `redact`, `block`
- `category` (enum, required) — custom for rules the organization creates; global and usa are seeded.
  - Allowed values: `global`, `usa`, `custom`
- `created_at` (datetime, required) — For a seeded rule never changed, the time of the request.
- `description` (string, required) — What the rule detects.
- `detection_method` (string, required) — How the rule finds matches, like `Pattern match and checksum`.
- `display_name` (string, required) — The name the dashboard shows.
- `enabled` (boolean, required) — Whether the rule scans requests.
- `entity_type` (string, required) — The rule's name. Unique among the organization's custom rules.
- `id` (string, required) — Stable for seeded rules, even before they are first changed.
- `is_seeded` (boolean, required) — Seeded rules can't be created or deleted, only enabled and given an action.
- `keywords` (list of string, required, nullable) — Words the rule matches, if it has any.
- `pattern` (string, required, nullable) — The rule's regular expression, if it has one.
- `updated_at` (datetime, required) — When the rule last changed.

## Errors

### 401 Unauthorized Error

The key is missing or invalid.

- `detail` (ErrorResponseDetail, required) — A message, or an object with a `code` to branch on and a `message`.

### 403 Forbidden Error

The key lacks the scope this route needs, or the change is not allowed.

- `detail` (ErrorResponseDetail, required) — A message, or an object with a `code` to branch on and a `message`.

### 404 Not Found Error

The resource does not exist in the key's organization.

- `detail` (ErrorResponseDetail, required) — A message, or an object with a `code` to branch on and a `message`.

### 409 Conflict Error

The request conflicts with the current state.

- `detail` (ErrorResponseDetail, required) — A message, or an object with a `code` to branch on and a `message`.

### 422 Unprocessable Entity Error

The request is invalid.

- `Update_dlp_ruleRequestUnprocessableEntityError`

### 502 Bad Gateway Error

The gateway could not be updated. Retrying the same request is safe.

- `detail` (ErrorResponseDetail, required) — A message, or an object with a `code` to branch on and a `message`.

## Types

### ErrorResponseDetail

A message, or an object with a `code` to branch on and a `message`.

### HTTPValidationError

- `detail` (list of ValidationError, optional)

### ErrorResponse

The body of an error response.

- `detail` (ErrorResponseDetail, required) — A message, or an object with a `code` to branch on and a `message`.

### ErrorDetail

A structured error. Some carry extra fields, like `count`.

- `code` (string, required) — A stable code to branch on, like `payment_method_required`.
- `message` (string, required) — A human-readable explanation.

### ValidationError

- `loc` (list of ValidationErrorLocItems, required)
- `msg` (string, required)
- `type` (string, required)
- `ctx` (ValidationErrorCtx, optional)
- `input` (any, optional)

### ValidationErrorLocItems

### ValidationErrorCtx

## Examples

**Request**

```json
{
  "action": "block"
}
```

**Response**

```json
{
  "action": "redact",
  "category": "custom",
  "created_at": "2026-06-02T17:04:00Z",
  "description": "Acme order numbers, like ACME-123456.",
  "detection_method": "Custom (regex + keywords)",
  "display_name": "ACME_ORDER_ID",
  "enabled": true,
  "entity_type": "ACME_ORDER_ID",
  "id": "4c8e2a6d-0b3f-4e7a-9d1c-5a7b9e3f2d60",
  "is_seeded": false,
  "keywords": [
    "order",
    "order number"
  ],
  "pattern": "\\bACME-\\d{6}\\b",
  "updated_at": "2026-09-14T09:30:00Z"
}
```

**SDK Code**

```python
import requests

url = "https://api-gateway.merge.dev/v1/dlp-rules/rule_id"

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

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

print(response.json())
```

```javascript
const url = 'https://api-gateway.merge.dev/v1/dlp-rules/rule_id';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"action":"block"}'
};

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://api-gateway.merge.dev/v1/dlp-rules/rule_id"

	payload := strings.NewReader("{\n  \"action\": \"block\"\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
require 'uri'
require 'net/http'

url = URI("https://api-gateway.merge.dev/v1/dlp-rules/rule_id")

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  \"action\": \"block\"\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.patch("https://api-gateway.merge.dev/v1/dlp-rules/rule_id")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"action\": \"block\"\n}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api-gateway.merge.dev/v1/dlp-rules/rule_id', [
  'body' => '{
  "action": "block"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp
using RestSharp;

var client = new RestClient("https://api-gateway.merge.dev/v1/dlp-rules/rule_id");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"action\": \"block\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["action": "block"] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api-gateway.merge.dev/v1/dlp-rules/rule_id")! 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()
```