DEV-FRIENDLY

Run AEO checks in your pipeline

Treat AI visibility like any other quality gate: scan the build on every deploy, and fail the pipeline if the score falls below your threshold. Catch a missing canonical, broken FAQ schema, or a regressed SSR render before it ships.

1.

Get an API key

Open Settings → API keys, click New API key, give it a label like ci-deploy, and copy the aeol_… token shown once. Add it as a secret in your CI provider (GitHub Actions: AEOLENS_API_KEY; GitLab: a masked variable).

API access ships on Growth ($99/mo) and Agency ($249/mo) plans.

2.

Call the scan endpoint

The endpoint runs synchronously: it queues the scan, waits up to max_wait_seconds, and returns a pass/fail body. Run it against the URL you just deployed (a staging URL is the common pattern).

curl -X POST https://aeolens.ai/api/v1/ci/scan \
  -H "Authorization: Bearer $AEOLENS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://staging.acme.com",
    "min_score": 70,
    "max_wait_seconds": 180
  }'

Response (status 200):

{
  "status": "complete",
  "passed": true,
  "score": 78,
  "threshold": 70,
  "scan_id": "0a1b2c3d-…",
  "scan_url": "https://aeolens.ai/scan/0a1b2c3d-…",
  "failed_checks": ["SCHEMA", "OG"],
  "error": null,
  "wait_seconds": 12.4
}

The endpoint always returns 200 on a successful scan — even when the threshold isn't met. Your script reads .passedand decides whether to fail the build. This keeps "AEOlens errored" distinguishable from "deploy was blocked."

3.

GitHub Actions snippet

Drop this into .github/workflows/aeo.yml (or merge into your existing deploy workflow). It runs after deploy and fails the job if AEOlens reports passed: false.

name: AEO gate

on:
  deployment_status:
    states: [success]

jobs:
  aeo-scan:
    runs-on: ubuntu-latest
    steps:
      - name: Run AEOlens scan
        env:
          AEOLENS_API_KEY: ${{ secrets.AEOLENS_API_KEY }}
          DEPLOY_URL: ${{ github.event.deployment_status.target_url }}
        run: |
          RESPONSE=$(curl -sf -X POST https://aeolens.ai/api/v1/ci/scan \
            -H "Authorization: Bearer $AEOLENS_API_KEY" \
            -H "Content-Type: application/json" \
            -d "{\"url\":\"$DEPLOY_URL\",\"min_score\":70}")
          echo "$RESPONSE" | jq .
          PASSED=$(echo "$RESPONSE" | jq -r .passed)
          if [ "$PASSED" != "true" ]; then
            echo "::error::AEO gate failed — see scan_url in the response."
            exit 1
          fi
4.

GitLab CI snippet

Drop into .gitlab-ci.yml. Set AEOLENS_API_KEY and DEPLOY_URL as project variables.

aeo_gate:
  stage: post-deploy
  image: curlimages/curl:latest
  script:
    - |
      RESPONSE=$(curl -sf -X POST https://aeolens.ai/api/v1/ci/scan \
        -H "Authorization: Bearer $AEOLENS_API_KEY" \
        -H "Content-Type: application/json" \
        -d "{\"url\":\"$DEPLOY_URL\",\"min_score\":70}")
      echo "$RESPONSE"
      echo "$RESPONSE" | grep -q '"passed":true' || exit 1
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
5.

Request reference

FieldTypeDefaultDescription
urlstringrequiredPublic URL to scan. Private/loopback hosts are rejected.
min_scoreint (0-100)70Threshold for .passed. Below this returns passed: false.
max_wait_secondsint (10-300)180How long to wait synchronously. After this, returns status: "timeout".
6.

Response statuses

statuspassedMeaning
completetrue / falseScan finished. Check passed against your threshold.
timeoutfalseScan still running after max_wait_seconds. Use scan_id to poll later, or increase the budget.
failedfalseScan errored (bad URL, network failure). See error field.
7.

Rate limits & quotas

The CI endpoint consumes a scan from your plan's monthly quota — it isn't a separate bucket. Growth covers unlimited scans with a fair-use cap of 15/day per workspace; Agency covers 50/day. If you scan on every PR you'll want Growth or above.

Hitting the cap returns a 402 with code: "QUOTA_EXCEEDED" rather than the 200 pass/fail shape.

Ready to gate your next deploy?

Spin up an API key in 30 seconds and drop the snippet above into your pipeline.

Get API key