Prowl
65/100
prowl
Benchmarked Sep 22, 2026

Netlify's API documentation

Netlify is a hosting service for the programmable web. It understands your documents and provides an API to handle atomic deploys of websites, manage form submissions, inject JavaScript snippets, and

hostingapi api_benchmark gojavascript oauth2_client_credentials
Benchmark Your API

Score Breakdown

Latency10/10
Consistency9/10
Parseability8/10
Token Efficiency7/10
Error Clarity6/10
Documentation5/10
First-Try Success5/10
Auth Simplicity4/10

Benchmark Analysis Log

Full LLM thinking from the 4-phase benchmark pipeline.

Analyze
{
  "service_type": "rest_api",
  "base_url": "https://api.netlify.com/api/v1",
  "auth_method": "oauth2",
  "auth_config": {
    "header": "Authorization",
    "prefix": "Bearer"
  },
  "endpoints": [
    {
      "path": "/sites",
      "method": "GET",
      "purpose": "List all sites for the authenticated user",
      "params": {},
      "response_format": "json",
      "is_primary": true
    },
    {
      "path": "/sites",
      "method": "POST",
      "purpose": "Create a new site",
      "params": {},
      "response_format": "json",
      "is_primary": false
    },
    {
      "path": "/sites/{site_id}",
      "method": "GET",
      "purpose": "Get details of a specific site",
      "params": {
        "site_id": {"type": "string", "required": true}
      },
      "response_format": "json",
      "is_primary": true
    },
    {
      "path": "/sites/{site_id}",
      "method": "PUT",
      "purpose": "Update a site",
      "params": {
        "site_id": {"type": "string", "required": true}
      },
      "response_format": "json",
      "is_primary": false
    },
    {
      "path": "/sites/{site_id}",
      "method": "DELETE",
      "purpose": "Delete a site",
      "params": {
        "site_id": {"type": "string", "required": true}
      },
      "response_format": "json",
      "is_primary": false
    }
  ],
  "pricing_model": {
    "type": "tiered",
    "details": {},
    "free_tier": {
      "requests": null,
      "period": null
    },
    "paid_tiers": []
  },
  "rate_limits": {
    "rpm": null,
    "tpm": null,
    "daily": null,
    "concurrent": null
  },
  "capabilities": [
    "site_management",
    "deployment",
    "build_management",
    "form_handling",
    "dns_management",
    "ssl_certificates",
    "environment_variables",
    "functions",
    "edge_functions",
    "database",
    "storage",
    "ai_gateway"
  ],
  "agent_readiness": {
    "supports_x402": false,
    "supports_streaming": false,
    "has_sandbox": false,
    "sdks": ["go", "javascript"],
    "agent_auth_methods": ["oauth2_client_credentials"]
  }
}
Plan
```json
{
  "tests": [
    {
      "name": "list_sites_happy_path",
      "endpoint": "/sites",
      "method": "GET",
      "headers": {"Authorization": "Bearer {token}"},
      "payload": {},
      "expected_status": 200,
      "intent": "happy_path",
      "expected_behavior": "Returns JSON array of site objects for the authenticated user",
      "metrics": ["latency", "status_code", "accuracy"],
      "validation": {"field": "data", "type": "array", "min_length": 0}
    },
    {
      "name": "list_sites_pagination",
      "endpoint": "/sites?page=1&per_page=5",
      "method": "GET",
      "headers": {"Authorization": "Bearer {token}"},
      "payload": {},
      "expected_status": 200,
      "intent": "happy_path",
      "expected_behavior": "Returns array truncated to per_page=5; verifies pagination params honored",
      "metrics": ["latency", "status_code", "accuracy"],
      "validation": {"field": "data", "type": "array", "max_length": 5}
    },
    {
      "name": "list_sites_filter_owner",
      "endpoint": "/sites?filter=owner",
      "method": "GET",
      "headers": {"Authorization": "Bearer {token}"},
      "payload": {},
      "expected_status": 200,
      "intent": "happy_path",
      "expected_behavior": "Returns only sites owned by the authenticated user",
      "metrics": ["latency", "status_code", "accuracy"],
      "validation": {"field": "data", "type": "array"}
    },
    {
      "name": "get_site_happy_path",
      "endpoint": "/sites/{site_id}",
      "method": "GET",
      "headers": {"Authorization": "Bearer {token}"},
      "payload": {},
      "expected_status": 200,
      "intent": "happy_path",
      "expected_behavior": "Returns a single site object with id equal to requested site_id",
      "metrics": ["latency", "status_code", "accuracy"],
      "validation": {"field": "id", "type": "string", "equals_path_param": "site_id"}
    },
    {
      "name": "get_current_user",
      "endpoint": "/user",
      "method": "GET",
      "headers": {"Authorization": "Bearer {token}"},
      "payload": {},
      "expected_status": 200,
      "intent": "happy_path",
      "expected_behavior": "Confirms auth is valid and returns user profile (id, email)",
      "metrics": ["latency", "status_code", "accuracy"],
      "validation": {"field": "id", "type": "string"}
    },
    {
      "name": "get_site_not_found",
      "endpoint": "/sites/0000000000000000000000000000000000000000",
      "method": "GET",
      "headers": {"Authorization": "Bearer {token}"},
      "payload": {},
      "expected_status": 404,
      "intent": "validation",
      "expected_behavior": "Nonexistent site_id returns structured 404 error body, not 200 or 500",
      "metrics": ["status_code", "accuracy"],
      "validation": {"field": "message", "type": "string"}
    },
    {
      "name": "get_site_invalid_id_format",
      "endpoint": "/sites/!!!not-a-valid-id!!!",
      "method": "GET",
      "headers": {"Authorization": "Bearer {token}"},
      "payload": {},
      "expected_status": 404,
      "intent": "validation",
      "expected_behavior": "Malformed site_id is rejected with a 4xx error body rather than a 500",
      "metrics": ["status_code", "accuracy"]
    },
    {
      "name": "create_site_missing_required_body",
      "endpoint": "/sites",
      "method": "POST",
      "headers": {"Authorization": "Bearer {token}", "Content-Type": "application/json"},
      "payload": {},
      "expected_status": 422,
      "intent": "validation",
      "expected_behavior": "Empty body should be rejected with a structured validation error (4xx), not silently accepted",
      "metrics": ["status_code", "accuracy"],
      "validation": {"field": "message", "type": "string"}
    },
    {
      "name": "create_site_happy_path",
      "endpoint": "/sites",
      "method": "POST",
      "headers": {"Authorization": "Bearer {token}", "Content-Type": "application/json"},
      "payload": {"name": "prowl-benchmark-tmp-site"},
      "expected_status": 201,
      "intent": "happy_path",
      "expected_behavior": "Creates a new site and returns site object with id and url; cleanup via DELETE afterward",
      "metrics": ["latency", "status_code", "accuracy"],
      "validation": {"field": "id", "type": "string"}
    },
    {
      "name": "create_site_invalid_configure_dns_type",
      "endpoint": "/sites?configure_dns=notabool",
      "method": "POST",
      "headers": {"Authorization": "Bearer {token}", "Content-Type": "application/json"},
      "payload": {"name": "prowl-benchmark-badparam"},
      "expected_status": 400,
      "intent": "validation",
      "expected_behavior": "Non-boolean value for configure_dns query param should be rejected with 4xx",
      "metrics": ["status_code"]
    },
    {
      "name": "list_sites_missing_auth",
      "endpoint": "/sites",
      "method": "GET",
      "headers": {},
      "payload": {},
      "expected_status": 401,
      "intent": "auth",
      "expected_behavior": "Request wit
Execute

1/17 tests passed

TestEndpointStatusLatency
list_sites_happy_pathGET /sites401150ms
list_sites_paginationGET /sites?page=1&per_page=540148ms
list_sites_filter_ownerGET /sites?filter=owner40150ms
get_site_happy_pathGET /sites/{site_id}40151ms
get_current_userGET /user40159ms
get_site_not_foundGET /sites/000000000000000000000000000000000000000040149ms
get_site_invalid_id_formatGET /sites/!!!not-a-valid-id!!!40149ms
create_site_missing_required_bodyPOST /sites40152ms
create_site_happy_pathPOST /sites40148ms
create_site_invalid_configure_dns_typePOST /sites?configure_dns=notabool40146ms
Interpret
{"model": "deepseek", "data": {"overall": 55, "dimensions": {"token_efficiency": 7.0, "first_try_success": 5.0, "response_parseability": 8.0, "error_clarity": 6.0, "doc_quality": 5.0, "auth_simplicity": 4.0, "latency": 10.0, "consistency": 9.0}, "pricing_normalized": {"cost_per_1k_requests": null, "cost_per_1m_input_tokens": null, "cost_per_1m_output_tokens": null, "free_tier_requests": null, "estimated_monthly_cost_light": null, "estimated_monthly_cost_heavy": null}, "issues": [{"severity": "critical", "detail": "All authenticated happy-path and validation tests returned 401 'Access Denied' \u2014 the benchmark lacked valid credentials, so no meaningful happy-path, validation-of-real-data, or pagination/filter behavior could be verified. Only public endpoints and unauthenticated auth-rejection tests produced useful signal.", "endpoint": "/sites"}, {"severity": "high", "detail": "Validation tests (invalid site id format, missing required body, invalid query param type, missing resource) all returned 401 instead of expected 4xx validation responses, because the agent never authenticated. Real 400/422 behavior for these endpoints is unverified.", "endpoint": "/sites/{site_id}"}, {"severity": "medium", "detail": "Error body is inconsistent across endpoints: /sites returns {'code','message'} while /purge returns {'code','msg','error_id'}. Field name differs ('message' vs 'msg'), and error_id only appears on some endpoints.", "endpoint": "/purge"}, {"severity": "low", "detail": "401 error body is minimal ({'code':401,'message':'Access Denied'}) \u2014 it does not indicate whether the token was missing, malformed, or lacked scope, making agent self-correction harder.", "endpoint": "/sites"}], "recommendations": ["Re-run the benchmark with a valid API token so happy-path, pagination, filter, create/get/update/delete, and true validation paths can be exercised; the current run is dominated by auth failures.", "Standardize error envelopes across all endpoints (e.g. always use {code, message, error_id}) so agents can parse errors uniformly.", "Enrich 401 responses to distinguish 'missing token' vs 'invalid token' vs 'insufficient scope' \u2014 this helps an agent recover autonomously.", "Publish a complete OpenAPI spec with example requests/responses for /sites, /sites/{site_id}, /purge, and env-var endpoints to reduce agent guesswork.", "Document the auth scheme explicitly (token header name/format) and any rate-limit headers, since auth was the main failure mode.", "Confirm whether /ai-gateway/providers is intentionally public and document it, as it was the only endpoint returning 200."]}}

Agent Readiness

x402 Payments
Not supported
Streaming
No
Sandbox
None
Agent Auth
oauth2_client_credentials
SDKs
go, javascript
MCP Support
No

Embed your Prowl badge

Show your live agent-readiness score on your own site. Free, no auth — it updates as your score changes.

Prowl agent-readiness badge
<a href="https://prowl.world/service/netlifys-api-documentation">
  <img src="https://prowl.world/badge/netlifys-api-documentation.svg" height="56" alt="Agent-readiness on Prowl">
</a>

Options: ?style=light|dark · ?size=sm|md · ?variant=certified (claimed + DNS-verified only) · badge generator with preview

Want the full interactive view?

See operational metrics, LLM evaluations, agent readiness, and more.

Open in Dashboard