TOOL1 Optimizer API

Critical CSS generation, unused CSS removal, CSS formatting, visual regression testing and Lighthouse PageSpeed analysis.

General

Base URL: https://optimize.tool1.app/api

POST requests take a JSON body (Content-Type: application/json, up to 50 MB). All responses are JSON.

For backward compatibility, the same endpoints also work at https://tool1.app/api/… and at https://api.tool1.app/… (without the /api prefix).

Authentication

Every endpoint except GET /api requires an API key, sent in the X-API-Key request header.

HeaderValue
X-API-Key requiredYour API key.

Examples

curl -H "X-API-Key: YOUR_API_KEY" https://optimize.tool1.app/api/test_analyze

curl -X POST https://optimize.tool1.app/api/validate-css \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"css":"a { color: red; }"}'
// PHP / WordPress
$response = wp_remote_post( 'https://optimize.tool1.app/api/purge', [
    'headers' => [ 'X-API-Key' => 'YOUR_API_KEY', 'Content-Type' => 'application/json' ],
    'body'    => wp_json_encode( [ 'html' => $html, 'css' => $css ] ),
    'timeout' => 120,
] );

Response 401: missing or invalid key

{ "success": false, "error": "Unauthorized", "details": "Missing or invalid API key. Send it in the \"X-API-Key\" header." }

Error format

{
  "success": false,
  "error": "CSS Syntax Error",
  "details": { "message": "Unknown word", "line": 3, "column": 5 }
}

details can be an object or a string, and some errors omit it. Status codes: 400 invalid parameters, 401 missing or invalid API key, 404 not found, 422 empty result, 500 internal error.

Endpoints

GET

/api

Health check: confirms the service is running. No API key required.

Response 200

{ "success": true, "service": "TOOL1 Unified Optimizer API" }
GET

/api/test_analyze

X-API-Key

Connection test to run before starting an analysis. It returns immediately and does not run any analysis. Because it requires the API key, it also confirms the key is valid (401 otherwise).

Response 200

{ "success": true, "message": "Connection successful" }
GET

/api/analyze

X-API-Key

Runs a Lighthouse performance analysis (Performance category). Takes 15–60 seconds.

Query parameters

ParameterTypeDescription
url requiredstringPage to analyze (URL-encoded).
devicestringdesktop (default) or mobile.

Example

GET /api/analyze?url=https%3A%2F%2Fexample.com&device=mobile

Response 200

{
  "success": true,
  "score": 87,                  // 0–100, Performance score
  "lighthouseResult": { … }     // full Lighthouse LHR object (audits, categories, …)
}

Errors

400 { "success": false, "error": "Query parameter \"url\" is required." }
500 { "success": false, "error": "An internal error occurred during the Lighthouse analysis.", "details": "…" }
POST

/api/generate

X-API-Key

Generates Critical CSS. The page is loaded in headless Chrome and the CSS rules actually used during page load are returned. The CSS is not minified. Navigation timeout: 120 s.

Request body

FieldTypeDescription
url requiredstringPage URL.
devicestringdesktop (1366×768, default) or mobile (375×812).
{ "url": "https://example.com/", "device": "desktop" }

Response 200

{ "criticalCss": "body{margin:0}…" }

Errors

400 { "error": "URL is required" }
422 { "error": "Empty CSS Generated", "details": "Puppeteer could not extract any critical CSS. …" }
500 { "error": "Failed to generate critical CSS.", "details": "Puppeteer Error: Navigation timeout. …" }
POST

/api/purge

X-API-Key

Removes CSS that the given HTML does not use (PurgeCSS). The CSS is formatted with Prettier first.

Request body

FieldTypeDescription
html requiredstringPage HTML.
css requiredstringCSS to clean.
safeliststringSelectors to always keep, separated by spaces or commas (e.g. "active open is-visible").
{ "html": "<html>…</html>", "css": ".a{color:red}.unused{color:blue}", "safelist": "active, open" }

Response 200

{ "purgedCss": ".a {\n  color: red;\n}\n" }   // "" if nothing remains

Errors

400 { "success": false, "error": "HTML and CSS content are required." }
400 { "success": false, "error": "CSS Syntax Error", "details": { "message", "reason", "line", "column" } }
500 { "success": false, "error": "Internal Server Error", "details": { "message": "…" } }
POST

/api/css-exclude

X-API-Key

Same as /purge, then also removes the rules already present in css_to_exclude (usually the Critical CSS). A rule is removed only if all of its selectors appear in css_to_exclude.

Request body

FieldTypeDescription
html requiredstringPage HTML.
css requiredstringCSS to clean.
safeliststringSame as in /purge (separator: space, newline or comma).
css_to_excludestringCSS whose selectors are removed from the result.

Response 200

{ "purgedCss": "…" }

Errors

Same as /purge.

POST

/api/css-subtract

X-API-Key

Removes from base_css the rules whose selectors appear in subtract_css. A rule is removed only if all of its selectors match. Used, for example, to remove manual Critical CSS rules from the Global Fallback CSS.

Request body

FieldTypeDescription
base_css requiredstringSource CSS.
subtract_cssstringCSS to subtract. If empty, base_css is returned unchanged.
{ "base_css": "h1{color:red} .x{margin:0}", "subtract_css": "h1{color:blue}" }

Response 200

{ "success": true, "cleaned_css": ".x{margin:0}" }

Errors

400 { "success": false, "error": "Parameter \"base_css\" is required." }
500 { "success": false, "error": "Failed to process CSS subtraction.", "details": "…" }
POST

/api/validate-css

X-API-Key

Checks CSS syntax with stylelint (stylelint-config-standard). If there are problems, the first one found is returned.

Request body

FieldTypeDescription
css requiredstringCSS to validate.
{ "css": "a { color: red; }" }

Response 200

{ "success": true, "message": "CSS syntax is valid." }

Errors

400 { "error": "CSS content is required." }
400 { "success": false, "error": "CSS Syntax Error", "details": { "message": "…", "line": 1, "column": 3 } }
500 { "success": false, "error": "Internal Server Error", "details": { "message": "…" } }
POST

/api/postcss-format

X-API-Key

Finds the rules for a selector in all_css and adds only the new ones to existing_css. The result then has its properties sorted alphabetically, duplicates removed, and is formatted with Prettier.

Request body

FieldTypeDescription
selector requiredstringOne or more selectors, separated by commas.
all_css requiredstringThe full CSS to search in.
existing_css requiredstringThe current CSS that new rules are added to. May be an empty string "", but the field must be present.
search_modestringcontain (default): the rule's selector contains the searched selector. exact: exact match.
{ "selector": ".header", "all_css": "…", "existing_css": "", "search_mode": "contain" }

Response 200

{
  "success": true,
  "formatted_css": ".header {\n  color: red;\n}",
  "stats": { "total_found": 3, "added": 2, "already_present": 1 }
}

Errors

400 { "error": "Parameters \"selector\" and \"all_css\" are required." }
404 { "error": "Selector \".header\" not found in the provided CSS." }
500 { "success": false, "error": "Failed to process CSS.", "details": "…" }
POST

/api/visual-test

X-API-Key

Visual regression test. First create a baseline screenshot (baseline_only). Each full_test then takes a new screenshot and compares it pixel by pixel with the baseline. Test and diff screenshots are deleted automatically after 7 days.

Request body

FieldTypeDescription
url requiredstringPage URL (may be URL-encoded).
item_id requiredstring | numberItem ID (e.g. the post ID).
item_type requiredstringItem type (e.g. post, page).
actionstringfull_test (default) or baseline_only.
devicestringdesktop (1366×768, default) or mobile (375×812).
{ "url": "https://example.com/", "item_id": 42, "item_type": "page", "action": "baseline_only", "device": "desktop" }

Response 200: baseline_only

{ "success": true, "message": "Baseline created successfully.", "baseline_path": "baseline-page-42-desktop.png" }

Response 200: full_test

{
  "success": true,
  "isMatch": false,
  "diffPixels": 1534,
  "message": "Visual differences detected (1534 pixels).",
  "images": {                       // only when differences are found
    "baseline": "data:image/png;base64,…",
    "test":     "data:image/png;base64,…",
    "diff":     "data:image/png;base64,…"
  }
}

Errors

400 { "error": "Parameters \"url\", \"item_id\", and \"item_type\" are required." }
400 { "success": false, "error": "Baseline file baseline-page-42-desktop.png does not exist." }
400 { "error": "Unknown action: …" }
500 { "success": false, "error": "Failed to perform visual test.", "details": "…" }