API Examples

Runnable examples for the Codity public API. Each one assumes your key is in an environment variable:

export CODITY_API_KEY="cdt_your_key_here"
export CODITY_API="https://api.codity.ai/v1"

The examples use a fictional repository, acme-corp/payments-service. Replace it with your own.

Remember that every job below draws from your organization's shared monthly pools. See Usage and Limits.

1. Check Your Usage

Start here to confirm the key works and see your headroom. This call is free.

curl -sS -H "X-API-Key: $CODITY_API_KEY" "$CODITY_API/me/usage"

2. Review a Diff

Send a unified diff. Codity reviews it and returns findings. This consumes one Review / Scan unit.

git diff origin/main...HEAD > changes.diff

jq -n --arg diff "$(cat changes.diff)" '{
  diff: $diff,
  owner: "acme-corp",
  repo: "payments-service",
  provider: "cli",
  branch: "feature/refund-rounding",
  diff_source: "api"
}' > review.json

curl -sS -X POST "$CODITY_API/review" \
  -H "X-API-Key: $CODITY_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @review.json

Response:

{
  "job_id": "3f2a9c84-1b7d-4e55-9a10-6c2f8b0d4e11",
  "workflow_id": "8d41e6b2-77a3-4c19-b0f5-2e9a1c7d3f6b",
  "status": "accepted"
}

Giving the review more context

A diff alone is enough, but reviews are sharper when Codity can see the surrounding code. Pass the relevant files:

{
  "diff": "<unified diff>",
  "owner": "acme-corp",
  "repo": "payments-service",
  "provider": "cli",
  "files": [
    { "path": "src/billing/refund.py", "content": "<full file contents>" },
    { "path": "src/billing/rounding.py", "content": "<full file contents>" }
  ]
}

3. Poll for the Result

Polling is free. Poll until the status is terminal (completed or failed).

JOB_ID="3f2a9c84-1b7d-4e55-9a10-6c2f8b0d4e11"

for i in $(seq 1 60); do
  STATUS=$(curl -sS -H "X-API-Key: $CODITY_API_KEY" "$CODITY_API/jobs/$JOB_ID" | jq -r '.status')
  echo "status: $STATUS"
  case "$STATUS" in
    completed|failed) break ;;
  esac
  sleep 5
done

curl -sS -H "X-API-Key: $CODITY_API_KEY" "$CODITY_API/jobs/$JOB_ID" | jq '.'

The job detail includes the operation type, overall status, per-step progress, and an error message if something failed.

4. Run a Security Scan

Each scan type is its own job and consumes one Review / Scan unit.

curl -sS -X POST "$CODITY_API/scan/security" \
  -H "X-API-Key: $CODITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "owner": "acme-corp",
    "repo": "payments-service",
    "provider": "cli",
    "branch": "main",
    "files": [
      { "path": "src/api/auth.py", "content": "<full file contents>" }
    ]
  }'

The same shape works for /v1/scan/license and /v1/scan/quality. Run them in parallel if you want all three, but remember that each one draws its own unit.

5. Ask a Question About a Repository

Navigation answers questions about code. This consumes one Chat / Navigation unit.

curl -sS -X POST "$CODITY_API/navigate" \
  -H "X-API-Key: $CODITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Where is the refund rounding logic and what calls it?",
    "owner": "acme-corp",
    "repo": "payments-service",
    "provider": "github"
  }'

6. Request an Automation Action

Automation takes an instruction rather than a question. This consumes one Automation unit.

curl -sS -X POST "$CODITY_API/automation" \
  -H "X-API-Key: $CODITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instruction": "Add a guard so refunds cannot round to a negative amount.",
    "owner": "acme-corp",
    "repo": "payments-service",
    "provider": "github"
  }'

7. Watch Your Quota From the Response

Every response carries quota headers, so a pipeline can track headroom without an extra call.

curl -sS -D headers.txt -o body.json -X POST "$CODITY_API/review" \
  -H "X-API-Key: $CODITY_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @review.json

grep -i "x-ratelimit" headers.txt
x-ratelimit-reviews-scans-limit: <your limit>
x-ratelimit-reviews-scans-remaining: <what's left>
x-ratelimit-reset: <next billing period start>

8. Handle a Limit in CI

On a hard cap, an exhausted pool returns 429. Decide deliberately whether that should fail your build.

HTTP=$(curl -sS -o body.json -w "%{http_code}" -X POST "$CODITY_API/review" \
  -H "X-API-Key: $CODITY_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @review.json)

case "$HTTP" in
  202)
    echo "Review submitted: $(jq -r '.job_id' body.json)"
    ;;
  429)
    # Monthly Review / Scan pool is exhausted.
    echo "Codity limit reached: $(jq -r '.detail' body.json)"
    echo "Skipping review for this build."
    exit 0          # use `exit 1` instead if reviews are required to merge
    ;;
  402)
    echo "Subscription issue: $(jq -r '.detail.message // .detail' body.json)"
    exit 1
    ;;
  *)
    echo "Unexpected response $HTTP: $(cat body.json)"
    exit 1
    ;;
esac

A 429 never consumes a unit, so it is safe to retry after the pool resets or after seats are added.

9. A Complete CI Flow

Submit a review, wait for it, and surface the findings.

#!/usr/bin/env bash
set -euo pipefail

: "${CODITY_API_KEY:?set CODITY_API_KEY}"
CODITY_API="https://api.codity.ai/v1"

git diff "origin/${TARGET_BRANCH:-main}...HEAD" > changes.diff
if [ ! -s changes.diff ]; then
  echo "No changes to review."
  exit 0
fi

jq -n --arg diff "$(cat changes.diff)" '{
  diff: $diff,
  owner: "acme-corp",
  repo: "payments-service",
  provider: "cli",
  diff_source: "api"
}' > review.json

HTTP=$(curl -sS -o submit.json -w "%{http_code}" -X POST "$CODITY_API/review" \
  -H "X-API-Key: $CODITY_API_KEY" -H "Content-Type: application/json" \
  --data-binary @review.json)

if [ "$HTTP" = "429" ]; then
  echo "Codity monthly limit reached; skipping review."
  exit 0
fi
if [ "$HTTP" != "202" ]; then
  echo "Submit failed ($HTTP): $(cat submit.json)"; exit 1
fi

JOB_ID=$(jq -r '.job_id' submit.json)
echo "Submitted job $JOB_ID"

for _ in $(seq 1 60); do
  curl -sS -H "X-API-Key: $CODITY_API_KEY" "$CODITY_API/jobs/$JOB_ID" > job.json
  STATUS=$(jq -r '.status' job.json)
  [ "$STATUS" = "completed" ] && break
  if [ "$STATUS" = "failed" ]; then
    echo "Review failed: $(jq -r '.error_message // "unknown"' job.json)"; exit 1
  fi
  sleep 5
done

jq '.' job.json

Tips

  • Poll with a sensible interval. Five seconds is usually plenty; polling is free but tight loops add no value.
  • Don't resubmit the same payload to "retry". Each submission is a new job and consumes another unit. Poll the existing job_id instead.
  • Send files when you can. A diff-only review works, but including the changed files and their close dependencies produces materially better findings.
  • Check /me/usage before large batches. If you're about to submit many jobs, confirm you have the headroom first.
  • Keep keys in secrets. Use your CI provider's secret store, never a committed file.