The same AI-powered configuration review that drives the Renovate Initializr UI is exposed as a small, public REST API. Send it a renovate.json and get back a plain-language summary, a list of concrete issues, and an improved configuration.
The API has a single job: analyse a Renovate configuration and tell you how to make it better. Under the hood your config is first validated against the official Renovate JSON schema, then handed to an DeepSeek model that returns structured, actionable feedback. It's the right tool when you want to lint and improve renovate.json files programmatically — in CI, a bot, or your own developer tooling.
https://renovate.oglimmer.com/apihttp://localhost:8080/apiConventions
application/json./api prefix is the server context path.Auth & CORS
https://renovate.oglimmer.com, so browser calls from other origins are blocked. Call it server-to-server instead.429 Too Many Requests./api/feedbackSubmit a Renovate configuration and receive AI feedback on it.
What it does: validates your config against the Renovate JSON schema, then asks an LLM to review it for best practices, security, and PR hygiene.
Why you'd use it: to catch misconfigurations and get an opinionated, improved config without reading the entire Renovate documentation — automatable from CI or your own tools.
renovateJson string is parsed and validated against the Renovate schema (draft-07).400 Bad Request immediately — no LLM call is made.RenovateFeedbackRequest
| Field | Type | Required | Description |
|---|---|---|---|
renovateJson | string | Yes | Your Renovate config, serialised as a JSON string (i.e. the file contents), not a nested JSON object. |
renovateJson is a string field. Stringify your config and place it inside the request object — see the examples below, which double-encode it. JavaScript (fetch)
// renovateJson is a *string* — stringify your config, then the request object.
const renovateConfig = {
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
extends: ['config:recommended', ':enableVulnerabilityAlerts'],
timezone: 'Europe/Berlin'
}
const res = await fetch('https://renovate.oglimmer.com/api/feedback', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ renovateJson: JSON.stringify(renovateConfig) })
})
if (!res.ok) throw new Error(`Validation failed: ${res.status}`)
const feedback = await res.json()
console.log(feedback.summary)
feedback.issues.forEach(i => console.log(`[${i.severity}] ${i.jsonPath}: ${i.message}`))cURL
curl -X POST https://renovate.oglimmer.com/api/feedback \
-H "Content-Type: application/json" \
-d '{
"renovateJson": "{\"extends\":[\"config:recommended\"],\"timezone\":\"Europe/Berlin\"}"
}'RenovateFeedbackResponse
{
"summary": "Solid baseline using recommended presets. A couple of tweaks would improve PR hygiene.",
"issues": [
{
"severity": "warning",
"jsonPath": "$.prConcurrentLimit",
"message": "No concurrency limit set; Renovate may open many PRs at once.",
"suggestion": "Add \"prConcurrentLimit\": 10 to cap simultaneous open PRs."
},
{
"severity": "info",
"jsonPath": "$.timezone",
"message": "Timezone is set but no schedule is defined, so it has no effect.",
"suggestion": "Add a \"schedule\", e.g. [\"before 5am on monday\"]."
}
],
"improvedRenovateJson": "{\n \"extends\": [\"config:recommended\", \":enableVulnerabilityAlerts\"],\n \"timezone\": \"Europe/Berlin\",\n \"prConcurrentLimit\": 10\n}"
}| Code | Meaning |
|---|---|
200 OK | Feedback generated successfully (see the graceful-degradation note below). |
400 Bad Request | The renovateJson is not valid JSON, or fails Renovate schema validation. The error message names the offending fields. |
429 Too Many Requests | Rate limit exceeded — the endpoint allows 1 request per minute per IP. Wait and retry. |
200 OK with a summary describing the failure, an empty issues array, and your original config echoed back in improvedRenovateJson. Check issues.length and the summary text rather than relying on the status code alone. /api/generateno auth · no rate limit Build a renovate.json straight from URL query parameters — the form, without the form. Returns application/json, so you can pipe it straight into a file from curl, CI or a bot.
What it does: maps query parameters onto the default configuration and returns the generated config as JSON. No request body — everything is in the query string.
Why it exists: it runs the exact same generation function as the interactive form (one shared module) — single source of truth, so the API and the UI can never drift apart.
How it differs from /api/feedback: this is a pure, deterministic mapping — no AI, no schema validation, no rate limit, no authentication. CORS is open (Access-Control-Allow-Origin: *), so unlike /api/feedback you can also call it from the browser cross-origin.
Prefer a browser? The same result is rendered as a human-friendly page at /generate (same query parameters) with a copy button.
grouping.npm=true.true/1/yes/on; anything else is false.cURL
curl 'https://renovate.oglimmer.com/api/generate?schedule=weekly&prLimitStrategy=conservative&groupAllNonMajor=false&grouping.npm=true&grouping.docker=true' \
-o renovate.jsonURL (also opens in a browser at /generate)
https://renovate.oglimmer.com/api/generate?schedule=weekly&prLimitStrategy=conservative&groupAllNonMajor=false&grouping.npm=true&grouping.docker=trueThe generated renovate.json for the request above (omitted parameters fall back to defaults):
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":enableVulnerabilityAlerts",
":dependencyDashboard",
":semanticCommits",
"docker:pinDigests",
"helpers:pinGitHubActionDigests",
":pinDevDependencies",
"abandonments:recommended"
],
"configMigration": true,
"timezone": "Europe/Berlin",
"schedule": ["before 5am on monday"],
"prHourlyLimit": 1,
"prConcurrentLimit": 3,
"rebaseWhen": "behind-base-branch",
"rangeStrategy": "bump",
"automergeType": "branch",
"packageRules": [
{ "description": "Group npm dependencies (non-major updates)", "matchManagers": ["npm"], "matchUpdateTypes": ["minor", "patch", "pin", "digest"], "groupName": "npm dependencies" },
{ "description": "Group Docker dependencies (non-major updates)", "matchManagers": ["dockerfile", "docker-compose"], "matchUpdateTypes": ["minor", "patch", "pin", "digest"], "groupName": "Docker dependencies" },
{ "description": "Automerge minor, patch, pin, digest updates (low-risk, non-major)", "matchUpdateTypes": ["minor", "patch", "pin", "digest"], "automerge": true },
{ "description": "Automerge all devDependencies (build/test tooling, not shipped to consumers)", "matchDepTypes": ["devDependencies"], "automerge": true },
{ "description": "Automerge Maven/Gradle wrapper updates", "matchManagers": ["maven-wrapper", "gradle-wrapper"], "automerge": true },
{ "description": "Never automerge 0.x releases — semver allows breaking changes before 1.0", "matchCurrentVersion": "/^0\\./", "automerge": false },
{ "description": "Isolate major updates behind Dependency Dashboard approval", "matchUpdateTypes": ["major"], "dependencyDashboardApproval": true }
],
"minimumReleaseAge": "7 days",
"internalChecksFilter": "strict",
"lockFileMaintenance": {
"enabled": true,
"schedule": ["before 5am on monday"],
"automerge": true
},
"vulnerabilityAlerts": {
"minimumReleaseAge": "0 days",
"labels": ["security"],
"schedule": ["at any time"],
"automerge": true
}
}| Parameter | Accepts | Default |
|---|---|---|
semanticCommits | boolean | true |
timezone | IANA timezone, e.g. UTC | Europe/Berlin |
schedule | at-any-time | weekly | monthly | weekends | outside-business-hours | at-any-time |
prLimitStrategy | default | conservative | active | active |
rebaseWhen | auto | never | conflicted | behind-base-branch | behind-base-branch |
rangeStrategy | auto | pin | bump | replace | widen | update-lockfile | bump |
automergeType | pr | branch | pr-comment | branch |
automergeLevel | disabled | patch | minor | all | minor |
automergeDevDependencies | boolean | false |
ignoreTests | boolean | false |
disablePreOneAutomerge | boolean | true |
requireMajorApproval | boolean | true |
minimumReleaseAge | never | 3-days | 7-days | 14-days | 7-days |
pinning.dockerDigests | boolean | true |
pinning.githubActionDigests | boolean | true |
pinning.devDependencies | boolean | true |
flagAbandonedPackages | boolean | true |
lockFileMaintenance.enabled | boolean | true |
lockFileMaintenance.schedule | same values as schedule | weekly |
lockFileMaintenance.automerge | boolean | true |
vulnerabilityAlerts.labels | comma-separated string | security |
vulnerabilityAlerts.scheduleOverride | boolean | true |
vulnerabilityAlerts.automerge | boolean | true |
grouping.<manager> | boolean — manager is one of: npm, docker, maven, gradle, pip, composer, helm, githubActions, terraform, gomod, cargo, bundler, nuget | false |
The top-level response object.
| Field | Type | Description |
|---|---|---|
summary | string | A 1-2 sentence plain-language assessment of the configuration and its quality. |
issues | Issue[] | Up to 8 concrete findings. Empty when nothing noteworthy was found (or the model call failed). |
improvedRenovateJson | string | A corrected/optimised version of your config as a JSON string. Falls back to your original input if generation fails. |
A single finding inside issues[].
| Field | Type | Description |
|---|---|---|
severity | string | Severity level: "info", "warning", or "error". |
jsonPath | string | JSONPath pointing at the relevant part of the config, e.g. "$.prConcurrentLimit". |
message | string | What the issue is. |
suggestion | string | A concrete recommendation for how to fix it. |
severity is one of: infowarningerror
Questions or an integration to share? Open an issue on GitHub.