openapi: 3.1.0
info:
  title: XDCID API
  version: 1.3.0
  description: |
    Versioned, read-only access to XDCID name and reverse-resolution data on
    XDC mainnet. The API version is present in both the URL and every
    application JSON response.
servers:
  - url: /
    description: Current XDCID deployment
tags:
  - name: Names
  - name: Reverse resolution
  - name: Wallet names
  - name: XDC AI gateway
paths:
  /api/v1/names/{name}:
    get:
      operationId: getName
      summary: Resolve and inspect an XDCID name
      description: |
        Accepts a bare label or a canonical .xdc name. Returns canonical name
        data, forward resolution, availability, registration status, pricing,
        expiry, and profile records.
      tags:
        - Names
      parameters:
        - name: name
          in: path
          required: true
          description: Bare label or .xdc name.
          schema:
            type: string
          examples:
            bare:
              value: alice
            canonical:
              value: alice.xdc
        - name: years
          in: query
          required: false
          description: Number of registration years used for the price quote.
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 1
      responses:
        "200":
          description: Name data returned.
          headers:
            Cache-Control:
              $ref: "#/components/headers/CacheControl"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NameResponse"
        "400":
          description: The name or years value is invalid.
          headers:
            Cache-Control:
              $ref: "#/components/headers/CacheControl"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiErrorResponse"
              examples:
                invalidName:
                  value:
                    version: v1
                    error:
                      code: INVALID_NAME
                      message: Invalid XDCID name
                invalidYears:
                  value:
                    version: v1
                    error:
                      code: INVALID_YEARS
                      message: years must be an integer between 1 and 100
        "429":
          $ref: "#/components/responses/RateLimited"
        "503":
          $ref: "#/components/responses/RpcUnavailable"
  /api/v1/reverse/{address}:
    get:
      operationId: getReverseName
      summary: Reverse-resolve an XDC address
      description: |
        Returns the verified primary name for an address. The name is null when
        no record exists or the stored reverse record no longer matches the
        current name owner.
      tags:
        - Reverse resolution
      parameters:
        - name: address
          in: path
          required: true
          description: EVM-compatible XDC address.
          schema:
            $ref: "#/components/schemas/Address"
      responses:
        "200":
          description: Reverse-resolution result returned.
          headers:
            Cache-Control:
              $ref: "#/components/headers/CacheControl"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReverseResponse"
        "400":
          description: The address is invalid.
          headers:
            Cache-Control:
              $ref: "#/components/headers/CacheControl"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiErrorResponse"
              example:
                version: v1
                error:
                  code: INVALID_ADDRESS
                  message: address must be a valid EVM address
        "429":
          $ref: "#/components/responses/RateLimited"
        "503":
          $ref: "#/components/responses/RpcUnavailable"
  /api/v1/addresses/{address}/names:
    get:
      operationId: getOwnedNames
      summary: List all active XDCID names owned by an address
      description: |
        Discovers registrations through XDCScan, then verifies current
        ownership and expiry directly against the XDCID registry. The response
        includes the address's verified primary ID and every active owned name.
      tags:
        - Wallet names
      parameters:
        - name: address
          in: path
          required: true
          description: EVM-compatible XDC address.
          schema:
            $ref: "#/components/schemas/Address"
      responses:
        "200":
          description: Verified primary ID and owned names returned.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OwnedNamesResponse"
        "400":
          $ref: "#/components/responses/InvalidRequest"
        "429":
          $ref: "#/components/responses/RateLimited"
        "503":
          $ref: "#/components/responses/IndexUnavailable"
  /api/xdcai/v1/resolve/{name}:
    get:
      operationId: getGatewayResolution
      summary: Resolve an XDCID name
      description: Protected upstream endpoint for the paid XDC AI capability.
      tags:
        - XDC AI gateway
      security:
        - XdcAiGatewayKey: []
      parameters:
        - name: name
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Ownership, forward resolution, and expiry returned.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ResolveResponse"
        "400":
          $ref: "#/components/responses/InvalidRequest"
        "401":
          $ref: "#/components/responses/GatewayUnauthorized"
        "503":
          $ref: "#/components/responses/GatewayServiceUnavailable"
  /api/xdcai/v1/reverse/{address}:
    get:
      operationId: getGatewayReverseResolution
      summary: Reverse-resolve an XDC address
      description: Protected upstream endpoint for the paid XDC AI capability.
      tags:
        - XDC AI gateway
      security:
        - XdcAiGatewayKey: []
      parameters:
        - name: address
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/Address"
      responses:
        "200":
          description: Verified reverse-resolution result returned.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReverseResponse"
        "400":
          $ref: "#/components/responses/InvalidRequest"
        "401":
          $ref: "#/components/responses/GatewayUnauthorized"
        "503":
          $ref: "#/components/responses/GatewayServiceUnavailable"
  /api/xdcai/v1/owned-names/{address}:
    get:
      operationId: getGatewayOwnedNames
      summary: List all active XDCID names owned by an address
      description: Protected upstream endpoint for the paid XDC AI capability.
      tags:
        - XDC AI gateway
      security:
        - XdcAiGatewayKey: []
      parameters:
        - name: address
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/Address"
      responses:
        "200":
          description: Verified primary ID and owned names returned.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OwnedNamesResponse"
        "400":
          $ref: "#/components/responses/InvalidRequest"
        "401":
          $ref: "#/components/responses/GatewayUnauthorized"
        "503":
          $ref: "#/components/responses/GatewayServiceUnavailable"
  /api/xdcai/v1/availability/{name}:
    get:
      operationId: getGatewayAvailability
      summary: Check availability and pricing
      description: Protected upstream endpoint for the paid XDC AI capability.
      tags:
        - XDC AI gateway
      security:
        - XdcAiGatewayKey: []
      parameters:
        - name: name
          in: path
          required: true
          schema:
            type: string
        - name: years
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 1
      responses:
        "200":
          description: Availability, expiry, and pricing returned.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AvailabilityResponse"
        "400":
          $ref: "#/components/responses/InvalidRequest"
        "401":
          $ref: "#/components/responses/GatewayUnauthorized"
        "503":
          $ref: "#/components/responses/GatewayServiceUnavailable"
  /api/xdcai/v1/profile/{name}:
    get:
      operationId: getGatewayProfile
      summary: Read XDCID profile records
      description: Protected upstream endpoint for the paid XDC AI capability.
      tags:
        - XDC AI gateway
      security:
        - XdcAiGatewayKey: []
      parameters:
        - name: name
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Profile records returned.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProfileResponse"
        "400":
          $ref: "#/components/responses/InvalidRequest"
        "401":
          $ref: "#/components/responses/GatewayUnauthorized"
        "503":
          $ref: "#/components/responses/GatewayServiceUnavailable"
  /api/v1/registrar/quote:
    post:
      operationId: createRegistrarQuote
      summary: Create a short-lived registration or renewal quote
      description: |
        Returns a ten-minute EIP-712 quote bound to the payer, owner, name,
        registrar, chain, policy version, and next nonce. The endpoint is
        available only after the registrar, policy, RPC, CoinGecko, and
        server-side signer settings are configured.
      tags:
        - Registration quotes
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - name
                - product
                - termYears
                - paymentCurrency
                - payer
                - nameOwner
              properties:
                name:
                  type: string
                  examples:
                    - alice.xdc
                product:
                  type: string
                  enum:
                    - registration
                    - renewal
                termYears:
                  type: integer
                  enum:
                    - 1
                    - 3
                    - 5
                    - 10
                paymentCurrency:
                  type: string
                  enum:
                    - XDC
                    - USDC
                payer:
                  $ref: "#/components/schemas/Address"
                nameOwner:
                  $ref: "#/components/schemas/Address"
      responses:
        "200":
          description: Signed quote returned.
          content:
            application/json:
              schema:
                type: object
                required:
                  - version
                  - data
                properties:
                  version:
                    type: string
                    const: v1
                  data:
                    type: object
                    required:
                      - authorizedForPayment
                      - chainId
                      - registrar
                      - policy
                      - product
                      - name
                      - paymentCurrency
                      - quote
                      - signature
                    properties:
                      authorizedForPayment:
                        type: boolean
                        const: true
                      chainId:
                        type: integer
                      registrar:
                        $ref: "#/components/schemas/Address"
                      policy:
                        $ref: "#/components/schemas/Address"
                      product:
                        type: string
                        enum:
                          - registration
                          - renewal
                      name:
                        type: string
                      paymentCurrency:
                        type: string
                        enum:
                          - XDC
                          - USDC
                      quote:
                        type: object
                      signature:
                        type: string
                        pattern: "^0x[a-fA-F0-9]+$"
                      market:
                        type:
                          - object
                          - "null"
        "400":
          description: Invalid request.
        "403":
          description: The payer is not authorized to renew the name.
        "409":
          description: The requested registration name is unavailable.
        "429":
          description: Quote request rate limit exceeded.
        "503":
          description: Quote signing, RPC, policy, or pricing is unavailable.
components:
  securitySchemes:
    XdcAiGatewayKey:
      type: apiKey
      in: header
      name: X-XDCID-Gateway-Key
      description: Server-only key injected by the XDC AI Gateway.
  headers:
    CacheControl:
      description: Application responses are not stored by shared or browser caches.
      schema:
        type: string
        const: no-store
    RetryAfter:
      description: Seconds until the client may retry.
      schema:
        type: integer
        minimum: 1
  responses:
    InvalidRequest:
      description: A path or query value is invalid.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiErrorResponse"
    GatewayUnauthorized:
      description: The gateway key is missing or invalid.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiErrorResponse"
          example:
            version: v1
            error:
              code: UNAUTHORIZED
              message: Invalid gateway credentials
    GatewayServiceUnavailable:
      description: The gateway key is not configured or XDC RPC is unavailable.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiErrorResponse"
    RateLimited:
      description: |
        The Vercel edge rate limit was exceeded. Because this response is
        generated before the application route runs, its body is
        platform-managed and is not part of the versioned JSON envelope.
      headers:
        Retry-After:
          $ref: "#/components/headers/RetryAfter"
    IndexUnavailable:
      description: XDCScan indexing or configured XDC RPC access is unavailable.
      headers:
        Cache-Control:
          $ref: "#/components/headers/CacheControl"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiErrorResponse"
    RpcUnavailable:
      description: All configured XDC RPC providers were unavailable.
      headers:
        Cache-Control:
          $ref: "#/components/headers/CacheControl"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiErrorResponse"
          example:
            version: v1
            error:
              code: XDC_RPC_UNAVAILABLE
              message: Unable to read the XDC Network
  schemas:
    ApiVersion:
      type: string
      enum:
        - v1
    Address:
      type: string
      pattern: "^0x[a-fA-F0-9]{40}$"
      examples:
        - "0xe82a4267CC310FC6Db334601671A043DFc8Ce06A"
    NameResponse:
      type: object
      additionalProperties: false
      required:
        - version
        - data
      properties:
        version:
          $ref: "#/components/schemas/ApiVersion"
        data:
          $ref: "#/components/schemas/NameData"
    ReverseResponse:
      type: object
      additionalProperties: false
      required:
        - version
        - data
      properties:
        version:
          $ref: "#/components/schemas/ApiVersion"
        data:
          $ref: "#/components/schemas/ReverseData"
    OwnedNamesResponse:
      type: object
      additionalProperties: false
      required:
        - version
        - data
      properties:
        version:
          $ref: "#/components/schemas/ApiVersion"
        data:
          $ref: "#/components/schemas/OwnedNamesData"
    OwnedNamesData:
      type: object
      additionalProperties: false
      required:
        - address
        - network
        - primaryName
        - names
      properties:
        address:
          $ref: "#/components/schemas/Address"
        network:
          $ref: "#/components/schemas/NameData/properties/network"
        primaryName:
          type:
            - string
            - "null"
          description: Verified canonical primary .xdc name, or null.
        names:
          type: array
          items:
            $ref: "#/components/schemas/OwnedName"
    OwnedName:
      type: object
      additionalProperties: false
      required:
        - name
        - node
        - primary
        - expiry
      properties:
        name:
          type: string
          description: Canonical lowercase name ending in .xdc.
        node:
          type: string
          pattern: "^0x[a-fA-F0-9]{64}$"
        primary:
          type: boolean
        expiry:
          type: object
          additionalProperties: false
          required:
            - timestamp
            - iso
          properties:
            timestamp:
              type: string
              pattern: "^[0-9]+$"
            iso:
              type: string
              format: date-time
    ApiErrorResponse:
      type: object
      additionalProperties: false
      required:
        - version
        - error
      properties:
        version:
          $ref: "#/components/schemas/ApiVersion"
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - INVALID_NAME
                - INVALID_ADDRESS
                - INVALID_YEARS
                - UNAUTHORIZED
                - NOT_FOUND
                - GATEWAY_UNAVAILABLE
                - XDC_INDEX_UNAVAILABLE
                - XDC_RPC_UNAVAILABLE
            message:
              type: string
    ResolveResponse:
      type: object
      additionalProperties: false
      required:
        - version
        - data
      properties:
        version:
          $ref: "#/components/schemas/ApiVersion"
        data:
          $ref: "#/components/schemas/ResolveData"
    AvailabilityResponse:
      type: object
      additionalProperties: false
      required:
        - version
        - data
      properties:
        version:
          $ref: "#/components/schemas/ApiVersion"
        data:
          $ref: "#/components/schemas/AvailabilityData"
    ProfileResponse:
      type: object
      additionalProperties: false
      required:
        - version
        - data
      properties:
        version:
          $ref: "#/components/schemas/ApiVersion"
        data:
          $ref: "#/components/schemas/ProfileData"
    ResolveData:
      type: object
      additionalProperties: false
      required:
        - name
        - label
        - node
        - network
        - registered
        - owner
        - resolvedAddress
        - expiry
      properties:
        name:
          $ref: "#/components/schemas/NameData/properties/name"
        label:
          $ref: "#/components/schemas/NameData/properties/label"
        node:
          $ref: "#/components/schemas/NameData/properties/node"
        network:
          $ref: "#/components/schemas/NameData/properties/network"
        registered:
          $ref: "#/components/schemas/NameData/properties/registered"
        owner:
          $ref: "#/components/schemas/NameData/properties/owner"
        resolvedAddress:
          $ref: "#/components/schemas/NameData/properties/resolvedAddress"
        expiry:
          $ref: "#/components/schemas/NameData/properties/expiry"
    AvailabilityData:
      type: object
      additionalProperties: false
      required:
        - name
        - label
        - node
        - network
        - available
        - registered
        - expiry
        - pricing
      properties:
        name:
          $ref: "#/components/schemas/NameData/properties/name"
        label:
          $ref: "#/components/schemas/NameData/properties/label"
        node:
          $ref: "#/components/schemas/NameData/properties/node"
        network:
          $ref: "#/components/schemas/NameData/properties/network"
        available:
          $ref: "#/components/schemas/NameData/properties/available"
        registered:
          $ref: "#/components/schemas/NameData/properties/registered"
        expiry:
          $ref: "#/components/schemas/NameData/properties/expiry"
        pricing:
          $ref: "#/components/schemas/Pricing"
    ProfileData:
      type: object
      additionalProperties: false
      required:
        - name
        - label
        - node
        - network
        - registered
        - owner
        - profile
      properties:
        name:
          $ref: "#/components/schemas/NameData/properties/name"
        label:
          $ref: "#/components/schemas/NameData/properties/label"
        node:
          $ref: "#/components/schemas/NameData/properties/node"
        network:
          $ref: "#/components/schemas/NameData/properties/network"
        registered:
          $ref: "#/components/schemas/NameData/properties/registered"
        owner:
          $ref: "#/components/schemas/NameData/properties/owner"
        profile:
          $ref: "#/components/schemas/Profile"
    NameData:
      type: object
      additionalProperties: false
      required:
        - name
        - label
        - node
        - network
        - available
        - registered
        - owner
        - resolvedAddress
        - expiry
        - pricing
        - profile
      properties:
        name:
          type: string
          description: Canonical lowercase name ending in .xdc.
          examples:
            - alice.xdc
        label:
          type: string
          description: Canonical lowercase label without the .xdc suffix.
          examples:
            - alice
        node:
          type: string
          pattern: "^0x[a-fA-F0-9]{64}$"
          description: keccak256 hash of the canonical name.
        network:
          type: object
          additionalProperties: false
          required:
            - chainId
            - name
          properties:
            chainId:
              type: integer
              const: 50
            name:
              type: string
        available:
          type: boolean
        registered:
          type: boolean
        owner:
          anyOf:
            - $ref: "#/components/schemas/Address"
            - type: "null"
        resolvedAddress:
          anyOf:
            - $ref: "#/components/schemas/Address"
            - type: "null"
        expiry:
          type: object
          additionalProperties: false
          required:
            - timestamp
            - iso
          properties:
            timestamp:
              type:
                - string
                - "null"
              pattern: "^[0-9]+$"
              description: Unix timestamp in seconds, encoded as a decimal string.
            iso:
              type:
                - string
                - "null"
              format: date-time
        pricing:
          $ref: "#/components/schemas/Pricing"
        profile:
          $ref: "#/components/schemas/Profile"
    ReverseData:
      type: object
      additionalProperties: false
      required:
        - address
        - name
        - verified
      properties:
        address:
          $ref: "#/components/schemas/Address"
        name:
          type:
            - string
            - "null"
          description: Verified canonical .xdc name, or null.
        verified:
          type: boolean
    Pricing:
      type: object
      additionalProperties: false
      required:
        - currency
        - years
        - perYear
        - total
      properties:
        currency:
          type: string
          const: XDC
        years:
          type: integer
          minimum: 1
          maximum: 100
        perYear:
          $ref: "#/components/schemas/Amount"
        total:
          $ref: "#/components/schemas/Amount"
    Amount:
      type: object
      additionalProperties: false
      required:
        - wei
        - xdc
      properties:
        wei:
          type: string
          pattern: "^[0-9]+$"
        xdc:
          type: string
          pattern: ^[0-9]+([.][0-9]+)?$
    Profile:
      type: object
      additionalProperties: false
      required:
        - avatar
        - website
        - twitter
        - telegram
        - bio
      properties:
        avatar:
          $ref: "#/components/schemas/NullableProfileValue"
        website:
          $ref: "#/components/schemas/NullableProfileValue"
        twitter:
          $ref: "#/components/schemas/NullableProfileValue"
        telegram:
          $ref: "#/components/schemas/NullableProfileValue"
        bio:
          $ref: "#/components/schemas/NullableProfileValue"
    NullableProfileValue:
      type:
        - string
        - "null"
