Rubric
The rubric is what the LLM grader scores a page against. Every score you see on a page (analysis.overall_score, overall_grade, the per-component scores, the per-criterion scores) comes from grading the page against exactly these criteria — this endpoint publishes the live configuration the analysis worker runs, not a documentation copy of it.
Read it before spending an analysis run. Knowing the criteria and their weights tells you what a page is measured on, which recommendations are worth the most, and how a raw score turns into a letter grade.
The rubric is per site. Each site starts from MetaMonster's system components and can be customized in the dashboard: weights changed, criteria replaced, extra components added. Don't cache one site's rubric and assume it applies to another.
Scope: sites:read
GET /sites/{siteId}/rubric
Path parameters
| Parameter | Type | Description |
|---|---|---|
siteId |
integer | The site's ID |
Request
curl -s https://new.metamonster.ai/api/v1/sites/25/rubric \
-H "Authorization: Bearer mm_YOUR_API_KEY"
Field meanings
| Field | Description |
|---|---|
components[] |
The scoring components, in list order: MetaMonster's system components first, then any custom components the site owner added. (Order is presentation only — the grader scores components in parallel.) |
components[].component_type |
Stable identifier. Matches component_type on the components in GET /pages/{pageId}/analysis, so you can line a score up with the criteria that produced it. |
components[].label |
Human-readable name (customizable per site). |
components[].weight |
How much this component counts toward the page's overall score, on a 0–1 scale (system default 1). The overall score is a weighted average of the component scores, so a component at 1.0 counts twice as much as one at 0.5. |
components[].is_system |
true for MetaMonster's built-in components, false for components the site owner created. |
components[].criteria[] |
The individual line items scored inside this component. A custom component may legitimately have an empty list. |
criteria[].key |
Stable identifier. This is what appears in a recommendation's rubric_criteria, and in criteria_scores on an analysis component. |
criteria[].label |
Short name for the criterion. |
criteria[].description |
What the grader is told to look for. This is the actual instruction, so it's the most useful thing on the page for deciding how to fix something. |
criteria[].category |
Grouping label (e.g. SEO Fundamentals, E-E-A-T Signals, Writing Quality), or null if the criterion isn't grouped. |
criteria[].max_score |
Points available for this criterion. A component's score is the share of its criteria points earned, normalized to 0–100. |
grade_bands[] |
The score → letter grade scale, highest band first. A score earns the grade of the first band whose min it reaches (so 85 → B). The last band (F, min: 0) is the floor. |
score_curve |
The site's display curve: none, medium (default), or large. Scores shown on analyses are curved with this before grading, so a raw criteria total is not directly comparable to a page's displayed overall_score. |
What this endpoint does not return
The grader's prompts, its model choices, the tools it's allowed to call, and the context fields it's given are MetaMonster internals and are never included. Everything you need to understand and pass the grading is in criteria[].description.
Response 200
{
"data": {
"components": [
{
"component_type": "serp_analysis",
"label": "SERP Analysis",
"weight": 1,
"is_system": true,
"criteria": [
{
"key": "unique_content",
"label": "Unique Content vs SERP",
"description": "Page contains commentary, anecdotes, statistics, or angles not present in the top 10 SERP results…",
"category": "Competitive Position",
"max_score": 5
}
]
},
{
"component_type": "seo_grade",
"label": "SEO Optimization Grade",
"weight": 1,
"is_system": true,
"criteria": [
{
"key": "core_elements",
"label": "Core Elements Present",
"description": "Page title, meta description, and H1 all present with non-empty, non-default content",
"category": "SEO Fundamentals",
"max_score": 3
}
]
}
],
"grade_bands": [
{ "grade": "A+", "min": 97 },
{ "grade": "A", "min": 93 },
{ "grade": "A-", "min": 90 },
{ "grade": "B+", "min": 87 },
{ "grade": "B", "min": 83 },
{ "grade": "B-", "min": 80 },
{ "grade": "C+", "min": 77 },
{ "grade": "C", "min": 73 },
{ "grade": "C-", "min": 70 },
{ "grade": "D+", "min": 67 },
{ "grade": "D", "min": 63 },
{ "grade": "D-", "min": 60 },
{ "grade": "F", "min": 0 }
],
"score_curve": "medium"
}
}
(Criteria lists are abbreviated above — the real response returns every criterion.)
Using it
- Before analyzing: read the rubric, then check the page against the criteria you can verify yourself (
GET /pages/{pageId}/briefgives you the resolved title, meta description, H1, and body markdown in one call). Fix the obvious misses first, then spend the analysis run. - After analyzing: join
criteria_scores[].keyfromGET /pages/{pageId}/analysisback tocriteria[].keyhere to see the full instruction behind a low line item, andrubric_criteriaon a recommendation to see which criteria it would move. - Prioritizing: a criterion's value to the overall score is roughly its
max_scoreshare of its component, times that component'sweightshare of the total. High-max_scorecriteria in a heavily weighted component are where the points are.
Errors
| Status | When |
|---|---|
401 unauthorized |
Missing/invalid key |
403 forbidden |
Key lacks sites:read |
404 not_found |
No such site in your organization |
429 rate_limited |
Rate limit exceeded |