Back to Docs

API Reference

Programmatic access to Axiomo analysis

Axiomo provides a JSON API for programmatic PR analysis. Use it to integrate Axiomo into your CI/CD pipelines, bots, or custom tooling.


Authentication

The API supports two authentication methods:

API Keys (Recommended)

For programmatic access, use API keys. Get yours from Settings.

Include your API key in the Authorization header:

Authorization: Bearer ax_your_key_here

API keys use your connected provider tokens, so they work with private repositories you have access to.

Direct Token (Alternative)

You can also pass a provider token directly in the request body:

{
  "url": "https://github.com/owner/private-repo/pull/123",
  "access_token": "ghp_xxxxxxxxxxxx"
}

Note: Never expose tokens in client-side code. Use API keys with server-side requests.

Public Repositories

No authentication is required for public repositories, but you'll be subject to lower rate limits.


POST /api/analyze

Analyze a pull request and generate an Axiomo Signal.

Request

Content-Type: application/json

You can provide either a PR URL or explicit parameters:

Option 1: URL (recommended)

{
  "url": "https://github.com/owner/repo/pull/123",
  "access_token": "ghp_xxxxxxxxxxxx"  // optional
}

Option 2: Explicit parameters

{
  "provider": "github",
  "owner": "owner",
  "repo": "repo",
  "pr_number": 123,
  "access_token": "ghp_xxxxxxxxxxxx"  // optional
}

Request Fields

Field Type Required Description
url string * Full PR URL (e.g., https://github.com/owner/repo/pull/123)
provider string * Git provider: "github" (more coming soon)
owner string * Repository owner/organization
repo string * Repository name
pr_number integer * Pull request number
access_token string No GitHub personal access token for private repos

* Either url OR all of provider, owner, repo, pr_number are required.

Response

Success (200):

{
  "signal_id": "ax-owner-repo-123-a1b2c3d4",
  "signal_url": "https://axiomo.app/s/ax-owner-repo-123-a1b2c3d4",
  "signal": {
    "version": "axiomo.signal.v1",
    "signal_id": "ax-owner-repo-123-a1b2c3d4",
    "pr": { ... },
    "risk": { ... },
    "contributors": [ ... ],
    "evidence": { ... },
    "supply_chain": { ... },
    "focus": { ... },
    "triage": { ... },
    "review": { ... },
    "meta": { ... }
  }
}

Error Responses

Bad Request (400):

{
  "error": "Invalid PR URL. Supported: GitHub PR URLs"
}

Server Error (500):

{
  "error": "Analysis failed: ...",
  "detail": "Error details"
}

GET /api/scans/{scan_id}

Retrieve a previously generated signal by its scan ID.

Request

No request body required. Authentication is optional (scan IDs are unguessable).

GET /api/scans/scan-a1b2c3d4e5f6

Response

Success (200):

{
  "signal_id": "ax-owner-repo-123-a1b2c3d4",
  "scan_id": "scan-a1b2c3d4e5f6",
  "signal": { ... },
  "created_at": "2024-01-26T12:00:00Z"
}

Not Found (404):

{
  "detail": "Scan not found"
}

Signal Schema

The signal object contains the full analysis. Key sections:

pr

PR metadata: provider, owner, repo, number, title, author, branches, timestamps.

risk

Risk assessment with level (low/medium/high/critical), score (0-1), and drivers explaining why.

contributors

Array of contributor profiles with trust levels, account age, prior PRs, and context.

evidence

CI/test signals with completeness score and individual check statuses.

supply_chain

Dependency and CI config changes: new dependencies, lockfile mods, CI file changes.

focus

Prioritized list of files to review, ranked by importance.

triage

Review effort estimate, staleness risk, and recommendations.

review

Suggested action (approve/comment/request_changes/needs_discussion) with rationale and draft comments.

See the main documentation for detailed explanations of each section.


Rate Limits

API rate limits depend on your authentication:

  • With API key: 60 requests/minute per user
  • Without authentication: 10 requests/minute per IP

Rate limit headers are included in all responses:

  • X-RateLimit-Limit: Maximum requests allowed
  • X-RateLimit-Remaining: Requests remaining
  • X-RateLimit-Reset: Unix timestamp when limit resets

Examples

cURL

# Public PR (no auth)
curl -X POST https://axiomo.app/api/analyze \
  -H "Content-Type: application/json" \
  -d '{"url": "https://github.com/facebook/react/pull/28000"}'

# Private PR (with API key)
curl -X POST https://axiomo.app/api/analyze \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ax_your_key_here" \
  -d '{"url": "https://github.com/your-org/private-repo/pull/42"}'

Python

import requests

# With API key for private repos
response = requests.post(
    "https://axiomo.app/api/analyze",
    headers={"Authorization": "Bearer ax_your_key_here"},
    json={"url": "https://github.com/your-org/private-repo/pull/42"}
)
signal = response.json()["signal"]
print(f"Risk: {signal['risk']['level']} ({signal['risk']['score']})")

JavaScript

// With API key for private repos
const response = await fetch("https://axiomo.app/api/analyze", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer ax_your_key_here"
  },
  body: JSON.stringify({
    url: "https://github.com/your-org/private-repo/pull/42"
  })
});
const { signal } = await response.json();
console.log(`Risk: ${signal.risk.level}`);