openapi: '3.2.0'
info:
  title: ISNIC - RESTful Provisioning Protocol
  version: '0.2'
  termsOfService: https://www.isnic.is/en/about/terms
  contact:
    name: API Support
    email: api-support@isnic.is

externalDocs:
  description: See url on how to get access
  url: https://www.isnic.is/en/api/rpp

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
      description: User is NIC-handle and API-key issued on website is the password.
  schemas:
    AuthInfo:
      type: object
      description: Object authorization info (draft-ietf-rpp-json)
      required:
        - '@type'
        - pw
      properties:
        '@type':
          type: string
          enum:
            - authInfo
        pw:
          type: string
          description: authorization password
    AuthInfoPatch:
      type: array
      description: JSON Patch (RFC 6902) document, partial update per
        draft-ietf-rpp-json section 5.2. Only a single replace operation on
        /authInfo is supported.
      minItems: 1
      items:
        type: object
        required:
          - op
          - path
          - value
        properties:
          op:
            type: string
            enum:
              - replace
          path:
            type: string
            enum:
              - /authInfo
          value:
            $ref: '#/components/schemas/AuthInfo'
    ClientIdentifier:
      type: string
      description: Client identifier, NIC-handle (draft-ietf-rpp-json 6.1.2,
        clientIdentifier)
      minLength: 3
      maxLength: 16
      pattern: '^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$'
    TransferRequest:
      description: >
        Transfer request (draft-ietf-rpp-json 6.3.3.1, transferProcess.create).
        For push gainingClientId MUST be set in the body; for pull the current
        authinfo MUST be sent in the RPP-Authorization header and MUST NOT be
        included in this body (Rule 26).
      oneOf:
        - type: object
          description: Push transfer, gainingClientId is required
          required:
            - '@type'
            - transferDir
            - gainingClientId
          properties:
            '@type':
              type: string
              enum:
                - transferProcess
            transferDir:
              type: string
              enum:
                - push
            gainingClientId:
              $ref: '#/components/schemas/ClientIdentifier'
        - type: object
          description: Pull transfer, authinfo is provided in the RPP-Authorization header
          required:
            - '@type'
            - transferDir
          properties:
            '@type':
              type: string
              enum:
                - transferProcess
            transferDir:
              type: string
              enum:
                - pull
    TransferProcess:
      type: object
      description: Transfer process read representation (draft-ietf-rpp-json 6.3.3.2,
        transferProcess.read)
      required:
        - '@type'
        - transferDir
        - trStatus
        - reqClientId
        - requestDate
        - actClientId
      properties:
        '@type':
          type: string
          enum:
            - transferProcess
        trStatus:
          type: string
          enum:
            - pending
            - clientApproved
            - clientCancelled
            - clientRejected
            - serverApproved
            - serverCancelled
        transferDir:
          type: string
          enum:
            - pull
            - push
        gainingClientId:
          $ref: '#/components/schemas/ClientIdentifier'
        reqClientId:
          $ref: '#/components/schemas/ClientIdentifier'
        requestDate:
          type: string
          format: date-time
        actClientId:
          $ref: '#/components/schemas/ClientIdentifier'
        actionDate:
          type: string
          format: date-time
          description: set once the transfer has been acted upon
    RppError:
      type: object
      description: Problem Detail response (draft-ietf-rpp-core 8, RFC 9457)
      required:
        - type
        - title
        - errors
      properties:
        type:
          type: string
          example: urn:ietf:params:rpp:error
        title:
          type: string
          example: RPP Error
        errors:
          type: array
          items:
            $ref: '#/components/schemas/RppErrorItem'
    RppErrorItem:
      type: object
      description: A single error in a Problem Detail response (draft-ietf-rpp-core 8)
      required:
        - type
        - result
        - reason
      properties:
        type:
          type: string
          description: URI that identifies the error type
          example: https://rpp.isnic.is/problems/domains/domain-syntax
        result:
          type: string
          description: RPP result code, 5 digits with a leading 0 for EPP codes
          example: '02005'
        paths:
          type: array
          description: JSONPath to the value(s) in the request that caused the error
          items:
            type: string
        reason:
          type: string
          description: human-readable detailed description of the error
    UpdateResponse:
      type: object
      description: The updated object representation, minimal payload for now
        (draft-ietf-rpp-core 14.7)
      required:
        - '@type'
        - name
      properties:
        '@type':
          type: string
          enum:
            - domainName
            - host
            - contact
        name:
          type: string
          description: identifier of the updated object, domain name, host name or
            NIC-handle
    Period:
      type: object
      description: Duration object (draft-ietf-rpp-json 6.2.1)
      required:
        - '@type'
        - value
        - unit
      properties:
        '@type':
          type: string
          enum:
            - period
        value:
          type: integer
          minimum: 1
          maximum: 99
        unit:
          type: string
          enum:
            - y
            - m
    ContactReference:
      type: object
      description: Reference to a contact by NIC-handle (draft-ietf-rpp-json 6.5.6)
      required:
        - '@type'
        - id
      properties:
        '@type':
          type: string
          enum:
            - contact
        id:
          type: string
          description: NIC-handle of the contact
    HostReference:
      type: object
      description: Reference to a host by fully qualified host name
        (draft-ietf-rpp-json 6.6)
      required:
        - '@type'
        - hostName
      properties:
        '@type':
          type: string
          enum:
            - host
        hostName:
          type: string
          format: hostname
    CreateProcess:
      type: object
      description: Registration period requested for a new domain (draft-ietf-rpp-json
        6.3.1)
      required:
        - '@type'
      properties:
        '@type':
          type: string
          enum:
            - createProcess
        period:
          $ref: '#/components/schemas/Period'
    DnsRecord:
      type: object
      description: >
        DNS resource record (draft-ietf-rpp-json 6.2.4). rdata property names
        are camelCase and all rdata values are strings, e.g. NS uses nsdname, A
        and AAAA use address, DS uses keyTag, algorithm, digestType and digest,
        DNSKEY uses flags, protocol, algorithm and publicKey.
      required:
        - '@type'
        - name
        - type
        - rdata
      properties:
        '@type':
          type: string
          enum:
            - dnsRecord
        name:
          type: string
          description: record owner name, MUST be the domain name itself or a subdomain
        class:
          type: string
          description: record class, omit to let the server assume IN
        type:
          type: string
          description: record type, e.g. ns, a, aaaa, ds, dnskey
        rdata:
          type: object
          description: record data, property names camelCase, values strings
          additionalProperties: true
    DnsControls:
      type: object
      description: DNS operational controls (draft-ietf-rpp-json 6.2.5), a server MAY
        ignore these values for policy reasons
      required:
        - '@type'
      properties:
        '@type':
          type: string
          enum:
            - dnsControls
        ttl:
          type: object
          description: 'TTL per record type, keys are lowercase record types, e.g. {ns:
            3600}'
          additionalProperties:
            type: integer
            minimum: 1
        maxSigLifetime:
          type: object
          description: 'maximum signature lifetime per record type, keys are lowercase
            record types, e.g. {ds: 300000}'
          additionalProperties:
            type: integer
            minimum: 1
    DnsData:
      type: object
      description: DNS data (draft-ietf-rpp-json 6.2.6)
      required:
        - '@type'
      properties:
        '@type':
          type: string
          enum:
            - dnsData
        records:
          type: array
          items:
            $ref: '#/components/schemas/DnsRecord'
        controls:
          $ref: '#/components/schemas/DnsControls'
    DomainCreateRequest:
      type: object
      description: >
        Domain create request body (draft-ietf-rpp-json 6.4.1,
        domainObject.create). At most one createProcess MAY be submitted under
        processes. authInfo MAY be used to set the initial authorization
        information of the new domain (method MUST be 'authinfo' in the EPP
        compatibility profile).
      required:
        - '@type'
        - name
      properties:
        '@type':
          type: string
          enum:
            - domainName
        name:
          type: string
          writeOnly: true
          description: Fully qualified name of the domain to register
        registrant:
          $ref: '#/components/schemas/ContactReference'
        contacts:
          type: array
          description: Additional labelled contact references (admin, tech, ...)
          items:
            type: object
            required:
              - label
              - object
            properties:
              label:
                type: string
              object:
                $ref: '#/components/schemas/ContactReference'
        nameservers:
          type: array
          description: Delegated nameservers
          items:
            $ref: '#/components/schemas/HostReference'
        dns:
          $ref: '#/components/schemas/DnsData'
        authInfo:
          type: object
          description: Initial authorization information for the new domain
            (draft-ietf-rpp-json 6.2.7)
          required:
            - '@type'
            - method
            - authdata
          properties:
            '@type':
              type: string
              enum:
                - authInfo
            method:
              type: string
              description: authorization method, MUST be 'authinfo' in the EPP compatibility
                profile
            authdata:
              type: string
              description: authorization data, e.g. the initial password
        processes:
          type: object
          description: Embedded process data
          required:
            - '@type'
          properties:
            '@type':
              type: string
              enum:
                - processes
            createProcess:
              type: array
              maxItems: 1
              items:
                $ref: '#/components/schemas/CreateProcess'
    RenewProcessRequest:
      type: object
      description: >
        Renew process request body (draft-ietf-rpp-json 6.3.2,
        renewProcess.create). expiryDate is the current expiry date of the
        domain and is REQUIRED, the server validates it to prevent unintended
        duplicate renewals. Only the date part, taken in UTC, is compared with
        the current expiry date (EPP curExpDate); the time of day is ignored.
        renewalPeriod is the duration to be added to the registration period, a
        server policy MAY define a default when absent.
      required:
        - '@type'
        - expiryDate
      properties:
        '@type':
          type: string
          enum:
            - renewProcess
        expiryDate:
          type: string
          format: date-time
          description: current expiry date of the domain, compared on the UTC date only
        renewalPeriod:
          $ref: '#/components/schemas/Period'
    RenewProcessResponse:
      type: object
      description: Renew process read representation (draft-ietf-rpp-json 6.3.2,
        renewProcess.read)
      required:
        - '@type'
      properties:
        '@type':
          type: string
          enum:
            - renewProcess
        expiryDate:
          type: string
          format: date-time
          readOnly: true
          description: new expiry date of the domain once the renewal is complete

tags:
  - name: Domains
    description: Register domain names, check availability, renew and transfer them,
      and update their authInfo
  - name: Hosts
    description: Check hostname availability, transfer hosts and update their authInfo
  - name: Contacts
    description: Check contact handle availability, transfer contacts and update
      their authInfo

security:
  - BasicAuth: []

servers:
  - url: https://rpp.isnic.is/v0
    description: Production server
  - url: https://rpp.sandbox.isnic.is/v0
    description: Sandbox server for testing, please do not use PII

paths:
  /domainNames/{id}/availability:
    head:
      operationId: checkDomainAvailability
      tags:
        - Domains
      summary: Check domain availability
      description: Check if domain is available for registration
      parameters:
        - name: id
          in: path
          schema:
            type: string
          required: true
          description: Domain to check
        - in: header
          name: RPP-Cltrid
          schema:
            type: string
          required: false
          description: optional client transaction id
      responses:
        '404':
          description: Domain is not available
          headers:
            RPP-Code:
              schema:
                type: string
                example: '01000'
            RPP-Svtrid:
              schema:
                type: string
            RPP-Cltrid:
              schema:
                type: string
        '200':
          description: Domain is available
          headers:
            RPP-Code:
              schema:
                type: string
                example: '01000'
            RPP-Svtrid:
              schema:
                type: string
            RPP-Cltrid:
              schema:
                type: string

  /domainNames/{id}/processes/renewProcesses:
    post:
      operationId: createDomainRenewProcess
      tags:
        - Domains
      summary: Create renew process
      description: >
        Start a renewal for the domain name (domain:renew). Renew is modelled as
        a Process Object, the response MUST include the Location header for the
        created renew process resource (draft-ietf-rpp-core 14.8.4).
      parameters:
        - name: id
          in: path
          schema:
            type: string
          required: true
          description: Domain to renew
        - in: header
          name: RPP-Cltrid
          schema:
            type: string
          required: false
          description: optional client transaction id
      requestBody:
        description: Renew process request
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RenewProcessRequest'
      responses:
        '201':
          description: renew process created
          headers:
            Location:
              schema:
                type: string
              description: >
                URI of the created renew process resource,
                /domainNames/{id}/processes/renewProcesses/{processId}
            RPP-Code:
              schema:
                type: string
                example: '01000'
            RPP-Svtrid:
              schema:
                type: string
            RPP-Cltrid:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RenewProcessResponse'
        '400':
          description: invalid renew request, e.g. expiryDate missing or malformed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RppError'
        '403':
          description: client is not the sponsoring registrar of the domain
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RppError'
        '404':
          description: domain does not exist
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RppError'
        '409':
          description: >
            a renew process is already pending, expiryDate does not match the
            current expiry date, the domain is not eligible for renewal, or its
            status prohibits renewal
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RppError'
        '422':
          description: renewal period does not meet registry policy, e.g. exceeds the
            maximum registration term
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RppError'
        '429':
          description: rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RppError'
