Results and Callbacks
Receiving Results via Callback
When the analysis completes (typically 2-5 minutes), ReviewerZero sends a POST request to the callback_url you provided.
Callback Request Headers
| Header | Description |
|---|---|
Content-Type | application/json |
X-ReviewerZero-Event | Event type: review.completed |
X-ReviewerZero-Timestamp | Time the request was sent, in Unix seconds (for example 1760788800) |
X-ReviewerZero-Signature-V2 | HMAC-SHA256 hex digest of <timestamp>.<raw body> (see Verifying Callback Signatures) |
X-ReviewerZero-Signature | HMAC-SHA256 hex digest of the raw request body. Kept for compatibility; verify X-ReviewerZero-Signature-V2 instead |
Callback Request Body
The JSON body contains the analysis results. By default (payload_detail=issues_only) the item arrays inside project.reports[].reportData and integrity.files[] contain only the red ("needs review") findings — retracted references, decision-flipping statistical errors, high-confidence AI text, failed author verification, AI-provenance or web-matched figures, high-priority peer-review issues — while integrity.issueSummary always reports the complete issue counts for every dimension (high, medium, totalAnalyzed). With payload_detail=full, every analyzed item is included. See Callback Payload Reference for the structure.
Your Callback Endpoint
Your endpoint should:
- Return
200 OK(or any 2xx status) to acknowledge receipt - Optionally verify the
X-ReviewerZero-Signature-V2andX-ReviewerZero-Timestampheaders (recommended)
If your endpoint returns a non-2xx status or is unreachable, ReviewerZero attempts delivery up to 3 times with exponential backoff (1s, 2s delays).
Callback Payload Reference
The example below shows the default payload_detail=issues_only shape. With payload_detail=full, the structure is identical but the item arrays (reports[].reportData.validation_results, integrity.files[].statchecks, authors, figures, and so on) contain every analyzed item instead of only the red ones.
{
"event": "review.completed",
"review_id": "proj_a1b2c3d4e5",
"payload_detail": "issues_only",
"project": {
"id": "proj_a1b2c3d4e5",
"name": "manuscript.pdf",
"description": null,
"status": "finished",
"createdAt": "2026-03-15T10:30:00.000Z",
"updatedAt": "2026-03-15T10:35:00.000Z",
"targetJournalOrConference": null,
"generatePeerReviewReport": true,
"generateResearchIntegrityReport": true,
"generateJournalRecommendation": false,
"reports": [
{
"id": "rpt_xyz",
"reportType": "review",
"reportData": { "...": "AI peer review results (red items only in issues_only mode)" },
"createdAt": "2026-03-15T10:34:00.000Z"
},
{
"id": "rpt_abc",
"reportType": "references",
"reportData": { "...": "reference validation results (red items only in issues_only mode)" },
"createdAt": "2026-03-15T10:34:30.000Z"
}
],
"user": { "id": "usr_...", "name": "...", "image": null },
"organization": { "id": "org_publisher_acme", "name": "Acme Publishing", "slug": "acme", "logo": null }
},
"integrity": {
"projectId": "proj_a1b2c3d4e5",
"files": [
{
"id": "pf_...",
"fileType": "application/pdf",
"pages": [{ "pageNumber": 1, "publicUrl": "..." }]
}
],
"issueSummary": {
"highTotal": 2,
"mediumTotal": 5,
"total": 7,
"dimensions": [
{
"dimension": "statistics",
"label": "Statistical Checks",
"issueCount": 1,
"high": 1,
"medium": 0,
"totalAnalyzed": 15,
"totalAnalyzedDisplay": "15 statistics"
},
{
"dimension": "figures",
"label": "Figure Integrity",
"issueCount": 1,
"high": 1,
"medium": 0,
"totalAnalyzed": 8,
"totalAnalyzedDisplay": "8 figures"
}
]
}
},
"report_url": "https://www.reviewerzero.ai/app/review/proj_a1b2c3d4e5",
"dismissed_items": [
{ "itemType": "peer-review", "itemId": "review-issue-2" }
],
"timestamp": "2026-03-15T10:35:01.000Z"
}Key Fields
| Field | Description |
|---|---|
event | Always review.completed |
review_id | The ID returned when you submitted the manuscript |
payload_detail | issues_only (red items only, default) or full (every analyzed item) |
project.status | finished when analysis is complete |
project.reports | Array of report objects. reportType can be review (AI peer review), references, replicability-assessment, submission-guidelines, table-duplication. In issues_only mode, report types without a defined red-signal (e.g. internal/in-development analyses) are omitted; they appear in payload_detail=full |
integrity.issueSummary | Aggregated issue counts by dimension and severity (high, medium). Always computed over ALL analyzed items, regardless of payload_detail, and EXCLUDING editor-dismissed items |
integrity.issueSummary.dimensions | Per-dimension breakdown: statistics, figures, panels, ai-text, plagiarism, authors, tables, references, peer-review, replicability, guidelines |
reportData.citations_missing_from_list (references report) | payload_detail=full only. In-text citations that no entry of the reference list answers, each { id, citation, sentence, page, severity, issue, consequence, action } (severity is always medium). Absent on reviews analyzed before this check existed; [] when none were found. Not counted in issueSummary |
integrity.files[].authors[].contributionCheck | Present on the author selected for the deep author check (run_contribution_check). { status, suggestion, reasons, writtenScore, selectedBecause, carriedOverFromReviewId, authorLink }. status is awaiting_author, in_progress, completed, incomplete, disputed, declined or revoked. Once completed, suggestion is no_issues_found, review_suggested or further_review_suggested (otherwise null) and reasons lists why. writtenScore is 0 to 100. selectedBecause is corresponding_author or first_author_with_email. carriedOverFromReviewId names the earlier version a revision took the result from. authorLink is the link to send the author while the check is open, given to the review's owner and editors only; otherwise null |
integrity.files[].contributionCheck | Present when the deep author check was requested but no author has one: { status: "skipped", reason: "no_corresponding_author_or_email" | "no_authors_extracted" } or { status: "failed", reason: "generation_failed" }. The manuscript is not charged in either case |
dismissed_items | Items an editor dismissed in the ReviewerZero app, each { itemType, itemId }. In payload_detail=full the report arrays still include these items; use this list to reconcile them with issueSummary (whose counts exclude them). A dismissed entry of citations_missing_from_list is listed with itemType missing-citation and its id as itemId |
report_url | Direct link to the full interactive report on ReviewerZero |
timestamp | ISO 8601 timestamp of when the callback was sent |
What counts as "red" (needs review)?
The issues_only payload keeps exactly the items the ReviewerZero report marks red:
| Dimension | Red condition |
|---|---|
references | Cited paper is retracted |
statistics | Statistical error that flips the significance conclusion, or a logically impossible result |
ai-text | Paragraph flagged as likely AI-generated with high confidence |
plagiarism | Paragraph with ≥50% matched text |
authors | Author verification failed or could not be completed, or the author's deep author check is unresolved: still waiting for the author (awaiting_author, in_progress), incomplete, declined, disputed, or completed with suggestion further_review_suggested |
figures | C2PA provenance shows AI generation, or a full/partial reverse-image-search match |
tables | High-severity cross-table duplication |
peer-review | High-priority issue raised by the AI peer review |
replicability | Checklist item with a critically low rating (except pre-registration items, which cap at amber) |
guidelines | Submission guideline rule not met |
In addition, integrity.files[].citationWorthiness (sentences flagged for problematic citation usage — a claim that needs a citation, or a citation where none is expected) is filtered to flagged items; these are counted in integrity.issueSummary.citations but are not part of the dimensions matrix.
Amber ("worth verifying") and green ("verified") items are excluded from the arrays; amber items are still counted in integrity.issueSummary (medium), and green items are reflected in totalAnalyzed.
Items an editor dismissed in the ReviewerZero app are excluded from the issues_only arrays and from every integrity.issueSummary count. In payload_detail=full they still appear in the report arrays (so "full" is a complete record), but each is listed in the top-level dismissed_items array so you can filter them out and reconcile against the counts.
Polling (Alternative)
If you prefer polling over callbacks (or need to re-fetch results), you can use:
Endpoint: GET https://www.reviewerzero.ai/api/v1/reviews/{review_id}
curl https://www.reviewerzero.ai/api/v1/reviews/proj_a1b2c3d4e5 \
-H "Authorization: Bearer rz_abc123def456"The response defaults to payload_detail=issues_only (red items only). To fetch every analyzed item:
curl "https://www.reviewerzero.ai/api/v1/reviews/proj_a1b2c3d4e5?payload_detail=full" \
-H "Authorization: Bearer rz_abc123def456"Check project.status:
open-- not yet startedprocessing-- analysis in progressfinished-- results are ready