Akamai integration — what it is and how to deploy
This article explains the Salespeak Akamai integration: what it does, what your team is responsible for, and the exact configuration steps to roll it out on your Akamai property.
What it is
The Salespeak Akamai integration is an Akamai EdgeWorker that runs on your property. For every request to your site it does one of two things:
- Regular human visitor → request is passed through to your origin with no changes. Zero added latency, zero behavioral change.
-
AI bot visitor (ChatGPT, Claude, Perplexity, Bing AI, GPTBot, and a few more) → the EdgeWorker fetches a Salespeak-managed optimization snippet from a Salespeak S3 bucket and injects it into the
<body>of the HTML response your origin returns. The bot sees a richer, more citation-friendly version of the page; the human cache is untouched.
It also sends Salespeak an analytics event for each AI bot visit so you can see which AI tools are citing which of your pages.
Why you'd want it
Generative-AI search tools (ChatGPT search, Perplexity, Claude with web access, Google AI Overviews, etc.) crawl the public web with their own bots. The HTML they see is what gets cited. Most websites are tuned for Google's classic SEO crawler, not for these new bots — they often miss key product/pricing/answer content, especially when it's rendered by JavaScript or buried below the fold.
The EdgeWorker fixes this without changing your origin: it inserts a purpose-built content block (provided by Salespeak, hosted on Salespeak-managed S3) into the response, but only when the visitor is one of the recognized AI bots. Your normal site, your normal cache, your normal traffic — all unchanged.
What it does not do
- It does not modify responses for human visitors.
- It does not modify responses for traditional SEO crawlers (Googlebot, Bingbot — these are explicitly filtered out).
- It does not inject
<script>tags or any executable code. - It does not read or modify cookies, headers, or query strings other than what's needed for bot detection.
- It does not call your origin more than once per request.
- It does not change your cache TTLs for human traffic.
- If anything goes wrong inside the EdgeWorker, it falls back to serving your origin response unchanged. The integration cannot break your site.
How it works
Visitor
↓
Akamai edge
│
├─ Is it an AI bot UA? ───── No ──► Origin response delivered as-is
│ (no EdgeWorker work — passthrough)
│
└─ Yes
│
├─ Fetch optimization snippet from Salespeak S3 (parallel)
├─ POST analytics event to Salespeak (parallel, fire-and-forget)
├─ Wait for origin's HTML response
├─ Inject snippet into <body>
└─ Return enriched HTML to bot
On any failure (Salespeak unreachable, snippet missing, parse error,
anything): origin response is delivered unchanged. The integration is
designed to fail open.Recognized AI bots
| User-Agent pattern | Source |
|---|---|
ChatGPT-User/1.0 |
OpenAI ChatGPT live-fetch |
GPTBot/1.0 |
OpenAI training crawler |
Google-Extended |
Google's AI training opt-out crawler |
bingpreview |
Bing AI / Copilot |
PerplexityBot |
Perplexity |
Claude-User, Claude-Web, ClaudeBot
|
Anthropic Claude |
(Googlebot is detected but currently treated as a regular SEO crawler — no AI optimization is served to it. This will change in a future release once Google's Gemini fingerprinting is more reliable.)
Responsibilities
| Salespeak | Your Akamai admin | |
|---|---|---|
| Publishes the EdgeWorker source to a public S3 bucket | ✅ | |
| Provides this article + your Salespeak organization ID | ✅ | |
| Maintains the optimization snippets (S3) | ✅ | |
| Owns the analytics ingestion endpoint | ✅ | |
| Creates the EdgeWorker ID in Akamai | ✅ | |
| Configures Property Manager (one-time setup) | ✅ | |
| Downloads + deploys the EdgeWorker bundle | ✅ | |
| Activates Property Manager changes | ✅ | |
| Rolls back the EdgeWorker bundle | ✅ | |
| Disables the EdgeWorker behavior in an emergency | ✅ |
Salespeak does not have access to your Akamai account in any form. All upload + activation actions happen on your account, by your team. The only thing crossing the boundary is the public S3 download of the source tarball.
Prerequisites
To deploy the integration, you'll need:
- An Akamai EdgeWorkers entitlement on your contract, Dynamic Compute tier or higher. (Basic Compute is not sufficient — it doesn't support sub-requests or body transformation.)
- Akamai EdgeScape (optional but recommended) — used to populate visitor country in analytics. Falls back to "unknown" if not enabled.
- Property Manager access on the property serving the hostname(s) you want to enable the integration on.
-
The Akamai CLI with the EdgeWorkers plugin installed on whoever will run the deploy script:
brew install akamai akamai install edgeworkers - An API client for your Akamai account with the
EdgeWorkers(read + write) scope, configured in~/.edgerc. See Akamai's API client docs.
What Salespeak provides you (just one thing):
- Your Salespeak organization ID (UUID format) — you'll pass it as a command-line argument when you run the deploy script in Step 5.
What Salespeak does NOT need:
- Any access to your Akamai account.
- Any access to your Property Manager configuration.
- Any API client tokens from your side.
The EdgeWorker source code is published to a public Salespeak S3 bucket; you download it directly in Step 5 below.
Setup — step by step
The setup is one-time per property. After this, all subsequent updates are EdgeWorker-only and don't require Property Manager changes.
Step 1 — Create the EdgeWorker config
In Akamai Control Center → EdgeWorkers → Create EdgeWorker ID:
- Name:
salespeak-ai-optimizer - Group: (your Akamai group)
- Resource tier: Dynamic Compute
Save the returned EdgeWorker ID (a number) — you'll reference it in Step 3 and every time you deploy.
CLI equivalent if you prefer:
akamai edgeworkers list-resource-tiers <your_contract_id>
akamai edgeworkers create-id \
--groupId <your_group_id> \
--resourceTierId <dynamic_compute_tier_id> \
"salespeak-ai-optimizer"Step 2 — Declare three Property Manager variables
In Property Manager, on the property serving your hostname, open the Property Variables tab and add these three user-defined variables:
| Variable name | Initial value | Hidden | Sensitive |
|---|---|---|---|
PMUSER_AI_BOT_TYPE |
(leave empty) | No | No |
PMUSER_AI_REQUEST_ID |
(leave empty) | No | No |
PMUSER_AI_GEMINI_DEBUG |
(leave empty) | No | No |
⚠️ Important. If these variables are not declared, the EdgeWorker will install successfully but will silently do nothing. Akamai's
setVariable()call is a no-op for undeclared variables — there is no error. Symptom: integration looks deployed, but you'll never see analytics events or any visible change.
Step 3 — Add the EdgeWorker rule
Add a new rule to your property configuration:
Match conditions:
Hostname is one of [your hostnames, e.g. example.com, www.example.com]
Request Method is GET
Path does NOT match /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|webp|avif|mp4|webm|pdf|json|map|xml|txt)$/The path exclusion is a defensive optimization — the EdgeWorker also short-circuits on static assets internally, but excluding them at the property level avoids invoking the EdgeWorker at all for ~90% of requests.
Behaviors (in this order):
-
EdgeWorker
- Identifier:
<ew_id from Step 1> - Enable: Yes
- Identifier:
-
Modify Outgoing Request — Allowed Sub-Resource Origins
Declare these two third-party origins so the EdgeWorker can fetch from them:salespeak-public-serving.s3.amazonaws.com22i9zfydr3.execute-api.us-west-2.amazonaws.com
-
Cache Key — Include User Variable
- Variable:
PMUSER_AI_BOT_TYPE - Why: ensures the AI-bot variant of a page is cached separately from the human variant. Without this, an AI bot's enriched response could be served to a human (or vice versa) on a cache hit.
- Variable:
-
EdgeWorker Failure Handling
- On error: Serve origin response
- Why: belt-and-suspenders. The EdgeWorker has its own internal fail-safe behavior, but this property-level setting guarantees that even an unrecoverable EdgeWorker failure (CPU exhaustion, runtime error) results in your origin response being served instead of an HTTP 5xx.
Step 4 — Activate Property Manager on STAGING
Activate your property configuration on the STAGING network only. Wait ~2–5 minutes for propagation.
Step 5 — Download from Salespeak's S3 and deploy to STAGING
Salespeak publishes the EdgeWorker source to a public S3 bucket. You download it, then run a single script that builds + uploads + activates the bundle in your Akamai account.
# 1. Download the latest release. (For production, pin to a version —
# see "Updating the EdgeWorker code" below.)
curl -LO https://salespeak-public-serving.s3.amazonaws.com/integrations/akamai/latest/akamai-edgeworker.tgz
# 2. Extract:
tar -xzf akamai-edgeworker.tgz
cd akamai-edgeworker-ai-optimizer
# 3. Deploy to staging. Pass YOUR Salespeak organization ID (from
# Salespeak) and YOUR EdgeWorker ID (from Step 1):
./deploy.sh stage <YOUR_SALESPEAK_ORG_ID> <YOUR_EDGEWORKER_ID>What deploy.sh stage does:
- Substitutes your
organization_idinto the EdgeWorker source. - Sets the
?user-agent=...debug override on for staging (it's flipped off automatically when you passprodinstead). - Stamps a unique version into the EdgeWorker bundle.
- Packages
bundle.tgz. - Uploads it to your EdgeWorker via the Akamai CLI.
- Activates the new version on the STAGING Akamai network.
Wait ~1–2 minutes for staging propagation.
No CLI access? You can alternatively use the Akamai Control Center web UI: run
./deploy.sh stage <YOUR_SALESPEAK_ORG_ID>(no EdgeWorker ID — it buildsbundle.tgzbut doesn't upload), then drag-drop the resultingbundle.tgzinto Akamai Control Center → EdgeWorkers → your EdgeWorker ID → Versions → Create Version, and activate from the Activations tab.
Step 6 — Verify on STAGING
Replace <staging_hostname> with your Akamai staging hostname (typically <your-host>.akamaized-staging.net or a custom staging URL).
# Should return the original page (no Vary, no no-store headers):
curl -i -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)" \
https://<staging_hostname>/ | head -20
# Should return the AI-enriched page with the snippet injected and
# response headers including:
# Vary: User-Agent
# Cache-Control: private, no-store, max-age=0
# Pragma: no-cache
curl -i -A "ChatGPT-User/1.0" https://<staging_hostname>/ | head -20
# Static asset — must passthrough (no Vary, no Cache-Control change):
curl -i -A "ChatGPT-User/1.0" https://<staging_hostname>/some-asset.css | head -10Confirm with Salespeak that the analytics event for your test request arrived.
Step 7 — Promote to PRODUCTION
Once Step 6 is green:
- Activate the property configuration on PRODUCTION (Property Manager). Wait ~10 minutes for propagation.
-
Deploy the EdgeWorker to PRODUCTION:
./deploy.sh prod <YOUR_SALESPEAK_ORG_ID> <YOUR_EDGEWORKER_ID>The
prodargument flips off the?user-agent=...debug override (so external traffic can't force the AI variant on production) and activates the uploaded version on the PRODUCTION Akamai network. - Wait ~5–10 minutes for propagation.
- Re-run the Step 6 verification against your production hostname.
That's it. The integration is live.
Updating the EdgeWorker code
Day-to-day Salespeak releases require only an EdgeWorker re-deploy — Property Manager configuration is unchanged.
# 1. Pull the latest from S3 (or pin to a specific version)
curl -LO https://salespeak-public-serving.s3.amazonaws.com/integrations/akamai/latest/akamai-edgeworker.tgz
# Pinned version example:
# curl -LO https://salespeak-public-serving.s3.amazonaws.com/integrations/akamai/v1.0.1/akamai-edgeworker.tgz
tar -xzf akamai-edgeworker.tgz
cd akamai-edgeworker-ai-optimizer
# 2. Deploy to staging
./deploy.sh stage <YOUR_SALESPEAK_ORG_ID> <YOUR_EDGEWORKER_ID>
# 3. Smoke test against staging (Step 6 above)
# 4. Deploy to production
./deploy.sh prod <YOUR_SALESPEAK_ORG_ID> <YOUR_EDGEWORKER_ID>For production deployments, pin to a specific version (/v1.0.1/...) rather than /latest/... so that a Salespeak release can't change your production behavior unexpectedly. Salespeak announces new releases via email; you decide when to bump.
Rollback
In order of escalating cost, three options:
Option A — Roll back to a previous EdgeWorker version (~5–10 min)
Use this for any code-introduced regression. Akamai keeps every uploaded version forever, so you can re-activate any prior version.
Web UI: Akamai Control Center → EdgeWorkers → your EdgeWorker ID → Activations → select the prior version → choose Production → Activate.
CLI:
akamai edgeworkers list-versions <YOUR_EDGEWORKER_ID>
akamai edgeworkers activate <YOUR_EDGEWORKER_ID> PRODUCTION <previous_version>Option B — Disable the EdgeWorker behavior in Property Manager (~5 min)
Use this if Option A isn't fast enough or if a Property Manager misconfig (e.g. undeclared PMUSER variables) is the cause.
In Property Manager, open the EdgeWorker rule from Step 3 and set the EdgeWorker behavior to Enable: No. Activate the property. Traffic flows through with the EdgeWorker doing nothing — exactly as if it weren't installed.
The bundle and EdgeWorker config remain — re-enable later by toggling back to Enable: Yes.
Option C — Remove the EdgeWorker rule entirely
Used only if both A and B are insufficient. Delete the rule added in Step 3 and re-activate the property.
Monitoring
Three signals worth a dashboard tile each:
- Origin error rate for the affected hostname(s). Should be flat across deploys. A spike right after an EdgeWorker activation is a strong signal to roll back via Option A.
- EdgeWorker execution count (visible in Akamai Control Center → EdgeWorkers). Should be approximately equal to your matched-path request count.
- Salespeak analytics inflow for AI bot events. Salespeak provides this dashboard. A sudden drop after a deploy means the EdgeWorker is no longer detecting bots correctly — typically caused by Property Manager variables being undeclared. See Step 2 above.
For richer logging, you can enable Akamai DataStream 2 scoped to this property and pipe the access logs to a Salespeak-owned ingest endpoint. Contact Salespeak to set this up if you want detailed observability.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| EdgeWorker deployed but no analytics events appearing | PMUSER variables not declared in Property Manager | Re-do Step 2 above. |
| AI bots get the original page, no enrichment, but logs show events arriving | The path the bot requested doesn't have an optimized variant in Salespeak's S3 bucket | Expected and correct (the EdgeWorker correctly skips injection when no snippet exists). Confirm with Salespeak that the URL is in their content-management plan. |
| Humans get the AI-enriched page from cache | Cache key not modified to include PMUSER_AI_BOT_TYPE
|
Re-do Step 3, behavior #3. |
| 5xx errors after EdgeWorker activation | EdgeWorker failure handling not set to "Serve origin response" AND the EdgeWorker is throwing | Set failure handling per Step 3 behavior #4, then roll back the EdgeWorker version per Option A. |
akamai edgeworkers upload returns 403 |
API client missing the EdgeWorkers (write) scope | Regenerate the API client with EdgeWorkers (read + write). |
| Activation stuck "PENDING" for >30 minutes | Akamai-side delay or queue contention | Check the Akamai Status page; contact Akamai support if it's not network-wide. |
| Bot type column always empty in analytics events | Same as row 1 — PMUSER variable read returning empty | Re-do Step 2. |
FAQ
Q: Will this slow down my site for human visitors?
No. For human visitors, the EdgeWorker exits immediately after a single regex check on the User-Agent header — typically under 1 millisecond. Your origin response is served unchanged.
Q: What happens if Salespeak's S3 bucket goes down?
The EdgeWorker fetches the snippet from S3 with a 1.5-second timeout. If S3 is unreachable or returns an error, the EdgeWorker serves your origin response unchanged. AI bots see the regular page; humans are unaffected.
Q: What happens if Salespeak's analytics endpoint goes down?
The analytics POST is fire-and-forget with a 1-second timeout. Failure of the analytics endpoint doesn't affect the response sent to the visitor. Worst case: a few AI visit events go unrecorded.
Q: Can the EdgeWorker break my site?
The EdgeWorker is designed to fail open — every failure path falls back to your origin response. The Property Manager "Serve origin response" failure handling (Step 3 behavior #4) is a second guarantee. The combination means a malfunctioning EdgeWorker degrades to a no-op, never to an error page.
Q: Does the EdgeWorker read or store cookies / PII?
No cookies are read. The only fields sent in analytics events are: bot user-agent, requested URL, client IP, country code, and your organization ID. No request body, no headers other than UA, no cookies.
Q: Can we run this on a subset of hostnames first?
Yes — Step 3's match condition can be scoped to any hostname or path pattern. Common pattern: enable on a single subdomain (e.g. docs.example.com) for a week, then expand.
Q: How do we add new AI bot user agents in the future?
Salespeak publishes a new release to S3 and notifies you by email. You re-pull the tarball and re-run deploy.sh per the "Updating the EdgeWorker code" section above. Property Manager doesn't change.
Support
For deployment help, integration questions, or to report an issue:
- Email: support@salespeak.ai
- Include: your Akamai property name, the EdgeWorker ID, and the approximate time of the issue (UTC if possible).