# Update a domain

> PATCH /domains/:id — toggle open and click tracking.

`PATCH /domains/:id`

Updates a domain’s settings. Send any subset of the body fields below; omitted fields are left unchanged. Returns a slim acknowledgement with the domain `id`. Requires a key with full access. See [Open and click tracking](https://www.sendping.co/docs/domains/tracking).

**Body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `open_tracking` | boolean | No | Enable or disable the open-tracking pixel for mail sent from this domain. Applied whenever enabled; the pixel is served from your `tracking_subdomain` when one is configured and verified, otherwise from a shared SendPing-hosted host. |
| `click_tracking` | boolean | No | Enable or disable link rewriting for click tracking on this domain. Applied whenever enabled; rewritten links pass through your `tracking_subdomain` when one is configured and verified, otherwise through a shared SendPing-hosted host. |
| `tracking_subdomain` | string | No | A custom subdomain for click and open tracking (e.g. `links` produces a CNAME for `links.yourdomain.com`). This value can only be changed after it has first been specified, never removed — this preserves links in already-sent email. After changing it, the new DNS record must be verified; until then links use the shared SendPing tracking host, and all previously used records remain active and are included in the response. |
| `tls` | string | No | The domain’s TLS preference. `opportunistic` (default) encrypts the connection when the receiving server supports TLS and otherwise sends unencrypted; `enforced` records a preference that delivery should require TLS. |
| `capabilities` | object | No | Update the domain capabilities. `sending` is always `enabled` and cannot be disabled. Set `receiving` (`enabled` | `disabled`) to toggle whether the domain also receives mail; omitting it keeps the current value. |
| `receiving` | boolean | No | A top-level alias for `capabilities.receiving`. Enabling it adds the Receiving MX record to `records`; disabling removes it. `capabilities.receiving` wins when both are sent. |
| `custom_return_path` | string | No | A new Return-Path (`MAIL FROM`) subdomain label — this is the only supported way to change it after creation. Must be a valid DNS label (letters, digits and hyphens, starting and ending alphanumeric, 63 characters or less); anything else returns a `validation_error`. Changing it re-points MAIL FROM and replaces the SPF MX and TXT records, which must then be published at your DNS provider and re-verified. |
| `custom_tracking` | boolean | No | Turn the custom tracking host on or off. Setting `tracking_subdomain` implies `true`. Setting `false` clears `tracking_domain`, `tracking_subdomain` and `tracking_verified` so new sends fall back to the shared SendPing tracking host — the historical tracking DNS records are retained so links in already-sent mail keep working. |

**Node.js**

```js
import { SendPing } from 'sendping';

const mb = new SendPing('mb_xxxxxxxxx');

const { data, error } = await mb.domains.update('d91a7c4e-1f2b-4a8c-9e3d-7b5f0a2c1d6e', {
  "open_tracking": true,
  "click_tracking": true
});
console.log({ data, error });
```

**Ruby**

```ruby
require "sendping"

SendPing.api_key = "mb_xxxxxxxxx"

SendPing::Domains.update("d91a7c4e-1f2b-4a8c-9e3d-7b5f0a2c1d6e", {
  "open_tracking": true,
  "click_tracking": true
})
```

**PHP**

```php
<?php
require 'vendor/autoload.php';

use SendPing\SendPing;

$sendping = SendPing::client('mb_xxxxxxxxx');

$sendping->domains->update('d91a7c4e-1f2b-4a8c-9e3d-7b5f0a2c1d6e', [
  'open_tracking' => true,
  'click_tracking' => true
]);
```

**Python**

```python
import sendping

sendping.api_key = "mb_xxxxxxxxx"

sendping.Domains.update("d91a7c4e-1f2b-4a8c-9e3d-7b5f0a2c1d6e", {
  "open_tracking": True,
  "click_tracking": True
})
```

**Go**

```go
import "github.com/shekhu10/sendping-sdks/sendping-go"

client := sendping.NewClient("mb_xxxxxxxxx")

updated, err := client.Domains.Update("d91a7c4e-1f2b-4a8c-9e3d-7b5f0a2c1d6e", &sendping.UpdateDomainRequest{
    OpenTracking:  sendping.Bool(true),
    ClickTracking: sendping.Bool(true),
})
```

**Rust**

```rust
use sendping::{SendPing, UpdateDomainOptions};

let mb = SendPing::new("mb_xxxxxxxxx");

let params = UpdateDomainOptions::new()
    .with_open_tracking(true)
    .with_click_tracking(true);
let _updated = mb.domains.update("d91a7c4e-1f2b-4a8c-9e3d-7b5f0a2c1d6e", params).await?;
```

**Java**

```java
import co.sendping.SendPing;
import co.sendping.SendPingResponse;
import co.sendping.requests.UpdateDomainRequest;

SendPing sendping = new SendPing("mb_xxxxxxxxx");

SendPingResponse response = sendping.domains().update(
        "d91a7c4e-1f2b-4a8c-9e3d-7b5f0a2c1d6e",
        UpdateDomainRequest.builder().openTracking(true).clickTracking(true).build());
```

**.NET**

```csharp
using SendPing;

ISendPing sendping = SendPingClient.Create("mb_xxxxxxxxx");

var resp = await sendping.DomainUpdateAsync("d91a7c4e-1f2b-4a8c-9e3d-7b5f0a2c1d6e", new DomainUpdateOptions
{
    OpenTracking = true,
    ClickTracking = true,
});
```

**cURL**

```bash
curl -X PATCH 'https://www.sendping.co/api/domains/d91a7c4e-1f2b-4a8c-9e3d-7b5f0a2c1d6e' \
  -H 'Authorization: Bearer mb_xxxxxxxxx' \
  -H 'Content-Type: application/json' \
  -d '{
  "open_tracking": true,
  "click_tracking": true
}'
```

**CLI**

```bash
sendping domains update d91a7c4e-1f2b-4a8c-9e3d-7b5f0a2c1d6e \
  --open-tracking \
  --click-tracking
```

Response:

```json
{
  "object": "domain",
  "id": "d91a7c4e-1f2b-4a8c-9e3d-7b5f0a2c1d6e"
}
```

> **Note:** The response is a slim acknowledgement with only `object` and `id`. To read the updated domain object, follow up with [`GET /domains/:id`](https://www.sendping.co/docs/api/domains-get).

Errors: `not_found` if the domain does not exist or is not yours, `restricted_api_key` if the key lacks full access. See [Errors](https://www.sendping.co/docs/api/errors).
