API: sites and clients

List and filter sites, read a site's plugins and themes, add sites, refresh inventory.

Updated Oct 11, 2026

List sites

GET /sites

Ability: read. Optional filters:

client_id Only this client’s sites
status connected, pending, disconnected
search Part of the name or URL
plugin Sites with a plugin whose name or slug contains this
plugin_below With plugin: only where it’s older than this version
has_updates 1 for sites with updates waiting
# Which sites run Gravity Forms older than 3.0?
curl "https://app.wpforeman.com/api/v1/sites?plugin=gravityforms&plugin_below=3.0" \
  -H "Authorization: Bearer YOUR_TOKEN"
{
  "data": [{
    "id": 12, "name": "Shop", "url": "https://shop.example", "status": "connected",
    "client": { "id": 3, "name": "Acme" },
    "wordpress_version": "6.9.1", "php_version": "8.3.14", "plugin_version": "0.5.0",
    "updates_available": 2, "last_seen_at": "2026-10-04T13:02:11+00:00",
    "inventory_checked_at": "2026-10-04T13:02:11+00:00", "last_error": null
  }]
}

Get one site

GET /sites/{id}

Ability: read. Adds core, plugins, themes (each with version, active, update_available, new_version), last_backup and backup_storage_bytes (what this site’s backups take up in storage).

Add a site

POST /sites

Ability: sites. Body: name, url, optional client_id. The response includes a one-time connection_key (valid 24 hours) and the plugin download URL. Paste the key into Settings › WP Foreman on the site. Answers 403 if your account is at its site limit.

DELETE /sites/{id}

Ability: sites. Removes the site. Its backups are kept for 30 days (it can be brought back from the Sites page until then), then deleted. Answers 409 while a backup, restore or update is running. See Disconnecting a site.

Refresh inventory

POST /sites/{id}/refresh

POST /sites/refresh

Ability: sites. Checks one site, or every connected site at once. The all-sites version returns [{ site_id, ok, error }].

Clients

GET /clients

POST /clients

PATCH /clients/{id}

Reading needs read; creating and updating need sites. Fields: name (required to create), contact_name, phone, website, report_emails (array), brand_color (#rrggbb), notes. PATCH changes only the fields you send. Logos are uploaded in the app. To move a site to a client, send client_id when adding the site, or change it in the app.

Activity log

GET /sites/{id}/activity

GET /activity/{id}

Ability: read. Every plugin, theme and core change, with summary lines like "Yoast SEO 26.1 → 26.2".

Site log

GET /log

GET /sites/{id}/log

Ability: read. The site log, newest first (see The site log). Optional filters: category (backups, restores, changes, detected, connection, access, users, rules, uptime, performance, reports, security, visual; repeat as category[] for several), type (one entry type such as wp.plugins.install; repeat as type[]), level (info, success, warning, error), q (text search), range (today, 7d, 30d, this_month, last_month), from and to (YYYY-MM-DD, in your timezone), and on /log only site (site id). Paginated with page and per_page.

Each entry: id, site_id, site_name, category, type (for example backup.succeeded, plugins.update, site.change_detected, admin.login), level, title, details (object; varies by type), actor_type (user, foreman, api, schedule, rule, site, site_user, support, system), actor_label, occurred_at.

curl -H "Authorization: Bearer wpf_…" \
  "https://app.wpforeman.com/api/v1/sites/12/log?level[]=warning&level[]=error&from=2026-10-01"

Notes

GET /sites/{id}/notes

POST /sites/{id}/notes

PATCH /sites/{id}/notes/{note}

DELETE /sites/{id}/notes/{note}

Abilities: read to list, sites to add, change and delete. Body: body (text, up to 10,000 characters) and pinned (true/false). Each note: id, body, pinned, by, created_at, updated_at; pinned first. See Site overview, notes and settings.

Performance

GET /sites/{id}/performance

Ability: read. Latest PageSpeed result for mobile and desktop: score (0–100), lcp_ms, tbt_ms, cls, fcp_ms, si_ms, ttfb_ms, field (real-visitor Core Web Vitals when Google has them, each with value and rating), opportunities, checked_at; plus history (90 days of scores). See Site speed.

GET /sites/{id}/visual

Ability: read. Visual checks: pages (each path and label), threshold (percent changed that gets flagged), and the last 10 checks, each with status (queued, running, done, changed, failed), changed (screenshots over the threshold) and shots (path, device desktop|mobile, diff_pct, error). See Visual checks.

POST /sites/{id}/visual/check

Ability: sites. Starts a check now. Answers 202 with the check’s id, or 409 if one is already running.

Uptime

GET /sites/{id}/uptime

Ability: read. Current status (up, down, blocked, unknown), uptime percentages for 24h, 7d and 30d, the last 20 incidents (each with reason, regions, started_at, ended_at, seconds), ssl.expires_at, domain.expires_at, and a series of checks. Optional range: 24h (every check), 7d or 30d (hourly). See How uptime monitoring works.

Site traffic

GET /sites/{id}/analytics

Ability: read. Traffic from the site’s Google Analytics, Plausible or Umami (see Connect Plausible or Umami). Optional range: 7d, 30d (default), 90d. Answers 409 if analytics isn’t set up for the site, 502 if the analytics service refused.

{ "data": {
  "provider": "plausible", "range": "30d", "from": "2026-09-08", "to": "2026-10-07",
  "totals":   { "visitors": 1840, "visits": 2310, "pageviews": 5120, "bounce_rate": 48, "avg_duration": 74 },
  "previous": { "visitors": 1610, "visits": 2050, "pageviews": 4700, "bounce_rate": 52, "avg_duration": 69 },
  "series":   [ { "date": "2026-09-08", "visitors": 61, "pageviews": 170 } ],
  "pages":    [ { "name": "/", "visitors": 900, "pageviews": 1300 } ],
  "sources":  [ { "name": "Google", "visitors": 700 } ],
  "fetched_at": "2026-10-07T14:02:11+00:00"
} }

avg_duration is in seconds, bounce_rate a percentage. For Umami, pages[].pageviews is null and visitors holds pageviews.

While you were away

GET /digest

Ability: read. The crew report described in While you were away, for any period. Optional since and until (ISO 8601; default the last 24 hours, at most 31 days back). Handy for posting a morning summary to Slack or your own dashboard.

{ "data": {
  "since_label": "since yesterday 7:00 AM",
  "headline": "The crew backed up 14 sites and applied 9 updates. 1 thing needs you. 2 things are ready for your OK.",
  "needs_you": [ { "kind": "backup", "level": "error", "site_id": 3, "site": "Acme Plumbing", "text": "Last backup failed: …", "href": "/sites/3/backups" } ],
  "ready": [ { "kind": "core", "site_id": 3, "site": "Acme Plumbing", "text": "WordPress 6.8.1 → 6.8.2 (security and bug fixes)",
               "action": "update", "picks": [ { "site_id": 3, "type": "core", "slug": "core" } ], "href": "/sites/3/plugins" } ],
  "crew": [ { "key": "lockup", "name": "Lockup", "role": "Backups", "lines": ["Backed up 14 sites, all good."], "count": 14, "ok": true } ],
  "good_to_know": [ { "site_id": null, "site": null, "text": "Your rules will take care of 6 more updates: Patch Tuesday (Tue 2:00 AM).", "href": "/rules" } ],
  "quiet": false
} }

To approve a ready item, send its picks to POST /updates (ability plugins); see API: plugins, themes and updates. href paths are relative to https://app.wpforeman.com.

Security

GET /sites/{id}/security

Ability: read. Open known vulnerabilities (worst first) with name, type, installed_version, fixed_in, severity, cvss_score, title, cve, link; counts by severity; issues fixed in the last 90 days; and when the vulnerability list was last updated. See Known vulnerabilities.

Client reports

GET /sites/{id}/reports

Ability: read. The site’s reports, newest first: { id, label, from, to, highlights, public_url, created_at, sent_at, sent_to }.

POST /sites/{id}/reports

Ability: sites. Send preset (last_month, this_month, last_7, last_30, last_quarter) or from and to (YYYY-MM-DD, inclusive, in your timezone). Optional sections: any of attention, updates, uptime, backups, speed, traffic, worklog, health, visual (saved as the site’s default; left out = the site’s saved choice). Answers 201 with the report, including report: the full snapshot (highlights, updates, backups, uptime, performance, traffic, health). See Client reports.

curl -X POST https://app.wpforeman.com/api/v1/sites/12/reports \
  -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{"from":"2026-09-01","to":"2026-09-30"}'

GET /reports/{id}

Ability: read. One report with its snapshot.

DELETE /reports/{id}

Ability: sites. Deletes it and turns off its client link.

POST /reports/{id}/send

Ability: sites. Emails the report: to (array of up to 10 addresses), optional note, optional remember (default true: saves the addresses on the site’s client). Answers { sent_to, sent_at }.

Was this helpful?