Domain Lab Domains API

The Domains API from Domain Lab — 10 operation(s) for domains.

Operations 14

GET /domains List all monitored domains with their latest scan snapshot #
POST /domains Start monitoring a new domain (counts as 5 requests against the monthly quota) #
GET /domains/{id} Get one domain with its full latest scan, DNS records, and latest AI review #
PATCH /domains/{id} Update monitoring settings for a domain #
DELETE /domains/{id} Stop monitoring and permanently delete a domain and all of its history #
GET /domains/{id}/scan Paginated scan history for one domain, newest first #
GET /domains/{id}/events Change events for one domain, newest first #
GET /domains/{id}/email Current email security for a domain: grade, SPF, DKIM, DMARC, mail servers… #
GET /domains/{id}/email/history Every distinct email security state for a domain, newest first, with what… #
POST /domains/{id}/rescan Queue an immediate scan of a domain (counts as 5 requests) #
POST /domains/{id}/ai-review Run a manual AI review of a domain (counts as 5 requests; uses monthly plan… #
GET /domains/{id}/ai-reviews Past AI reviews for a domain, newest first (degraded reviews excluded) #
GET /domains/{id}/alerts Alert settings for one domain: master switch and per-event-type mute state #
PUT /domains/{id}/alerts Change alert settings for one domain #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/domainlab-app:domainlab-app-domains-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

domainlab-app-domains-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Domain Lab Domains API
  version: 1.0.0
  description: 'REST API for Domain Lab, a domain-monitoring service. Query monitored domains, plan limits and usage, per-domain alert settings, AI reviews, registrar connections, WHOIS/registration data, SSL certificates, DNS records, email security (SPF, DKIM, DMARC, MTA-STS, TLS reporting, BIMI, DNSSEC) with grades and history, change events, and alert history; add, update, and remove monitored domains. Requires an active subscription or trial. Limits: 120 requests/minute, 50,000 requests/month (adding a domain, rescanning, running an AI review and syncing a registrar connection each count as 5). Every response carries X-RateLimit-Remaining-Minute and X-RateLimit-Remaining-Month headers.'
  contact:
    url: https://www.domainlab.app/help
servers:
- url: https://www.domainlab.app/api/v1
security:
- apiKey: []
tags:
- name: Domains
paths:
  /domains:
    get:
      operationId: listDomains
      summary: List all monitored domains with their latest scan snapshot
      parameters:
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          default: 50
          maximum: 100
          minimum: 1
        description: Maximum number of items to return
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          default: 0
          minimum: 0
        description: Number of items to skip
      responses:
        '200':
          description: Paginated domain list
          content:
            application/json:
              schema:
                type: object
                properties:
                  domains:
                    type: array
                    items:
                      $ref: '#/components/schemas/DomainSummary'
                  total:
                    type: integer
                  limit:
                    type: integer
                  offset:
                    type: integer
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
    post:
      operationId: addDomain
      summary: Start monitoring a new domain (counts as 5 requests against the monthly quota)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - domain_name
              properties:
                domain_name:
                  type: string
                  description: Bare hostname; scheme/path/port are stripped and it is lowercased
                frequency_interval:
                  type: string
                  description: Defaults to the fastest frequency your plan allows
                  enum:
                  - always
                  - hourly
                  - daily
                  - weekly
                  - monthly
                  - quarterly
                  - biannually
                  - annually
                notification_enabled:
                  type: boolean
                  default: true
      responses:
        '201':
          description: Domain created; first scan queued automatically
        '400':
          description: 'Invalid input. data.code is INVALID_BODY, MISSING_DOMAIN_NAME, INVALID_DOMAIN_NAME, INVALID_FREQUENCY, or FREQUENCY_NOT_IN_PLAN (data: { plan, allowed }).'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '409':
          description: Domain already exists for this account
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
  /domains/{id}:
    get:
      operationId: getDomain
      summary: Get one domain with its full latest scan, DNS records, and latest AI review
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      responses:
        '200':
          description: Domain detail. Includes latest_scan (Scan) and latest_ai_review ({ id, status, summary, completed_at, created_at } or null).
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: Not found or not owned by this account
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
    patch:
      operationId: updateDomain
      summary: Update monitoring settings for a domain
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Send at least one field
              properties:
                frequency_interval:
                  type: string
                  enum:
                  - always
                  - hourly
                  - daily
                  - weekly
                  - monthly
                  - quarterly
                  - biannually
                  - annually
                notification_enabled:
                  type: boolean
                monitoring_enabled:
                  type: boolean
      responses:
        '200':
          description: Updated domain settings
        '400':
          description: 'Invalid input or no updatable fields provided. data.code includes FREQUENCY_NOT_IN_PLAN (data: { plan, allowed }).'
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: Not found or not owned by this account
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
    delete:
      operationId: deleteDomain
      summary: Stop monitoring and permanently delete a domain and all of its history
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      responses:
        '200':
          description: Deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  deleted:
                    type: boolean
                  id:
                    type: integer
                  domain_name:
                    type: string
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: Not found or not owned by this account
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
  /domains/{id}/scan:
    get:
      operationId: getScanHistory
      summary: Paginated scan history for one domain, newest first
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          default: 10
          maximum: 50
          minimum: 1
        description: Maximum number of items to return
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          default: 0
          minimum: 0
        description: Number of items to skip
      responses:
        '200':
          description: Paginated scans
          content:
            application/json:
              schema:
                type: object
                properties:
                  scans:
                    type: array
                    items:
                      $ref: '#/components/schemas/Scan'
                  total:
                    type: integer
                  limit:
                    type: integer
                  offset:
                    type: integer
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: Not found or not owned by this account
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
  /domains/{id}/events:
    get:
      operationId: getDomainEvents
      summary: Change events for one domain, newest first
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          default: 50
          maximum: 100
          minimum: 1
        description: Maximum number of items to return
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          default: 0
          minimum: 0
        description: Number of items to skip
      responses:
        '200':
          description: Paginated events
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: Not found or not owned by this account
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
  /domains/{id}/email:
    get:
      operationId: getDomainEmailSecurity
      summary: 'Current email security for a domain: grade, SPF, DKIM, DMARC, mail servers…'
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      - name: full
        in: query
        required: false
        schema:
          type: boolean
          default: false
        description: Include the raw per-protocol results
      responses:
        '200':
          description: '{ domain_id, domain_name, checked_at, next_check_at, scan: { scan_id, grade, rubric, grade_reasons, first_seen_at, last_checked_at, protocols: [{ protocol, label, status, record, verdict, issues }], fixes, details? } | null }'
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: NOT_FOUND
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
  /domains/{id}/email/history:
    get:
      operationId: getDomainEmailSecurityHistory
      summary: Every distinct email security state for a domain, newest first, with what…
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          default: 10
          maximum: 50
          minimum: 1
        description: Maximum number of items to return
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          default: 0
          minimum: 0
        description: Number of items to skip
      responses:
        '200':
          description: '{ domain_id, domain_name, states: [{ scan_id, first_seen_at, last_checked_at, confirmed, grade, rubric, statuses, changes: [{ protocol, label, before, after, before_status, after_status }] }], total, limit, offset }'
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: NOT_FOUND
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
  /domains/{id}/rescan:
    post:
      operationId: rescanDomain
      summary: Queue an immediate scan of a domain (counts as 5 requests)
      description: 10-minute cooldown between scans.
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      responses:
        '202':
          description: 'Scan queued: { ok, domain_id, domain_name, queued_at }'
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: NOT_FOUND
        '409':
          description: 'MONITORING_DISABLED: enable monitoring first'
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
        '502':
          description: SCAN_START_FAILED
      tags:
      - Domains
  /domains/{id}/ai-review:
    post:
      operationId: runAiReview
      summary: Run a manual AI review of a domain (counts as 5 requests; uses monthly plan…
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      responses:
        '200':
          description: 'Review result: { review_id, status, degraded, summary, recommendations, quota }. degraded is true when AI enhancement was unavailable.'
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: NOT_FOUND
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
        '502':
          description: AI_REVIEW_FAILED
      tags:
      - Domains
  /domains/{id}/ai-reviews:
    get:
      operationId: listAiReviews
      summary: Past AI reviews for a domain, newest first (degraded reviews excluded)
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          default: 10
          maximum: 25
          minimum: 1
        description: Maximum reviews to return
      responses:
        '200':
          description: Reviews and manual-review quota
          content:
            application/json:
              schema:
                type: object
                properties:
                  reviews:
                    type: array
                    items:
                      $ref: '#/components/schemas/AiReview'
                  quota:
                    $ref: '#/components/schemas/Quota'
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: NOT_FOUND
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
  /domains/{id}/alerts:
    get:
      operationId: getDomainAlerts
      summary: 'Alert settings for one domain: master switch and per-event-type mute state'
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      responses:
        '200':
          description: Domain alert settings
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DomainAlerts'
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: NOT_FOUND
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
    put:
      operationId: updateDomainAlerts
      summary: Change alert settings for one domain
      description: 'threshold_days has no per-domain storage: it updates the account-wide threshold for that event type (response has thresholds_scope "account").'
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Domain id (find it via GET /domains)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Send notification_enabled and/or rules
              properties:
                notification_enabled:
                  type: boolean
                rules:
                  type: array
                  items:
                    type: object
                    required:
                    - event_type_id
                    properties:
                      event_type_id:
                        type: integer
                      is_enabled:
                        type: boolean
                        description: false mutes this alert type for the domain
                      threshold_days:
                        type: array
                        items:
                          type: integer
                          minimum: 0
                          maximum: 365
                        minItems: 1
                        maxItems: 10
                        description: Days-before reminders (account-wide)
      responses:
        '200':
          description: Updated domain alert settings
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DomainAlerts'
        '400':
          description: INVALID_BODY, NO_UPDATES, INVALID_THRESHOLD, or INVALID_EVENT_TYPE (data.invalid_ids)
        '401':
          description: Missing or invalid API key
        '403':
          description: Account lacks API access (no active subscription or trial)
        '404':
          description: NOT_FOUND
        '429':
          description: Rate limit or monthly quota exceeded. Respect the Retry-After header. code is RATE_LIMITED (short-lived) or MONTHLY_QUOTA_EXCEEDED (resets next period).
      tags:
      - Domains
components:
  schemas:
    Quota:
      type: object
      properties:
        used:
          type: integer
        limit:
          type: integer
        resets_at:
          type: string
          format: date-time
    DomainAlerts:
      type: object
      properties:
        domain_id:
          type: integer
        domain_name:
          type: string
        notification_enabled:
          type: boolean
        rules:
          type: array
          items:
            $ref: '#/components/schemas/AlertRule'
        thresholds_scope:
          type: string
          enum:
          - account
          description: Present on PUT when threshold_days changed; thresholds are account-wide
    Scan:
      type: object
      description: One monitoring result (scan snapshot) for a domain
      properties:
        id:
          type: integer
        checked_at:
          type: string
          format: date-time
        registrar:
          type:
          - string
          - 'null'
        expiration_date:
          type:
          - string
          - 'null'
          format: date-time
        creation_date:
          type:
          - string
          - 'null'
          format: date-time
        updated_date:
          type:
          - string
          - 'null'
          format: date-time
        domain_status:
          type:
          - string
          - 'null'
          description: Registry EPP status codes, normalized (sorted, lowercase), or "available"
        site_status:
          type:
          - string
          - 'null'
          enum:
          - available
          - parked
          - for-sale
          - dead
          - down
          - active
          - null
          description: Web-layer status computed each scan (down = the site answers with a server error); null when classification was unavailable
        ssl_issuer:
          type:
          - string
          - 'null'
        ssl_valid_from:
          type:
          - string
          - 'null'
          format: date-time
        ssl_valid_to:
          type:
          - string
          - 'null'
          format: date-time
        ssl_cipher:
          type:
          - string
          - 'null'
        ssl_protocol:
          type:
          - string
          - 'null'
        subject:
          type:
          - string
          - 'null'
        serial_number:
          type:
          - string
          - 'null'
        fingerprint:
          type:
          - string
          - 'null'
        security_score:
          type:
          - integer
          - 'null'
        nameservers:
          type:
          - string
          - 'null'
        error:
          type:
          - string
          - 'null'
          description: Non-null when this scan failed
        dns_records:
          type: array
          items:
            $ref: '#/components/schemas/DnsRecord'
    Error:
      type: object
      properties:
        statusCode:
          type: integer
        message:
          type: string
    DnsRecord:
      type: object
      properties:
        id:
          type: integer
        record_type:
          type: string
          description: A, AAAA, CNAME, MX, TXT, or NS
        name:
          type: string
        value:
          type: string
        ttl:
          type:
          - integer
          - 'null'
        priority:
          type:
          - integer
          - 'null'
          description: MX priority
    AiReview:
      type: object
      properties:
        id:
          type: integer
        review_type:
          type: string
        status:
          type: string
        summary:
          type:
          - string
          - 'null'
        recommendations:
          type:
          - array
          - object
          - 'null'
        ai_confidence_score:
          type:
          - number
          - 'null'
        completed_at:
          type:
          - string
          - 'null'
          format: date-time
        created_at:
          type: string
          format: date-time
    AlertRule:
      type: object
      properties:
        event_type_id:
          type: integer
        event_type_name:
          type: string
        muted:
          type: boolean
        is_enabled:
          type: boolean
    DomainSummary:
      type: object
      properties:
        id:
          type: integer
        domain_name:
          type: string
        notification_enabled:
          type: boolean
        monitoring_enabled:
          type: boolean
        frequency_interval:
          type: string
          enum:
          - always
          - hourly
          - daily
          - weekly
          - monthly
          - quarterly
          - biannually
          - annually
        last_checked_at:
          type:
          - string
          - 'null'
          format: date-time
        created_at:
          type: string
          format: date-time
        registrar:
          type:
          - string
          - 'null'
        ssl_issuer:
          type:
          - string
          - 'null'
        ssl_valid_to:
          type:
          - string
          - 'null'
          format: date-time
        security_score:
          type:
          - integer
          - 'null'
        nameservers:
          type:
          - string
          - 'null'
          description: Comma-separated nameserver hostnames
        days_until_domain_expires:
          type:
          - integer
          - 'null'
          description: Negative means already expired
        days_until_ssl_expires:
          type:
          - integer
          - 'null'
          description: Negative means already expired
        has_error:
          type: boolean
          description: True when the most recent scan failed
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: 'Domain Lab API key (dlb_...), created in Preferences → API. Send as: Authorization: Bearer dlb_...'