Route bots to EdgeComet with Akamai Property Manager
On Akamai, one Property Manager rule sends search engine and AI bot page requests to EdgeComet. The rule switches the origin to EdgeComet's render host, rewrites the path to the render endpoint and adds your render key. A child rule sends bots back to your origin when EdgeComet cannot answer.
This is the Akamai setup for prerendering or dynamic rendering, plus EdgeComet's caching and bot analytics. It works on properties that support variables, such as Ion. Visitors keep getting your site from your usual origin.
The dashboard has no Akamai guide. Take your render key and render host from the Generic Integration guide under Configuration > Connections > CDN integration.
How it works
The rule EdgeComet bot routing sits last under the Default Rule and matches when all of these hold:
- The method is
GETorHEAD, through the built-in variableAK_METHOD. - The request uses HTTPS.
- The user agent contains a crawler token.
- The file extension is not a static file.
- The request has no
X-Edge-Renderheader, which EdgeComet adds to its own requests, and no failover marker.
Its behaviors then build the request to EdgeComet:
- Origin Server switches to
render-us.edgecomet.comon port 443, with SNI. - Set Variable URL-encodes the full page URL into
PMUSER_EC_URL. - Modify Outgoing Request Path replaces the path with
/render?url={{user.PMUSER_EC_URL}}. - Modify Outgoing Request Header adds
X-Render-Keyfrom a sensitive variable. - Caching: No store keeps EdgeComet's responses out of Akamai's cache. The path rewrite also changes the cache key, which keeps bot copies apart from visitor copies.
The child rule EdgeComet fail open runs Site Failover when EdgeComet times out, answers 5xx, or answers without an EC-Source header. The failover request goes back through the property to your normal origin.
Akamai adds the bot's IP address to X-Forwarded-For, which EdgeComet reads. Leave Send True Client IP Header off in this rule: EdgeComet does not read True-Client-IP.
With Tiered Distribution, or any other Akamai layer between the bot and the rule, check in Data Explorer > Bot log that bot requests show the bots' addresses, not Akamai's.
Before you start
- Property Manager access with edit and activate rights on the property that serves your site.
- A product that supports property variables, such as Ion.
- Your Render Key and Render Host from the dashboard. If your guide shows
render-de.edgecomet.com, use it in place ofrender-us.edgecomet.com. - A loop guard for the failover request. The recommended one needs your Akamai account team. See Loop guard for the failover request.
Add the rule in Property Manager
- In Control Center, open Content delivery > CDN > Properties, open the property and create a new version.
- Under Property Variables, click Add Variable twice. Property Manager adds the
PMUSER_prefix:EC_RENDER_KEY, Initial Value your render key, security setting Sensitive.EC_URL, Initial Value empty. Keep it Visible while you test, then set it to Hidden.
- Save the property, which makes the variables available to behaviors.
- Select the Default Rule, click Add Rule, choose the blank template and name it
EdgeComet bot routing. Drag it to the bottom of the Default Rule's children: the last matching behavior wins. - Set the criteria to Match All and add:
- Variable:
AK_METHODis one ofGET HEAD. - Request Protocol: HTTPS.
- User Agent: is one of
*bot**crawl**spider**slurp**WhatsApp**Snapchat**facebookexternalhit**AMZN-User**Claude-User**Perplexity-User**ChatGPT-User*, with Wildcards in value on and Case-sensitive value off. - File Extension: is not one of
avif css eot gif gz ico jpeg jpg js json map mp3 mp4 ogg otf pdf png svg ttf txt wasm wav webm webmanifest webp woff woff2 xml zip, case-insensitive. - Request Header:
X-Edge-Renderdoes not exist. - Request Header:
X-EC-Failoverdoes not exist.
- Variable:
- Add the behaviors, in this order:
- Origin Server: Origin Type Your Origin, Origin Server Hostname
render-us.edgecomet.com, Forward Host Header Origin Hostname, Cache Key Hostname Incoming Host Header, Send True Client IP Header off, Verification Settings the same as the Default Rule, Use SNI TLS Extension Yes, ports 80 and 443. - Set Variable: Variable
PMUSER_EC_URL, Create Value From Expression,{{builtin.AK_SCHEME}}://{{builtin.AK_HOST}}{{builtin.AK_URL}}, Operation URL Encode, Force Chars+. - Modify Outgoing Request Path: Replace the entire path with
/render?url={{user.PMUSER_EC_URL}}. - Modify Outgoing Request Header: Modify, Other..., Custom Header Name
X-Render-Key, New Header Value{{user.PMUSER_EC_RENDER_KEY}}, Avoid Duplicate Headers on. - Caching: No store.
- Read Timeout: First Byte Timeout 30 seconds, above EdgeComet's 15-second render timeout.
- Chase Redirects: off, which passes EdgeComet's redirects to the bot.
- SureRoute: off. Its race requests fetch a test object the render host does not serve.
- Origin Server: Origin Type Your Origin, Origin Server Hostname
- Add the child rule from Fall back to your origin.
- Save, check the Errors / Warnings tab, then test on staging.
Force Chars + matters. Akamai's URL encoding leaves + as it is, and EdgeComet would read it as a space, which turns ?q=a+b into ?q=a b.
Use SNI TLS Extension is required. The render host refuses TLS connections without SNI.
Rule JSON
For the Property Manager API, rule format v2026-09-30. Declare the variables in the Default Rule's variables array:
[
{
"name": "PMUSER_EC_RENDER_KEY",
"value": "YOUR_RENDER_KEY",
"description": "EdgeComet render key sent as X-Render-Key",
"hidden": true,
"sensitive": true
},
{
"name": "PMUSER_EC_URL",
"value": "",
"description": "URL-encoded original URL sent to EdgeComet",
"hidden": false,
"sensitive": false
}
]Then append this rule as the last element of the Default Rule's children:
{
"name": "EdgeComet bot routing",
"comments": "Sends crawler GET/HEAD page requests to EdgeComet. Keep this rule last under the Default Rule.",
"criteriaMustSatisfy": "all",
"criteria": [
{
"name": "matchVariable",
"options": {
"variableName": "AK_METHOD",
"matchOperator": "IS_ONE_OF",
"variableValues": ["GET", "HEAD"],
"matchWildcard": false,
"matchCaseSensitive": false
}
},
{
"name": "requestProtocol",
"options": { "value": "HTTPS" }
},
{
"name": "userAgent",
"options": {
"matchOperator": "IS_ONE_OF",
"values": [
"*bot*", "*crawl*", "*spider*", "*slurp*", "*WhatsApp*", "*Snapchat*",
"*facebookexternalhit*", "*AMZN-User*", "*Claude-User*", "*Perplexity-User*", "*ChatGPT-User*"
],
"matchWildcard": true,
"matchCaseSensitive": false
}
},
{
"name": "fileExtension",
"options": {
"matchOperator": "IS_NOT_ONE_OF",
"values": [
"avif", "css", "eot", "gif", "gz", "ico", "jpeg", "jpg", "js", "json", "map", "mp3", "mp4", "ogg",
"otf", "pdf", "png", "svg", "ttf", "txt", "wasm", "wav", "webm", "webmanifest", "webp", "woff",
"woff2", "xml", "zip"
],
"matchCaseSensitive": false
}
},
{
"name": "requestHeader",
"options": {
"headerName": "X-Edge-Render",
"matchOperator": "DOES_NOT_EXIST",
"matchWildcardName": false
}
},
{
"name": "requestHeader",
"options": {
"headerName": "X-EC-Failover",
"matchOperator": "DOES_NOT_EXIST",
"matchWildcardName": false
}
}
],
"behaviors": [
{
"name": "origin",
"options": {
"originType": "CUSTOMER",
"hostname": "render-us.edgecomet.com",
"forwardHostHeader": "ORIGIN_HOSTNAME",
"cacheKeyHostname": "REQUEST_HOST_HEADER",
"compress": true,
"enableTrueClientIp": false,
"verificationMode": "PLATFORM_SETTINGS",
"originSni": true,
"httpPort": 80,
"httpsPort": 443,
"ipVersion": "IPV4"
}
},
{
"name": "setVariable",
"options": {
"variableName": "PMUSER_EC_URL",
"valueSource": "EXPRESSION",
"variableValue": "{{builtin.AK_SCHEME}}://{{builtin.AK_HOST}}{{builtin.AK_URL}}",
"transform": "URL_ENCODE",
"forceChars": "+"
}
},
{
"name": "rewriteUrl",
"options": {
"behavior": "REWRITE",
"targetUrl": "/render?url={{user.PMUSER_EC_URL}}"
}
},
{
"name": "modifyOutgoingRequestHeader",
"options": {
"action": "MODIFY",
"standardModifyHeaderName": "OTHER",
"customHeaderName": "X-Render-Key",
"newHeaderValue": "{{user.PMUSER_EC_RENDER_KEY}}",
"avoidDuplicateHeaders": true
}
},
{
"name": "caching",
"options": { "behavior": "NO_STORE" }
},
{
"name": "readTimeout",
"options": { "value": "30s", "firstByteTimeout": "30s" }
},
{
"name": "chaseRedirects",
"options": { "enabled": false }
},
{
"name": "sureRoute",
"options": { "enabled": false }
}
],
"children": [
{
"name": "EdgeComet fail open",
"comments": "On timeout, 5xx, or a response without EC-Source, re-run the request against the normal origin.",
"criteriaMustSatisfy": "any",
"criteria": [
{
"name": "originTimeout",
"options": { "matchOperator": "ORIGIN_TIMED_OUT" }
},
{
"name": "matchResponseCode",
"options": { "matchOperator": "IS_BETWEEN", "lowerBound": 500, "upperBound": 599 }
},
{
"name": "responseHeader",
"options": {
"headerName": "EC-Source",
"matchOperator": "DOES_NOT_EXIST",
"matchWildcardName": false
}
}
],
"behaviors": [
{
"name": "failAction",
"options": {
"enabled": true,
"actionType": "RECREATED_CO",
"contentHostname": "{{builtin.AK_HOST}}",
"contentCustomPath": true,
"contentPath": "{{builtin.AK_PATH}}",
"preserveQueryString": true
}
}
]
}
]
}Set verificationMode to the mode your Default Rule's Origin Server uses. A different mode can fail the activation.
The workflow: create a property version, get its rule tree, add the variables and the rule, put the tree back, fix any errors, then activate.
If the Variable criterion does not offer AK_METHOD in your editor, make EdgeComet bot routing a Match Any parent with two Request Method criteria, GET and HEAD, and move the other criteria and the behaviors into a Match All child. Request Method takes one value per criterion.
Fall back to your origin
Select EdgeComet bot routing, add a Child Rule named EdgeComet fail open, and set its criteria to Match Any:
- Origin Timeout: yes.
- Response Status Code: is in range 500 to 599.
- Response Header:
EC-Sourcedoes not exist.
Add the Site Failover behavior: Enable on, Action Use alternate hostname in this property, Alternate Hostname in This Property {{builtin.AK_HOST}}, Modify Request Path yes with {{builtin.AK_PATH}}, Include Query String yes. The failover request uses the bot's original path and query string, not the rewritten one.
| Case | Bots get |
|---|---|
EdgeComet answers with EC-Source and a status below 500, including redirects, 404 and 410 | EdgeComet's response |
EdgeComet answers 5xx | Your origin's page |
EdgeComet answers without EC-Source: 401 for a wrong key, 400, a 404 for a wrong path | Your origin's page |
| EdgeComet does not answer in time | Your origin's page |
Akamai documents Site Failover on Origin Timeout and Response Status Code. Other vendors' Akamai integrations also trigger it on a missing response header, as the third criterion does.
Test each case on staging before you activate on production. See Test the fallback.
Loop guard for the failover request
The failover request passes through the property again, and it would match EdgeComet bot routing once more. The X-EC-Failover criterion stops that, once the failover request carries the header.
Akamai Professional Services adds the header to Site Failover through an Advanced behavior, which only Akamai can configure. Ask your Akamai account team to add this to EdgeComet fail open:
<forward:availability.fail-action2>
<add-header>
<status>on</status>
<name>X-EC-Failover</name>
<value>1</value>
</add-header>
</forward:availability.fail-action2>Without access to Akamai Professional Services, use a failover hostname instead:
- Under Property Hostnames, add a hostname such as
ec-failover.example.comon the property's existing edge hostname. It needs no DNS record. - In
EdgeComet bot routing, replace theX-EC-Failovercriterion with Hostname is not one ofec-failover.example.com. - In Site Failover, set Alternate Hostname in This Property to
ec-failover.example.com. - Set the Default Rule's Forward Host Header to a Custom Value with your main hostname. Otherwise your origin receives
Host: ec-failover.example.comon failover.
The failover hostname suits a property that serves one hostname. A property with several hostnames needs one failover hostname for each.
Test on staging
- On the Activate tab, click Activate v# on Staging. Akamai says staging activation usually takes under 3 minutes.
- Resolve the staging edge hostname, with
-stagingbefore the final.net, and use its address withcurl --resolve:
dig +short www.example.com.edgekey-staging.net
H=www.example.com; IP=STAGING_IP
GB="Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
# Bot page: expect ec-source and x-akamai-staging
curl -sS -D - -o /dev/null --resolve $H:443:$IP -A "$GB" "https://$H/"
# Browser: expect no ec- headers
curl -sS -D - -o /dev/null --resolve $H:443:$IP -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)" "https://$H/"
# Static file and loop guard: expect no ec-source
curl -sS -D - -o /dev/null --resolve $H:443:$IP -A "$GB" "https://$H/favicon.ico"
curl -sS -D - -o /dev/null --resolve $H:443:$IP -A "$GB" -H "X-Edge-Render: test" "https://$H/"Staging servers change over time. Resolve the address again before each round of tests.
To check the encoded URL, send an Enhanced Debug header, Akamai-Debug: YOUR_TOKEN vars, and look for PMUSER_EC_URL with %3F, %26 and %2B in it.
Test the fallback
- A missing
EC-Source: setPMUSER_EC_RENDER_KEYto a wrong value on a staging version. EdgeComet answers401withoutEC-Source, and bots must get your origin page withoutEC-headers. - A failed connection: add this staging-only child rule to
EdgeComet bot routing, aboveEdgeComet fail open, and send a crawler request with the headerX-EC-Test-Failover: YOUR_TEST_SECRET. Bots must get your origin page.
{
"name": "EdgeComet failover test (staging only)",
"criteriaMustSatisfy": "all",
"criteria": [
{
"name": "contentDeliveryNetwork",
"options": { "matchOperator": "IS", "network": "STAGING" }
},
{
"name": "requestHeader",
"options": {
"headerName": "X-EC-Test-Failover",
"matchOperator": "IS_ONE_OF",
"values": ["YOUR_TEST_SECRET"],
"matchWildcardName": false,
"matchWildcardValue": false,
"matchCaseSensitiveValue": true
}
}
],
"behaviors": [
{ "name": "breakConnection", "options": { "enabled": true } }
]
}The rule matches only on the staging network.
Activate on production
Click Activate v# on Production, which Akamai says usually takes under 4 minutes, and run Verify install in the dashboard guide. To roll back, activate the previous version.
Let EdgeComet through Akamai security
EdgeComet's own requests to your site carry X-Render-Key and X-Edge-Render, which sends them past this rule to your origin. App & API Protector and Bot Manager see them first.
Add exceptions on the request header X-Render-Key with your exact key. See Akamai App & API Protector and Bot Manager.
Check the integration
After the production activation, run Test connection and Verify install in the Generic Integration guide, then see Check that search and AI bots reach EdgeComet.
Update or remove
After a render key rotation, update PMUSER_EC_RENDER_KEY and the security exceptions, then activate. To remove EdgeComet, delete the rule or activate a version without it.
If it does not work
Bots get your origin page without EC-Source
The rule did not match, or the fallback ran. Check that each user agent token has wildcards on both sides, the path is not a static file, the rule is last under the Default Rule and the request uses HTTPS. To see EdgeComet's own answer, turn off EdgeComet fail open on a staging version.
401 Authentication failed: invalid render key or domain mismatch
PMUSER_EC_RENDER_KEY is wrong, or the host in the URL is not one of your website's domains. www and the root domain count as different domains.
400 Invalid URL
The url parameter is missing or damaged. Check PMUSER_EC_URL with the vars debug option, and look for a behavior in a parent rule that removes query parameters.
A plain 404 Not Found without EC-Source
The path EdgeComet received is not /render. An Origin Base Path in a parent rule adds a prefix, and other behaviors cannot override it.
Bots get a 301 to render-us.edgecomet.com
The request reached the render host over plain HTTP, which redirects to HTTPS. Keep the Request Protocol: HTTPS criterion, and keep Chase Redirects off.
TLS errors to the render host
Set Use SNI TLS Extension to Yes.
Activation fails after you add the rule
Use the same Verification Settings in the rule's Origin Server as in the Default Rule.
Failover loops or errors
The loop guard is missing: the Advanced behavior is not in place yet, or the failover hostname is not excluded.
Test connection fails
App & API Protector or Bot Manager blocks EdgeComet's requests. Add the exceptions. See Let EdgeComet through Akamai security.