API Integration Guide
This guide walks through how to integrate with the ReviewerZero screening API. It covers authentication, submitting manuscripts, receiving results via callback, and verifying callback signatures.
Overview
The integration flow has four steps:
API Integration Flow
- One API call submits the manuscript and runs all screening tools (statistical validation, AI text detection, figure integrity, author verification, table duplication, reference analysis, AI peer review).
- One callback delivers the complete results when analysis finishes.
Authentication
Every request requires an Authorization header. The x-organization-id header is optional.
| Header | Value | Required | Description |
|---|---|---|---|
Authorization | Bearer rz_xxxxxxxxxxxx | Yes | Your API key |
x-organization-id | org_xxxxxxxx | No | Your organization ID |
When x-organization-id is provided, the submission is scoped to that organization and billed against the organization's plan. When omitted, the submission is associated with your personal account. You can find your organization ID in your Organization Settings.
Example (with organization):
Authorization: Bearer rz_abc123def456
x-organization-id: org_publisher_acmeExample (personal account):
Authorization: Bearer rz_abc123def456Submitting a Manuscript
Endpoint: POST https://www.reviewerzero.ai/api/v1/reviews
Content-Type: multipart/form-data
Input (one required)
Provide either file or url, but not both.
| Field | Type | Description |
|---|---|---|
file | File (PDF) | The manuscript PDF to analyze (multipart upload) |
url | string (URL) | URL pointing to a publicly accessible PDF (alternative to file upload) |
Optional Fields
| Field | Type | Default | Description |
|---|---|---|---|
callback_url | string (URL) | -- | URL where ReviewerZero will POST results when analysis completes |
run_integrity_report | boolean | true | Run research integrity analysis (figures, statistics, authors, references, etc.) |
run_peer_review | boolean | true | Run AI peer review (novelty, methodological issues, logical flaws) |
run_statistics_check | boolean | true | Statistical validation (p-values, effect sizes) |
run_ai_text_detection | boolean | true | AI-generated text detection |
run_plagiarism_detection | boolean | true | Plagiarism/text similarity detection |
run_figure_integrity | boolean | true | Figure duplication and manipulation detection |
run_figure_web_usage | boolean | true | Reverse image search for figures |
run_author_verification | boolean | false | Author identity verification via ORCID/OpenAlex |
run_table_duplication_check | boolean | true | Table duplication detection |
run_reference_analysis | boolean | true | Reference validation (DOI checks, retractions, PubPeer flags) |
All sub-flags require run_integrity_report=true to take effect. When omitted, sub-flags use their default values. You do not need to send every flag -- only include the ones you want to override.
Example Request -- File Upload (cURL)
curl -X POST https://www.reviewerzero.ai/api/v1/reviews \
-H "Authorization: Bearer rz_abc123def456" \
-H "x-organization-id: org_publisher_acme" \ # optional
-F "file=@manuscript.pdf" \
-F "callback_url=https://your-system.example.com/callbacks/reviewerzero" \
-F "run_integrity_report=true" \
-F "run_peer_review=true"Example Request -- URL Submission (cURL)
curl -X POST https://www.reviewerzero.ai/api/v1/reviews \
-H "Authorization: Bearer rz_abc123def456" \
-F "url=https://arxiv.org/pdf/2301.00001" \
-F "callback_url=https://your-system.example.com/callbacks/reviewerzero"When using url, ReviewerZero downloads the PDF server-side. The URL must be publicly accessible, return a Content-Type of application/pdf, and the file must not exceed the maximum upload size.
Response
{
"review_id": "proj_a1b2c3d4e5"
}Store the review_id to correlate with the callback you will receive later.
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-Signature | HMAC-SHA256 hex digest of the request body (see Verifying the Callback Signature) |
Callback Request Body
The JSON body contains the full analysis results. See Callback Payload Reference for the complete structure.
Your Callback Endpoint
Your endpoint should:
- Return
200 OK(or any 2xx status) to acknowledge receipt - Optionally verify the
X-ReviewerZero-Signatureheader (recommended)
If your endpoint returns a non-2xx status or is unreachable, ReviewerZero retries up to 3 times with exponential backoff (1s, 2s, 4s delays).
Verifying the Callback Signature
To verify that a callback genuinely came from ReviewerZero, compute the HMAC-SHA256 of the raw request body using your API key as the secret, and compare it to the X-ReviewerZero-Signature header.
Important: The signature is computed over a SHA-256 hash of your API key, not the raw API key itself. ReviewerZero does not store your raw API key.
Python Example
import hmac
import hashlib
def verify_signature(raw_body: bytes, signature_header: str, api_key: str) -> bool:
"""Verify the X-ReviewerZero-Signature header."""
api_key_hash = hashlib.sha256(api_key.encode()).hexdigest()
expected = hmac.new(
api_key_hash.encode(),
raw_body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header)Node.js Example
const crypto = require('crypto');
function verifySignature(rawBody, signatureHeader, apiKey) {
const apiKeyHash = crypto.createHash('sha256').update(apiKey).digest('hex');
const expected = crypto.createHmac('sha256', apiKeyHash)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader)
);
}Callback Payload Reference
{
"event": "review.completed",
"review_id": "proj_a1b2c3d4e5",
"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" },
"createdAt": "2026-03-15T10:34:00.000Z"
},
{
"id": "rpt_abc",
"reportType": "references",
"reportData": { "...": "reference validation results" },
"createdAt": "2026-03-15T10:34:30.000Z"
}
],
"user": { "id": "usr_...", "name": "...", "email": "...", "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",
"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 |
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 |
integrity.issueSummary | Aggregated issue counts by dimension and severity (high, medium) |
integrity.issueSummary.dimensions | Per-dimension breakdown: statistics, figures, panels, ai-text, plagiarism, authors, tables, references, peer-review, replicability, guidelines |
report_url | Direct link to the full interactive report on ReviewerZero |
timestamp | ISO 8601 timestamp of when the callback was sent |
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"Check project.status:
open-- not yet startedprocessing-- analysis in progressfinished-- results are ready
Interactive API Documentation
Full interactive API documentation with request/response schemas is available at:
https://www.reviewerzero.ai/docs/api
You can try out endpoints directly from the browser using your API key.
Questions? Contact us at support@reviewerzero.ai.