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_idinstead. - 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/usagebefore 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.

