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

# Rotate DKIM Key Pair

> Rotate an active DKIM key pair. Mark the original key as 'rotated', and create a new key pair with the required new key selector, reusing the same algorithm and key length. The rotated key remains valid for signing for a 3-day grace period, and is automatically changed to 'retired' 2 weeks after rotation. Publish the new key to its DNS TXT record before rotated key expires for signing as emails sent with an unpublished key will fail DKIM validation by receiving providers. After the grace period, only the new key is valid for signing if published.



## OpenAPI

````yaml /email-api/api-reference/openapi.yaml post /domains/{domain}/dkim-keys/{selector}/rotate
openapi: 3.0.0
info:
  contact:
    email: support@mailchannels.com
    name: MailChannels Corporation
  description: >
    This is the API reference for Email API. Here, you'll find more detailed
    information on every endpoint, including parameters, response formats, and
    error codes.
  title: Email API
  version: 1.4.0
servers:
  - url: https://api.mailchannels.net/tx/v1
security: []
tags:
  - name: Send
  - name: DKIM
  - name: Metrics
  - name: Sub-accounts
  - name: Suppression
  - name: Webhooks
  - name: Usage
  - name: Custom Tracking
paths:
  /domains/{domain}/dkim-keys/{selector}/rotate:
    post:
      tags:
        - DKIM
      summary: Rotate DKIM Key Pair
      description: >-
        Rotate an active DKIM key pair. Mark the original key as 'rotated', and
        create a new key pair with the required new key selector, reusing the
        same algorithm and key length. The rotated key remains valid for signing
        for a 3-day grace period, and is automatically changed to 'retired' 2
        weeks after rotation. Publish the new key to its DNS TXT record before
        rotated key expires for signing as emails sent with an unpublished key
        will fail DKIM validation by receiving providers. After the grace
        period, only the new key is valid for signing if published.
      parameters:
        - in: path
          name: domain
          required: true
          schema:
            type: string
        - in: path
          name: selector
          required: true
          schema:
            maxLength: 63
            minLength: 1
            type: string
        - in: header
          name: X-Api-Key
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DKIMKeyRotateRequest'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DKIMKeyRotateResponse'
          description: Key pair status updated and new key pair created successfully
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '404':
          description: Specified key pair not found
        '409':
          description: |
            Key pair already created for domain, and provided new key selector.
        '500':
          description: Internal Server Error
        '503':
          description: Temporarily unavailable for maintenance
          headers:
            Retry-After:
              description: |
                Suggested wait time in seconds before retrying.
              schema:
                example: '20'
                type: string
      x-codeSamples:
        - label: Node.js
          lang: javascript
          source: >-
            import { MailChannels } from "mailchannels-sdk";


            const { MAILCHANNELS_API_KEY, DOMAIN, CURRENT_SELECTOR, NEW_SELECTOR
            } = process.env;

            if (!MAILCHANNELS_API_KEY) throw new Error("Set MAILCHANNELS_API_KEY
            before running");

            if (!DOMAIN) throw new Error("Set DOMAIN (the sending domain, e.g.
            example.com)");

            if (!CURRENT_SELECTOR) throw new Error("Set CURRENT_SELECTOR (the
            active key to rotate out)");

            if (!NEW_SELECTOR) throw new Error("Set NEW_SELECTOR (the selector
            for the new active key)");


            const mailchannels = new MailChannels(MAILCHANNELS_API_KEY);


            const { data, error } = await
            mailchannels.domains.dkim.rotate(DOMAIN, CURRENT_SELECTOR, {
              newKey: { selector: NEW_SELECTOR },
            });


            if (error) {
              console.error("Rotate DKIM key failed:", error);
              process.exit(1);
            }

            console.log(data);
        - label: Python
          lang: python
          source: |-
            import os
            import sys

            import mailchannels

            if not os.environ.get("MAILCHANNELS_API_KEY"):
                sys.exit("Set MAILCHANNELS_API_KEY before running")

            domain = os.environ.get("DOMAIN")
            current_selector = os.environ.get("CURRENT_SELECTOR")
            new_selector = os.environ.get("NEW_SELECTOR")
            if not domain:
                sys.exit("Set DOMAIN (the sending domain, e.g. example.com)")
            if not current_selector:
                sys.exit("Set CURRENT_SELECTOR (the active key to rotate out)")
            if not new_selector:
                sys.exit("Set NEW_SELECTOR (the selector for the new active key)")

            response = mailchannels.Dkim.rotate(
                domain,
                current_selector,
                new_selector=new_selector,
            )

            print(response)
        - label: PHP
          lang: php
          source: >-
            <?php


            require_once __DIR__ . '/vendor/autoload.php';


            use MailChannels\Client;


            $api_key          = getenv('MAILCHANNELS_API_KEY') or exit("Error:
            MAILCHANNELS_API_KEY is not set\n");

            $domain           = getenv('DOMAIN') or exit("Error: DOMAIN is not
            set\n");

            $current_selector = getenv('CURRENT_SELECTOR') or exit("Error:
            CURRENT_SELECTOR is not set\n");

            $new_selector     = getenv('NEW_SELECTOR') or exit("Error:
            NEW_SELECTOR is not set\n");


            $client = new Client(apiKey: $api_key);


            $response = $client->dkim->rotate($domain, $current_selector,
            $new_selector);


            print_r($response->toArray());
components:
  schemas:
    DKIMKeyRotateRequest:
      properties:
        new_key:
          $ref: '#/components/schemas/NewKey'
      required:
        - new_key
      type: object
    DKIMKeyRotateResponse:
      properties:
        new_key:
          $ref: '#/components/schemas/DKIMKeyInfo'
        rotated_key:
          $ref: '#/components/schemas/DKIMKeyInfo'
      required:
        - new_key
        - rotated_key
      type: object
    ErrorResponse:
      properties:
        errors:
          description: >
            This is an array error objects that provide machine and human
            readable descriptions of the errors.
          items:
            type: string
          type: array
      type: object
    NewKey:
      properties:
        selector:
          description: Selector for the new key pair
          maxLength: 63
          minLength: 1
          type: string
      required:
        - selector
      type: object
    DKIMKeyInfo:
      properties:
        algorithm:
          description: |
            Algorithm used for the key pair
          type: string
        created_at:
          description: |
            Timestamp when the key pair was created
          format: date-time
          nullable: true
          type: string
        dkim_dns_records:
          description: |
            Suggested DNS records for the DKIM key
          items:
            $ref: '#/components/schemas/DKIMDnsRecord'
          type: array
        domain:
          description: |
            Domain associated with the key pair
          type: string
        gracePeriodExpiresAt:
          description: >
            UTC timestamp after which you can no longer use the rotated key for
            signing
          format: date-time
          nullable: true
          type: string
        key_length:
          description: |
            Key length in bits
          type: integer
        public_key:
          type: string
        retiresAt:
          description: |
            UTC timestamp when a rotated key pair is retired
          format: date-time
          nullable: true
          type: string
        selector:
          description: |
            Selector assigned to the key pair
          type: string
        status:
          enum:
            - active
            - retired
            - revoked
            - rotated
          type: string
        status_modified_at:
          description: |
            Timestamp when the key was last modified
          format: date-time
          nullable: true
          type: string
      required:
        - domain
        - selector
        - public_key
        - status
        - algorithm
      type: object
    DKIMDnsRecord:
      description: |
        Suggested DNS record for the DKIM key
      nullable: true
      properties:
        name:
          type: string
        type:
          example: TXT
          type: string
        value:
          type: string
      required:
        - name
        - type
        - value
      type: object

````