Skip to content
Back to skills

Websites

ASecurity

Use this skill when working with Hudu website records - website monitoring, SSL/TLS tracking, email security (DMARC, DKIM, SPF), DNS records, and linking websites to companies. Covers website CRUD, monitoring fields, and email security verification patterns.

  • 48 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 27, 2026
data-aijavascriptgojavaawsazureapisecuritydocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add wyre-technology/msp-claude-plugins --skill websites --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Websites?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Websites
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wyre-technology-websites/badge)](https://www.skillsdirectory.com/skills/wyre-technology-websites)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: "Hudu Websites"
description: >
  Use this skill when working with Hudu website records - website monitoring,
  SSL/TLS tracking, email security (DMARC, DKIM, SPF), DNS records, and
  linking websites to companies. Covers website CRUD, monitoring fields,
  and email security verification patterns.
when_to_use: "When working with website monitoring, SSL/TLS tracking, email security (DMARC, DKIM, SPF), DNS records, and linking websites to companies in Hudu website records"
triggers:
  - hudu website
  - website monitoring
  - ssl certificate
  - email security
  - dmarc check
  - dkim check
  - spf record
  - website management
  - hudu dns
  - website tracking
---

# Hudu Websites Management

## Overview

Websites in Hudu represent website records associated with client companies. Beyond basic URL tracking, Hudu provides monitoring for SSL/TLS certificates and email security standards (DMARC, DKIM, SPF). MSPs use website records to track client web properties, monitor certificate expiration, and verify email authentication configuration.

## Key Concepts

### Website Monitoring

Hudu can automatically monitor websites for:

| Monitoring Area | Description |
|----------------|-------------|
| SSL/TLS | Certificate validity, expiration date, issuer |
| DMARC | Domain-based Message Authentication, Reporting & Conformance |
| DKIM | DomainKeys Identified Mail |
| SPF | Sender Policy Framework |
| HTTP Status | Whether the site is reachable |

### Email Security Trifecta

The three email security standards that Hudu tracks:

| Standard | Purpose | DNS Record Type |
|----------|---------|----------------|
| **SPF** | Specifies authorized mail servers | TXT record on domain |
| **DKIM** | Cryptographic email authentication | TXT record on selector._domainkey |
| **DMARC** | Policy for handling failed SPF/DKIM | TXT record on _dmarc subdomain |

### Website Scope

Each website record is linked to a company. A company can have multiple website records (e.g., primary domain, marketing site, client portal).

## Field Reference

### Core Fields

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | integer | System | Auto-generated unique identifier |
| `company_id` | integer | Yes | Parent company |
| `name` | string | Yes | Website display name / URL |
| `slug` | string | System | URL-friendly identifier |
| `notes` | string | No | Additional notes |
| `paused` | boolean | No | Whether monitoring is paused |
| `disable_dns` | boolean | No | Disable DNS checks |
| `disable_ssl` | boolean | No | Disable SSL checks |
| `disable_whois` | boolean | No | Disable WHOIS checks |

### Monitoring Fields

| Field | Type | Description |
|-------|------|-------------|
| `url` | string | The monitored URL |
| `monitoring_status` | string | Current monitoring status |

### SSL/TLS Fields

| Field | Type | Description |
|-------|------|-------------|
| `ssl_status` | string | SSL certificate status |
| `ssl_expiration` | datetime | SSL certificate expiration date |
| `ssl_issuer` | string | SSL certificate issuer |

### Email Security Fields

| Field | Type | Description |
|-------|------|-------------|
| `dmarc_status` | string | DMARC record status |
| `dmarc_policy` | string | DMARC policy (none, quarantine, reject) |
| `dkim_status` | string | DKIM record status |
| `spf_status` | string | SPF record status |
| `spf_record` | string | SPF record value |

### DNS Fields

| Field | Type | Description |
|-------|------|-------------|
| `dns_a_records` | array | A record values |
| `dns_mx_records` | array | MX record values |
| `dns_ns_records` | array | NS record values |

### Metadata Fields

| Field | Type | Description |
|-------|------|-------------|
| `created_at` | datetime | Creation timestamp |
| `updated_at` | datetime | Last update timestamp |
| `object_type` | string | Always "Website" |
| `company_name` | string | Parent company name (read-only) |

## API Patterns

### List Websites

```http
GET /api/v1/websites
x-api-key: YOUR_API_KEY
Content-Type: application/json
```

**By Company:**
```http
GET /api/v1/websites?company_id=123
```

**By Name:**
```http
GET /api/v1/websites?name=acme.com
```

**With Pagination:**
```http
GET /api/v1/websites?page=1
```

### Get Single Website

```http
GET /api/v1/websites/456
x-api-key: YOUR_API_KEY
```

**Response:**
```json
{
  "website": {
    "id": 456,
    "company_id": 123,
    "company_name": "Acme Corporation",
    "name": "acme.com",
    "url": "https://www.acme.com",
    "notes": "Primary company website",
    "paused": false,
    "disable_dns": false,
    "disable_ssl": false,
    "disable_whois": false,
    "monitoring_status": "up",
    "ssl_status": "valid",
    "ssl_expiration": "2026-08-15T00:00:00.000Z",
    "ssl_issuer": "Let's Encrypt Authority X3",
    "dmarc_status": "pass",
    "dmarc_policy": "reject",
    "dkim_status": "pass",
    "spf_status": "pass",
    "spf_record": "v=spf1 include:_spf.google.com include:spf.protection.outlook.com ~all",
    "dns_a_records": ["203.0.113.10"],
    "dns_mx_records": ["aspmx.l.google.com"],
    "dns_ns_records": ["ns1.example.com", "ns2.example.com"],
    "created_at": "2024-03-15T10:30:00.000Z",
    "updated_at": "2026-02-20T08:00:00.000Z"
  }
}
```

### Create Website

```http
POST /api/v1/websites
Content-Type: application/json
x-api-key: YOUR_API_KEY
```

```json
{
  "website": {
    "name": "acme.com",
    "company_id": 123,
    "notes": "Primary company website. Hosted on AWS.",
    "paused": false,
    "disable_dns": false,
    "disable_ssl": false,
    "disable_whois": false
  }
}
```

### Update Website

```http
PUT /api/v1/websites/456
Content-Type: application/json
x-api-key: YOUR_API_KEY
```

```json
{
  "website": {
    "notes": "Primary company website. Migrated to Azure on 2026-02-15.",
    "paused": false
  }
}
```

### Delete Website

```http
DELETE /api/v1/websites/456
x-api-key: YOUR_API_KEY
```

## Common Workflows

### SSL Expiration Monitoring

```javascript
async function getExpiringSslCerts(daysAhead = 30) {
  const today = new Date();
  const futureDate = new Date();
  futureDate.setDate(futureDate.getDate() + daysAhead);

  const websites = await fetchAllWebsites();

  return websites
    .filter(w => {
      if (!w.ssl_expiration || w.paused) return false;
      const expiry = new Date(w.ssl_expiration);
      return expiry >= today && expiry <= futureDate;
    })
    .map(w => ({
      name: w.name,
      company: w.company_name,
      sslExpiration: w.ssl_expiration,
      daysRemaining: Math.ceil(
        (new Date(w.ssl_expiration) - today) / (1000 * 60 * 60 * 24)
      ),
      issuer: w.ssl_issuer
    }))
    .sort((a, b) => a.daysRemaining - b.daysRemaining);
}
```

### Email Security Audit

```javascript
async function emailSecurityAudit(companyId) {
  const websites = await fetchWebsites({ company_id: companyId });

  return websites.map(w => ({
    domain: w.name,
    spf: {
      status: w.spf_status || 'Not checked',
      record: w.spf_record || 'Not found'
    },
    dkim: {
      status: w.dkim_status || 'Not checked'
    },
    dmarc: {
      status: w.dmarc_status || 'Not checked',
      policy: w.dmarc_policy || 'Not set'
    },
    overallScore: calculateEmailSecurityScore(w)
  }));
}

function calculateEmailSecurityScore(website) {
  let score = 0;
  if (website.spf_status === 'pass') score += 33;
  if (website.dkim_status === 'pass') score += 33;
  if (website.dmarc_status === 'pass') score += 34;
  if (website.dmarc_policy === 'reject') score += 10; // bonus for strict policy
  return Math.min(score, 100);
}
```

### Website Inventory Report

```javascript
async function generateWebsiteReport(companyId) {
  const websites = await fetchWebsites({ company_id: companyId });

  return {
    total: websites.length,
    monitored: websites.filter(w => !w.paused).length,
    paused: websites.filter(w => w.paused).length,
    sslValid: websites.filter(w => w.ssl_status === 'valid').length,
    sslExpiring: websites.filter(w => {
      if (!w.ssl_expiration) return false;
      const daysLeft = Math.ceil(
        (new Date(w.ssl_expiration) - new Date()) / (1000 * 60 * 60 * 24)
      );
      return daysLeft <= 30;
    }).length,
    emailSecurityComplete: websites.filter(w =>
      w.spf_status === 'pass' &&
      w.dkim_status === 'pass' &&
      w.dmarc_status === 'pass'
    ).length,
    websites: websites.map(w => ({
      name: w.name,
      ssl: w.ssl_status,
      sslExpiry: w.ssl_expiration,
      spf: w.spf_status,
      dkim: w.dkim_status,
      dmarc: w.dmarc_status
    }))
  };
}
```

### Onboard Client Domains

```javascript
async function onboardClientDomains(companyId, domains) {
  const results = [];

  for (const domain of domains) {
    const website = await createWebsite({
      name: domain.name,
      company_id: companyId,
      notes: domain.notes || `Added during onboarding on ${new Date().toLocaleDateString()}`,
      paused: false
    });
    results.push(website);
  }

  return results;
}
```

## Error Handling

### Common API Errors

| Code | Message | Resolution |
|------|---------|------------|
| 400 | Name can't be blank | Provide website name/domain |
| 400 | Company is required | Include company_id |
| 401 | Invalid API key | Check HUDU_API_KEY |
| 404 | Website not found | Verify website ID |
| 422 | Validation failed | Check required fields |

### Validation Errors

| Error | Cause | Fix |
|-------|-------|-----|
| Name required | Missing name | Add domain name to request |
| Company required | No company_id | Include company_id |
| Invalid company | Bad company_id | Query /companies first |
| Duplicate domain | Domain already tracked | Check existing websites first |

### Error Recovery Pattern

```javascript
async function safeCreateWebsite(data) {
  try {
    return await createWebsite(data);
  } catch (error) {
    if (error.status === 422 && error.message?.includes('already')) {
      // Website already exists - find and return it
      const existing = await fetchWebsites({
        company_id: data.company_id,
        name: data.name
      });
      return existing[0];
    }

    throw error;
  }
}
```

## Best Practices

1. **Track all client domains** - Add every domain the client owns
2. **Monitor SSL certificates** - Set up alerts for expiring certificates
3. **Verify email security** - Check SPF, DKIM, DMARC for all domains
4. **Document hosting info** - Use notes to record hosting provider and account details
5. **Regular audits** - Verify website records match actual client domains quarterly
6. **Don't pause monitoring** - Keep monitoring active unless there is a specific reason to pause
7. **Track secondary domains** - Include marketing sites, client portals, subdomains
8. **DMARC enforcement** - Work toward "reject" policy for all client domains
9. **Link to credentials** - Cross-reference with Hudu passwords for domain registrar and hosting credentials
10. **Record DNS providers** - Note which DNS provider each domain uses

## Related Skills

- [Hudu Companies](../companies/SKILL.md) - Website company scope
- [Hudu Passwords](../passwords/SKILL.md) - Domain registrar and hosting credentials
- [Hudu Articles](../articles/SKILL.md) - DNS and hosting documentation
- [Hudu Assets](../assets/SKILL.md) - Server/hosting infrastructure
- [Hudu API Patterns](../api-patterns/SKILL.md) - API reference

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.