> ## Documentation Index
> Fetch the complete documentation index at: https://docs.basaltic.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration sets and suppressions

> Control sending, engagement tracking, dedicated IP selection, and suppression exceptions.

A configuration set applies optional delivery settings to messages that select it.
It does not change the verified identity required for sending.

## Create and apply a configuration set

<Tabs>
  <Tab title="Console">
    Open Email and **Configuration sets**, then click **Create configuration set**.
    Open the set to change sending, tracking, IP pool, and suppression overrides.
  </Tab>

  <Tab title="API">
    Send `POST /v1/configuration-sets`:

    ```json theme={null}
    {"name":"transactional","sending_enabled":true,"tags":{"environment":"production"}}
    ```

    Then send `PATCH /v1/configuration-sets/{configuration_set_id}`:

    ```json theme={null}
    {"tracking_open":true,"tracking_click":true,"ip_pool":"transactional"}
    ```

    Add `"configuration_set":"transactional"` to each send request that should
    use these settings.
  </Tab>

  <Tab title="CLI">
    Save the JSON requests from the API tab, in order, as `request-1.json`, `request-2.json`. Set `CONFIGURATION_SET_ID` to the resource UUID. Use your configured account and region.

    ```bash theme={null}
    basaltic email configuration-set create --from-file request-1.json
    basaltic email configuration-set update "$CONFIGURATION_SET_ID" --from-file request-2.json
    ```
  </Tab>

  <Tab title="Go">
    Save the JSON requests from the API tab, in order, as `request-1.json`, `request-2.json`. Set `CONFIGURATION_SET_ID` to the resource UUID. Configure credentials, account, and region through the SDK environment variables.

    ```go theme={null}
    package main

    import (
    	"context"
    	"encoding/json"
    	"fmt"
    	"os"

    	basaltic "github.com/basaltic-sh/sdk-go"
    	"github.com/basaltic-sh/sdk-go/email"
    )

    func readJSON(path string, value any) error {
    	data, err := os.ReadFile(path)
    	if err != nil {
    		return err
    	}
    	return json.Unmarshal(data, value)
    }

    func run() error {
    	ctx := context.Background()
    	cfg, err := basaltic.NewConfig(ctx)
    	if err != nil {
    		return err
    	}
    	client := email.New(cfg)
    	var request1 email.CreateConfigurationSetRequest
    	if err := readJSON("request-1.json", &request1); err != nil {
    		return err
    	}
    	result1, err := client.CreateConfigurationSet(ctx, &request1)
    	if err != nil {
    		return err
    	}
    	fmt.Printf("%+v\n", result1)
    	var request2 email.UpdateConfigurationSetRequest
    	if err := readJSON("request-2.json", &request2); err != nil {
    		return err
    	}
    	result2, err := client.UpdateConfigurationSet(ctx, os.Getenv("CONFIGURATION_SET_ID"), &request2)
    	if err != nil {
    		return err
    	}
    	fmt.Printf("%+v\n", result2)
    	return nil
    }

    func main() {
    	if err := run(); err != nil {
    		fmt.Fprintln(os.Stderr, err)
    		os.Exit(1)
    	}
    }
    ```
  </Tab>
</Tabs>

`sending_enabled` defaults to true. Disabling it rejects new sends through that
set. Configuration is applied when a message is accepted, so editing a set does
not rewrite messages already queued.

## Open and click tracking

Tracking applies to HTML messages. Text-only messages are unchanged. Open
tracking adds a pixel; click tracking rewrites eligible links to record a visit
before redirecting. Recipient mail clients load these URLs automatically; they
are not management APIs for SDK or CLI use.

Opens and clicks measure recorded requests. Image blocking, mail proxies,
security scanners, and repeated visits affect these counts. Do not interpret
an open as proof that a person read the message. Aggregate events appear in
[Telemetry metrics](/email/metrics); per-message engagement retains diagnostic
counts and timestamps within its event-retention window.

## Pool assignment and nullable updates

`ip_pool` in a response is a ResourceRef with `id`, `crn`, and optional `name`.
On PATCH, omit `ip_pool` to preserve it, send a UUID/name/CRN to change it, or
send `{"ip_pool":null}` to detach it. Empty strings are rejected.

A pool contains account-owned [dedicated IPs](/email/dedicated-ips). If no eligible
IP can be selected, sending falls back to shared platform IPs. The message's
`outbound_ip` records a dedicated address selected for that message.

## Suppression overrides

`suppression_overrides` replaces the entire list when supplied; `[]` removes all
overrides. You can also add or remove a single address through the nested
`/suppression-overrides` endpoints. An override bypasses the account suppression
for that address only on messages using this configuration set.

Automatic suppressions come from bounce and complaint feedback. A manual
suppression uses `POST /v1/suppressions` with `address` and optional description
and expiration. The optional `source_message` response field identifies the
message that caused a suppression. It is not a request selector.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.