openapi: 3.1.0
info:
  title: reg.ly Reseller API
  version: "2.3"
  summary: Register, renew, transfer and manage .ly domains from your own system.
  description: |
    The reg.ly reseller API. REST over HTTPS, form-encoded requests, JSON responses.
    Every call can be tested with .ote.ly names on the same endpoint without spending credit.
    No request limit applies to reseller accounts.

    Changelog, newest first
    - v2.3 (2026). Automatic top-ups in the reseller account. No change to the API surface.
    - v2.2 (2025). The WHMCS module ships two files of your own, for custom registrar
      functions and for hooks.
    - v2.1 (2023). The registrar module on the WHMCS Marketplace, then the Blesta extension.
    - v2 (2021). The API rebuilt as REST with JSON responses and signed hourly tokens.
      The v2 generation introduces availability lookup, domain suggestions, the TLD list,
      TLD and order pricing, account credits, domain information, transfer sync and a
      version call, structured models, a generated WHMCS module and the .ote.ly test zone.
    - v1 (2017). The first reseller API. Static API key authentication, an IP allowlist,
      the core registry operations and a generated WHMCS registrar module.
  contact:
    name: reg.ly
    url: https://reg.ly/ly-domain-reseller/
servers:
  - url: https://api.reg.ly
    description: Production and test. Register .ote.ly names to test without spending credit.
security:
  - username: []
    token: []
tags:
  - name: Orders
    description: Register, transfer and renew .ly domains.
  - name: Domains
    description: Manage a domain you hold. EPP codes, locks, contacts, DNS, email forwarding, ID protection, sync, release and deletion.
  - name: Lookup
    description: Availability and suggestions.
  - name: Nameservers
    description: A domain's name servers and private host records.
  - name: Pricing
    description: TLDs and their prices.
  - name: Account
    description: Credits and the API version.
paths:
  /order/domains/register:
    post:
      operationId: RegisterDomain
      tags: [Orders]
      summary: Register a domain
      description: Registers a .ly domain to your reseller account and charges your credit.
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [domain, regperiod, nameservers, contacts]
              properties:
                domain: { type: string, description: The domain to register. }
                regperiod: { type: integer, description: Registration period in years. }
                nameservers: { $ref: "#/components/schemas/nameservers" }
                contacts: { $ref: "#/components/schemas/contacts" }
                domainfields: { type: string, description: Additional domain fields where the TLD requires them. }
                addons: { $ref: "#/components/schemas/addons" }
                idnLanguage: { type: string, description: IDN language code where the name needs one. }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /order/domains/transfer:
    post:
      operationId: TransferDomain
      tags: [Orders]
      summary: Transfer a domain in
      description: Starts a transfer into your reseller account. The auth code can follow when the registry asks for it.
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [domain, regperiod, nameservers, contacts]
              properties:
                domain: { type: string }
                eppcode: { type: string, description: The auth code from the current registrar. }
                regperiod: { type: integer }
                nameservers: { $ref: "#/components/schemas/nameservers" }
                contacts: { $ref: "#/components/schemas/contacts" }
                domainfields: { type: string }
                addons: { $ref: "#/components/schemas/addons" }
                idnLanguage: { type: string }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /order/domains/renew:
    post:
      operationId: RenewDomain
      tags: [Orders]
      summary: Renew a domain
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [domain, regperiod]
              properties:
                domain: { type: string }
                regperiod: { type: integer, description: Years to add. }
                addons: { $ref: "#/components/schemas/addons" }
                idnLanguage: { type: string }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /order/pricing/domains/{type}:
    get:
      operationId: CartGetPricing
      tags: [Pricing]
      summary: Order pricing for a domain
      description: The price of an order of the given type. The type path segment is register, renew or transfer.
      parameters:
        - { name: type, in: path, required: true, schema: { type: string, enum: [register, renew, transfer] } }
        - { name: domain, in: query, required: true, schema: { type: string } }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/lookup:
    post:
      operationId: CheckAvailability
      tags: [Lookup]
      summary: Check availability
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                searchTerm: { type: string }
                punyCodeSearchTerm: { type: string }
                tldsToInclude: { type: array, items: { type: string } }
                isIdnDomain: { type: boolean }
                premiumEnabled: { type: boolean }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/lookup/suggestions:
    post:
      operationId: GetDomainSuggestions
      tags: [Lookup]
      summary: Domain suggestions
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                searchTerm: { type: string }
                punyCodeSearchTerm: { type: string }
                tldsToInclude: { type: array, items: { type: string } }
                isIdnDomain: { type: boolean }
                premiumEnabled: { type: boolean }
                suggestionSettings: { type: array, items: { type: string } }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/information:
    get:
      operationId: GetDomainInformation
      tags: [Domains]
      summary: Domain information
      parameters: [{ $ref: "#/components/parameters/domain" }]
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/eppcode:
    get:
      operationId: GetEPPCode
      tags: [Domains]
      summary: Get the auth code
      parameters: [{ $ref: "#/components/parameters/domain" }]
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/contact:
    get:
      operationId: GetContactDetails
      tags: [Domains]
      summary: Get contact details
      parameters: [{ $ref: "#/components/parameters/domain" }]
      responses:
        "200": { $ref: "#/components/responses/ok" }
    post:
      operationId: SaveContactDetails
      tags: [Domains]
      summary: Save contact details
      parameters: [{ $ref: "#/components/parameters/domain" }]
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [contactdetails]
              properties:
                contactdetails: { $ref: "#/components/schemas/contactdetails" }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/lock:
    get:
      operationId: GetRegistrarLock
      tags: [Domains]
      summary: Get the registrar lock
      parameters: [{ $ref: "#/components/parameters/domain" }]
      responses:
        "200": { $ref: "#/components/responses/ok" }
    post:
      operationId: SaveRegistrarLock
      tags: [Domains]
      summary: Set the registrar lock
      parameters: [{ $ref: "#/components/parameters/domain" }]
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [lockstatus]
              properties:
                lockstatus: { type: string }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/dns:
    get:
      operationId: GetDNS
      tags: [Domains]
      summary: Get DNS records
      description: Not currently supported for .ly names.
      parameters: [{ $ref: "#/components/parameters/domain" }]
      responses:
        "200": { $ref: "#/components/responses/ok" }
    post:
      operationId: SaveDNS
      tags: [Domains]
      summary: Save DNS records
      description: Not currently supported for .ly names.
      parameters: [{ $ref: "#/components/parameters/domain" }]
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [dnsrecords]
              properties:
                dnsrecords:
                  type: array
                  items: { $ref: "#/components/schemas/dnsrecord" }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/email:
    get:
      operationId: GetEmailForwarding
      tags: [Domains]
      summary: Get email forwarding
      parameters: [{ $ref: "#/components/parameters/domain" }]
      responses:
        "200": { $ref: "#/components/responses/ok" }
    post:
      operationId: SaveEmailForwarding
      tags: [Domains]
      summary: Save email forwarding
      parameters: [{ $ref: "#/components/parameters/domain" }]
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                prefix: { type: array, items: { type: string } }
                forwardto: { type: array, items: { type: string } }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/protectid:
    post:
      operationId: IDProtectToggle
      tags: [Domains]
      summary: Toggle ID protection
      parameters: [{ $ref: "#/components/parameters/domain" }]
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [status]
              properties:
                status: { type: integer, description: 1 on, 0 off. }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/sync:
    post:
      operationId: DomainSync
      tags: [Domains]
      summary: Sync a domain
      description: Reads the authoritative status and expiry so your records stay current.
      parameters: [{ $ref: "#/components/parameters/domain" }]
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/transfersync:
    post:
      operationId: TransferSync
      tags: [Domains]
      summary: Sync a transfer
      parameters: [{ $ref: "#/components/parameters/domain" }]
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/release:
    post:
      operationId: ReleaseDomain
      tags: [Domains]
      summary: Release a domain
      parameters: [{ $ref: "#/components/parameters/domain" }]
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [transfertag]
              properties:
                transfertag: { type: string }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/delete:
    post:
      operationId: RequestDelete
      tags: [Domains]
      summary: Request deletion
      parameters: [{ $ref: "#/components/parameters/domain" }]
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/nameservers:
    get:
      operationId: GetNameServers
      tags: [Nameservers]
      summary: Get name servers
      parameters: [{ $ref: "#/components/parameters/domain" }]
      responses:
        "200": { $ref: "#/components/responses/ok" }
    post:
      operationId: SaveNameServers
      tags: [Nameservers]
      summary: Save name servers
      parameters: [{ $ref: "#/components/parameters/domain" }]
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [ns1, ns2]
              properties:
                ns1: { type: string }
                ns2: { type: string }
                ns3: { type: string }
                ns4: { type: string }
                ns5: { type: string }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/nameservers/register:
    post:
      operationId: RegisterNameserver
      tags: [Nameservers]
      summary: Register a host record
      parameters: [{ $ref: "#/components/parameters/domain" }]
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [nameserver, ipaddress]
              properties:
                nameserver: { type: string }
                ipaddress: { type: string }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/nameservers/modify:
    post:
      operationId: ModifyNameserver
      tags: [Nameservers]
      summary: Modify a host record
      parameters: [{ $ref: "#/components/parameters/domain" }]
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [nameserver, currentipaddress, newipaddress]
              properties:
                nameserver: { type: string }
                currentipaddress: { type: string }
                newipaddress: { type: string }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /domains/{domain}/nameservers/delete:
    post:
      operationId: DeleteNameserver
      tags: [Nameservers]
      summary: Delete a host record
      parameters: [{ $ref: "#/components/parameters/domain" }]
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [nameserver]
              properties:
                nameserver: { type: string }
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /tlds:
    get:
      operationId: GetAvailableTLDs
      tags: [Pricing]
      summary: Available TLDs
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /tlds/pricing:
    get:
      operationId: GetTldPricing
      tags: [Pricing]
      summary: TLD pricing
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /billing/credits:
    get:
      operationId: GetCredits
      tags: [Account]
      summary: Account credits
      description: The prepaid balance available to your reseller account.
      responses:
        "200": { $ref: "#/components/responses/ok" }
  /version:
    get:
      operationId: GetVersion
      tags: [Account]
      summary: API version
      responses:
        "200": { $ref: "#/components/responses/ok" }
components:
  parameters:
    domain:
      name: domain
      in: path
      required: true
      description: The domain name.
      schema: { type: string }
      example: yourname.ly
  securitySchemes:
    username:
      type: apiKey
      in: header
      name: username
      description: Your reseller account email address.
    token:
      type: apiKey
      in: header
      name: token
      description: |
        base64_encode( hash_hmac("sha256", apiKey, email + ":" + gmdate("y-m-d H")) ).
        An HMAC-SHA256 of your API key, keyed by your email and the current UTC hour
        (hex digest, then base64). The token expires on its own within the hour.
  responses:
    ok:
      description: JSON. The shape is specific to the call.
      content:
        application/json:
          schema: {}
  schemas:
    nameservers:
      type: object
      description: A domain's name servers. Two required, up to five.
      required: [ns1, ns2]
      properties:
        ns1: { type: string }
        ns2: { type: string }
        ns3: { type: string }
        ns4: { type: string }
        ns5: { type: string }
    contact:
      type: object
      description: One domain contact.
      required: [firstname, lastname, fullname, companyname, email, address1, city, state, postcode, country, phonenumber]
      properties:
        firstname: { type: string }
        lastname: { type: string }
        fullname: { type: string }
        companyname: { type: string }
        email: { type: string }
        address1: { type: string }
        address2: { type: string }
        city: { type: string }
        state: { type: string }
        postcode: { type: string }
        country: { type: string }
        phonenumber: { type: string }
    contacts:
      type: object
      description: The contacts on an order. registrant also answers to owner, tech to technical.
      properties:
        registrant: { $ref: "#/components/schemas/contact" }
        tech: { $ref: "#/components/schemas/contact" }
        billing: { $ref: "#/components/schemas/contact" }
        admin: { $ref: "#/components/schemas/contact" }
    contactdetails:
      type: object
      description: The four contact roles of a domain, each a contact.
      required: [Registrant, Technical, Billing, Admin]
      properties:
        Registrant: { $ref: "#/components/schemas/contact" }
        Technical: { $ref: "#/components/schemas/contact" }
        Billing: { $ref: "#/components/schemas/contact" }
        Admin: { $ref: "#/components/schemas/contact" }
    dnsrecord:
      type: object
      description: One DNS record.
      required: [hostname, type, address, priority]
      properties:
        hostname: { type: string }
        type: { type: string }
        address: { type: string }
        priority: { type: integer }
        recid: { type: string, description: The record id when changing an existing record. }
    addons:
      type: object
      description: Domain addons. 1 on, 0 off.
      properties:
        dnsmanagement: { type: integer }
        emailforwarding: { type: integer }
        idprotection: { type: integer }
