API Quickstart
One key, six calls — create a project on a repository, wait for setup, run two reviewers on a pull request, and read what they found.
Create a key in MCP & API Keys and set IONWARP_API_KEY. A key minted from a project page is pinned to that project; a workspace key sends Project-ID once the project exists. Install the GitHub App once and use its installation id below. Every call on this page is rendered from IonWarp's declared operations, so what you read is what the API answers.
Create the project. setup: true runs repository setup in the same call; setup.task is what to poll.
RESPONSE=$(curl --fail-with-body "https://ionwarp.com/api/v1/projects" \
-H "Authorization: Bearer $IONWARP_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: acme-projects.create-1' \
-d '{"setup":true,"name":"Acme API","repository":{"full_name":"acme/api","installation_id":123456}}')
PROJECT_ID=$(printf '%s' "$RESPONSE" | jq -er '.project.id')
TASK_ID=$(printf '%s' "$RESPONSE" | jq -er '.setup.task.id')Read the setup task until run.status is terminal.
curl --fail-with-body "https://ionwarp.com/api/v1/tasks/$TASK_ID" \
-H "Authorization: Bearer $IONWARP_API_KEY" \
-H "Project-ID: $PROJECT_ID"Create a review — it starts immediately. Omit reviewers to let the planner pick; code-review runs the governed pin, @model pins a model.
REVIEW_ID=$(curl --fail-with-body "https://ionwarp.com/api/v1/reviews" \
-H "Authorization: Bearer $IONWARP_API_KEY" \
-H "Project-ID: $PROJECT_ID" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: acme-reviews.create-1' \
-d '{"pr":42,"reviewers":["code-review","security-review@google/gemini-3.8-flash"]}' | jq -er '.id')Read the review: run is the latest receipt and findings are inlined once it is done.
curl --fail-with-body "https://ionwarp.com/api/v1/reviews/$REVIEW_ID" \
-H "Authorization: Bearer $IONWARP_API_KEY" \
-H "Project-ID: $PROJECT_ID"Which reviewers exist and which model each runs, most popular first.
curl --fail-with-body "https://ionwarp.com/api/v1/reviewers?limit=5" \
-H "Authorization: Bearer $IONWARP_API_KEY" \
-H "Project-ID: $PROJECT_ID"The models measured for one reviewer, current pin flagged, from the benchmarks app.
curl --fail-with-body "https://ionwarp.com/api/v1/reviewers/code-review/models" \
-H "Authorization: Bearer $IONWARP_API_KEY" \
-H "Project-ID: $PROJECT_ID"Reading work
GET /api/v1/tasks/{id} is the one read for anything asynchronous — the task with its latest run's receipt inlined as run: status, result, usage, cost_usd (null when unknown, never 0), a named error on failure, and gaps[] on a success that fell short somewhere. A review is a task, so GET /api/v1/reviews/{id} reads the same receipt plus findings once the run is done. GET /api/v1/tasks/{id}/runs is the history; POST /api/v1/tasks/{id}/cancel stops the active run.
Retries and the advanced forms
Send the same Idempotency-Key with the same body to recover an acknowledgement; a changed body under an existing key is 409 idempotency_conflict. The advanced forms live on the reference pages: {"base": "<sha>", "head": "<sha>"} targets a commit range, delivery: "github" posts the result on the PR, and a reviewer given as an object can pin an immutable skill revision alongside its model.