External Reviewer Suggestions via Relay API

Overview

The Relay API supports submission and management of third-party reviewer suggestions for manuscripts in ScholarOne Manuscripts. It allows integrated reviewer-matching providers to push their recommendations directly into the editor's reviewer selection workflow, so editors can evaluate, compare, and invite suggested reviewers without leaving ScholarOne.

Using a single endpoint, a provider can:

  • Submit a batch of suggested reviewers (candidates) for a specific manuscript - for example, when the provider's matching engine first produces recommendations.
  • Add further candidates to an existing batch over time - for example, when a user hand-picks an additional reviewer in the provider's interface.
  • Update details of previously sent candidates - for example, refreshed relevance scores or match explanations.
  • Delete candidates that should no longer be shown to editors.
📘

Prerequisites

  • The Relay feature must be enabled for the target site.
  • The provider must be registered and active in the ScholarOne provider registry. Requests from unregistered or disabled providers are rejected.
  • The API account provisioned by ScholarOne must be entitled to the addJSONData operation and to the target site.

Method: POST

Resource

/api/s1m/v2/system/addJSONData


Terminology

TermMeaning
ManuscriptThe paper under review in ScholarOne. Always identified by documentId.
Suggestion batch (submissionId)One batch of reviewer suggestions sent by a provider for one manuscript. Identified by the combination of provider + submissionId (the provider's own ID, e.g. GC-2026-001). This is what the submit operation creates and what add/update/delete target.
CandidateOne suggested reviewer inside a batch. Identified within the batch by providerCandidateId (the provider's own ID). ScholarOne internal IDs are never exposed or required.
ProviderThe integrated third-party system. The provider identifier is assigned during onboarding.

A manuscript can accumulate multiple suggestion batches, from different providers, or several from the same provider over time.


Request Parameters

ElementTypeDescriptionRequiredExample or Default Value
addJSONDataRootYes
usernameStringProfile User Name. This is the user name used by the API, not a ScholarOne Manuscripts user. This is from the Caller's profile.Yessample_user
passwordStringThe API Key. Encrypted value uniquely identifying and authenticating CallerYesSRU4DQ5WOJ2PX8CA
site_nameStringSite short name. The short name is the abbreviated or truncated name of the journal, society, publisher, or family.Yessalesdemoplus
urlStringThe Web Service URL, which identifies the specific service to handle the request.Yesv2/system/addJSONData
external_idStringAn id value that can be set by the client for call tracking. Caller supplied Text string to be stored with Audit History information.No123456
📘

Authentication and routing notes

  • Authentication uses HTTP Digest (realm S1ApiService) with the API account ScholarOne provisions for the provider.
  • The Host header must match the target environment's domain. The v2 endpoints resolve the environment from the Host header, not only from the environment_name query parameter.
  • Requests for a site the account is not entitled to are rejected.

Request Body Elements

  • The request body must be in JSON format.
  • The reviewer suggestion payload is wrapped in a data root element, with the processor type as a string ("4") and the payload nested under payload:

JSON

{
  "data": {
    "type": "4",
    "payload": {
      ...reviewer suggestion payload...
    }
  }
}	
  • Every payload requires an operation field: "submit", "add", "update", or "delete". Unknown values are rejected.
  • The reviewers field is always an array. A single entry is fine, and a bare object is also accepted anywhere an array is expected.
OperationPurpose
submitCreates a new suggestion batch for a manuscript with its initial set of candidates. Use once per batch, e.g. when your system first produces recommendations.
addAppends candidates to an existing batch (e.g. a user hand-picks an additional candidate). The batch must already exist, or the request fails with "Submission not found".
updateModifies fields on existing candidates in a batch. Send only the fields being changed, plus providerCandidateId.
deleteRemoves candidates from a batch (soft delete, see Delete Behavior below).
⚠️

🔄 [TEMP - finalize before release] Note: All four operations require the target manuscript to be in an active peer-review state - its current version must be submitted, revised, or resubmitted, and not in the author's draft. Requests against manuscripts outside these states are rejected at the request level. See Request-Level Failure below.


Operation: submit - Creates a Batch

Request Body Elements for submit example

JSON

{
  "data": {
    "type": "4",
    "payload": {
      "operation": "submit",
      "provider": "GlobalCampus" or "Prophy" ,
      "providerVersion": "2.1",
      "submissionId": "WRK-2026-001",
      "documentId": 12345,
      "timestamp": "2026-02-25T10:30:00Z",
      "reviewers": [
        {
          "providerCandidateId": "gc-001",
          "firstName": "Jane",
          "lastName": "Doe",
          "email": "[email protected]",
          "orcid": "0000-0001-2345-6789",
          "relevanceScore": 95,
          "matchReason": "Expert in quantum computing, 7 related publications",
          "matchDetails": "<ul><li><a href=\"https://doi.org/10.1136/example\">Paper title</a></li></ul>"
        }
      ]
    }
  }
}

Request Body Elements Description - submit

Request Body Elements/ExampleTypeDescriptionReq
dataObjectRoot object that defines the request structureYes
type
"4"
StringThis field specifies the request type: set "4" to submit Reviewer Suggestions.Yes
payloadObjectContains the specific details relevant to the request.Yes
operation
"submit"
StringThe operation to perform. Must be "submit" to create a new suggestion batch.Yes
provider
"GlobalCampus"
or "Prophy"
StringProvider identifier, assigned during onboarding. Must be registered and active in the ScholarOne provider registry.Yes
providerVersion
"2.1"
StringVersion of the provider software producing the suggestions. Used for submit only.Yes
submissionId
"WRK-2026-001"
StringThe provider's unique ID for this suggestion batch. Together with the provider, identifies the batch for later add/update/delete operations and retry handling.Yes
documentId
12345
IntegerUnique identifier of the manuscript in ScholarOne. Must belong to the target site.Yes
timestamp
"2026-02-25T10:30:00Z"
StringISO 8601 instant with offset. Informational; not used to order or reconcile operations.Yes
reviewersArrayArray of candidate objects - the suggested reviewers in this batch. A single entry is accepted. Must not be empty. See Candidate Field Reference for the fields of each candidate object.Yes

For candidate-level fields inside reviewers (names, email, ORCID, relevance score, match explanations, metrics), see the Candidate Field Reference section below. On submit, the required candidate fields are providerCandidateId, firstName, lastName, and email.


Operation: add - Appends Candidates to an Existing Batch

Request Body Elements for add example

JSON

{
  "data": {
    "type": "4",
    "payload": {
      "operation": "add",
      "provider": "GlobalCampus" or "Prophy",
      "submissionId": "WRK-2026-001",
      "timestamp": "2026-02-26T09:15:00Z",
      "reviewers": [
        {
          "providerCandidateId": "gc-003",
          "firstName": "Maria",
          "lastName": "Garcia",
          "email": "[email protected]",
          "relevanceScore": 91,
          "matchReason": "Hand-picked by the requesting user"
        }
      ]
    }
  }
}

Request Body Elements Description - add

Request Body Elements/ExampleTypeDescriptionReq
dataObjectRoot object that defines the request structureYes
type
"4"
StringThis field specifies the request type: set "4" to submit Reviewer Suggestions.Yes
payloadObjectContains the specific details relevant to the request.Yes
operation
"add"
StringThe operation to perform. Must be "add" to append candidates to an existing batch. The batch must already exist, or the request fails with "Submission not found".Yes
provider
"GlobalCampus" or "Prophy"
StringProvider identifier. Must match the batch being targeted.Yes
submissionId
"WRK-2026-001"
StringThe provider's ID for the batch being targeted. Must match an existing batch for this provider.Yes
timestamp
"2026-02-26T09:15:00Z"
StringISO 8601 instant with offset. Accepted but not validated on add; sending it is recommended.No
reviewersArrayArray of candidate objects to append to the batch. A single entry is accepted. Must not be empty.Yes

Candidate-level requirements on add are identical to submit: providerCandidateId, firstName, lastName, and email are required; all other fields in the Candidate Field Reference are optional. If a providerCandidateId already exists as a live record in the batch, that entry is skipped and audited (the existing record is not modified - use update for that).


Operation: update - Modifies Existing Candidates

Request Body Elements for update example

JSON

{
  "data": {
    "type": "4",
    "payload": {
      "operation": "update",
      "provider": "GlobalCampus" or "Prophy",
      "submissionId": "WRK-2026-001",
      "timestamp": "2026-02-27T14:00:00Z",
      "reviewers": [
        {
          "providerCandidateId": "gc-003",
          "relevanceScore": 90,
          "matchReason": "Updated after full-text analysis"
        }
      ]
    }
  }
}

Request Body Elements Description - update

Request Body Elements/ExampleTypeDescriptionReq
dataObjectRoot object that defines the request structureYes
type
"4"
StringThis field specifies the request type: set "4" to submit Reviewer Suggestions.Yes
payloadObjectContains the specific details relevant to the request.Yes
operation
"update"
StringThe operation to perform. Must be "update" to modify fields on existing candidates in a batch.Yes
provider
"GlobalCampus" or "Prophy"
StringProvider identifier. Must match the batch being targeted.Yes
submissionId
"WRK-2026-001"
StringThe provider's ID for the batch being targeted. Must match an existing batch for this provider.Yes
timestamp
"2026-02-27T14:00:00Z"
StringISO 8601 instant with offset. Accepted but not validated on update; sending it is recommended.No
reviewersArrayArray of candidate objects to update. Each entry must include providerCandidateId plus only the fields being changed; omitted fields are left untouched.Yes
reviewers[].providerCandidateId
"gc-003"
StringThe provider's ID of the existing candidate to modify. If no live record matches, that entry is skipped and audited; the request still returns SUCCESS.Yes

Any field from the Candidate Field Reference may be sent alongside providerCandidateId to change it. Note: sending personId on update re-validates and re-links the person record, but changing email or orcid alone does not re-trigger automated person matching.


Operation: delete - Removes Candidates from a Batch

Request Body Elements for delete example

JSON

{
  "data": {
    "type": "4",
    "payload": {
      "operation": "delete",
      "provider": "GlobalCampus" or "Prophy",
      "submissionId": "WRK-2026-001",
      "timestamp": "2026-02-28T08:45:00Z",
      "reviewers": [
        {
          "providerCandidateId": "gc-002"
        }
      ]
    }
  }
}

Request Body Elements Description - delete

Request Body Elements/ExampleTypeDescriptionReq
dataObjectRoot object that defines the request structureYes
type
"4"
StringThis field specifies the request type: set "4" to submit Reviewer Suggestions.Yes
payloadObjectContains the specific details relevant to the request.Yes
operation
"delete"
StringThe operation to perform. Must be "delete" to remove candidates from a batch. Delete is a soft delete, see Delete Behavior below.Yes
provider
"GlobalCampus" or "Prophy"
StringProvider identifier. Must match the batch being targeted.Yes
submissionId
"WRK-2026-001"
StringThe provider's ID for the batch being targeted. Must match an existing batch for this provider.Yes
timestamp
"2026-02-28T08:45:00Z"
StringISO 8601 instant with offset. Accepted but not validated on delete; sending it is recommended.No
reviewersArrayArray of candidate objects identifying the records to remove. Only providerCandidateId is used; any other fields are ignored.Yes
reviewers[].providerCandidateId
"gc-002"
StringThe provider's ID of the existing candidate to remove. If no live record matches, that entry is skipped and audited; the request still returns SUCCESS.Yes

Candidate Field Reference

The fields below apply to each object inside the reviewers array.

FieldReq*TypeLimitOn Oversized/InvalidNotes
providerCandidateIdYesString100 charsTruncatedProvider's unique ID within the batch
firstNameYesString100 charsTruncated
lastNameYesString100 charsTruncated
emailYesString255 charsTruncated; invalid format → candidate rejectedStored lowercased; used for automated person matching
displayNameNoString200 charsTruncatede.g. "Dr. Jane Doe"
orcidNoString19 chars storedInvalid format → candidate rejectedURL form accepted, normalized to bare form (see ORCID Format)
institutionNoString255 charsTruncated
countryNoString2 chars
Invalid → candidate rejected
🔄 [TEMP - finalize before release] Non-two-letter value → candidate rejected
🔄 [TEMP - finalize before release] Two ASCII letters, upper-cased on store (e.g. US, GB). Only the two-letter shape is validated; the value is not checked against the ISO 3166-1 list, so a non-existent two-letter code (e.g. ZZ) is accepted and stored.
relevanceScoreNoInteger0–100Out of range → candidate rejectedNull sorts last (see Display Order)
personIdNoInteger-Never causes rejection (see Person Matching)Optional ScholarOne person hint
matchReasonNoString2,000 charsOver limit or disallowed HTML → candidate rejectedShort summary, shown in list view
matchDetailsNoString4,000 charsOver limit or disallowed HTML → candidate rejectedRich HTML, shown in expanded detail view
metricsNoArray1,000 chars**Over limit → candidate rejectedProvider-defined metrics
flagsNoArray1,000 chars**Over limit → candidate rejectedProvider-defined flags
providerDataNoArray1,000 chars**Over limit → candidate rejectedAdditional provider data

* "Required" applies to submit and add. For update and delete, only providerCandidateId is required.

** Limit applies to the serialized JSON of each field independently, measured in both characters and UTF-8 bytes (the stricter applies).

"Candidate rejected" means that one candidate is skipped and the reason is written to the manuscript's audit trail; the rest of the batch still processes (see Per-Candidate Failures).


Person Matching

When personId is not provided, ScholarOne automatically matches each candidate to its user records: first by email address, then by ORCID, scoped to the journal's configuration family.

When personId is provided:

  • If the person exists, belongs to the target site's configuration family, and does not conflict with the email/ORCID match, it is used directly (bypassing automated matching).
  • If the email/ORCID resolves to a different person, the automated match wins, and the conflict is written to the manuscript's audit trail.
  • If the person is not found, or does not belong to the site's configuration family, ScholarOne falls back to automated matching and logs the issue.
⚠️

🔄 [TEMP - finalize before release] A bad optional personId hint never costs the editor a suggestion - the candidate is still saved. (One exception, unrelated to the hint: if the candidate's email or ORCID matches more than one un-merged ScholarOne account, the candidate cannot be resolved to a single person and is skipped and audited - see Per-Candidate Failures.)

On update: sending personId re-validates and re-links the record. Changing email or orcid alone does not re-trigger automated matching.


ORCID Format

Both forms are accepted on input and normalized to the bare form for storage:

After normalization the value must match 0000-0000-0000-000X (the final character may be X); otherwise the candidate is rejected.


Metrics and Flags

The metrics and flagsfields accept an array of JSON objects with free-form keys. There are no reserved or recognized keys; content is stored and displayed as-is. All of the following are accepted and equivalent:

JSON

"metrics": [{"hIndex": 24, "citationCount": 3456}]

"metrics": [{"hIndex": 24}, {"citationCount": 3456}]

"metrics": {"hIndex": 24}
📘

Display note

The editor interface derives its metric columns from the keys present in metrics, so consistent key naming across candidates produces a clean comparison table. Candidates lacking a key show a blank cell.


Provider Data: Recognized Keys (relevantWorks / relatedWorks)

Within providerData, two keys are recognized specially by the reviewer suggestion interface: relevantWorks and relatedWorks. When either key is present, its contents render in the candidate's detail view as a titled list of links, labeled "Most Relevant Works" instead of being shown as generic, unformatted detail.

Each entry in a relevantWorks / relatedWorks array is an object describing one linked item:

FieldTypeDescriptionReq
title or nameStringThe link's display text. title is checked first; name is used if title is absent.Yes
detailUrl, url, or linkStringThe link's destination. Checked in that order, the first one present is used.Yes

If an item is missing both a recognized title field and a recognized URL field, it does not render as a link.

JSON

"providerData": [
  {
    "relevantWorks": [
      { "title": "Machine Learning Approaches in Peer Review", "detailUrl": "https://provider.example.com/works/12345" },
      { "title": "Bias Detection in Reviewer Matching Systems", "detailUrl": "https://provider.example.com/works/12346" }
    ]
  },
  {
    "expertiseArea": "Natural Language Processing"
  }
]

In this example, relevantWorks renders as a two-item "Most Relevant Works" list with working links, while expertiseArea not a recognized key, displays as plain, unformatted detail alongside it.

relatedWorks is accepted as an alias for relevantWorks and behaves identically; use whichever name best matches your own data model.


Allowed HTML (matchReason, matchDetails)

Accepted tags:

a, abbr, b, blockquote, br, cite, code, dd, div, dl, dt, em, h1, h2, h3, h4, h5, h6, hr, i, img, li, ol, p, pre, q, small, span, strike, strong, sub, sup, table, tbody, td, th, thead, tr, u, ul

Attribute rules:

  • a: href only, and it must use the http:// or https:// scheme.
  • img: src (must use https://) and alt (always allowed, for accessibility).
  • All other tags, including div and span: no attributes. CSS classes and inline styles are not accepted; visual presentation is controlled by ScholarOne.
❗️

Rejected, not sanitized

Content containing a disallowed tag or attribute is rejected - the candidate record is not saved and the issue is written to the manuscript's audit trail. ScholarOne does not strip or alter provider content; it must meet the allowlist as submitted.

Character limits count the full content including markup, attribute values, and entity references. As sizing guidance: ten DOI links in list format consume roughly 3,500 of 'matchDetails' 4,000 characters.


Responses

All responses use the standard ScholarOne API envelope. Results are reported at the request level; there is no per-candidate detail in the response.

Success - HTTP 200

{
  "Response": {
    "status": "SUCCESS",
    "callId": "...",
    "result": {
      "returnCode": "OK",
      "type": 4
    }
  }
}

The request was accepted and processed. Individual candidates may still have been skipped or rejected (see Per-Candidate Failures).

Request-Level Failure - HTTP 400

{
  "Response": {
    "status": "FAILURE",
    "callId": "...",
    "errorDetails": {
      "errorCode": 100,
      "moreInfo": {
        "errors": {
          "errorCode": 100,
          "errorMessage": "Duplicate submission already processed: GC-2026-001"
        }
      },
      "userMessage": "An unexpected error has occurred"
    }
  }
}

The entire request was rejected and nothing was stored. The underlying reason is in errorDetails.moreInfo.errors.errorMessage. Request-level failures include:

  • Missing/unknown operation, missing required batch-level fields, malformed timestamp
  • documentId not found or not belonging to the caller's site (submit)
  • 🔄 [TEMP - finalize before release] The target manuscript is not in an active peer-review state. Suggestions are accepted only for a manuscript whose current version is submitted, revised, or resubmitted and is not in the author's draft. Manuscripts in draft (including a revised/resubmitted version still in the author's hands), in appeal, or in any terminal state (decisioned, accepted, withdrawn, …) are rejected. Applies to all four operations. The rejection message is: "Document is not accepting reviewer suggestions: the manuscript must be a submitted, revised, or resubmitted version that is not in draft."
  • Batch not found for provider + submissionId (add/update/delete)
  • Duplicate fully-processed batch on submit retry (see Idempotency)
  • Provider not active, or the Relay feature disabled for the site
  • Empty reviewers array
  • 🔄 [TEMP - finalize before release] reviewers array exceeding twice the configured per-document maximum (more than 200 candidates at the default maximum of 100) - see Candidate Limits
  • 🔄 [TEMP - finalize before release] ScholarOne is unable to determine the provider's current live candidate count for the manuscript (a data-tier error); the request is rejected rather than risk exceeding the limit

Per-Candidate Failures - Audited, Not Returned

Within an otherwise valid request, individual candidates can be skipped (duplicate ID, over the per-request cap) or rejected (validation failure: disallowed HTML, bad ORCID, bad country, missing required fields, oversized JSON fields). The remaining candidates are still committed. Each skip/rejection is written to the manuscript's audit trail in ScholarOne with the provider, submissionId, providerCandidateId, and reason.

⚠️

🔄 [TEMP - finalize before release] Ambiguous person match: if a candidate's email or ORCID matches more than one un-merged ScholarOne account, the candidate cannot be resolved to a single person and is skipped and audited. Resolve the duplicate with the user-administration / merge tools, then re-send the candidate.

The response does not enumerate these. Providers who need to verify ingestion can coordinate with the journal team, who can read the audit trail and the suggestion list in the editor interface. A batch that loses candidates this way is marked partial, and a partial batch can be wholly replaced by re-submitting the same submissionId (see Idempotency, case c).


Batch Lifecycle

Statuses

StatusMeaning
1 - receivedBatch row created, processing not finished
2 - processedAll candidates in the batch were stored
3 - partialSome candidates stored; the rest were skipped/rejected and audited
4 - failedNo candidates could be stored

Idempotency (Submit Retries)

A submit retry is identified by the same provider + submissionId on the same site.

  • (a) Happy path. First submit of GC-2026-001 → batch stored, status 2 (processed). Response: SUCCESS.
  • (b) Retry after full processing. Second submit of GC-2026-001 → rejected, HTTP 400, "Duplicate submission already processed: GC-2026-001". The original batch is untouched. A fully-processed batch is immutable via submit; use add/update/delete to change it.
  • (c) Retry after incomplete processing. If the existing GC-2026-001 batch is in any state other than fully processed (received, partial, failed), the old batch is marked superseded (soft-deleted) and the retry creates a fresh batch from the new payload. This is the intended recovery path after a partial failure: fix the offending records and re-submit the entire batch under the same submissionId.
⚠️

🔄 [TEMP finalize before release] Send an identical provider string on every call for a given batch. The retry match on provider is exact and case/separator-sensitive (unlike the provider-active check), so varying its casing or separators between submit and a retry e.g. GlobalCampus vs. globalcampus will not be recognized as the same batch and will create a duplicate batch instead of the (b)/(c) behavior above.

Duplicate Candidates

  • Within a single submit: if the same providerCandidateId appears twice, the first occurrence wins; later duplicates are skipped and audited.
  • On add: if the providerCandidateId already exists as a live record in the batch, the add is skipped and audited (the existing record is not modified - use update for that).
  • On update/delete: if no live record matches the providerCandidateId, that entry is skipped and audited; the request still returns SUCCESS.
⚠️

🔄 [TEMP finalize before release] Candidate LimitsTwo limits apply:

Per-request ceiling (hard reject). A single request whose reviewers array exceeds twice the configured maximum is rejected at the request level (HTTP 400; nothing stored). With the default maximum of 100, a request of more than 200 candidates is rejected. This guards against runaway payloads.

Per-document / per-provider cap (truncate-and-audit). Within that ceiling, candidates are accepted up to the provider's total live candidate count for the manuscript - counted across all of that provider's live batches, not per request. The maximum defaults to 100 and is clamped to a hard ceiling of 100 (it may be lowered per site, never raised above 100). When the provider already has live suggestions on the manuscript (a follow-up add, or a second submissionId), a growth allowance of +50 applies, so the per-document/provider total may reach max + 50 (never more than 150). Candidates beyond the cap are skipped and written to the audit trail; on submit the batch is marked partial (on add, over-cap candidates are audited but the batch status is not changed).

If ScholarOne cannot determine the current live count (a data-tier error), the request is rejected rather than risk exceeding the limit.


Delete Behavior and Modeling User Actions

Delete is a soft delete: the record disappears from all editor-facing views but is retained internally. A deleted providerCandidateId can be re-added later via add;🔄 [TEMP - finalize before release] this creates a new record with a new activity time (so it surfaces at the top of the editor's list - see Display Order).

If an editor has already actioned a candidate (e.g. sent a review invitation), that workflow is independent of this API; deleting the suggestion does not retract the invitation.

Automated vs. user-selected candidates: the API does not record why a candidate was sent (there is no addedBy field). Both kinds coexist freely in one batch and are distinguished only by providerCandidateId. If your system needs the distinction to be visible to editors or to itself later, either:

  • Use separate batches (submissionIds) for the automated run vs. user selections, or
  • Carry an origin marker in providerData (e.g. [{"origin": "user-selected"}]), which editors can see in the candidate's detail view.

Ordering and Concurrency

Display Order

⚠️

🔄 [TEMP - finalize before release] Candidates are ordered for editors newest first by the record's most recent activity - the time ScholarOne added or last updated it - with relevanceScore (descending) as the tiebreaker; records without a score sort last. Because an update re-stamps this time, editing any field on a candidate resurfaces it at the top of its provider section, just as a newly added candidate does. Records within a single submit are stamped individually as they are inserted, so they sort in insert order, with relevance as the tiebreaker only among records stamped at the same instant. Editors can also re-sort and filter the list in the interface (by name, relevance, and the provider-supplied metric columns).

Operation Ordering

Operations are applied in the order ScholarOne receives them. The timestamp field is informational and is not used to order or reconcile operations. There is no server-side conflict resolution for out-of-order delivery: for example, if a delete that was issued before a re-add arrives after it, the candidate ends up deleted.

Providers should therefore serialize operations per candidate - wait for the response to one operation before issuing the next operation that touches the same providerCandidateId. Independent candidates may be sent concurrently.


Quick Reference - What Fails Where

ConditionOutcome
Bad credentials / wrong site / Host mismatchRequest-level failure (auth error envelope)
Provider not active; feature disabledHTTP 400, request-level
Unknown operation; missing batch-level required field; bad timestamp (submit)HTTP 400, request-level
documentId not found / wrong site (submit)HTTP 400, request-level
🔄 [TEMP - finalize before release] Manuscript not in an active in-review state (submitted / revised / resubmitted, and not draft) - all four operations
HTTP 400, request-level
Batch not found (add/update/delete)HTTP 400, request-level
Duplicate fully-processed batch (submit retry)HTTP 400, request-level
Empty reviewers arrayHTTP 400, request-level
🔄 [TEMP - finalize before release] reviewers array exceeds 2× the configured maximum (more than 200 at the default max of 100)
HTTP 400, request-level
🔄 [TEMP - finalize before release] Live candidate count for the manuscript cannot be determined (data-tier error)
HTTP 400, request-level
Candidate: disallowed HTML, bad ORCID/country/email format, score out of range, oversized matchReason/matchDetails/metrics/flags/providerData, missing required candidate fieldCandidate rejected + audited; request still succeeds
🔄 [TEMP - finalize before release] Candidate: duplicate ID; over the per-document/per-provider cap; email or ORCID matches more than one un-merged ScholarOne account
Candidate skipped + audited; request still succeeds
Candidate: name/institution/displayName/candidateId over max lengthSilently truncated and stored


Did this page help you?