openapi: '3.1.0'
info:
  version: '1.6.2'
  title: 'regfish DNS & TLS API'
  description: Manage your Domains, DNS, and TLS certificates
  termsOfService: https://regfish.com/terms
  contact:
    name: API Support
    url: https://regfish.com/docs
    email: support@regfish.com

servers:
  - url: https://api.regfish.com
    description: Production Server

tags:
  - name: Meta
    description: Metadata and API specification endpoints.
  - name: Domains
    description: Customer domain portfolio and registrar metadata.
  - name: DNS
    description: DNS zone and resource record operations.
  - name: TLS
    description: TLS certificate and product operations.

paths:
  /openapi.yaml:
    x-controller: OpenAPISpec
    get:
      tags:
        - Meta
      summary: Download OpenAPI specification
      description: Download the current OpenAPI specification as YAML.
      operationId: DownloadOpenAPISpec
      responses:
        '200':
          description: The current OpenAPI YAML document
          content:
            application/yaml:
              schema:
                type: string
              example: |-
                openapi: '3.1.0'
                info:
                  version: '1.4.0'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /domains:
    x-controller: Domains
    parameters:
      - name: search
        in: query
        required: false
        description: Case-insensitive partial match against the domain name, owner label, or primary nameserver.
        schema:
          type: string
      - name: filter
        in: query
        required: false
        description: Comma-separated list of filters. Supported values are `cancelled` and `dnssec-inactive`.
        schema:
          type: string
      - name: sortBy
        in: query
        required: false
        description: Sort by one of the public response fields listed in `domainListSortKey`.
        schema:
          $ref: '#/components/schemas/domainListSortKey'
      - name: sortOrder
        in: query
        required: false
        schema:
          $ref: '#/components/schemas/sortOrder'
      - name: page
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          default: 1
      - name: pageSize
        in: query
        required: false
        schema:
          type: integer
          enum: [10, 25, 50, 100]
          default: 100
    get:
      tags:
        - Domains
      summary: List customer domains
      description: |
        List registered domains together with key portfolio details such as owner label,
        DNSSEC status, renewal status, and expiry date.

        Supports text search, filtering, sorting, and pagination.
      operationId: ListDomains
      responses:
        '200':
          description: Customer domain list
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/domainListResponse'
        '400':
          description: Invalid query parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /dns/rr/{rrid}:
    x-controller: ResourceRecordsByID
    parameters:
      - name: rrid
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/rrid'
    get:
      tags:
        - DNS
      summary: Get DNS record
      description: Retrieve details about a specific Resource Record (`rrid`).
      operationId: GetRecordByRRID
      responses:
        '200':
          description: The record corresponding to the provided `rrid`
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/recordResponse'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: DNS record not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    patch:
      tags:
        - DNS
      summary: Update DNS record
      description: Update a specific Resource Record (`rrid`). This is useful for modifying the record’s name or type, or when managing multiple records with the same name and type combination.
      operationId: PatchRecordByRRID
      requestBody:
        description: Data object for the record
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/recordRequest'
      responses:
        '200':
          description: The updated record
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/recordResponse'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: DNS record not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '417':
          description: DNS record update violates a zone constraint
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    delete:
      tags:
        - DNS
      summary: Delete DNS record
      description: Delete a specific Resource Record (`rrid`).
      operationId: DeleteRecordByRRID
      responses:
        '200':
          description: The updated record
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: DNS record not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /dns/{domain}/rr:
    parameters:
      - name: domain
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/fqdn_relaxed'
    x-controller: ResourceRecordsByDomain
    get:
      tags:
        - DNS
      summary: Get DNS records
      description: List all DNS records stored in the zone for the specified domain.
      operationId: GetRecordsByDomain
      responses:
        '200':
          description: The record created, with its new ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        type: array
                        items:
                          $ref: '#/components/schemas/recordResponse'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: DNS zone or records not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /dns/zones:
    x-controller: DNSZones
    get:
      tags:
        - DNS
      summary: List DNS zones
      description: List DNS zones with SOA data, delegated nameservers, DNSSEC status, and record counts.
      operationId: ListDNSZones
      responses:
        '200':
          description: DNS zone list
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        type: array
                        items:
                          $ref: '#/components/schemas/dnsZoneSummaryResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /dns/zones/{domain}:
    parameters:
      - name: domain
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/fqdn_relaxed'
    x-controller: DNSZonesByDomain
    get:
      tags:
        - DNS
      summary: Get DNS zone details
      description: |
        Retrieve the complete DNS zone for the specified domain.

        The response includes SOA metadata, delegated nameservers, DNSSEC status,
        record counts, and all records stored in the zone, including `NS` records.
      operationId: GetDNSZoneByDomain
      responses:
        '200':
          description: Detailed DNS zone
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/dnsZoneDetailResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: DNS zone not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /dns/zones/{domain}/export:
    parameters:
      - name: domain
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/fqdn_relaxed'
    x-controller: DNSZoneExportsByDomain
    get:
      tags:
        - DNS
      summary: Export DNS zone as BIND file
      description: |
        Export the specified zone as a BIND-compatible zone file.

        Non-standard `ALIAS` records are included as comments and, when possible,
        as resolved `A` records.
      operationId: ExportDNSZoneBindByDomain
      responses:
        '200':
          description: BIND zone file
          headers:
            Content-Disposition:
              schema:
                type: string
            Cache-Control:
              schema:
                type: string
          content:
            text/plain:
              schema:
                type: string
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: DNS zone not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /dns/rr:
    x-controller: ResourceRecords
    post:
      tags:
        - DNS
      summary: Create DNS record
      description: Create a new DNS record and automatically detect the zone based on the `fqdn` specified in the `name` parameter.
      operationId: AddRecord
      requestBody:
        description: Data object for the record
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/recordRequestFQDN'
      responses:
        '200':
          description: The record created, with its new ID
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/recordResponse'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: No matching DNS zone found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '417':
          description: DNS record creation violates a zone constraint
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
##
    patch:
      tags:
        - DNS
      summary: Update DNS record
      description: Update a DNS record and automatically detect the record based on the `name` and `type` specified in the parameters. If you want to update the `name` or `type` attribute, please refer to the `PATCH /dns/rr/{rrid}` endpoint. 
      operationId: PatchRecord
      requestBody:
        description: Data object for the record
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/recordRequestFQDN'

      responses:
        '200':
          description: The record corresponding to the provided `name`/`type` combination
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/recordResponse'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: No record found for the provided `name`/`type` combination
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '417':
          description: DNS record update violates a zone constraint
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /dns/{domain}/dnssec:
    parameters:
      - name: domain
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/fqdn_relaxed'
    x-controller: DomainDNSSECByDomain
    get:
      tags:
        - DNS
      summary: Get DNSSEC configuration
      description: |
        Retrieve the current DNSSEC configuration and status for the specified domain.

        Important response fields:
        - `desired_state`: the target DNSSEC state
        - `live_state`: the last state observed from the registry and delegation checks
        - `dnssec_state`: high-level status for quick status checks (`active`, `pending`, `inactive`)
        - `pending_job`: the current DNSSEC transition job, if processing is still in progress

        DNSSEC changes can be asynchronous, so `desired_state` and `live_state` may differ temporarily.
      operationId: GetDNSSECByDomain
      responses:
        '200':
          description: DNSSEC configuration
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/dnssecResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Domain not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    put:
      tags:
        - DNS
      summary: Upsert DNSSEC configuration
      description: |
        Enable, disable, or update registry DNSSEC for the specified domain.

        Use `mode=regfish` only when the domain uses regfish authoritative nameservers.
        Use `mode=external` only when DNSSEC data must be supplied for external nameservers.
        Use `mode=none` together with `state=disabled` to disable registry DNSSEC.

        The response may already be final, or it may include a `pending_job` while
        the registry or DNS delegation is still converging.
        If the update cannot be completed, the response returns the last stable DNSSEC state.
      operationId: PutDNSSECByDomain
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/dnssecRequest'
      responses:
        '200':
          description: DNSSEC configuration accepted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/dnssecResponse'
        '400':
          description: Invalid DNSSEC payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Domain not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: DNSSEC cannot be applied in the requested mode or provider state
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '417':
          description: DNSSEC record set is invalid for this TLD or provider
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: Registry-side DNSSEC operation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /dns/{domain}/dnssec/cancel:
    parameters:
      - name: domain
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/fqdn_relaxed'
    x-controller: DomainDNSSECCancelByDomain
    post:
      tags:
        - DNS
      summary: Cancel pending DNSSEC transition
      description: |
        Cancel a currently pending DNSSEC activation or, for regfish-managed nameservers, a pending DNSSEC deactivation.

        If no cancellable transition exists, the request fails with `409`.
      operationId: CancelDNSSECByDomain
      responses:
        '200':
          description: DNSSEC transition cancelled or current stable state returned
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/dnssecResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Domain not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: No cancellable DNSSEC transition exists for this domain or the current transition cannot be rolled back automatically
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /dns/{domain}/dnssec/verify:
    parameters:
      - name: domain
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/fqdn_relaxed'
    x-controller: DomainDNSSECVerifyByDomain
    post:
      tags:
        - DNS
      summary: Verify DNSSEC state
      description: |
        Refresh registry DNSSEC state and verify whether delegation is visible.

        This endpoint is useful after asynchronous registry processing or delayed DS/DNSKEY delegation.
        A successful response can still be `pending` when the target state has not propagated completely yet.
      operationId: VerifyDNSSECByDomain
      responses:
        '200':
          description: DNSSEC verification result
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/dnssecResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Domain not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: DNSSEC verification failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /dns/{domain}/dnssec/jobs:
    parameters:
      - name: domain
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/fqdn_relaxed'
    x-controller: DomainDNSSECJobsByDomain
    get:
      tags:
        - DNS
      summary: List DNSSEC jobs
      description: Retrieve recent registry DNSSEC jobs for the specified domain.
      operationId: ListDNSSECJobsByDomain
      responses:
        '200':
          description: DNSSEC job list
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        type: array
                        items:
                          $ref: '#/components/schemas/dnssecJobResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Domain not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /tls/certificate:
    x-controller: TLSCertificates
    get:
      tags:
        - TLS
      summary: List TLS certificates
      description: List TLS certificates in the current account.
      operationId: ListCertificates
      responses:
        '200':
          description: TLS certificate list
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        type: array
                        items:
                          $ref: '#/components/schemas/tlsCertificateResponse'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    post:
      tags:
        - TLS
      summary: Order or renew TLS certificate
      description: Create a new TLS certificate order or renew an existing certificate. When `renewal_of_certificate_id` is set, `validity_days` still describes the purchased base term. If the provider accepts the renewal, any remaining validity from the previous certificate may be added after issuance. OV and EV-style products can return `action_required=true` together with a `completion_url` when additional organization or validation details are needed before submission.
      operationId: CreateCertificate
      requestBody:
        description: TLS certificate order payload
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/tlsCertificateRequest'
      responses:
        '200':
          description: TLS certificate order created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/tlsCertificateResponse'
              example:
                success: true
                code: 0
                response:
                  id: ABCDEFGHJKM23
                  status: pending
                  common_name: example.com
                  product: RapidSSL
                  provider: digicert
                  dns_names:
                    - www.example.com
                  order_state: PENDING
                  action_required: false
                  pending_reason: validation_pending
                  pending_message: The TLS certificate order is waiting for domain validation.
                  completion_url: ''
                  organization_id: null
                  validity_days: 199
                  certificate_pem_available: false
                  validation:
                    method: dns-cname-token
                    dns_records:
                      - name: _dnsauth.example.com.
                        type: CNAME
                        value: 0123456789abcdef.dcv.digicert.com.
        '400':
          description: Invalid request payload, TLS product, or CSR
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Renewal source TLS certificate not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: The TLS certificate order cannot be submitted in its current state, for example because the renewal is invalid or a usable CA organization is missing
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: Upstream TLS provider error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /tls/products:
    x-controller: TLSProducts
    get:
      tags:
        - TLS
      summary: List TLS products
      description: List available TLS certificate products together with the current account pricing.
      operationId: ListTLSProducts
      responses:
        '200':
          description: TLS product catalog
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        type: array
                        items:
                          $ref: '#/components/schemas/tlsProductResponse'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /tls/organization:
    x-controller: TLSOrganizations
    get:
      tags:
        - TLS
      summary: List TLS organizations
      description: List TLS organizations that can be used for OV and EV certificate orders, including readiness information.
      operationId: ListOrganizations
      responses:
        '200':
          description: TLS organization list
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        type: array
                        items:
                          $ref: '#/components/schemas/tlsOrganizationResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    post:
      tags:
        - TLS
      summary: Create TLS organization
      description: Create a DigiCert-backed TLS organization including the local contact record used for OV or EV certificate ordering.
      operationId: CreateOrganization
      requestBody:
        description: TLS organization payload
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/tlsOrganizationCreateRequest'
      responses:
        '200':
          description: TLS organization created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/tlsOrganizationResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: Upstream TLS provider error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /tls/organization/{organization_id}:
    parameters:
      - name: organization_id
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/tlsOrganizationId'
    x-controller: TLSOrganizationsByID
    get:
      tags:
        - TLS
      summary: Get TLS organization
      description: Retrieve a single DigiCert-backed TLS organization by its public organization id.
      operationId: GetOrganizationByID
      responses:
        '200':
          description: TLS organization details
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/tlsOrganizationResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: TLS organization not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    patch:
      tags:
        - TLS
      summary: Update TLS organization
      description: Update the local TLS organization contact data used for readiness checks and order completion.
      operationId: PatchOrganizationByID
      requestBody:
        description: Partial TLS organization payload
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/tlsOrganizationPatchRequest'
      responses:
        '200':
          description: TLS organization updated
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/tlsOrganizationResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: TLS organization not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /tls/certificate/{certificate_id}:
    parameters:
      - name: certificate_id
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/tlsCertificateId'
    x-controller: TLSCertificatesByID
    get:
      tags:
        - TLS
      summary: Get TLS certificate
      description: Retrieve a single TLS certificate including staged/action-required state, validation details, and provider metadata.
      operationId: GetCertificateByID
      responses:
        '200':
          description: TLS certificate details
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/tlsCertificateResponse'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: TLS certificate not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /tls/certificate/{certificate_id}/complete:
    parameters:
      - name: certificate_id
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/tlsCertificateId'
    x-controller: TLSCertificatesByID
    post:
      tags:
        - TLS
      summary: Complete staged TLS certificate order
      description: Complete an action-required TLS certificate order by binding it to an existing usable DigiCert organization and submitting the provider order.
      operationId: CompleteCertificate
      requestBody:
        description: TLS certificate completion payload
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/tlsCertificateCompleteRequest'
      responses:
        '200':
          description: TLS certificate order completed
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/tlsCertificateResponse'
        '400':
          description: Invalid request payload or stored CSR
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: TLS certificate or referenced renewal source not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: The TLS certificate order cannot be completed in its current state
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: Upstream TLS provider error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /tls/certificate/{certificate_id}/cancel:
    parameters:
      - name: certificate_id
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/tlsCertificateId'
    x-controller: TLSCertificatesByID
    post:
      tags:
        - TLS
      summary: Cancel TLS certificate order
      description: Cancel a pending TLS certificate order. Use `/tls/certificate/{certificate_id}/order-cancel` when an already issued order should be revoked in full.
      operationId: CancelCertificate
      requestBody:
        description: Optional cancellation note
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/tlsCertificateCancelRequest'
      responses:
        '200':
          description: TLS certificate cancellation accepted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/tlsCertificateResponse'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: TLS certificate not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: Only pending TLS certificate orders can be cancelled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: Upstream TLS provider error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /tls/certificate/{certificate_id}/revoke:
    parameters:
      - name: certificate_id
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/tlsCertificateId'
    x-controller: TLSCertificatesByID
    post:
      tags:
        - TLS
      summary: Revoke TLS certificate
      description: Revoke only the currently selected TLS certificate while keeping the order available for later reissue.
      operationId: RevokeCertificate
      requestBody:
        description: Revocation request payload
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/tlsCertificateRevokeRequest'
      responses:
        '200':
          description: TLS certificate revocation accepted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/tlsCertificateResponse'
        '400':
          description: Invalid request or revocation reason
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: TLS certificate not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: The TLS certificate cannot be revoked in its current state
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: Upstream TLS provider error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /tls/certificate/{certificate_id}/order-cancel:
    parameters:
      - name: certificate_id
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/tlsCertificateId'
    x-controller: TLSCertificatesByID
    post:
      tags:
        - TLS
      summary: Cancel or revoke TLS certificate order
      description: Cancel a not-yet-issued order before issuance, or revoke the complete issued order within the first 7 days after ordering. A full revocation invalidates all certificate versions on that order and prevents further reissue.
      operationId: CancelIssuedCertificateOrder
      requestBody:
        description: Optional order cancellation payload
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/tlsCertificateOrderCancelRequest'
      responses:
        '200':
          description: TLS certificate order cancellation accepted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/tlsCertificateResponse'
        '400':
          description: Invalid request or revocation reason
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: TLS certificate not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: The TLS certificate order cannot be cancelled or revoked in its current state
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: Upstream TLS provider error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /tls/certificate/{certificate_id}/reissue:
    parameters:
      - name: certificate_id
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/tlsCertificateId'
    x-controller: TLSCertificatesByID
    post:
      tags:
        - TLS
      summary: Reissue TLS certificate
      description: Reissue an already issued or certificate-revoked TLS certificate with a new CSR while keeping the same order. Optionally, `validity_days` can request a shorter replacement certificate lifetime, but the CA only supports that for eligible multi-year plan orders and never beyond the remaining order contract.
      operationId: ReissueCertificate
      requestBody:
        description: Reissue request payload
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/tlsCertificateReissueRequest'
      responses:
        '200':
          description: TLS certificate reissue accepted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/baseResult'
                  - type: object
                    properties:
                      response:
                        $ref: '#/components/schemas/tlsCertificateResponse'
        '400':
          description: Invalid request payload or CSR
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: TLS certificate not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: The TLS certificate cannot be reissued in its current state
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: Upstream TLS provider error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /tls/certificate/{certificate_id}/download/{format}:
    parameters:
      - name: certificate_id
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/tlsCertificateId'
      - name: format
        required: true
        in: path
        schema:
          $ref: '#/components/schemas/tlsCertificateDownloadFormat'
    x-controller: TLSCertificateDownloads
    get:
      tags:
        - TLS
      summary: Download TLS certificate
      description: Download the issued TLS certificate either as PEM text or as a ZIP bundle.
      operationId: DownloadCertificate
      responses:
        '200':
          description: TLS certificate payload
          content:
            text/plain:
              schema:
                type: string
              example: |-
                -----BEGIN CERTIFICATE-----
                MIID...
                -----END CERTIFICATE-----
            application/zip:
              schema:
                type: string
                format: binary
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized 
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: TLS certificate not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: The requested certificate artifact is not available yet
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: Upstream TLS provider error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'


components:

  schemas:

    rrid:
      description: Resource Record ID
      type: number

    tlsCertificateId:
      description: Public TLS certificate ID
      type: string
      pattern: '^[ABCDEFGHJKMNPQRSTUVWXYZ23456789]{13}$'
      example: '7K9QW3M2ZT8HJ'

    tlsOrganizationId:
      description: Public TLS organization ID
      type: string
      pattern: '^hdl_[ABCDEFGHJKMNPQRSTUVWXYZ23456789]{13}$'
      example: 'hdl_7K9QW3M2ZT8HJ'

    fqdn:
      type: string
      description: Fully Qualified Domain Name (FQDN, ending with a period).
      pattern: '^((?=.{1,253}$)(\*\.)?(_?[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}\.)$'
      example: 'www.example.com.'

    fqdn_relaxed:
      type: string
      description: Fully Qualified Domain Name.
      pattern: '^((?=.{1,253}$)(\*\.)?(_?[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}(\.)?)$'
      example: 'www.example.com'

    fqdn_or_subdomain:
      type: string
      description: Fully Qualified Domain Name (FQDN) or subdomain. You can use the `@` symbol to represent your apex domain (e.g., example.com). Wildcards are supported.
      pattern: '^(@|(?=.{1,253}$)(\*\.)?(_?[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.)?)+[a-zA-Z]{0,}(\.)?)$'
      example: 'www'

    ipv4:
      type: string
      example: '12.12.12.12'
      pattern: '^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])$'

    ipv6:
      type: string
      example: '2001:0db8:85a3:0000:0000:8a2e:0370:7334'
      pattern: '^(([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){1,6}:[0-9A-Fa-f]{1,4}|([0-9A-Fa-f]{1,4}:){1,5}(:[0-9A-Fa-f]{1,4}){1,2}|([0-9A-Fa-f]{1,4}:){1,4}(:[0-9A-Fa-f]{1,4}){1,3}|([0-9A-Fa-f]{1,4}:){1,3}(:[0-9A-Fa-f]{1,4}){1,4}|([0-9A-Fa-f]{1,4}:){1,2}(:[0-9A-Fa-f]{1,4}){1,5}|[0-9A-Fa-f]{1,4}:((:[0-9A-Fa-f]{1,4}){1,6})|:((:[0-9A-Fa-f]{1,4}){1,7}|:))$'

    baseResult:
      type: object
      required:
        - success
      properties:
        success:
          description: Success indicator
          type: boolean
        code:
          description: Response/Error Code
          type: integer

    recordResponseAdditionalReqRRID:
      type: object
      required:
        - id
      properties:
        id:
          $ref: '#/components/schemas/rrid'

    recordResponseAdditionalReqFQDN:
      type: object
      required:
        - name
      properties:
        name:
          $ref: '#/components/schemas/fqdn'

    recordResponse:
      allOf:
      - $ref: '#/components/schemas/recordType'
      - $ref: '#/components/schemas/recordResponseAdditionalReqRRID'
      - $ref: '#/components/schemas/recordResponseAdditionalReqFQDN'
      - $ref: '#/components/schemas/recordResponseAdditionalState'

    recordResponseAdditionalState:
      type: object
      required:
        - auto
        - active
        - ts_created
        - ts_updated
      properties:
        auto:
          type: boolean
          description: Whether the DNS record is managed automatically by regfish.
        active:
          type: boolean
          description: Whether the DNS record is currently active.
        ts_created:
          type: integer
          description: Unix timestamp when the record was created.
        ts_updated:
          type: integer
          description: Unix timestamp when the record was last updated.

    recordRequest:
      $ref: '#/components/schemas/recordType'

    recordRequestFQDN:
      allOf:
      - $ref: '#/components/schemas/recordType'
      - $ref: '#/components/schemas/recordResponseAdditionalReqFQDN'

    dnssecMode:
      type: string
      description: |
        Requested DNSSEC operating mode.
        - `none`: no registry DNSSEC should remain active
        - `regfish`: regfish signs the zone and manages registry trust anchors
        - `external`: the caller supplies DNSSEC records for external authoritative nameservers
      enum:
        - none
        - regfish
        - external

    dnssecState:
      type: string
      description: Fine-grained registry DNSSEC state.
      enum:
        - disabled
        - pending_enable
        - enabled
        - pending_disable
        - error
        - drift
        - unknown

    dnssecDisplayState:
      type: string
      description: High-level DNSSEC status.
      enum:
        - active
        - pending
        - inactive

    dnssecRecordKind:
      type: string
      enum:
        - ds
        - dnskey

    dnssecRecord:
      type: object
      required:
        - kind
        - algorithm
      properties:
        kind:
          $ref: '#/components/schemas/dnssecRecordKind'
        key_tag:
          type: integer
          minimum: 0
        flags:
          type: integer
          minimum: 0
        protocol:
          type: integer
          minimum: 0
        algorithm:
          type: integer
          minimum: 0
        digest_type:
          type: integer
          minimum: 0
        digest:
          type: string
        public_key:
          type: string
        comment:
          type: string

    sortOrder:
      type: string
      enum:
        - asc
        - desc

    domainListSortKey:
      type: string
      enum:
        - domain
        - expires_at
        - cancelled
        - primary_nameserver
        - dnssec_state
        - owner
        - registered_at

    domainListFilter:
      type: string
      enum:
        - cancelled
        - dnssec-inactive

    domainResponse:
      type: object
      required:
        - domain
        - sld
        - tld
        - favorite
        - owner
        - primary_nameserver
        - dnssec_state
        - auto_renew
        - cancelled
        - registered_at
        - expires_at
      properties:
        domain:
          $ref: '#/components/schemas/fqdn_relaxed'
        sld:
          type: string
          description: Second-level domain label.
        tld:
          type: string
          description: Top-level domain.
        favorite:
          type: boolean
          description: Whether the domain is marked as a favorite.
        owner_contact_id:
          type: integer
          nullable: true
          description: Registrant contact identifier, if available.
        owner:
          type: string
          description: Registrant name or organization label.
        primary_nameserver:
          type: string
          description: Primary delegated nameserver.
        dnssec_state:
          $ref: '#/components/schemas/dnssecDisplayState'
        auto_renew:
          type: boolean
          description: Whether the domain is set to renew automatically.
        cancelled:
          type: boolean
          description: Whether the domain has been cancelled.
        registered_at:
          type: integer
          nullable: true
          description: Unix timestamp when the domain was registered.
        expires_at:
          type: integer
          nullable: true
          description: Unix timestamp when the domain expires.

    domainListResponse:
      type: object
      required:
        - domains
        - total_items
        - total_pages
        - page
        - page_size
        - search
        - filters
        - sort_by
        - sort_order
      properties:
        domains:
          type: array
          description: Domain list for the current result page.
          items:
            $ref: '#/components/schemas/domainResponse'
        total_items:
          type: integer
          description: Total number of matching domains.
        total_pages:
          type: integer
          description: Total number of available pages.
        page:
          type: integer
          description: Current page number.
        page_size:
          type: integer
          description: Number of items returned per page.
        search:
          type: string
          description: Applied search term.
        filters:
          type: array
          description: Applied filters.
          items:
            $ref: '#/components/schemas/domainListFilter'
        sort_by:
          description: Applied sort field.
          $ref: '#/components/schemas/domainListSortKey'
        sort_order:
          description: Applied sort direction.
          $ref: '#/components/schemas/sortOrder'

    dnssecRequest:
      type: object
      required:
        - mode
        - state
      properties:
        mode:
          $ref: '#/components/schemas/dnssecMode'
        state:
          type: string
          description: Desired high-level DNSSEC state.
          enum:
            - disabled
            - enabled
        verify_after_apply:
          type: boolean
          description: When true, the API immediately refreshes registry state and checks DNS delegation after the update.
          default: true
        records:
          type: array
          description: Required for `mode=external,state=enabled`. Ignored for regfish-managed activation and for disable operations.
          items:
            $ref: '#/components/schemas/dnssecRecord'

    dnssecCapabilities:
      type: object
      required:
        - supported
        - provider
        - mode_regfish_available
        - mode_external_available
        - accepted_record_kinds
        - min_records
        - accepted_algorithms
      properties:
        supported:
          type: boolean
        provider:
          type: string
        mode_regfish_available:
          type: boolean
        mode_external_available:
          type: boolean
        accepted_record_kinds:
          type: array
          items:
            $ref: '#/components/schemas/dnssecRecordKind'
        min_records:
          type: integer
        max_records:
          type: integer
          nullable: true
        accepted_algorithms:
          type: array
          items:
            type: integer
        reason_unavailable:
          type: string

    dnssecJobResponse:
      type: object
      required:
        - id
        - action
        - mode
        - status
        - source
        - ts_created
        - ts_updated
      properties:
        id:
          type: integer
        action:
          type: string
        mode:
          type: string
        status:
          type: string
          description: Job lifecycle status such as `PENDING`, `RUNNING`, `WAITING`, `OK`, `ERROR`, or `CANCELLED`.
        source:
          type: string
        registry_name:
          type: string
          nullable: true
        registry_reference:
          type: string
          nullable: true
        error_code:
          type: string
          nullable: true
        error_text:
          type: string
          nullable: true
        ts_created:
          type: integer
        ts_updated:
          type: integer
        ts_started:
          type: integer
          nullable: true
        ts_finished:
          type: integer
          nullable: true

    dnssecResponse:
      type: object
      required:
        - configured
        - dnssec_state
        - mode
        - desired_state
        - live_state
        - capabilities
        - desired_records
        - live_records
        - using_regfish_nameservers
        - legacy_mode
        - zone_signed
        - zone_pending_disable
      properties:
        configured:
          type: boolean
          description: Whether DNSSEC has been configured for the domain.
        dnssec_state:
          $ref: '#/components/schemas/dnssecDisplayState'
        mode:
          $ref: '#/components/schemas/dnssecMode'
        desired_state:
          $ref: '#/components/schemas/dnssecState'
        live_state:
          $ref: '#/components/schemas/dnssecState'
        capabilities:
          $ref: '#/components/schemas/dnssecCapabilities'
        desired_records:
          type: array
          items:
            $ref: '#/components/schemas/dnssecRecord'
        live_records:
          type: array
          items:
            $ref: '#/components/schemas/dnssecRecord'
        last_error_code:
          type: string
          nullable: true
        last_error:
          type: string
          nullable: true
        last_registry_name:
          type: string
          nullable: true
        last_registry_reference:
          type: string
          nullable: true
        last_registry_status:
          type: string
          nullable: true
        last_verified_at:
          type: integer
          nullable: true
        last_applied_at:
          type: integer
          nullable: true
        pending_job:
          allOf:
            - $ref: '#/components/schemas/dnssecJobResponse'
          nullable: true
          description: Current DNSSEC transition job, if processing is still in progress.
        using_regfish_nameservers:
          type: boolean
        legacy_mode:
          type: boolean
        zone_signed:
          type: boolean
        zone_pending_disable:
          type: boolean
        zone_propagated_at:
          type: integer
          nullable: true
        jobs:
          type: array
          description: Recent DNSSEC jobs for the domain. This is history, not just the current pending item.
          items:
            $ref: '#/components/schemas/dnssecJobResponse'

    dnsZoneDelegationNameserver:
      type: object
      required:
        - host
      properties:
        host:
          $ref: '#/components/schemas/fqdn'
        ipv4:
          allOf:
            - $ref: '#/components/schemas/ipv4'
          nullable: true

    dnsZoneSOA:
      type: object
      required:
        - primary_nameserver
        - mailbox
        - serial
        - refresh
        - retry
        - expire
        - minimum
        - ttl
      properties:
        primary_nameserver:
          $ref: '#/components/schemas/fqdn'
        mailbox:
          $ref: '#/components/schemas/fqdn'
        serial:
          type: integer
        refresh:
          type: integer
        retry:
          type: integer
        expire:
          type: integer
        minimum:
          type: integer
        ttl:
          type: integer

    dnsZoneCounts:
      type: object
      required:
        - records_total
        - records_active
        - records_auto
        - records_manual
        - by_type
      properties:
        records_total:
          type: integer
        records_active:
          type: integer
        records_auto:
          type: integer
        records_manual:
          type: integer
        by_type:
          type: object
          additionalProperties:
            type: integer

    dnsZoneRecordResponse:
      type: object
      description: Superset record representation returned by the detailed zone endpoint. Record-specific fields such as `priority`, `flags`, or `tag` are included when applicable.
      required:
        - id
        - name
        - type
        - ttl
        - auto
        - active
        - ts_created
        - ts_updated
      properties:
        id:
          $ref: '#/components/schemas/rrid'
        name:
          type: string
          description: Record owner name. Apex records are returned as `@`; other records use their fully-qualified name.
        type:
          type: string
        data:
          type: string
        priority:
          type: integer
        flags:
          type: integer
        tag:
          type: string
        ttl:
          type: integer
        auto:
          type: boolean
        active:
          type: boolean
        annotation:
          type: string
        ts_created:
          type: integer
        ts_updated:
          type: integer

    dnsZoneSummaryResponse:
      type: object
      required:
        - domain
        - origin
        - active
        - signed
        - using_regfish_nameservers
        - delegation_nameservers
        - soa
        - record_count
        - dnssec_state
      properties:
        domain:
          $ref: '#/components/schemas/fqdn_relaxed'
        origin:
          $ref: '#/components/schemas/fqdn'
        active:
          type: boolean
        signed:
          type: boolean
          description: Whether the regfish-hosted zone itself is signed.
        using_regfish_nameservers:
          type: boolean
          description: Whether the domain currently uses regfish authoritative nameservers.
        delegation_nameservers:
          type: array
          items:
            $ref: '#/components/schemas/dnsZoneDelegationNameserver'
        soa:
          $ref: '#/components/schemas/dnsZoneSOA'
        record_count:
          type: integer
        dnssec_state:
          $ref: '#/components/schemas/dnssecDisplayState'
          description: High-level DNSSEC status for the domain and its delegation.

    dnsZoneDetailResponse:
      allOf:
        - $ref: '#/components/schemas/dnsZoneSummaryResponse'
        - type: object
          required:
            - dnssec
            - counts
            - records
          properties:
            dnssec:
              $ref: '#/components/schemas/dnssecResponse'
            counts:
              $ref: '#/components/schemas/dnsZoneCounts'
            records:
              type: array
              items:
                $ref: '#/components/schemas/dnsZoneRecordResponse'

    recordType:
      oneOf:
      - $ref: '#/components/schemas/A'
      - $ref: '#/components/schemas/AAAA'
      - $ref: '#/components/schemas/CNAME'
      - $ref: '#/components/schemas/CAA'
      - $ref: '#/components/schemas/ALIAS'
      - $ref: '#/components/schemas/MX'
      - $ref: '#/components/schemas/TXT'
      discriminator:
        propertyName: type

    type:
      type: string
      example: A
      enum:
      - A
      - AAAA
      - CNAME
      - CAA
      - ALIAS
      - TXT
      - MX

    # record type without |id| and |data|
    record:
      type: object
      required:
        - name
        - type
      properties:
        type:
          $ref: '#/components/schemas/type'
        name:
          $ref: '#/components/schemas/fqdn_or_subdomain'
        ttl:
          $ref: '#/components/schemas/ttl'
        annotation:
          description: A custom note for this particular record.
          type: string

    ttl:
      description: Time To Live (60-604800)
      type: integer
      example: 600
      minimum: 60
      maximum: 604800

    tlsCertificateStatus:
      type: string
      enum:
        - pending
        - issued
        - pending_cancellation
        - pending_revocation
        - pending_order_revocation
        - cancelled
        - order_cancelled
        - revoked
        - order_revoked
        - rejected
        - expired
        - unknown

    tlsCertificateRevocationScope:
      type: string
      enum:
        - certificate
        - order

    tlsCertificateOrderCancellationMode:
      type: string
      enum:
        - cancel_pending
        - revoke_issued

    tlsCertificateProvider:
      type: string
      enum:
        - digicert

    tlsProductAuthority:
      type: string
      enum:
        - digicert
        - geotrust
        - rapidssl
        - thawte

    tlsProductValidationType:
      type: string
      enum:
        - DV
        - OV
        - EV

    tlsProductValidationLevel:
      type: string
      enum:
        - dv
        - ov
        - ev

    tlsProductSpecs:
      type: object
      properties:
        seal:
          type: boolean
        san_support:
          type: boolean
        www_on_apex:
          type: boolean
        apex_on_wc:
          type: boolean
        wc_support:
          type: boolean
        san_wc_support:
          type: boolean
        max_sans:
          type: integer
        malware_check:
          type: boolean

    tlsProductResponse:
      type: object
      required:
        - sku
        - name
        - type
        - validation_level
        - organization_required
        - ca
        - price
        - specs
      properties:
        sku:
          $ref: '#/components/schemas/tlsCertificateProduct'
        name:
          type: string
        type:
          $ref: '#/components/schemas/tlsProductValidationType'
        validation_level:
          $ref: '#/components/schemas/tlsProductValidationLevel'
        organization_required:
          type: boolean
        ca:
          $ref: '#/components/schemas/tlsProductAuthority'
        price:
          type: object
          required:
            - yearly
            - daily
          properties:
            yearly:
              type: number
              format: float
            daily:
              type: number
              format: float
        recommended:
          type: boolean
        specs:
          $ref: '#/components/schemas/tlsProductSpecs'

    tlsCertificateOrganization:
      type: object
      required:
        - id
        - name
        - status
        - usable_for_ordering
      properties:
        id:
          $ref: '#/components/schemas/tlsOrganizationId'
        name:
          type: string
        status:
          $ref: '#/components/schemas/tlsOrganizationStatus'
        usable_for_ordering:
          type: boolean

    tlsOrganizationStatus:
      type: string
      enum:
        - ready
        - incomplete

    tlsOrganizationCreateRequest:
      type: object
      required:
        - organization
        - first_name
        - last_name
        - address
        - postal_code
        - city
        - country_code
        - phone
        - email
      properties:
        organization:
          type: string
        first_name:
          type: string
        last_name:
          type: string
        address:
          type: string
        postal_code:
          type: string
        city:
          type: string
        country_code:
          type: string
          minLength: 2
          maxLength: 2
        phone:
          type: string
        email:
          type: string

    tlsOrganizationPatchRequest:
      type: object
      minProperties: 1
      properties:
        edit_mode:
          type: string
          enum:
            - create_replacement
            - update_provider
        organization:
          type: string
        first_name:
          type: string
        last_name:
          type: string
        address:
          type: string
        postal_code:
          type: string
        city:
          type: string
        country_code:
          type: string
          minLength: 2
          maxLength: 2
        phone:
          type: string
        email:
          type: string

    tlsOrganizationResponse:
      type: object
      required:
        - id
        - organization
        - status
        - usable_for_ordering
        - first_name
        - last_name
        - address
        - postal_code
        - city
        - country_code
        - phone
        - email
      properties:
        id:
          $ref: '#/components/schemas/tlsOrganizationId'
        organization:
          type: string
        status:
          $ref: '#/components/schemas/tlsOrganizationStatus'
        usable_for_ordering:
          type: boolean
        provider:
          type: string
        provider_status:
          type: string
        validation_status:
          type: string
          enum:
            - unknown
            - pending
            - validated
            - expired
            - revalidation_required
        validation_type:
          type: string
        validated_until:
          type: string
        revalidation_required:
          type: boolean
        first_name:
          type: string
        last_name:
          type: string
        address:
          type: string
        postal_code:
          type: string
        city:
          type: string
        country_code:
          type: string
        phone:
          type: string
        email:
          type: string

    tlsCertificateProduct:
      type: string
      description: regfish TLS certificate product identifier.
      enum:
        - RapidSSL
        - RapidSSLWildcard
        - QuickSSLPremium
        - SSL123
        - TrueBusinessID
        - SecureSite
        - SSLWebServer

    tlsCertificateDcvMethod:
      type: string
      enum:
        - dns-cname-token
        - email

    tlsCertificateRevocationReason:
      type: string
      description: Revocation reason.
      enum:
        - unspecified
        - keyCompromise
        - affiliationChanged
        - superseded
        - cessationOfOperation

    tlsCertificateDownloadFormat:
      type: string
      enum:
        - pem
        - zip

    tlsCertificateReissueStatus:
      type: string
      enum:
        - pending
        - processing
        - pending_approval
        - issued
        - cancelled
        - rejected
        - failed

    csr:
      type: string
      description: PEM encoded certificate signing request (CSR).
      example: |-
        -----BEGIN CERTIFICATE REQUEST-----
        MIIC...
        -----END CERTIFICATE REQUEST-----

    tlsValidationDnsRecord:
      type: object
      required:
        - name
        - type
        - value
      properties:
        name:
          $ref: '#/components/schemas/fqdn'
        type:
          type: string
          enum:
            - CNAME
        value:
          $ref: '#/components/schemas/fqdn'

    tlsValidation:
      type: object
      required:
        - method
      properties:
        method:
          $ref: '#/components/schemas/tlsCertificateDcvMethod'
        dns_records:
          type: array
          items:
            $ref: '#/components/schemas/tlsValidationDnsRecord'
        email_targets:
          type: array
          items:
            type: string

    tlsCertificateRequest:
      type: object
      required:
        - sku
        - common_name
        - csr
        - dcv_method
      properties:
        sku:
          $ref: '#/components/schemas/tlsCertificateProduct'
        common_name:
          $ref: '#/components/schemas/fqdn_relaxed'
        dns_names:
          type: array
          items:
            $ref: '#/components/schemas/fqdn_relaxed'
        csr:
          $ref: '#/components/schemas/csr'
        dcv_method:
          $ref: '#/components/schemas/tlsCertificateDcvMethod'
        dcv_emails:
          type: array
          items:
            type: string
        org_id:
          $ref: '#/components/schemas/tlsOrganizationId'
          description: Optional public TLS organization id to use for OV or EV ordering. Use `/tls/organization` to list or create eligible organizations.
        renewal_of_certificate_id:
          $ref: '#/components/schemas/tlsCertificateId'
          description: Optional TLS certificate `id` to renew. When set, the order is submitted as a provider-linked renewal of the referenced certificate. Any remaining validity may increase the final issued lifetime after the provider accepts the renewal.
          example: '7K9QW3M2ZT8HJ'
        validity_days:
          type: integer
          minimum: 1
          maximum: 199
          default: 199
          description: Purchased base order validity in days. For renewal orders this value is not reduced by any expected remaining-validity bonus from the previous certificate. If the provider credits remaining validity, the issued certificate may end up with a longer effective lifetime than this value.

    tlsCertificateCancelRequest:
      type: object
      properties:
        note:
          type: string
          description: Optional provider note stored with the cancellation request. If omitted, regfish sends a default note because the CA requires one for pending-order cancellations.

    tlsCertificateCompleteRequest:
      type: object
      required:
        - org_id
      properties:
        org_id:
          $ref: '#/components/schemas/tlsOrganizationId'
          description: Public TLS organization id to use for completing the staged TLS certificate order.

    tlsCertificateRevokeRequest:
      type: object
      properties:
        comment:
          type: string
          description: Optional provider comment for the revocation request.
        revocation_reason:
          allOf:
            - $ref: '#/components/schemas/tlsCertificateRevocationReason'
          description: Optional revocation reason forwarded to the CA. Defaults to `unspecified` when omitted.
          example: cessationOfOperation

    tlsCertificateOrderCancelRequest:
      type: object
      properties:
        comment:
          type: string
          description: Optional provider comment for the full order cancellation request. If the request resolves to a pending-order cancellation, regfish sends a default provider note when this field is omitted.
        revocation_reason:
          allOf:
            - $ref: '#/components/schemas/tlsCertificateRevocationReason'
          description: Optional revocation reason. Defaults to `unspecified`.
          example: unspecified

    tlsCertificateReissueRequest:
      type: object
      required:
        - csr
        - dcv_method
      properties:
        csr:
          $ref: '#/components/schemas/csr'
        common_name:
          $ref: '#/components/schemas/fqdn_relaxed'
          description: Optional. If provided, it must match the current order common name exactly.
        dns_names:
          type: array
          items:
            $ref: '#/components/schemas/fqdn_relaxed'
          description: Optional. If provided, the SAN list must match the current order exactly.
        dcv_method:
          $ref: '#/components/schemas/tlsCertificateDcvMethod'
        comments:
          type: string
          description: Optional provider comment stored with the reissue request.
        validity_days:
          type: integer
          minimum: 1
          maximum: 199
          description: Optional requested certificate lifetime in days for the replacement certificate. The CA only honors this for eligible multi-year plan orders and never beyond the remaining order contract.

    tlsCertificateReissueResponse:
      type: object
      required:
        - id
        - status
        - common_name
        - dns_names
      properties:
        id:
          type: integer
        status:
          $ref: '#/components/schemas/tlsCertificateReissueStatus'
        common_name:
          type: string
        dns_names:
          type: array
          items:
            type: string
        order_state:
          type: string
        requested_at:
          type: string
          format: date-time
        last_updated_at:
          type: string
          format: date-time
        validation:
          $ref: '#/components/schemas/tlsValidation'

    tlsCertificateResponse:
      type: object
      required:
        - id
        - status
        - common_name
        - product
        - provider
        - dns_names
        - action_required
        - pending_reason
        - pending_message
        - completion_url
        - organization_id
        - certificate_pem_available
      properties:
        id:
          $ref: '#/components/schemas/tlsCertificateId'
        status:
          $ref: '#/components/schemas/tlsCertificateStatus'
        common_name:
          type: string
        product:
          type: string
        provider:
          $ref: '#/components/schemas/tlsCertificateProvider'
        dns_names:
          type: array
          items:
            type: string
        action_required:
          type: boolean
        pending_reason:
          type: string
        pending_message:
          type: string
        completion_url:
          type: string
          description: Absolute URL where the remaining order details can be completed in the web interface. API clients can alternatively use `/tls/certificate/{certificate_id}/complete`.
        organization_id:
          type: string
          nullable: true
          pattern: '^hdl_[ABCDEFGHJKMNPQRSTUVWXYZ23456789]{13}$'
        organization:
          $ref: '#/components/schemas/tlsCertificateOrganization'
        order_state:
          type: string
        revocation_scope:
          $ref: '#/components/schemas/tlsCertificateRevocationScope'
        revocation_pending_scope:
          $ref: '#/components/schemas/tlsCertificateRevocationScope'
        reissue_supported:
          type: boolean
        validity_days:
          type: integer
          description: Purchased base order validity in days as submitted for the order. On provider-linked renewals the effective issued certificate lifetime can be longer. Use `valid_from` and `valid_until` as the authoritative issued lifetime.
        renewal_bonus_days:
          type: integer
          minimum: 0
          description: Confirmed additional validity days on top of `validity_days`, derived from the actually issued renewal certificate. This field is only present for renewal certificates once the effective issued lifetime can be determined.
        serial_number:
          type: string
        valid_from:
          type: string
          format: date-time
        valid_until:
          type: string
          format: date-time
          description: Authoritative expiration timestamp of the currently issued certificate. On provider-linked renewals this can be later than `validity_days` would suggest if the provider adds remaining validity from the previous certificate.
        contract_valid_from:
          type: string
          format: date-time
        contract_valid_until:
          type: string
          format: date-time
        last_status_check:
          type: string
          format: date-time
        certificate_pem_available:
          type: boolean
        order_cancellable:
          type: boolean
        order_cancellation_mode:
          $ref: '#/components/schemas/tlsCertificateOrderCancellationMode'
        order_cancellable_until:
          type: string
          format: date-time
        validation:
          $ref: '#/components/schemas/tlsValidation'
        reissue:
          $ref: '#/components/schemas/tlsCertificateReissueResponse'
  
    A:
      allOf:
      - $ref: '#/components/schemas/record'
      - type: object
        required:
        - type
        - data
        properties:
          type:
            type: string
            enum:
              - A
          data:
            $ref: '#/components/schemas/ipv4'

    AAAA:
      allOf:
      - $ref: '#/components/schemas/record'
      - type: object
        required:
        - type
        - data
        properties:
          type:
            type: string
            enum:
              - AAAA
          data:
            $ref: '#/components/schemas/ipv6'

    CNAME:
      allOf:
      - $ref: '#/components/schemas/record'
      - type: object
        required:
        - type
        - data
        properties:
          type:
            type: string
            enum:
              - CNAME
          data:
            $ref: '#/components/schemas/fqdn'

    CAA:
      allOf:
      - $ref: '#/components/schemas/record'
      - type: object
        required:
        - type
        - flags
        - tag
        - data
        properties:
          type:
            type: string
            enum:
              - CAA
          flags:
            type: integer
            example: 1
            description: indicates criticality, with a value of 1 meaning that the record must be understood and respected by the CA before issuing a certificate, while 0 means it’s optional.
            enum:
              - 0
              - 1
          tag:
            type: string
            example: issue
            description: Specifies the type of authorization or reporting policy, such as allowing specific CAs to issue certificates (issue), wildcard certificates (issuewild), or report issues (iodef).
            enum:
            - issue
            - issuewild
            - iodef
          data:
            type: string
            example: 'letsencrypt.org'
            description: Use the CA’s domain to authorize a specific CA or to include a URI when used with iodef.

    ALIAS:
      allOf:
      - $ref: '#/components/schemas/record'
      - type: object
        required:
        - type
        - data
        properties:
          type:
            type: string
            enum:
              - ALIAS
          data:
            $ref: '#/components/schemas/fqdn'

    TXT:
      allOf:
      - $ref: '#/components/schemas/record'
      - type: object
        required:
        - type
        - data
        properties:
          type:
            type: string
            enum:
              - TXT
          data:
            type: string

    MX:
      allOf:
      - $ref: '#/components/schemas/record'
      - type: object
        required:
        - type
        - data
        - priority
        properties:
          type:
            type: string
            enum:
              - MX
          data:
            $ref: '#/components/schemas/fqdn'
          priority:
            type: integer
            minimum: 0
            maximum: 10000

    Error:
      type: object
      required:
        - success
      example:
        success: false
        message: Unauthorized
        error: Invalid API key
      properties:
        success:
          description: Indicator of success (always `false`)
          type: boolean
        message:
          description: A human readable message
          type: string
        error:
          description: A human readable error message
          type: string

  securitySchemes:
    api_key:
      type: apiKey
      in: header
      name: x-api-key
security:
  - api_key: []
