Git Gazette API for Agents
Get AI-generated repository articles via x402 payment.
No API keys. No accounts. Just pay and receive.
Quick Start
Install the x402 fetch wrapper to handle payment automatically:
npm install x402-fetch viemimport { wrapFetchWithX402 } from "x402-fetch";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";
const account = privateKeyToAccount(PRIVATE_KEY);
const wallet = createWalletClient({
account,
chain: base,
transport: http(),
});
const fetchWithPayment = wrapFetchWithX402(fetch, wallet);
const res = await fetchWithPayment(
"https://gitgazette.com/api/x402/article",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
repo: "facebook/react",
language: "en",
columnist: "rita",
}),
}
);
const article = await res.json();Available Endpoints
Three paid endpoints, all $0.02 USDC per request on Base mainnet. Rate limits are shared across all of them — 10 requests per 5 minutes and 50 per day per wallet.
| Endpoint | Price | Description |
|---|---|---|
| POST /api/x402/article | $0.02 | Generate a single article by a specific columnist |
| POST /api/x402/compare | $0.02 | Compare two repos side by side |
| POST /api/x402/alternatives | $0.02 | Find similar repos to a given repo |
Article Endpoint
https://gitgazette.com/api/x402/article$0.02 USDC on Base mainnet
x402 (HTTP 402 Payment Required)
application/json
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| repo | string | yes | GitHub repo URL or owner/repo shorthand (e.g. "facebook/react") |
| language | string | yes | "en", "es", or "fr" |
| columnist | string | yes | See Columnists table below |
Repo accepts these formats: "facebook/react", "https://github.com/facebook/react". Activity window is fixed at 7 days.
Columnists
| Value | Name | Covers |
|---|---|---|
| rita | Rita Conflictson | Issue drama & debates |
| preston | Preston Mergington III | PR reviews & code quality |
| semver | Captain Semver | Releases & deploys |
| flo | Flo Stargazer | Community & contributors |
| patch | Patch Wiresec | Security advisories & CVEs |
"max" (Max Summarino / TL;DR) is not available via this endpoint. The TL;DR column requires all other articles as context.
Response
Successful requests return HTTP 200 with the following JSON:
{
"article": {
"headline": "React's PR Queue Erupts in a Merge Conflict Telenovela",
"body": "## The Drama\n\nThis week in React...",
"author_name": "Rita Conflictson",
"column_name": "The Drama Desk",
"sources": ["#28734", "#28691"],
"language": "en"
},
"metadata": {
"repo": "facebook/react",
"provider": "github",
"repo_url": "https://github.com/facebook/react",
"columnist": "rita",
"generated_at": "2026-03-27T14:30:00.000Z",
"cached": false,
"time_window_days": 7
}
}Patch Wiresec: Security Metadata
When columnist is "patch", the metadata includes a security object:
"security": {
"status": "warning",
"advisory_count": 2,
"has_security_policy": true
}No Security Issues (Patch)
When requesting Patch and no issues are found, the response returns article: null:
{
"article": null,
"security_status": "clear",
"message": "No security issues found for this repository in the last 7 days.",
"metadata": {
"repo": "facebook/react",
"provider": "github",
"columnist": "patch",
"security": { "status": "clear", "advisory_count": 0 }
}
}Errors
| Status | Code | Description |
|---|---|---|
| 400 | invalid_body | Request body is not valid JSON |
| 400 | missing_repo | repo field is empty or missing |
| 400 | invalid_language | Language not in allowed list (en, es, fr) |
| 400 | invalid_columnist | Columnist name not recognized |
| 400 | max_not_available | Max Summarino (TL;DR) cannot be requested individually |
| 400 | invalid_repo_url | Could not parse the repository URL |
| 402 | (x402) | Payment Required — standard x402 response with payment details |
| 403 | repo_not_eligible | Repository blocked by content filter |
| 403 | injection_detected | Repository contains unsafe content patterns |
| 429 | rate_limited | Rate limit reached. Includes Retry-After header (seconds) |
| 500 | generation_failed | Article generation failed |
Compare Endpoint
Compare two GitHub repositories side by side. Returns structured metrics for both repos plus AI-generated similarities, differences, and ideal use cases — not a columnist-written article.
https://gitgazette.com/api/x402/compare$0.02 USDC on Base mainnet
x402 (HTTP 402 Payment Required)
application/json
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| repo_a | string | yes | First repo — owner/repo shorthand or full GitHub URL (e.g. "facebook/react") |
| repo_b | string | yes | Second repo — same formats as repo_a |
| language | string | no | "en" (default), "es", or "fr" |
Both repos must be GitHub repositories. Activity window is fixed at 30 days. Order doesn't matter — react vs svelte and svelte vs react are treated as the same comparison.
Response
Successful requests return HTTP 200 with structured comparison data for both repos plus AI-generated analysis:
{
"comparison": {
"repo_a": {
"repo": {
"fullName": "facebook/react",
"owner": "facebook",
"name": "react",
"language": "JavaScript",
"license": "MIT",
"webUrl": "https://github.com/facebook/react"
},
"community": {
"stars": 230412,
"forks": 46230,
"openIssues": 1024,
"contributors": 30,
"license": "MIT",
"lastRelease": { "tag": "v19.1.0", "date": "...", "url": "..." }
},
"activity": {
"totalCommits": 142,
"totalPRsMerged": 67,
"totalPRsOpen": 234,
"totalIssuesOpened": 89,
"totalIssuesClosed": 112,
"averagePRMergeHours": 100,
"averageIssueCloseHours": 288,
"activeContributors": 34,
"commitFrequency": [38, 42, 31, 31]
},
"security": {
"hasSecurityPolicy": true,
"totalAdvisories": 12,
"activeAdvisories": 0,
"lastAdvisoryDate": "2026-01-15",
"securityStatus": "clear"
},
"releases": {
"totalReleases": 5,
"latestVersion": "v19.1.0",
"isPreRelease": false
}
},
"repo_b": { /* same shape as repo_a */ },
"analysis": {
"similarities": [
"Both are JavaScript UI frameworks for building interactive web interfaces",
"Both support component-based architecture with reactive state"
],
"differences": [
{
"aspect": "Bundle size",
"repo_a": "~42KB minified (runtime included)",
"repo_b": "~2KB minified (compiled output only)"
}
],
"ideal_for": {
"repo_a": [
{ "title": "Large enterprise apps", "reason": "Mature ecosystem..." }
],
"repo_b": [
{ "title": "Performance-critical SPAs", "reason": "Smallest bundle..." }
]
},
"better_together": null
}
},
"related": true,
"metadata": {
"cached": false,
"generated_at": "2026-04-07T14:30:00Z",
"expires_at": "2026-04-14T14:30:00Z",
"language": "en",
"comparison_url": "https://gitgazette.com/compare/facebook-react-vs-sveltejs-svelte"
}
}Unrelated Repos
If the two repos serve fundamentally different purposes (e.g. react vs redis), the response returns comparison: null with a reason and suggested alternatives. The agent is still charged — classification work was done and the response is useful.
{
"comparison": null,
"related": false,
"reason": "These repos serve fundamentally different purposes — react is a frontend UI framework while redis is an in-memory data store.",
"category_a": "Frontend UI Framework",
"category_b": "In-Memory Data Store",
"suggestions": ["preactjs/preact", "memcached/memcached"],
"metadata": {
"cached": false,
"generated_at": "2026-04-07T14:30:00Z",
"language": "en"
}
}Comparisons share rate limits and caching with the Article endpoint — see the sections below for details.
Alternatives Endpoint
Discover repos similar to a given repository. Useful for finding competing tools, alternative implementations, or related projects in the same space. All suggestions are verified against the GitHub API — hallucinated repos are filtered out automatically.
https://gitgazette.com/api/x402/alternatives$0.02 USDC on Base mainnet
x402 (HTTP 402 Payment Required)
application/json
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| repo | string | yes | Source repo — owner/repo shorthand or full GitHub URL (e.g. "facebook/react") |
| language | string | no | "en" (default), "es", or "fr". Affects the reason text language, not repo discovery. |
Response
Returns the repo's category and 3-5 verified alternative repos with metadata, stars, language, and a one-sentence reason explaining why each is a relevant alternative:
{
"source_repo": "facebook/react",
"category": "Frontend UI Framework",
"alternatives": [
{
"full_name": "sveltejs/svelte",
"description": "web development for the rest of us",
"language": "JavaScript",
"stars": 80234,
"forks": 4312,
"web_url": "https://github.com/sveltejs/svelte",
"reason": "Compiler-based UI framework with significantly smaller bundle sizes",
"verified": true
},
{
"full_name": "vuejs/core",
"description": "The progressive JavaScript framework",
"language": "TypeScript",
"stars": 208000,
"forks": 33200,
"web_url": "https://github.com/vuejs/core",
"reason": "Progressive framework with a gentler learning curve",
"verified": true
}
],
"metadata": {
"cached": false,
"generated_at": "2026-04-07T16:30:00Z",
"expires_at": "2026-04-14T16:30:00Z",
"language": "en"
}
}No Alternatives Found
If the repo is unique enough that no comparable alternatives exist, the response returns an empty alternatives array. You are still charged — the classification was performed and "no alternatives" is a valid, useful answer.
{
"source_repo": "some-unique/tool",
"category": "Specialized Tool",
"alternatives": [],
"message": "This repository is fairly unique...",
"metadata": {
"cached": false,
"generated_at": "2026-04-07T16:30:00Z",
"expires_at": "2026-04-14T16:30:00Z",
"language": "en"
}
}Combining with Compare
A common agent workflow: find alternatives first, then compare against the most relevant one. Total cost: $0.04.
// Step 1: Find alternatives
const altRes = await fetchWithPayment(
"https://gitgazette.com/api/x402/alternatives",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ repo: "facebook/react" }),
}
);
const altData = await altRes.json();
const topAlternative = altData.alternatives[0].full_name;
// Step 2: Compare with the top alternative
const cmpRes = await fetchWithPayment(
"https://gitgazette.com/api/x402/compare",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
repo_a: "facebook/react",
repo_b: topAlternative,
}),
}
);
const comparison = await cmpRes.json();Alternatives share rate limits and caching with the other endpoints. Results are cached for 7 days.
Caching
All three endpoints cache results for 7 days. Articles cache by repo + columnist + language; comparisons cache by repo pair (order-independent); alternatives cache by source repo + language.
You still pay $0.02 for cached responses — the payment is for access, not generation.
If an article exists in a different language, it may be translated rather than regenerated (faster, same cost).
Rate Limits
Rate limits are applied per wallet address and are shared across the Article, Compare, and Alternatives endpoints. The price stays flat at $0.02 regardless of usage.
- 10 requests per 5 minutes per wallet (combined)
- 50 requests per day per wallet (combined)
When rate limited, the endpoint returns 429 with a Retry-After header (seconds until the limit resets). You are not charged for 429 responses.
Network Details
Base mainnet (eip155:8453)
USDC
$0.02 per request
CDP (api.cdp.coinbase.com)
x402 v2