Skip to content

Services

A vService is one protected hostname with its aliases, origins and settings. Every setting in this API section is a field of the service. Requests need a key, see API access.

Creating and deleting a vService over the API is for dedicated edges and own prefixes (BYOIP) only; a Shared vService is ordered in the customer portal and removed by cancelling the order. Both are configured the same way. Details: Shared and Dedicated.

Endpoints

Method Path Key Purpose
GET /attacks read Attacks running now on your vServices
GET /attacks/{month} read Attacks of one month on your vServices
GET /services read List your vServices
POST /services write Create a vService from one of your IP pools
GET /services/health read Health of all your vServices
DELETE /services/{fqdn} write Delete a vService of a dedicated or BYOIP account
GET /services/{fqdn} read Get a vService
PATCH /services/{fqdn} write Change a vService
GET /services/{fqdn}/dns read DNS records the vService expects
GET /services/{fqdn}/history read Change history of a vService
POST /services/{fqdn}/rename write Make an alias the primary name

GET /attacks

Returns: 200, AttackList

Answer 200
{
  "attacks": [
    {
      "fqdn": "a.example.com",
      "state": "under_attack",
      "start": "2026-10-04T08:00:00+00:00",
      "end": null,
      "ended_as": null,
      "reason": "protection_stack_stopping_traffic",
      "techniques": [
        "l7"
      ],
      "signals": {
        "requests_per_sec": 80.0,
        "blocked_per_sec": 50.0,
        "rejected_conn_per_sec": 2.0
      },
      "escalations": []
    }
  ]
}

GET /attacks/{month}

Returns: 200, AttackArchive

Answer 200
{
  "month": "2026-10",
  "attacks": [
    {
      "fqdn": "a.example.com",
      "state": "under_attack",
      "start": "2026-10-04T08:00:00+00:00",
      "end": null,
      "ended_as": null,
      "reason": "protection_stack_stopping_traffic",
      "techniques": [
        "l7"
      ],
      "signals": {
        "requests_per_sec": 80.0,
        "blocked_per_sec": 50.0,
        "rejected_conn_per_sec": 2.0
      },
      "escalations": []
    },
    {
      "fqdn": "tcp.example.com",
      "state": "under_attack",
      "start": "2026-10-03T10:00:00+00:00",
      "end": "2026-10-03T10:20:00+00:00",
      "ended_as": "normal",
      "reason": "l4_dropping_at_edge",
      "techniques": [
        "xdp"
      ],
      "signals": {
        "l4_dropped_pps": 90000.0
      },
      "escalations": [
        {
          "action": "rtbh",
          "site": "FRA2",
          "vip": "203.0.113.5",
          "start": "2026-10-03T10:02:00+00:00",
          "end": "2026-10-03T10:12:00+00:00"
        }
      ]
    }
  ]
}

GET /services

Returns: 200, list of ServiceSummary

Answer 200
[
  {
    "fqdn": "a.example.com",
    "tenant": "tenant-a",
    "account_id": "acc-a",
    "enabled": true,
    "mode": "https",
    "ports": [
      443
    ],
    "udp_ports": [],
    "network": {
      "vips": [
        {
          "anycast_ipv4": "203.0.113.1",
          "anycast_ipv6": "2001:db8:a::1"
        }
      ],
      "edge_hostname": "a-example-com.edge.protect.zeroservices.eu"
    },
    "waf": {},
    "maintenance_mode": false,
    "aliases": [
      {
        "fqdn": "www.a.example.com"
      }
    ],
    "edges": [],
    "alias_limit": 20,
    "serving_edges": [
      "shared-1"
    ],
    "posture_drift": [],
    "baseline": null,
    "delegations": [],
    "origin_count": 1,
    "redirect_count": 0
  },
  {
    "fqdn": "deleg.example.com",
    "tenant": "tenant-a",
    "account_id": "acc-a",
    "enabled": true,
    "mode": "https",
    "ports": [
      443
    ],
    "udp_ports": [],
    "network": {
      "vips": []
    },
    "waf": {},
    "maintenance_mode": false,
    "aliases": [],
    "edges": [],
    "alias_limit": 20,
    "serving_edges": [
      "shared-1"
    ],
    "posture_drift": [],
    "baseline": null,
    "delegations": [
      "EFFORTA"
    ],
    "origin_count": 0,
    "redirect_count": 0
  },
  {
    "fqdn": "tcp.example.com",
    "tenant": "tenant-a",
    "account_id": "acc-a",
    "enabled": true,
    "mode": "tcp",
    "ports": [
      5000
    ],
    "udp_ports": [
      5000
    ],
    "network": {
      "vips": [
        {
          "anycast_ipv4": "203.0.113.2",
          "anycast_ipv6": null
        }
      ]
    },
    "waf": {},
    "maintenance_mode": false,
    "aliases": [],
    "edges": [],
    "alias_limit": 20,
    "serving_edges": [
      "shared-1"
    ],
    "posture_drift": [],
    "baseline": null,
    "delegations": [],
    "origin_count": 1,
    "redirect_count": 0
  }
]

POST /services

Body: ServiceCreate
Returns: 201, Service

Request
{
  "account_id": "acc-a",
  "fqdn": "shop.example.com",
  "pool": "P-A",
  "origins": [
    {
      "address": "192.0.2.10",
      "port": 443
    }
  ]
}
Answer 201
{
  "fqdn": "shop.example.com",
  "tenant": "tenant-a",
  "account_id": "acc-a",
  "enabled": true,
  "ports": [
    443
  ],
  "created": "2026-10-01T00:00:00+00:00",
  "created_by": "",
  "network": {
    "vips": [
      {
        "anycast_ipv4": "203.0.113.1",
        "anycast_ipv6": "2001:db8:a::1"
      }
    ],
    "edge_hostname": "a-example-com.edge.protect.zeroservices.eu"
  },
  "origins": [
    {
      "name": "origin-1",
      "address": "192.0.2.10",
      "port": 443
    }
  ],
  "aliases": [],
  "cache": {
    "enabled": true
  },
  "alias_limit": 20,
  "serving_edges": [
    "shared-1"
  ],
  "posture_drift": [],
  "baseline": null
}

GET /services/health

Returns: 200, HealthOverview

Answer 200
{
  "summary": {
    "total": 3,
    "worst": "unknown",
    "counts": {
      "blackholed": 0,
      "origin_down": 0,
      "misconfigured": 0,
      "errors": 0,
      "origin_slow": 0,
      "under_attack": 0,
      "normal": 0,
      "maintenance": 0,
      "disabled": 0,
      "unknown": 3
    }
  },
  "services": {
    "a.example.com": {
      "status": "unknown",
      "fault": "none",
      "reason": "warming_up",
      "signals": {
        "requests_per_sec": 2.0,
        "errors_per_sec": 2.0,
        "error_ratio": 1.0,
        "origin_response_seconds": null,
        "origins_up": null,
        "origins_total": null
      }
    },
    "deleg.example.com": {
      "status": "unknown",
      "fault": "none",
      "reason": "warming_up",
      "signals": {
        "requests_per_sec": 0.0,
        "errors_per_sec": 0.0,
        "error_ratio": 0.0,
        "origin_response_seconds": null,
        "origins_up": null,
        "origins_total": null
      }
    },
    "tcp.example.com": {
      "status": "unknown",
      "fault": "none",
      "reason": "dns_not_measured",
      "signals": {
        "requests_per_sec": 0.0,
        "errors_per_sec": 0.0,
        "error_ratio": 0.0,
        "origin_response_seconds": null,
        "origins_up": null,
        "origins_total": null
      }
    }
  }
}

DELETE /services/{fqdn}

Returns: 204, no body

GET /services/{fqdn}

Returns: 200, Service

Answer 200
{
  "fqdn": "a.example.com",
  "tenant": "tenant-a",
  "account_id": "acc-a",
  "enabled": true,
  "ports": [
    443
  ],
  "created": "2026-10-01T00:00:00+00:00",
  "created_by": "",
  "network": {
    "vips": [
      {
        "anycast_ipv4": "203.0.113.1",
        "anycast_ipv6": "2001:db8:a::1"
      }
    ],
    "edge_hostname": "a-example-com.edge.protect.zeroservices.eu"
  },
  "origins": [
    {
      "name": "origin-1",
      "address": "192.0.2.10",
      "port": 443
    }
  ],
  "aliases": [
    {
      "fqdn": "www.a.example.com"
    }
  ],
  "cache": {
    "enabled": true
  },
  "alias_limit": 20,
  "serving_edges": [
    "shared-1"
  ],
  "posture_drift": [],
  "baseline": null
}

PATCH /services/{fqdn}

Body: ServicePatch
Returns: 200, Service

Request: waf_and_limit
{
  "waf": {
    "enabled": true
  },
  "rate_limiting": {
    "req_per_10s": 800
  }
}
Request: replace_origins
{
  "origins": [
    {
      "name": "origin-1",
      "address": "192.0.2.10",
      "port": 443
    }
  ]
}
Answer 200: waf_and_limit
{
  "fqdn": "a.example.com",
  "tenant": "tenant-a",
  "enabled": true,
  "mode": "https",
  "ports": [
    443
  ],
  "udp_ports": [],
  "created": "2026-10-01T00:00:00+00:00",
  "created_by": "",
  "account_id": "acc-a",
  "network": {
    "vips": [
      {
        "anycast_ipv4": "203.0.113.1",
        "anycast_ipv6": "2001:db8:a::1"
      }
    ],
    "pool": null,
    "edge_hostname": "a-example-com.edge.protect.zeroservices.eu"
  },
  "network_protection": {
    "enabled": true
  },
  "backend": {
    "algorithm": "roundrobin",
    "health_check": {}
  },
  "origins": [
    {
      "name": "origin-1",
      "address": "192.0.2.10",
      "port": 443,
      "tls": true,
      "ssl_verify": true,
      "weight": 100,
      "maxconn": 100
    }
  ],
  "waf": {
    "enabled": true,
    "fail_open": true,
    "mode": "On",
    "paranoia_level": 1,
    "inbound_threshold": 5,
    "disabled_rules": []
  },
  "rate_limiting": {
    "challenge_req_per_10s": 200,
    "req_per_10s": 800,
    "conn_per_10s": 50,
    "conn_drop_per_10s": 500,
    "path_default": 1000,
    "path_aggregate_per_10s": 5000,
    "geo_tcp_reject_sess_rate": 200,
    "ja4_enabled": false,
    "ja4_req_per_10s": 100,
    "ja4_action": "challenge"
  },
  "pow": {
    "enabled": true,
    "difficulty": 18,
    "cookie_ttl": 86400,
    "always_challenge": false,
    "exempt_crawlers": true,
    "bind_ip": true,
    "botcheck_per_10s": 1000
  },
  "admission": {
    "enabled": false,
    "credit_required": 5,
    "credit_window": "60s",
    "known_ttl": "24h",
    "unknown_conn_rate": 1500,
    "table_size": "1m"
  },
  "ssl": {
    "mode": "acme",
    "acme_provider": "zerossl",
    "acme_email": null,
    "https_redirect": false,
    "cert_status": "none",
    "cert_issued": null,
    "cert_expires": null,
    "cert_last_renewal": null,
    "days_remaining": null
  },
  "aliases": [
    {
      "fqdn": "www.a.example.com",
      "ssl": {
        "mode": "acme",
        "acme_provider": "zerossl",
        "acme_email": null,
        "https_redirect": false,
        "cert_status": "none",
        "cert_issued": null,
        "cert_expires": null,
        "cert_last_renewal": null,
        "days_remaining": null
      }
    }
  ],
  "cache": {
    "enabled": true
  },
  "slow_http": {
    "enabled": true,
    "timeout_http_request": "5s",
    "timeout_client_fin": "5s"
  },
  "tcp_timeout": {
    "client": "30s",
    "server": "30s",
    "tunnel": "30s"
  },
  "udp_timeout": {
    "idle": "300s",
    "unreplied": "30s",
    "unreplied_pkts": 32,
    "src_pps": 0
  },
  "sni_policy": "allowlist",
  "proxy_protocol": false,
  "tls_termination": false,
  "priority": {
    "enabled": true,
    "session_signal": []
  },
  "response_headers": {
    "hsts": {},
    "cors": {},
    "x_frame_options": null,
    "x_content_type_options": false,
    "referrer_policy": null
  },
  "content_negotiation": {
    "enabled": false,
    "encodings": [
      "zstd",
      "gzip"
    ],
    "file_types": [
      "css",
      "js",
      "html"
    ]
  },
  "logging": {
    "enabled": false
  },
  "threat_intel": {
    "mode": "log",
    "abuse": "log",
    "tor": "log"
  },
  "redirects": [],
  "origin_host": null,
  "origin_sni": null,
  "maintenance_mode": false,
  "auto_mitigation": false,
  "defense_posture": null,
  "protection_allowlist": null,
  "edges": [],
  "protection_rules": [],
  "append_trailing_slash": false,
  "exceed_no_rtbh": false,
  "exceed_no_flowspec": false,
  "origin_kind": "dynamic",
  "alias_limit": 20,
  "serving_edges": [
    "shared-1"
  ],
  "posture_drift": [],
  "baseline": null
}
Answer 200: replace_origins
{
  "fqdn": "a.example.com",
  "tenant": "tenant-a",
  "enabled": true,
  "mode": "https",
  "ports": [
    443
  ],
  "udp_ports": [],
  "created": "2026-10-01T00:00:00+00:00",
  "created_by": "",
  "account_id": "acc-a",
  "network": {
    "vips": [
      {
        "anycast_ipv4": "203.0.113.1",
        "anycast_ipv6": "2001:db8:a::1"
      }
    ],
    "pool": null,
    "edge_hostname": "a-example-com.edge.protect.zeroservices.eu"
  },
  "network_protection": {
    "enabled": true
  },
  "backend": {
    "algorithm": "roundrobin",
    "health_check": {
      "method": "GET",
      "path": "/",
      "host": null,
      "interval": "10s",
      "rise": 2,
      "fall": 3,
      "expect": null
    }
  },
  "origins": [
    {
      "name": "origin-1",
      "address": "192.0.2.10",
      "port": 443,
      "tls": true,
      "ssl_verify": true,
      "weight": 100,
      "maxconn": 100
    }
  ],
  "waf": {
    "enabled": true,
    "fail_open": true,
    "mode": "On",
    "paranoia_level": 1,
    "inbound_threshold": 5,
    "disabled_rules": []
  },
  "rate_limiting": {
    "challenge_req_per_10s": 200,
    "req_per_10s": 800,
    "conn_per_10s": 50,
    "conn_drop_per_10s": 500,
    "path_default": 1000,
    "path_aggregate_per_10s": 5000,
    "geo_tcp_reject_sess_rate": 200,
    "ja4_enabled": false,
    "ja4_req_per_10s": 100,
    "ja4_action": "challenge"
  },
  "pow": {
    "enabled": true,
    "difficulty": 18,
    "cookie_ttl": 86400,
    "always_challenge": false,
    "exempt_crawlers": true,
    "bind_ip": true,
    "botcheck_per_10s": 1000
  },
  "admission": {
    "enabled": false,
    "credit_required": 5,
    "credit_window": "60s",
    "known_ttl": "24h",
    "unknown_conn_rate": 1500,
    "table_size": "1m"
  },
  "ssl": {
    "mode": "acme",
    "acme_provider": "zerossl",
    "acme_email": null,
    "https_redirect": false,
    "cert_status": "none",
    "cert_issued": null,
    "cert_expires": null,
    "cert_last_renewal": null,
    "days_remaining": null
  },
  "aliases": [
    {
      "fqdn": "www.a.example.com",
      "ssl": {
        "mode": "acme",
        "acme_provider": "zerossl",
        "acme_email": null,
        "https_redirect": false,
        "cert_status": "none",
        "cert_issued": null,
        "cert_expires": null,
        "cert_last_renewal": null,
        "days_remaining": null
      }
    }
  ],
  "cache": {
    "enabled": true
  },
  "slow_http": {
    "enabled": true,
    "timeout_http_request": "5s",
    "timeout_client_fin": "5s"
  },
  "tcp_timeout": {
    "client": "30s",
    "server": "30s",
    "tunnel": "30s"
  },
  "udp_timeout": {
    "idle": "300s",
    "unreplied": "30s",
    "unreplied_pkts": 32,
    "src_pps": 0
  },
  "sni_policy": "allowlist",
  "proxy_protocol": false,
  "tls_termination": false,
  "priority": {
    "enabled": true,
    "session_signal": []
  },
  "response_headers": {
    "hsts": {
      "enabled": false,
      "max_age": 31536000,
      "include_subdomains": false,
      "preload": false
    },
    "cors": {
      "enabled": false,
      "rules": []
    },
    "x_frame_options": null,
    "x_content_type_options": false,
    "referrer_policy": null
  },
  "content_negotiation": {
    "enabled": false,
    "encodings": [
      "zstd",
      "gzip"
    ],
    "file_types": [
      "css",
      "js",
      "html"
    ]
  },
  "logging": {
    "enabled": false
  },
  "threat_intel": {
    "mode": "log",
    "abuse": "log",
    "tor": "log"
  },
  "redirects": [],
  "origin_host": null,
  "origin_sni": null,
  "maintenance_mode": false,
  "auto_mitigation": false,
  "defense_posture": null,
  "protection_allowlist": null,
  "edges": [],
  "protection_rules": [],
  "append_trailing_slash": false,
  "exceed_no_rtbh": false,
  "exceed_no_flowspec": false,
  "origin_kind": "dynamic",
  "alias_limit": 20,
  "serving_edges": [
    "shared-1"
  ],
  "posture_drift": [],
  "baseline": null
}

GET /services/{fqdn}/dns

Parameter In Meaning
refresh query Look the records up again instead of the last minute's answer; default false

Returns: 200, DnsStatus

Answer 200
{
  "fqdn": "a.example.com",
  "edge_hostname": "a-example-com.edge.protect.zeroservices.eu",
  "anycast_ipv4": "203.0.113.1",
  "anycast_ipv6": "2001:db8:a::1",
  "status": "ok_cname",
  "ok": true,
  "hostnames": [
    {
      "fqdn": "a.example.com",
      "status": "ok_cname",
      "detail": null,
      "is_apex": false,
      "zone_apex": "example.com",
      "expected_cname": "a-example-com.edge.protect.zeroservices.eu",
      "expected_ipv4": "203.0.113.1",
      "expected_ipv6": "2001:db8:a::1",
      "cname_target": "a-example-com.edge.protect.zeroservices.eu",
      "cname_chain": [
        "a-example-com.edge.protect.zeroservices.eu"
      ],
      "resolved_ipv4": [
        "203.0.113.1"
      ],
      "resolved_ipv6": [
        "2001:db8:a::1"
      ],
      "ttl": 60,
      "public_ipv4": [
        "203.0.113.1"
      ],
      "public_ipv6": [
        "2001:db8:a::1"
      ],
      "public_cname_target": null,
      "propagating": false,
      "caa": {
        "status": "none",
        "owner": null,
        "records": [],
        "issuer": "sectigo.com"
      },
      "checked_at": "2026-10-23T10:13:25.197620+00:00",
      "role": "primary"
    },
    {
      "fqdn": "www.a.example.com",
      "status": "ok_cname",
      "detail": null,
      "is_apex": false,
      "zone_apex": "example.com",
      "expected_cname": "a-example-com.edge.protect.zeroservices.eu",
      "expected_ipv4": "203.0.113.1",
      "expected_ipv6": "2001:db8:a::1",
      "cname_target": "a-example-com.edge.protect.zeroservices.eu",
      "cname_chain": [
        "a-example-com.edge.protect.zeroservices.eu"
      ],
      "resolved_ipv4": [
        "203.0.113.1"
      ],
      "resolved_ipv6": [
        "2001:db8:a::1"
      ],
      "ttl": 60,
      "public_ipv4": [
        "203.0.113.1"
      ],
      "public_ipv6": [
        "2001:db8:a::1"
      ],
      "public_cname_target": null,
      "propagating": false,
      "caa": {
        "status": "none",
        "owner": null,
        "records": [],
        "issuer": "sectigo.com"
      },
      "checked_at": "2026-10-23T10:13:25.197641+00:00",
      "role": "alias",
      "cert_status": null
    }
  ]
}

GET /services/{fqdn}/history

Parameter In Meaning
range query Time window; one of 5m, 15m, 1h, 6h, 24h, 7d; default "24h"

Returns: 200, History

Answer 200
{
  "fqdn": "a.example.com",
  "range": "24h",
  "entries": [
    {
      "kind": "config_change",
      "category": "config",
      "at": "2026-10-23T10:13:25+00:00",
      "sha": "7454e1cb177219e234491676fc66582d0d37342f",
      "short_sha": "7454e1cb",
      "action": "Patch service a.example.com",
      "user": "API key ci",
      "by_zero_services": false
    },
    {
      "kind": "config_change",
      "category": "config",
      "at": "2026-10-23T10:13:25+00:00",
      "sha": "e89a055a4305b33b66f5d08f9659f89b11a79dd3",
      "short_sha": "e89a055a",
      "action": "Patch service a.example.com",
      "user": "API key ci",
      "by_zero_services": false
    }
  ]
}

POST /services/{fqdn}/rename

Body: Rename
Returns: 200, Service

Request
{
  "to": "www.a.example.com"
}
Answer 200
{
  "fqdn": "www.a.example.com",
  "tenant": "tenant-a",
  "enabled": true,
  "mode": "https",
  "ports": [
    443
  ],
  "udp_ports": [],
  "created": "2026-10-01T00:00:00+00:00",
  "created_by": "",
  "account_id": "acc-a",
  "network": {
    "vips": [
      {
        "anycast_ipv4": "203.0.113.1",
        "anycast_ipv6": "2001:db8:a::1"
      },
      {
        "anycast_ipv4": "203.0.113.0",
        "anycast_ipv6": "2001:db8:a::"
      }
    ],
    "pool": "P-A",
    "edge_hostname": "a-example-com.edge.protect.zeroservices.eu"
  },
  "network_protection": {
    "enabled": true
  },
  "backend": {
    "algorithm": "roundrobin",
    "health_check": {
      "method": "GET",
      "path": "/",
      "host": null,
      "interval": "10s",
      "rise": 2,
      "fall": 3,
      "expect": null
    }
  },
  "origins": [
    {
      "name": "origin-1",
      "address": "192.0.2.14",
      "port": 443,
      "tls": true,
      "ssl_verify": true,
      "weight": 100,
      "maxconn": 100
    },
    {
      "name": "origin-2",
      "address": "192.0.2.13",
      "port": 443,
      "tls": true,
      "ssl_verify": true,
      "weight": 100,
      "maxconn": 100
    }
  ],
  "waf": {
    "enabled": true,
    "fail_open": true,
    "mode": "On",
    "paranoia_level": 1,
    "inbound_threshold": 5,
    "disabled_rules": []
  },
  "rate_limiting": {
    "challenge_req_per_10s": 200,
    "req_per_10s": 800,
    "conn_per_10s": 50,
    "conn_drop_per_10s": 500,
    "path_default": 1000,
    "path_aggregate_per_10s": 5000,
    "geo_tcp_reject_sess_rate": 200,
    "ja4_enabled": false,
    "ja4_req_per_10s": 100,
    "ja4_action": "challenge"
  },
  "pow": {
    "enabled": true,
    "difficulty": 18,
    "cookie_ttl": 86400,
    "always_challenge": false,
    "exempt_crawlers": true,
    "bind_ip": true,
    "botcheck_per_10s": 1000
  },
  "admission": {
    "enabled": false,
    "credit_required": 5,
    "credit_window": "60s",
    "known_ttl": "24h",
    "unknown_conn_rate": 1500,
    "table_size": "1m"
  },
  "ssl": {
    "mode": "acme",
    "acme_provider": "zerossl",
    "acme_email": null,
    "https_redirect": false,
    "cert_status": "none",
    "cert_issued": null,
    "cert_expires": null,
    "cert_last_renewal": null,
    "days_remaining": null
  },
  "aliases": [
    {
      "fqdn": "a.example.com",
      "ssl": {
        "mode": "acme",
        "acme_provider": "zerossl",
        "acme_email": null,
        "https_redirect": false,
        "cert_status": "none",
        "cert_issued": null,
        "cert_expires": null,
        "cert_last_renewal": null,
        "days_remaining": null
      }
    }
  ],
  "cache": {
    "enabled": true
  },
  "slow_http": {
    "enabled": true,
    "timeout_http_request": "5s",
    "timeout_client_fin": "5s"
  },
  "tcp_timeout": {
    "client": "30s",
    "server": "30s",
    "tunnel": "30s"
  },
  "udp_timeout": {
    "idle": "300s",
    "unreplied": "30s",
    "unreplied_pkts": 32,
    "src_pps": 0
  },
  "sni_policy": "allowlist",
  "proxy_protocol": false,
  "tls_termination": false,
  "priority": {
    "enabled": true,
    "session_signal": []
  },
  "response_headers": {
    "hsts": {
      "enabled": false,
      "max_age": 31536000,
      "include_subdomains": false,
      "preload": false
    },
    "cors": {
      "enabled": false,
      "rules": []
    },
    "x_frame_options": null,
    "x_content_type_options": false,
    "referrer_policy": null
  },
  "content_negotiation": {
    "enabled": false,
    "encodings": [
      "zstd",
      "gzip"
    ],
    "file_types": [
      "css",
      "js",
      "html"
    ]
  },
  "logging": {
    "enabled": false
  },
  "threat_intel": {
    "mode": "log",
    "abuse": "log",
    "tor": "log"
  },
  "redirects": [],
  "origin_host": "a.example.com",
  "origin_sni": "a.example.com",
  "maintenance_mode": false,
  "auto_mitigation": false,
  "defense_posture": null,
  "protection_allowlist": null,
  "edges": [],
  "protection_rules": [],
  "append_trailing_slash": false,
  "exceed_no_rtbh": false,
  "exceed_no_flowspec": false,
  "origin_kind": "dynamic",
  "alias_limit": 20,
  "serving_edges": [
    "shared-1"
  ],
  "posture_drift": [],
  "baseline": null
}

Fields

Part of the service: send them with PATCH /services/{fqdn}; only the fields you send change, on all edges in about 30 seconds. Origins, ports and certificates have their own pages: Origins, Ports, TLS.

Field Type Notes
enabled boolean may be null; false switches the vService off: the edges stop serving it and its health reads disabled. The configuration stays
maintenance_mode boolean may be null; true: the edges answer every request with a 503 maintenance page (JSON for service_profile api) and do not contact your origins. HTTPS only
service_profile string one of api, web_dynamic, web_static, hls; may be null; What talks to the vService: web_dynamic (browsers), web_static (static files), api (apps and devices; the edge answers its own errors as JSON) or hls (video streaming). It picks the posture bundle, which applies when you next set defense_posture
defense_posture string one of off, standard, under_attack; may be null; Protection bundle for the service type. off: loose limits only, no challenge, WAF or threat intelligence. standard: denies the network reputation list and, for browser services, challenges busy login and admin paths. under_attack: strictest, challenges every request where the type allows proof-of-work. Setting it applies the bundle's values to rate_limiting, pow, slow_http, cache, waf, threat_intel, admission and priority and replaces the rules it added
sensitivity string one of low, medium, high; may be null; Learn the service-wide limits (path_aggregate_per_10s, geo_tcp_reject_sess_rate, challenge answers, origin maxconn) from your normal peak: low 3 times, medium 2 times, high 1.5 times, never below the floor. Null: the fixed values apply. HTTPS only
size_tier string one of S, M, L, XL; may be null; S, M, L or XL: scales the floors of the learned limits by 0.5, 1, 2 or 4. Only with a sensitivity
auto_mitigation boolean may be null; true: automatic attack response may add time-limited protection rules to the vService itself, never against your allowlist. false: it only suggests them
append_trailing_slash boolean may be null; Redirect /foo to /foo/ with 301 for GET and HEAD when the path has neither a trailing slash nor a file extension, for directory-style static origins. HTTPS only
aliases list of Alias may be null; Further hostnames of the vService
redirects list of Redirect at most 200; may be null; Redirects and response_headers.cors.rules together: at most 200 per vService

ServiceCreate

POST /services creates a vService on your dedicated edges, or from one of your own prefixes on our edges.

Field Type Notes
account_id (required) string up to 64 characters; Your dedicated or BYOIP account the vService is booked under
defense_posture string one of off, standard, under_attack; may be null; Protection bundle: off, standard or under_attack. Default: your tenant's default_posture, else standard
edges list of string Dedicated accounts: your dedicated edges, default all. BYOIP accounts: not allowed
fqdn (required) string The hostname to protect; it becomes the vService's name
mode string one of https, tcp, anyconnect; default "https"; https (HTTP and TLS at the edge), tcp (TCP passed through, UDP forwarded) or anyconnect (a Cisco Secure Client VPN gateway). Fixed after creation
origins list of Origin at most 50; May be empty: add origins later; the vService answers 503 until then
pool string One of your IP pools; default the first
ports list of integer or string at most 8; may be null; TCP ports the edge accepts, up to 8 entries. https: 443 and 80 by default, any further port is plain HTTP to the same port on your origins. tcp: also ranges ("40000-40009") and mappings ("40000-40009=50000": edge range to origin start)
service_profile string one of api, web_dynamic, web_static, hls; may be null; What talks to the vService: web_dynamic (browsers), web_static (static files), api (apps and devices; the edge answers its own errors as JSON) or hls (video streaming). It picks the posture bundle applied at creation
size_tier string one of S, M, L, XL; may be null; S, M, L or XL: scales the floors of the learned limits by 0.5, 1, 2 or 4. Only with a sensitivity
udp_ports list of integer or string at most 8; may be null; UDP ports of a tcp or anyconnect vService, up to 8 entries: forwarded to your origins, to the same port unless mapped (ranges and mappings tcp only). Not for https (no UDP listener). Empty: all UDP to the vService's addresses is dropped

Alias

Field Type Notes
fqdn (required) string up to 253 characters; The alias hostname
ssl Ssl Certificate settings of the alias

Redirect

Field Type Notes
path (required) string Request path to match
target (required) string Relative path or https:// URL
code integer one of 301, 302, 307, 308; default 301; HTTP status of the redirect
match_type string one of exact, prefix; default "exact"; exact: the request path equals path. prefix: the request path starts with path
condition RedirectCondition may be null; Optional condition on a request header
redirect_type string one of location, prefix; default "location"; location: send to target as written. prefix: target followed by the request's path and query string; a trailing slash of target is removed
bind_to string may be null; Only for requests to this hostname: the FQDN or one of its aliases. Null: every hostname

RedirectCondition

Field Type Notes
header (required) string one of accept-language; Request header to test; only accept-language
value (required) string Language code, 2 or 3 lower-case letters; matches when one of the languages in the header starts with it (de matches de-AT)

Read-only fields

Returned by GET /services/{fqdn}. A PATCH with a field that is not in ServicePatch is rejected.

Field Type Notes
fqdn string read-only; Rename with POST /services/{fqdn}/rename
mode string one of https, tcp, anyconnect; default "https"; read-only; Set when the vService is created
network Network read-only; Change addresses with POST /vip-operations
serving_edges list of string read-only; Edges that serve the vService now
posture_drift list of string read-only; Sections that differ from the posture
baseline object may be null; read-only; Learned limits, null before the first measurement
created string may be null; read-only; Set by the server

ServiceSummary

GET /services lists each vService in short; GET /services/{fqdn} has every field.

Field Type Notes
fqdn string read-only; Rename with POST /services/{fqdn}/rename
tenant string up to 64 characters; read-only; Set by the server
account_id string may be null; read-only; Set when the vService is created
enabled boolean default true; false switches the vService off: the edges stop serving it and its health reads disabled. The configuration stays
mode string one of https, tcp, anyconnect; default "https"; read-only; Set when the vService is created
ports list of integer or string at most 8; may be null; TCP ports the edge accepts, up to 8 entries. https: 443 and 80 by default, any further port is plain HTTP to the same port on your origins. tcp: also ranges ("40000-40009") and mappings ("40000-40009=50000": edge range to origin start)
udp_ports list of integer or string at most 8; may be null; UDP ports of a tcp or anyconnect vService, up to 8 entries: forwarded to your origins, to the same port unless mapped (ranges and mappings tcp only). Not for https (no UDP listener). Empty: all UDP to the vService's addresses is dropped
network Network read-only; Change addresses with POST /vip-operations
waf Waf Web application firewall
maintenance_mode boolean default false; true: the edges answer every request with a 503 maintenance page (JSON for service_profile api) and do not contact your origins. HTTPS only
aliases list of Alias Further hostnames of the vService
edges list of string at most 50; read-only; Set when the vService is created
alias_limit integer may be null; read-only; Aliases you may add; null = no limit
serving_edges list of string read-only; Edges that serve the vService now
posture_drift list of string read-only; Sections that differ from the posture
baseline object may be null; read-only; Learned limits, null before the first measurement
delegations list of string read-only; Delegations the vService is part of (GET /services only)
origin_count integer Number of origins; the origins are in GET /services/{fqdn}
redirect_count integer Number of redirects

DnsStatus

Field Type Notes
fqdn (required) string The vService
edge_hostname string may be null; CNAME target for your records
anycast_ipv4 string may be null; Primary IPv4 VIP of the vService
anycast_ipv6 string may be null; Primary IPv6 VIP of the vService
status (required) string one of error, not_found, wrong_target, apex_cname, partial, ok_cname_foreign, ok_a, ok_cname; The worst of all names
ok (required) boolean Every name points at us
hostnames (required) list of DnsHostname The vService's name first, then every alias

DnsHostname

Field Type Notes
fqdn (required) string The hostname checked
role (required) string one of primary, alias; primary: the vService's name. alias: one of its aliases
status (required) string one of error, not_found, wrong_target, apex_cname, partial, ok_cname_foreign, ok_a, ok_cname; ok_cname, ok_a and ok_cname_foreign point at us
detail string may be null; What to change
is_apex boolean The name is the apex of its DNS zone, where a CNAME is not allowed: use A and AAAA
zone_apex string may be null; Apex of the DNS zone the name lies in; null when the lookup failed
expected_cname string may be null; Edge hostname a CNAME should point at
expected_ipv4 string may be null; IPv4 address an A record should hold: the primary VIP
expected_ipv6 string may be null; IPv6 address an AAAA record should hold: the primary VIP; null without IPv6
cname_target string may be null; First CNAME target, as the authoritative nameservers answer; null without CNAME
cname_chain list of string CNAME targets in order, as the authoritative nameservers answer
resolved_ipv4 list of string IPv4 addresses the authoritative answer resolves to
resolved_ipv6 list of string IPv6 addresses the authoritative answer resolves to
ttl integer may be null; TTL in seconds of your first record, the CNAME or the A/AAAA; null when unknown
public_ipv4 list of string IPv4 addresses a public resolver answers
public_ipv6 list of string IPv6 addresses a public resolver answers
public_cname_target string may be null; First CNAME target as a public resolver answers
propagating boolean Authoritative servers are right, public resolvers not yet
caa object CAA records of the name and whether they let your certificate authority issue
checked_at string When the check ran; answers are reused for 60 s unless you send refresh=true
cert_status string may be null; Alias only: state of its certificate

HistoryEntry

Field Type Notes
kind (required) string one of config_change, health_change; config_change: the vService's configuration or certificate changed. health_change: its health state changed
at (required) string When it happened
category string one of config, certificate; config_change only
sha string config_change: id of the configuration revision
short_sha string config_change: the revision id, shortened
action string config_change: what changed
user string config_change: your e-mail or key label; empty = Zero Services
by_zero_services boolean config_change: true when Zero Services made the change, false when you did, in the portal or with an API key
from string one of blackholed, origin_down, misconfigured, errors, origin_slow, under_attack, normal, maintenance, disabled, unknown; may be null; health_change only
to string one of blackholed, origin_down, misconfigured, errors, origin_slow, under_attack, normal, maintenance, disabled, unknown; may be null; health_change only
fault string one of zp, customer, none; health_change: who has to act on the new state, as in ServiceHealth
reason string health_change: machine-readable reason of the new state, as in ServiceHealth
signals HealthSignals health_change: the measurements when the state changed
techniques list of string Attack techniques seen, on a change to or from under_attack

Attack

GET /attacks lists the attacks running now (an empty list: none), GET /attacks/{month} those of one month. Poll it from your own monitoring.

Field Type Notes
fqdn (required) string The vService
state (required) string one of under_attack, blackholed; under_attack: the edge stops it; blackholed: your addresses are dark upstream
start (required) string Started
end (required) string may be null; Ended; null while it runs
ended_as (required) string one of blackholed, origin_down, misconfigured, errors, origin_slow, under_attack, normal, maintenance, disabled; may be null; State of the vService after the attack; null while it runs
reason (required) string may be null; Machine-readable, as reason of the health light
techniques (required) list of string Every technique that stopped traffic during the attack
signals (required) HealthSignals Measured at the start; empty while it runs and not yet known
escalations (required) list of AttackEscalation What we did beyond the edge; empty when the edge handled it alone

Example

A device API: no browser challenges.

curl -s -X PATCH -H "Authorization: Bearer $ZP_KEY" -H 'Content-Type: application/json' \
  $API/services/api.example.com -d '{"service_profile": "api", "defense_posture": "off"}'

Apex alias that redirects to www:

curl -s -X PATCH -H "Authorization: Bearer $ZP_KEY" -H 'Content-Type: application/json' \
  $API/services/www.example.com -d '{
    "aliases": [{"fqdn": "example.com"}],
    "redirects": [{"path": "/", "target": "https://www.example.com", "match_type": "prefix",
                   "redirect_type": "prefix", "bind_to": "example.com"}]}'

Behaviour

  • mode is set at creation: https (ports 443 and 80), tcp or anyconnect, see Ports.
  • Shared: 1 FQDN plus up to 20 aliases. Dedicated: up to 100 vServices per account, addresses from your own pools, see Limits.
  • service_profile is what talks to the service: web_dynamic (browsers), web_static (static, downloads), api (apps, set-top boxes, callbacks, no JavaScript; the edge answers its own errors as JSON, {"error", "status", "ray"}), hls (video streaming). After changing it, send defense_posture again so the type's settings take effect.
  • defense_posture: standard for browser services, it limits login and admin paths; off for a device API or HLS, whose clients cannot solve a challenge; under_attack during an attack.
  • sensitivity derives service-wide limits from your own normal peak; size_tier scales the posture's floor and needs a sensitivity. Details: Rate limits.
  • maintenance_mode serves a branded maintenance page instead of contacting the origin. auto_mitigation (beta) lets the platform apply time-limited challenges itself, see Under attack.
  • Redirects: redirect_type: prefix keeps the rest of the path, so write target without a trailing slash; bind_to limits a redirect to one alias. append_trailing_slash adds / to directory-style paths.
  • Rename: add the new name as an alias, point its DNS at the service, wait for its certificate, then rename. The old name stays as an alias; statistics and cache start fresh.

In the portal: the service's Overview (type, posture, sensitivity) and Aliases (Make primary).