API and command line

Run an analysis from a pipeline after every deploy, fail the build when a statement got slower, pull the report as an artefact. Everything the browser does with a run is available over HTTPS with a token; the pgqa command line wraps it.

1. Get a token

Owners and analysts create tokens under Team → API tokens (Starter plan and above). A token acts as its creator, inside that organisation, and can be given an expiry. It starts with pgs_ and is shown once.

Store it as a CI secret named PGQA_CLOUD_TOKEN. Rotate it by creating a new one and revoking the old.

2. The command line

Install the analyzer (pip install pgqa, or pipx install pgqa) and point it at this site:

# once, on a laptop (writes ~/.config/pgqa/cloud.json, mode 600)
pgqa cloud login --url https://pgsenpai.employeekickoff2027.com

# in CI, use the environment instead
export PGQA_CLOUD_URL=https://pgsenpai.employeekickoff2027.com
export PGQA_CLOUD_TOKEN=$PGQA_CLOUD_TOKEN

pgqa cloud whoami
pgqa cloud connections                      # saved connections and their ids
pgqa cloud run --connection-id 3 --wait --report report.html --fail-on-regression
pgqa cloud run --connection "postgresql://pgsenpai_reader@db.example.com:5432/shop" \
    --password-env DB_PASSWORD --title "post-deploy $GITHUB_SHA" --wait
pgqa cloud list --limit 10
pgqa cloud status <id>
pgqa cloud report <id> -o report.html
pgqa cloud recommendations <id>

Exit codes: 0 done, 1 the analysis failed, 2 usage or configuration error, 3 regressions found (with --fail-on-regression), 4 the API could not be reached or refused the request. Add --json to any read command for machine-readable output.

3. GitHub Actions example

jobs:
  slow-queries:
    runs-on: ubuntu-latest
    steps:
      - run: pipx install pgqa
      - name: Analyse production after the deploy
        env:
          PGQA_CLOUD_URL: https://pgsenpai.employeekickoff2027.com
          PGQA_CLOUD_TOKEN: ${{ secrets.PGQA_CLOUD_TOKEN }}
        run: pgqa cloud run --connection-id 3 --title "deploy ${{ github.sha }}" --wait --report report.html --fail-on-regression
      - uses: actions/upload-artifact@v4
        if: always()
        with: { name: slow-query-report, path: report.html }

4. Endpoints

Base URL https://pgsenpai.employeekickoff2027.com/api/v1. Send Authorization: Bearer pgs_…. JSON in, JSON out; errors are {"error": {"status": 4xx, "message": "…"}}. Limited to a number of requests per minute per token (429 when exceeded).

Method and pathWhat it does
GET /meMember, organisation, plan and analyses used this month.
GET /connectionsSaved connections with their ids (use connection_id to run without sending credentials).
POST /analysesStart a run. Body: connection_string + password, or connection_id; optional title, source, max_rows, min_calls, min_avg_ms, run_queries, statement_timeout_ms, explain_timeout. Returns 202 with the run's id.
GET /analyses?limit=50Recent runs of the organisation.
GET /analyses/{id}Status (queued, running, done, failed, cancelled), summary, comparison with the previous run (regressions, improvements, new), stored files.
GET /analyses/{id}/reportThe HTML report.
GET /analyses/{id}/files/{name}Any stored file: analysis.json, run.log, pev2_*.html.
GET /analyses/{id}/recommendationsRule-based index, rewrite and maintenance findings with SQL and estimated benefit.

Machine-readable description: OpenAPI 3 document.

5. curl

curl -sS -H "Authorization: Bearer $PGQA_CLOUD_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"connection_id": 3, "title": "nightly"}' \
  https://pgsenpai.employeekickoff2027.com/api/v1/analyses
# → {"id":"…","status":"queued","url":"…","notes":[]}

curl -sS -H "Authorization: Bearer $PGQA_CLOUD_TOKEN" https://pgsenpai.employeekickoff2027.com/api/v1/analyses/<id>
curl -sS -H "Authorization: Bearer $PGQA_CLOUD_TOKEN" https://pgsenpai.employeekickoff2027.com/api/v1/analyses/<id>/report -o report.html