Skip to main content

DKIM

You can choose to manage your own keys, or let MailChannels manage your keys for you. If you choose to manage your own keys, you are responsible for creating the key pair, publishing the DNS record, and rotating keys when necessary. If you choose to let MailChannels manage your keys, we manage the keys, and all you have to do is update the DNS. If you want to manage your own keys: include dkim_domain, dkim_selector and dkim_private_key in your API request to send a message. If you want MailChannels to manage your keys: MailChannels generates and stores the private key, and handles the signing process.

Create a key pair

Generate a key pair for your domain. selector is a string that identifies the key and is used in the DNS record and email headers. algorithm defaults to rsa and key_length defaults to 2048. Choose a short, descriptive selector that helps you identify the key, for example “marketing2026” or “transactional20260101”.
#!/usr/bin/env bash
# Create a DKIM key pair managed by MailChannels. The response includes the
# public key and the DNS TXT record to publish.
  set -u
  : "${MAILCHANNELS_API_KEY:?Set MAILCHANNELS_API_KEY before running}"
  : "${DOMAIN:?Set DOMAIN (the sending domain, e.g. example.com)}"
  : "${SELECTOR:?Set SELECTOR (e.g. mc1)}"

curl -X POST "https://api.mailchannels.net/tx/v1/domains/$DOMAIN/dkim-keys" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $MAILCHANNELS_API_KEY" \
  -d @- <<JSON
{
  "selector": "$SELECTOR",
  "algorithm": "rsa",
  "key_length": 2048
}
JSON
The response includes the suggested DNS record under dkim_dns_records:
{
  "domain": "example.com",
  "selector": "mc1",
  "public_key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...",
  "status": "active",
  "algorithm": "rsa",
  "key_length": 2048,
  "created_at": "2026-05-13T18:30:00Z",
  "dkim_dns_records": [
    {
      "name": "mc1._domainkey.example.com",
      "type": "TXT",
      "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
    }
  ]
}

Publish the DNS record

Add the returned TXT record to your domain’s DNS. Receivers fetch this record to verify the DKIM signatures on your mail. Here is an example record: DNS Name: mc1._domainkey.example.com TXT Record value: v=DKIM1; k=rsa; p=public_key_value The format of the record is specified in RFC 6376, section 3.6.1.

Send a message using the managed key

Once you have created a key and published the DNS record, your mail will automatically be signed using that key. If you have multiple keys and want to specify which one to use, include dkim_selector in your send request. See the API reference for more details.
#!/usr/bin/env bash
# Send a message signed with a MailChannels-managed DKIM key. Optionally set
# dkim_selector; the private key stays with MailChannels.

  set -u
  : "${MAILCHANNELS_API_KEY:?Set MAILCHANNELS_API_KEY before running}"
  : "${FROM_EMAIL:?Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)}"
  : "${TO_EMAIL:?Set TO_EMAIL}"
  : "${DKIM_SELECTOR:?Set DKIM_SELECTOR (the selector of an active key)}"

curl -X POST https://api.mailchannels.net/tx/v1/send \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $MAILCHANNELS_API_KEY" \
  -d @- <<JSON
{
  "personalizations": [
    { "to": [{ "email": "$TO_EMAIL" }] }
  ],
  "from": { "email": "$FROM_EMAIL" },
  "subject": "Hello from MailChannels",
  "content": [
    { "type": "text/plain", "value": "Signed with a MailChannels-managed DKIM key." }
  ],
  "dkim_selector": "$DKIM_SELECTOR"
}
JSON

Rotate a key

Rotating a key refers to the process of creating a new key, updating your DNS records, and retiring the old key. This is a security best practice that limits the potential damage if a private key is compromised. MailChannels provides a tool to rotate your DKIM keys. When you rotate a key, a new key pair is generated, and the old key is marked as rotated.
#!/usr/bin/env bash
# Rotate an active DKIM key.
  set -u
  : "${MAILCHANNELS_API_KEY:?Set MAILCHANNELS_API_KEY before running}"
  : "${DOMAIN:?Set DOMAIN (the sending domain, e.g. example.com)}"
  : "${CURRENT_SELECTOR:?Set CURRENT_SELECTOR (the active key to rotate out)}"
  : "${NEW_SELECTOR:?Set NEW_SELECTOR (the selector for the new active key)}"

curl -X POST "https://api.mailchannels.net/tx/v1/domains/$DOMAIN/dkim-keys/$CURRENT_SELECTOR/rotate" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: $MAILCHANNELS_API_KEY" \
  -d @- <<JSON
{
  "new_key": { "selector": "$NEW_SELECTOR" }
}
JSON
The response contains both keys, each with its suggested DNS record:
{
  "new_key": {
    "domain": "example.com",
    "selector": "mc2",
    "public_key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...new...",
    "status": "active",
    "algorithm": "rsa",
    "key_length": 2048,
    "created_at": "2026-05-13T18:30:00Z",
    "dkim_dns_records": [
      {
        "name": "mc2._domainkey.example.com",
        "type": "TXT",
        "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...new..."
      }
    ]
  },
  "rotated_key": {
    "domain": "example.com",
    "selector": "mc1",
    "public_key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...",
    "status": "rotated",
    "algorithm": "rsa",
    "key_length": 2048,
    "status_modified_at": "2026-05-13T18:30:00Z",
    "gracePeriodExpiresAt": "2026-05-16T18:30:00Z",
    "retiresAt": "2026-05-27T18:30:00Z",
    "dkim_dns_records": [
      {
        "name": "mc1._domainkey.example.com",
        "type": "TXT",
        "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
      }
    ]
  }
}
The rotated key remains valid for signing for a 3-day grace period (gracePeriodExpiresAt) and is automatically marked retired 2 weeks after rotation (retiresAt). To avoid signature-verification failures during the cutover:
  1. Publish the new key’s DNS record before updating your send requests to use the new selector.
  2. Leave the rotated key’s DNS record in place until the grace period ends — in-flight mail signed with it still needs the record for verification.
  3. Once the grace period ends, update your send requests to use the new selector. Signing with the old selector will fail after it transitions to retired.