HotCRP REST API

HotCRP conference management software API

Introduction

HotCRP is conference review software. It is open source; a supported version runs on hotcrp.com. This documentation is for the HotCRP REST API.

To request documentation for an API method, please open a GitHub issue. We also welcome pull requests.

Overview

API calls use paths under api. For instance, to call the paper endpoint on a server at https://example.hotcrp.org/funconf25, you might use a URL like https://example.hotcrp.org/funconf25/api/paper?p=1.

GET operations retrieve system state and POST operations modify system state. Other operations are occasionally used when semantically meaningful—for example, the /paper endpoint supports DELETE.

Parameters may be provided in the query string or (for non-GET requests) the request body. In most cases, the request body should have Content-Type application/x-www-form-urlencoded or multipart/form-data; exceptions are documented.

Responses are formatted as JSON. Every response has an ok field, which is true if the request passed initial validation and false otherwise. Typically "ok": false indicates a serious error, such as a missing or malformatted parameter or a permission problem. "ok": true does not necessarily mean that the request fully succeeded. Messages about the request, if any, are expressed in a message_list field; a successful response may still carry errors and warnings there.

Operations marked with a yellow star () are featured: the parts of the API most useful to external integrations, which we aim to keep stable and well documented. When several endpoints can accomplish a task, the featured one is usually the best choice. Other API endpoints may be unstable or may be intended to serve HotCRP’s own web client.

External applications should authenticate to HotCRP’s API using bearer tokens obtained using Account settings > Developer.

Parameter types

Boolean parameters accept 1 or true for true and 0 or false or the empty string for false; the values on/yes and off/no are also accepted. For example, dry_run=1 and dry_run=true are equivalent.

Integer and number parameters are written in decimal, such as p=10. String parameters are sent literally; an enumerated parameter is a string restricted to a fixed set of values.

More complex inputs use other encodings. Some requests group parameters into logical objects using structured keys, such as named_search/1/q; others define an object using JSON, supplied either as the request body or as a JSON-valued parameter such as json. Use multipart/form-data encoding for requests that include uploaded files; since servers limit upload size, you may need the upload API to send a large file before processing it with another call.

Common parameters

p: The p parameter defines a submission ID. It can appear either in the query string or immediately following api/ in the query path: api/comment?p=1 and api/1/comment are the same API call. p is a positive decimal integer, but some API calls accept p=new when defining a new submission.

forceShow: HotCRP site administrators and track managers can administer submissions with which they are conflicted. For instance, when viewing a conflicted submission in the web UI, they see the conflicted view, but selecting “Override conflict” shows them a full administrator view. Conflict overriding can affect many aspects of site behavior, including search order, visible tags, and whether modifications are accepted. The forceShow boolean API parameter determines whether conflicts should be overridden when that is possible. It defaults to true, so administrators override their conflicts by default; pass forceShow=false to respect conflicts instead.

actas: HotCRP site administrators can assume other users’ identities, allowing them to check how the site appears to users with less authority. The actas parameter implements this in the API. Site administrators can set actas to an email address or numeric user ID; the API call will execute with the named user’s privileges.

:method:: The :method: parameter overrides the request’s HTTP method. Setting :method:=GET on a POST request makes HotCRP process it with GET semantics. The parameter must appear in the URL query string, not the request body, and GET is its only meaningful value. Use this for read requests whose parameters are too large to fit within a URL’s length limit: send the parameters in a POST body while still getting GET behavior.

q and search modifiers: Many endpoints act on a set of submissions chosen by a search rather than by a single p. These share a family of search parameters: q (the search expression), t (the search scope—the collection of submissions to search), and the modifiers qt, sort, scoresort, and reviewer. They mean the same thing everywhere they appear—for example in /papers, /reviews, and /assign. See Search for the search-string syntax and the full meaning of each parameter.

Message lists

The message_list response field holds an array of diagnostics about a request, such as why it failed, which field was invalid, or a note about what changed. It can appear on successful or unsuccessful responses and may be empty. The messages appear in display order.

Each entry is a message object whose only required field is status, an integer that classifies the message:

  • 2 or 3—an error; the request was rejected or could not be fully processed. (3 marks an especially serious error.)
  • 1—a warning.
  • 0—a plain informational message.
  • -3—a success message.
  • -5—an informational note about the preceding non-informational message (rendered indented).
  • other negative values—notes that are not full errors, but that should be rendered with highlights.

A message object may also have these fields:

  • message—the human-readable text, as a formatted-text string: a leading format sigil gives the encoding, with <0> for plain text, <1> for Markdown, and <5> for HTML. For example, "<0>Entry required" is the plain text “Entry required”. The field may be absent or empty, since a message object can carry only a field status.
  • field—when present, names the request parameter or submission field the message is about (such as title or abstract), letting a client attach the diagnostic to the corresponding input or highlight that input.
  • pos1, pos2, context—locate the message within the text it concerns. A message carries either pos1 and pos2 (byte offsets of a span in the UTF-8-encoded value of field) or a context array ["…excerpt…", pos1, pos2] that bundles an excerpt of that text with the span’s byte offsets into the excerpt. These let the web client underline the exact problem text.

For example, an unsuccessful submission update might return:

{
    "ok": false,
    "message_list": [
        {
            "status": 2,
            "field": "abstract",
            "message": "<0>Entry required to complete submission"
        },
        {
            "status": 1,
            "field": "other_topics",
            "message": "<0>Please avoid superlatives",
            "context": ["Extremely interesting ideas", 0, 9]
        },
        {
            "status": 2,
            "message": "<0>Submission not saved"
        }
    ]
}

User rights

Two terms describe administrative authority in this documentation, and they are not interchangeable.

A site administrator has site-wide authority over the whole conference. Chairs and sysadmins are site administrators; they can act on every submission, the review process, and conference settings. Endpoints restricted to this authority are badged Site admin only.

A submission administrator has administrative authority over a particular submission or a subset of submissions. For example, a track manager has administrative authority over a track, and each submission can have an explicit manager assigned from the PC. For most submissions, site administrators are also submission administrators (there are exceptions involving track rights and conflicts), but a submission manager is not necessarily a site administrator. Endpoints that require administrative authority over specific submissions, but do not require broad site administration rights, are badged Admin only or Track manager only.

Server and authentication

Base URL: https://demo.hotcrp.com/api

  • apiToken bearer
    External applications should authenticate to HotCRP’s API using bearer tokens. Users can create tokens via Account settings > Developer; tokens can have limited scope (e.g., read-only rights, or rights only for a subset of papers). API requests supply a token with the Authorization header: Authorization: bearer TOKENNAME.
  • session apiKey
    Browser sessions authenticate to HotCRP’s API via a cookie. The name of the cookie varies by installation. Operations other than GET and HEAD also require a post query parameter for CSRF protection.

Submissions section

These endpoints query and modify HotCRP submissions. They deal with submission objects, which are JSON representations of submissions.

Each submission object has an object field (set to the constant string "paper"), a pid field, and a status field. Complete submission objects also include every submission field, such as title, abstract, authors, topics, and pc_conflicts. However, methods that return submissions only fill in fields that exist and that the accessing user is allowed to see.

Submission endpoints always return complete submission objects. To select specific fields of submissions, or to return computed fields, use the /search or /searchaction endpoints.

Downloads

download=1 returns the response as a file, and drops HotCRP’s JSON envelope in favor of the bare payload that the matching POST accepts—so a client can download a submission, edit it, and upload it again:

  • paper with download=1 returns one submission object, ready to POST to paper.
  • papers with download=1 returns a bare array of submission objects, ready to POST to papers.

The parameter means the same thing on the review endpoints. Because a bare payload has no message_list, download=1 discards search diagnostics; errors still arrive in the usual envelope.

GET/{p}/paper

Retrieve submission

Retrieve a submission object specified by p, a submission ID. The submission object is returned in the paper response field. Error messages—for instance, about permission errors or nonexistent submissions—are returned in message_list.

Parameters

  • p integer

    Submission ID

  • forceShow boolean default true

    Whether to override administrator conflicts. Defaults to true; set forceShow=false to respect conflicts instead.

  • download boolean

    True returns the bare submission object as a file (see Downloads) instead of the usual response envelope.

Returns

  • ok boolean
  • if !download
    • paper paper object

      The requested submission object.

      + Show child attributes× Hide child attributes
      • paper.object "paper"
      • paper.pid integer

        Submission ID

      • paper.status string

        Submission status

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/paper

Create or modify submission

Create or modify a submission specified by p, a submission ID.

Setting p=new will create a new submission; the response will contain the chosen submission ID.

The modification is specified in JSON in any of these forms:

  1. In a JSON-formatted request parameter named json.
  2. As a JSON request body (when the request body has content-type application/json).
  3. As a ZIP archive (when the request body has content-type application/zip). The archive must contain a file named data.json; it may contain other files too.
  4. As a previously-uploaded JSON or ZIP file, represented by an upload token in the upload parameter.

The JSON object is a submission object whose fields define the modifications applied to the submission. The object need not specify all submission fields; absent fields remain unchanged.

The p request parameter is optional. If it is unset, HotCRP uses the pid from the supplied JSON. If both the p parameter and the JSON pid field are present, then they must match.

The API also supports form upload using the parameter conventions of the HotCRP web application. These conventions are subject to change, and third-party applications should prefer JSON.

To test a modification without saving, supply a dry_run=1 parameter. This will test the uploaded JSON but make no changes to the database.

ZIP and form uploads

A ZIP upload should contain a file named data.json (PREFIX-data.json is also acceptable). This file’s content is parsed as JSON. Submission fields in the JSON can refer to other files in the ZIP. For instance, this shell session uploads a new submission with content paper.pdf:

$ cat data.json
{
    "object": "paper",
    "pid": "new",
    "title": "Aught: A Methodology for the Visualization of Scheme",
    "authors": [{"name": "Nevaeh Gomez", "email": "ngomez@example.edu"}],
    "submission": {"content_file": "paper.pdf"},
    "status": "submitted"
}
$ zip upload.zip data.json paper.pdf
$ curl -H "Authorization: bearer hct_XXX" --data-binary @upload.zip -H "Content-Type: application/zip" SITEURL/api/paper

This shell session does the same, but using multipart/form-data.

$ curl -H "Authorization: bearer hct_XXX" -F "json=<data.json" -F paper.pdf=@paper.pdf SITEURL/api/paper

Administrator use

Submission administrators can use this endpoint to set some submission fields, such as decision, that have other endpoints as well.

Site administrators can choose specific IDs for new submissions by setting p (or JSON pid) to the chosen ID. Such a request will either modify an existing submission or create a new submission with that ID. To avoid overwriting an existing submission, set the submission JSON’s if_unmodified_since to 0.

Parameters

  • one of
    • application/json request body paper object

      A submission object sent as a raw JSON body.

      + Show child attributes× Hide child attributes
      • object "paper"
      • pid integer

        Submission ID

      • status string

        Submission status

    • application/zip request body binary

      A ZIP archive containing data.json (and any files it references).

    • json string

      A submission object supplied in a json request parameter. Body parameter

    • upload string

      An upload token for a previously-uploaded JSON or ZIP file.

  • dry_run boolean

    True checks input for errors, but does not save changes

  • if_unmodified_since string

    Reject the modification if the submission has been modified since this time (a Unix timestamp, or 0). If set, a submission JSON’s if_unmodified_since takes precedence over this parameter.

  • disable_users boolean Site admin only

    True disables any newly-created users.

    When an administrator creates submissions on behalf of other people, HotCRP normally creates accounts for any new contacts named in the input. Set disable_users=1 to create those accounts as disabled: the new users cannot sign in or receive email until an administrator explicitly enables them. This is useful when importing submissions in bulk and you don’t yet want to notify the people involved.

  • add_topics boolean Site admin only

    True automatically adds topics from input papers to the conference’s topics list.

  • reason string

    Optional text included in notification emails

  • notify boolean Site admin only default true

    False disables all email notifications

  • notify_authors boolean Admin only default true

    False disables email notifications to authors

  • p integer

    Submission ID

  • forceShow boolean default true

    Whether to override administrator conflicts. Defaults to true; set forceShow=false to respect conflicts instead.

Additional parameters are accepted.

Returns

  • ok boolean
  • dry_run boolean

    True for dry_run requests.

  • pid integer

    ID of the modified or newly created submission.

  • valid boolean

    True if and only if the modification was valid.

    For a non-dry-run request, "valid": true also means the database changes were committed.

  • change_list array of strings

    Names of the fields the request attempted to modify.

    change_list reflects what the request attempted to change, so successful, failed, and dry-run requests can all return a nonempty list. If the submission is new, the change_list will begin with "new".

  • conflict boolean

    True when the modification was rejected by an if_unmodified_since edit-conflict check.

  • if valid and !dry_run
    • paper paper object

      The modified submission object.

      + Show child attributes× Hide child attributes
      • paper.object "paper"
      • paper.pid integer

        Submission ID

      • paper.status string

        Submission status

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
DELETE/{p}/paperAdmin only

Delete submission

Delete the submission specified by p, a submission ID.

Parameters

  • p integer

    Submission ID

  • if_unmodified_since string

    Don’t delete if modified since this time

  • forceShow boolean default true

    Whether to override administrator conflicts. Defaults to true; set forceShow=false to respect conflicts instead.

  • dry_run boolean

    True checks input for errors, but does not save changes

  • notify boolean Site admin only default true

    False disables all email notifications

  • notify_authors boolean default true

    False disables email notifications to authors

  • reason string

    Optional text included in notification emails

Returns

  • ok boolean
  • valid boolean

    True if the delete request was valid

  • change_list array of strings

    Always ["delete"].

  • dry_run boolean

    True for dry_run requests

  • conflict boolean

    True when the delete was rejected by the if_unmodified_since edit-conflict check.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/papers

Retrieve multiple submissions

Retrieve submission objects matching a search.

The search is specified in the q parameter (and other search parameters, such as t and qt). All matching visible submissions are returned, as an array of submission objects, in the response field papers.

Since searches silently filter out non-viewable submissions, /papers?q=1010 and /paper?p=1010 can return different error messages. The /paper request might return an error like “Submission #1010 does not exist” or “You aren’t allowed to view submission #1010”, whereas the /papers request will return no errors. To obtain warnings for missing submissions that were explicitly listed in a query, supply a warn_missing=1 parameter.

Parameters

  • q string

    The search expression.

  • Search modifiers
    • t string default viewable

      The scope of submissions to search, such as s (complete submissions) or all.

    • qt string

      Default fields to search for query terms that do not name a field, such as ti or au.

    • sort string

      Sort order for the returned submissions, such as id or -title.

    • scoresort string

      Sort order for review-score fields, such as average or counts.

    • reviewer string

      Email or ID of the reviewer whose viewpoint evaluates reviewer-relative search terms such as myreview.

  • warn_missing boolean

    Get warnings for missing submissions

  • download boolean

    True returns a bare array of submission objects as a file (see Downloads) instead of the usual response envelope.

  • forceShow boolean default true

    Whether to override administrator conflicts. Defaults to true; set forceShow=false to respect conflicts instead.

Returns

  • ok boolean
  • if !download
    • papers array of paper objects

      The matching submission objects.

      + Show child attributes× Hide child attributes
      • papers[].object "paper"
      • papers[].pid integer

        Submission ID

      • papers[].status string

        Submission status

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/papersSite admin only

Create or modify multiple submissions

Create or modify multiple submissions.

This administrator-only endpoint modifies multiple submissions at once. Its request formats are similar to that of POST /{p}/paper: it can accept a JSON, ZIP, or form-encoded request body with a json parameter, and ZIP and form-encoded requests can also include attached files.

The JSON provided for /papers should be an array of JSON objects; each object is applied independently. The per-submission results are returned in the status_list response field (described below). The response message_list contains all messages relating to the save; each message’s landmark field is set to the integer index of the relevant submission in the input array.

Modify matching submissions

Alternatively, you can provide a q search query parameter and a single JSON modification object lacking the pid field. The JSON modification will be applied to all papers returned by the q search query.

Parameters

  • one of
    • application/json request body array of paper objects

      An array of submission objects sent as a raw JSON body.

      + Show child attributes× Hide child attributes
      • [].object "paper"
      • [].pid integer

        Submission ID

      • [].status string

        Submission status

    • application/zip request body binary

      A ZIP archive containing data.json (and any files it references).

    • json string

      Submission objects supplied in a json request parameter. Body parameter

    • upload string

      An upload token for a previously-uploaded JSON or ZIP file.

  • dry_run boolean

    True checks input for errors, but does not save changes

  • disable_users boolean Site admin only

    True disables any newly-created users

  • add_topics boolean Site admin only

    True automatically adds topics from input papers

  • notify boolean Site admin only default true

    False disables all email notifications

  • q string

    Search query for match requests

  • Search modifiers
    • t string default viewable

      The scope of submissions to search, such as s (complete submissions) or all.

    • qt string

      Default fields to search for query terms that do not name a field, such as ti or au.

    • sort string

      Sort order for the returned submissions, such as id or -title.

    • scoresort string

      Sort order for review-score fields, such as average or counts.

    • reviewer string

      Email or ID of the reviewer whose viewpoint evaluates reviewer-relative search terms such as myreview.

  • notify_authors any
  • reason any
  • forceShow boolean default true

    Whether to override administrator conflicts. Defaults to true; set forceShow=false to respect conflicts instead.

Returns

  • ok boolean
  • dry_run boolean

    True for dry_run requests.

  • papers array of paper objects

    The modified submission objects.

    + Show child attributes× Hide child attributes
    • papers[].object "paper"
    • papers[].pid integer

      Submission ID

    • papers[].status string

      Submission status

  • status_list array of update_status objects

    Per-submission results, one entry per input object.

    For array input, status_list has the same length and order as the input: entry i reports the valid flag, change_list, pid, and (for an edit-conflict rejection) conflict of update i.

    + Show child attributes× Hide child attributes
    • status_list[].valid boolean
    • status_list[].change_list array of strings
    • status_list[].pid integer or string
    • status_list[].conflict boolean

      True when this update was rejected by an if_unmodified_since edit-conflict check

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/potentialconflicts

Compute potential PC conflicts

Return the program-committee members who potentially conflict with a submission—either because they are an author of it, or because their name, affiliation, or collaborators overlap with the submission’s. Authors use this while preparing a submission to see who is conflicted; administrators use it to audit declared conflicts. It is available to a submission’s authors and to administrators, and only when the submission’s PC-conflicts field is present and visible to the caller.

Identify the submission with p, or pass p=new (with an optional sclass) to analyze a not-yet-created submission.

By default conflicts are computed from the submission’s saved authors and collaborators. To preview conflicts for unsaved data—as the submission form does while an author edits—supply prospective values instead, in one of two ways:

  • a json object with authors and/or collaborators members; or
  • submission-form fields: collaborators text, and author entries as authors:<n>:<field> together with has_authors=1.

Each entry in potential_conflicts carries the conflicting PC member’s uid and email and a type: author when they author the submission, or potentialconflict for a name/affiliation/collaborator match. A potentialconflict entry also includes a description (plain-text explanation) and a tooltip (HTML).

Parameters

  • p integer

    Submission to analyze; use new for an unsaved submission.

  • sclass string

    Submission class, used when p=new.

  • one of
    • json string

      JSON object of prospective authors and/or collaborators to apply to the submission before analysis.

    • collaborators string

      Prospective collaborators text (a form-field alternative to json).

    • authors string

      Prospective author fields, authors:<n>:<field> (a form-field alternative to json).

    • has_authors boolean

      Set when supplying authors:<n>:<field> fields.

Returns

  • ok boolean
  • potential_conflicts array of potential_conflict objects

    The potentially-conflicted PC members.

    + Show child attributes× Hide child attributes
    • potential_conflicts[].uid integer

      User ID of the PC member.

    • potential_conflicts[].email string

      Email of the PC member.

    • potential_conflicts[].type "author" | "potentialconflict"

      author when the PC member is an author of the submission; potentialconflict for a name, affiliation, or collaborator match.

    • potential_conflicts[].description string

      Plain-text explanation of the match, as a formatted-text string beginning with the <0> format sigil. Present only when type is potentialconflict.

    • potential_conflicts[].tooltip string

      HTML explanation of the match suitable for a tooltip, as a formatted-text string beginning with the <5> format sigil. Present only when type is potentialconflict.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/{p}/share

Retrieve share link

Retrieve the share link for a submission. This link can be accessed by users not signed in to HotCRP; it grants view-only access to the submission and its documents. Only authors and submission administrators can fetch the share link.

Parameters

  • p integer

    Submission ID

Returns

  • ok boolean
  • url any

    The share link

  • token string

    Token for this share link

  • token_type string

    "author_view"

  • expires_at integer
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/share

Create, modify, or remove share link

Change the share link for a submission. The share parameter determines whether a link should be created; it must be one of:

no
Delete the current share link, if any.
yes
Update a share link or create one if necessary. The expiration time of a current share link may be extended if expires_in requests it.
reset
Reset the expiration time of an existing share link, if one exists.
new
Delete any existing share link and create a new one.

Only authors and submission administrators can modify a share link.

Parameters

  • share "yes" | "no" | "new" | "reset"

    Type of sharing desired

  • p integer

    Submission ID

  • expires_in integer

Returns

  • ok boolean
  • token string or null
  • token_type string
  • expires_at integer
  • url any
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
DELETE/{p}/share

Remove share link

Delete the share link for a submission, if any has been created.

Parameters

  • p integer

    Submission ID

  • share any
  • expires_in any

Returns

  • ok boolean
  • token null
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Documents section

These endpoints query documents associated with HotCRP submissions, reviews, and comments. The /upload endpoint can be used to upload a large file using multiple requests; this file can be a document or a temporary file intended for input to another API.

GET/document

Retrieve document

Retrieve a document and return it in the response body. Add hash or docid to retrieve a specific document version; such requests are usually cacheable, and only administrators and authors can make them.

Successful requests (HTTP status code 200) return the requested document as the response, without any JSON wrapper. Find the document’s MIME type using the response’s Content-Type header. Unsuccessful requests (HTTP status code 300 or higher) usually return a JSON object with ok set to false and a message_list describing the error.

This API understands conditional requests with HTTP headers If-Match, If-None-Match, If-Modified-Since, and If-Unmodified-Since, and many responses include ETag and Last-Modified HTTP headers. It also understands range requests.

Parameters

  • one of
    • doc string

      Document name, e.g. testconf-paper1.pdf.

    • p integer

      Submission ID. Combine with dt, and optionally file, to identify a document by submission field.

    • dt integer or string

      Submission field holding the document.

    • file string

      For fields that hold multiple documents, the name of the desired file.

  • hash string

    Document version selected by hash.

  • docid integer

    Document version selected by internal document ID.

Returns

The document contents. The response Content-Type header is the document's MIME type (e.g. application/pdf).

*/* binary

Error return

  • ok boolean

    always false

  • status_code integer
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/documentlist

List documents

Retrieve information about documents and document versions accessible to the requesting user. A request with just the p=PID parameter lists all available documents currently associated with the submission. To request information about a specific submission field, add a dt or doc parameter. Setting history=1 requests information about past document versions as well as current ones.

Parameters

  • one of
    • doc string

      Document name

    • p integer

      Submission ID

    • dt integer or string

      Document type

  • history boolean

Returns

  • ok boolean
  • dt integer or string

    Document type

  • document_history array of document_history_entry objects
    + Show child attributes× Hide child attributes
    • document_history[].docid integer
    • document_history[].hash string
    • document_history[].mimetype string

      MIME type

    • document_history[].created_at integer

      Time this version was first uploaded

    • document_history[].attached_at integer

      Most recent time this version was uploaded

    • document_history[].link string

      Link to this specific version of the document

    • document_history[].size integer
    • document_history[].filename string

      Filename used for upload

    • document_history[].active boolean

      True if this document is currently active

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/formatcheck

Check PDF format

Run HotCRP’s PDF format checker on a specified document. A human-readable response is returned in message_list. The problem_fields response field lists the names of any PDF checks that failed; examples include "papersize", "pagelimit", "columns", "textblock", "bodyfontsize", "bodylineheight", and "wordlimit". The npages_detail response field is provided only if the request’s detail parameter is truthy.

Parameters

  • one of
    • doc string

      Document name

    • p integer

      Submission ID

    • dt integer or string

      Document type

    • file string

      Filename of document uploaded to multi-document field

  • docid integer

    Document ID

  • hash string

    Hash of document

  • soft boolean

    If true, reuse a cached format check when one is available instead of re-running the checks. Defaults to false (always re-run).

  • detail boolean

    If true, include the per-page-type npages_detail breakdown.

Returns

  • ok boolean
  • docid integer

    ID of the checked document.

  • npages null or integer

    Number of pages in PDF

  • nwords null or integer

    Number of words in PDF

  • problem_fields array of strings

    Names of the format checks that failed (e.g. papersize, pagelimit).

  • has_error boolean

    True if any check failed.

  • if detail
    • npages_detail object

      Number of pages in PDF per page type

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/archivecontents

List contents of archive document

List the contents of a ZIP, .tar, .tar.gz, .tar.bz2, or .tar.xz archive. Returns the list of included filenames in the archive_contents field. The summary=1 parameter requests an additional archive_contents_summary, which a preformatted string that uses {} notation to represent subdirectories; for instance, subdir/{file1.txt, file2.txt}.

Parameters

  • one of
    • doc string

      Document name

    • p integer

      Submission ID

    • dt integer or string

      Document type

    • file string

      Filename of document uploaded to multi-document field

  • docid integer

    Document ID

  • hash string

    Hash of document

  • summary boolean

    True requests archive_contents_summary

Returns

  • ok boolean
  • archive_contents array of strings

    List of archive elements

  • if summary
    • archive_contents_summary string

      Parsed archive listing

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/upload

Upload file

Upload large files for later use.

Servers limit how much data they will accept in a single request. The upload API can upload large files using multiple requests. When an upload is complete, later API requests can refer to that file using an upload token.

The lifecycle of an upload is as follows.

  1. A request with start=1 begins a new upload. This request should also include a size parameter to define the size of the uploaded file, if that is known, and parameters defining its purpose (dt, mimetype, filename, and temp).
  2. The response to this request includes the upload token in its token field. This is a string like hcupwhvGDVmHNYyDKdqeqA. All subsequent requests relating to the upload must include this token as a token parameter.
  3. Subsequent requests upload the contents of the file in chunks. The blob parameter (which can be an attached file) contains the chunk itself, and the offset parameter defines the offset of chunk relative to the file.
  4. A request with finish=1 completes the upload. The server seals the upload and responds with the file’s content hash. A finish=1 request will fail unless all expected chunks have been received.

start=1 and finish=1 requests can also include a chunk. The ranges response field represents the ranges of bytes received so far.

The upload API is only available on sites that have enabled the document store.

Parameters

  • p integer

    Submission ID

  • start boolean

    Set to true to start a new upload.

  • if start
    • dt integer or string

      Purpose of uploaded document; typically corresponds to a submission field ID

    • temp boolean

      If true, the uploaded file is expected to be temporary

    • mimetype string

      MIME type Body parameter

    • filename string

      Name of uploaded file Body parameter

    • size integer

      Size of uploaded file in bytes.

  • token string

    Token for the ongoing upload. Required unless start=1.

  • blob any

    Chunk being uploaded. Body parameter

  • if blob
    • offset integer

      Offset of blob in uploaded file.

    • length integer

      Length of blob in bytes (must match actual length of blob).

  • finish boolean

    Set to true to complete the upload.

  • cancel boolean

    Set to true to cancel an ongoing upload.

Returns

  • ok boolean
  • token string

    Token identifying this upload; include it as token in later requests.

  • dt integer or string

    Document type

  • filename string
  • mimetype string

    MIME type

  • size integer
  • ranges array of arrays

    Byte ranges received so far.

  • hash string

    The completed file’s content hash; present once the upload is finished.

  • crc32 string

    The completed file’s CRC32 checksum; present once the upload is finished.

  • progress_value integer

    Bytes received so far, for progress display.

  • progress_max integer

    Total expected bytes, when known.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Tags section

These endpoints read and modify submission tags and the per-tag display metadata that depends on them.

A tag is a label attached to a submission. A tag may carry a numeric value, written tag#4; if omitted, the value #0 is the default, and tag#0 is typically displayed as just tag. Tags drive much of HotCRP’s organization: chairs can configure tags as votes or approval votes (each PC member has an allotment), as rankings, or as colors/styles that highlight a submission. Some tags are automatic (maintained by a formula and read-only) or otherwise read-only to non-chairs.

Tags also have visibility rules. Twiddle tags are private: ~tag is stored per user (only you see your ~tag), and ~~tag is visible only to chairs. Ordinary tags are visible to the PC, except that a conflicted PC member may see a different set of tags on submissions they are conflicted with—which is why several responses carry both a normal and a …_conflicted variant.

Tag objects

Most endpoints return a submission’s tags as a tag object (the tag_response schema). Because tags feed several different UI elements, the same tags are presented in several forms:

  • tags—the machine-readable list of tags (with values), as a tag_value_list.
  • tags_edit_text—the tags as editable text.
  • tags_view_html—rendered HTML for display.
  • tag_decoration_html—HTML for any badges and emoji the tags imply.
  • color_classes—CSS style classes implied by the tags.

When the viewer is conflicted, tags_conflicted and color_classes_conflicted give the conflict-blind versions.

Throughout, the tag parameter names a single tag, and tag-assignment input uses HotCRP’s tag syntax (tag, tag#value, tag#clear to remove). Bulk changes go through the assignment machinery, so the same permission rules apply.

Tag annotations

An ordered tag—one used for a ranking or for votes—can carry annotations that divide its submissions into labeled groups, such as the section headings in a discussion order. Each annotation is a tag_annotation object:

  • annoid—a stable integer ID for the annotation within the tag.
  • tagval—the tag value at which the group begins. An annotation labels the run of submissions whose value for the tag is at least its tagval and less than the next annotation’s, so the annotations’ tagvals define the group boundaries.
  • legend—the group’s display text (with a format code when it is not the default text format). A divider with no text instead carries blank: true.
  • tag—the tag the annotation belongs to.
  • pos—when annotations accompany a search result, the index in that result at which the annotation falls (the same meaning as groups[].pos from /search).

When the tag organizes a meeting agenda, an annotation may also carry session-scheduling metadata: session_title, time, location, and session_chair.

GET/{p}/tags

Retrieve a submission’s tags

Return the tags visible to the caller on submission p, as a tag object.

Parameters

  • p integer

    Submission ID

Returns

  • ok boolean
  • pid integer

    Submission ID

  • tags array of strings

    List of tag names with values

  • tags_edit_text string

    Textual representation for editing

  • tags_view_html string

    HTML representation for display

  • tag_decoration_html string

    HTML representation of badges and emoji

  • color_classes string

    Space-separated list of tag style classes

  • tags_conflicted array of strings

    List of tag names with values

  • color_classes_conflicted string

    Space-separated list of tag style classes

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/tags

Change a submission’s tags

Modify the tags on submission p and return the updated tag object.

Two modes of change are available, and may be combined:

  • Replacetags sets the submission’s complete tag list, removing any tags not listed (subject to permissions).
  • Incrementaladd_tags adds tags and remove_tags removes them, leaving other tags untouched.

To make a change conditional, set expected_tags to the tag list you believe is current; if the submission’s tags differ, the request fails without changing anything (optimistic concurrency control). As with other modifying endpoints, supplying search re-runs that search after the change so a client can refresh a list in one round trip.

Parameters

  • p integer

    Submission ID

  • tags string

    Complete new tag list; replaces all editable tags on the submission. Body parameter

  • add_tags string

    Tags to add, leaving others in place. Body parameter

  • remove_tags string

    Tags to remove, leaving others in place. Body parameter

  • expected_tags string

    If set, apply the change only if the submission’s current tags match this list. Body parameter

  • search string or search_parameters object

    Encoded description of a search, as returned from the search_params response field of /search. Provide to recompute the search after the assignment. The response will include ids, groups, and search_params from that search. Body parameter

Returns

  • ok boolean
  • pid integer

    Submission ID

  • tags array of strings

    List of tag names with values

  • tags_edit_text string

    Textual representation for editing

  • tags_view_html string

    HTML representation for display

  • tag_decoration_html string

    HTML representation of badges and emoji

  • color_classes string

    Space-separated list of tag style classes

  • if search
    • ids array of integers

      Array of submission IDs matching the search, in the order implied by the search.

    • groups array of tag_annotation objects

      Array of search annotations corresponding to the search, sourced from tag annotations, headings, or THEN searches. Often empty.

      + Show child attributes× Hide child attributes
      • groups[].annoid integer

        Unique identifier for this annotation within the tag. (When creating an annotation via POST /taganno, supply a string beginning with n, such as n1, in place of an ID.)

      • groups[].tag string

        The tag this annotation belongs to.

      • groups[].tagval number

        Tag value at which the annotation begins; the annotation labels submissions whose value for the tag is at least this and less than the next annotation's value.

      • groups[].legend string

        Display text (heading) for the group. Absent for a blank separator.

      • groups[].format integer

        Text format code for legend, present only when it is not the default format.

      • groups[].blank boolean

        Present and true when the annotation is a blank separator with no legend.

      • groups[].pos integer

        Position of the annotation in the associated submission list, as an index into the result. Present only when the annotation is returned alongside a search result.

      • groups[].session_title string

        Optional session-scheduling metadata: the session's title, used when the tag organizes a meeting agenda.

      • groups[].time string

        Optional session-scheduling metadata: the session's time.

      • groups[].location string

        Optional session-scheduling metadata: the session's location.

      • groups[].session_chair string

        Optional session-scheduling metadata: the session's chair.

    • search_params string

      URL-encoded string defining all relevant parameters for the search.

  • tags_conflicted array of strings

    List of tag names with values

  • color_classes_conflicted string

    Space-separated list of tag style classes

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/assigntags

Change tags on several submissions

Apply tags to many submissions in one request. tagassignment is a whitespace/comma-separated stream of submission IDs and tags: each number sets the “current” submission, and each following tag (until the next number) is assigned to it. For example, 1 discuss 2 discuss reject tags submission 1 with discuss and submission 2 with discuss and reject.

The response’s p array carries refreshed tag objects for the affected submissions. Supplying search adds that search’s results to the response as well.

Parameters

  • tagassignment string

    Submission IDs interleaved with the tags to assign to them. Body parameter

  • search string or search_parameters object

    Encoded description of a search, as returned from the search_params response field of /search. Provide to recompute the search after the assignment. The response will include ids, groups, and search_params from that search. Body parameter

Returns

  • ok boolean
  • p array of tag_response objects

    Refreshed tag objects for the affected submissions.

    + Show child attributes× Hide child attributes
    • p[].pid integer

      Submission ID

    • p[].tags array of strings

      List of tag names with values

    • p[].tags_edit_text string

      Textual representation for editing

    • p[].tags_view_html string

      HTML representation for display

    • p[].tag_decoration_html string

      HTML representation of badges and emoji

    • p[].color_classes string

      Space-separated list of tag style classes

    • p[].tags_conflicted array of strings

      List of tag names with values

    • p[].color_classes_conflicted string

      Space-separated list of tag style classes

  • if search
    • ids array of integers

      Array of submission IDs matching the search, in the order implied by the search.

    • groups array of tag_annotation objects

      Array of search annotations corresponding to the search, sourced from tag annotations, headings, or THEN searches. Often empty.

      + Show child attributes× Hide child attributes
      • groups[].annoid integer

        Unique identifier for this annotation within the tag. (When creating an annotation via POST /taganno, supply a string beginning with n, such as n1, in place of an ID.)

      • groups[].tag string

        The tag this annotation belongs to.

      • groups[].tagval number

        Tag value at which the annotation begins; the annotation labels submissions whose value for the tag is at least this and less than the next annotation's value.

      • groups[].legend string

        Display text (heading) for the group. Absent for a blank separator.

      • groups[].format integer

        Text format code for legend, present only when it is not the default format.

      • groups[].blank boolean

        Present and true when the annotation is a blank separator with no legend.

      • groups[].pos integer

        Position of the annotation in the associated submission list, as an index into the result. Present only when the annotation is returned alongside a search result.

      • groups[].session_title string

        Optional session-scheduling metadata: the session's title, used when the tag organizes a meeting agenda.

      • groups[].time string

        Optional session-scheduling metadata: the session's time.

      • groups[].location string

        Optional session-scheduling metadata: the session's location.

      • groups[].session_chair string

        Optional session-scheduling metadata: the session's chair.

    • search_params string

      URL-encoded string defining all relevant parameters for the search.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/alltags

List all visible tags

Return every tag name the caller can see, for tag completion and similar uses. This endpoint is available to PC members only; the result is the set of tag names across all viewable submissions, not the tags of any one submission.

readonly_tagmap and sitewide_tagmap, when present, are objects whose keys are the (lowercased) tags that are read-only or site-wide, respectively.

Returns

  • ok boolean
  • tags array of strings

    All visible tag names.

  • readonly_tagmap object

    Map whose keys are the read-only tags.

  • sitewide_tagmap object

    Map whose keys are the site-wide tags (chairs only).

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/taganno

Retrieve tag annotations

Return the annotations of a tag. Annotations divide an ordered (ranking or votes) tag into labeled groups—for example, section headings in a discussion order. editable reports whether the caller may change them.

Parameters

  • tag string

    The tag whose annotations to return.

  • search string or search_parameters object

    Encoded description of a search, as returned from the search_params response field of /search. Provide to recompute the search after the assignment. The response will include ids, groups, and search_params from that search.

Returns

  • ok boolean
  • tag string

    The tag.

  • editable boolean

    Whether the caller may edit these annotations.

  • anno array of tag_annotation objects

    The tag’s annotations, in order.

    + Show child attributes× Hide child attributes
    • anno[].annoid integer

      Unique identifier for this annotation within the tag. (When creating an annotation via POST /taganno, supply a string beginning with n, such as n1, in place of an ID.)

    • anno[].tag string

      The tag this annotation belongs to.

    • anno[].tagval number

      Tag value at which the annotation begins; the annotation labels submissions whose value for the tag is at least this and less than the next annotation's value.

    • anno[].legend string

      Display text (heading) for the group. Absent for a blank separator.

    • anno[].format integer

      Text format code for legend, present only when it is not the default format.

    • anno[].blank boolean

      Present and true when the annotation is a blank separator with no legend.

    • anno[].pos integer

      Position of the annotation in the associated submission list, as an index into the result. Present only when the annotation is returned alongside a search result.

    • anno[].session_title string

      Optional session-scheduling metadata: the session's title, used when the tag organizes a meeting agenda.

    • anno[].time string

      Optional session-scheduling metadata: the session's time.

    • anno[].location string

      Optional session-scheduling metadata: the session's location.

    • anno[].session_chair string

      Optional session-scheduling metadata: the session's chair.

  • if search
    • ids array of integers

      Array of submission IDs matching the search, in the order implied by the search.

    • groups array of tag_annotation objects

      Array of search annotations corresponding to the search, sourced from tag annotations, headings, or THEN searches. Often empty.

      + Show child attributes× Hide child attributes
      • groups[].annoid integer

        Unique identifier for this annotation within the tag. (When creating an annotation via POST /taganno, supply a string beginning with n, such as n1, in place of an ID.)

      • groups[].tag string

        The tag this annotation belongs to.

      • groups[].tagval number

        Tag value at which the annotation begins; the annotation labels submissions whose value for the tag is at least this and less than the next annotation's value.

      • groups[].legend string

        Display text (heading) for the group. Absent for a blank separator.

      • groups[].format integer

        Text format code for legend, present only when it is not the default format.

      • groups[].blank boolean

        Present and true when the annotation is a blank separator with no legend.

      • groups[].pos integer

        Position of the annotation in the associated submission list, as an index into the result. Present only when the annotation is returned alongside a search result.

      • groups[].session_title string

        Optional session-scheduling metadata: the session's title, used when the tag organizes a meeting agenda.

      • groups[].time string

        Optional session-scheduling metadata: the session's time.

      • groups[].location string

        Optional session-scheduling metadata: the session's location.

      • groups[].session_chair string

        Optional session-scheduling metadata: the session's chair.

    • search_params string

      URL-encoded string defining all relevant parameters for the search.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/taganno

Change tag annotations

Replace the annotations of a tag. Supply the desired changes in anno, a JSON array of tag_annotation objects (a single object is also accepted). Each entry is matched to an existing annotation by its annoid:

  • To modify an annotation, give its existing integer annoid along with the fields to change (legend, tagval, and/or the session-scheduling fields session_title, time, location, session_chair; pass none for a session field to clear it).
  • To create an annotation, use an annoid string beginning with n (for example n1); the server assigns the real ID.
  • To delete an annotation, give its annoid and "delete": true.

Only the fields you supply are changed; omitted fields are left as they were. Requires permission to administer the tag. Returns the updated annotations, as for taganno GET.

Parameters

  • tag string

    The tag whose annotations to change.

  • anno array of tag_annotation objects

    The new annotation list. Body parameter

    + Show child attributes× Hide child attributes
    • anno[].annoid integer

      Unique identifier for this annotation within the tag. (When creating an annotation via POST /taganno, supply a string beginning with n, such as n1, in place of an ID.)

    • anno[].tag string

      The tag this annotation belongs to.

    • anno[].tagval number

      Tag value at which the annotation begins; the annotation labels submissions whose value for the tag is at least this and less than the next annotation's value.

    • anno[].legend string

      Display text (heading) for the group. Absent for a blank separator.

    • anno[].format integer

      Text format code for legend, present only when it is not the default format.

    • anno[].blank boolean

      Present and true when the annotation is a blank separator with no legend.

    • anno[].pos integer

      Position of the annotation in the associated submission list, as an index into the result. Present only when the annotation is returned alongside a search result.

    • anno[].session_title string

      Optional session-scheduling metadata: the session's title, used when the tag organizes a meeting agenda.

    • anno[].time string

      Optional session-scheduling metadata: the session's time.

    • anno[].location string

      Optional session-scheduling metadata: the session's location.

    • anno[].session_chair string

      Optional session-scheduling metadata: the session's chair.

  • search string or search_parameters object

    Encoded description of a search, as returned from the search_params response field of /search. Provide to recompute the search after the assignment. The response will include ids, groups, and search_params from that search.

Returns

  • ok boolean
  • tag string

    The tag.

  • editable boolean

    Whether the caller may edit these annotations.

  • anno array of tag_annotation objects

    The updated annotations, in order.

    + Show child attributes× Hide child attributes
    • anno[].annoid integer

      Unique identifier for this annotation within the tag. (When creating an annotation via POST /taganno, supply a string beginning with n, such as n1, in place of an ID.)

    • anno[].tag string

      The tag this annotation belongs to.

    • anno[].tagval number

      Tag value at which the annotation begins; the annotation labels submissions whose value for the tag is at least this and less than the next annotation's value.

    • anno[].legend string

      Display text (heading) for the group. Absent for a blank separator.

    • anno[].format integer

      Text format code for legend, present only when it is not the default format.

    • anno[].blank boolean

      Present and true when the annotation is a blank separator with no legend.

    • anno[].pos integer

      Position of the annotation in the associated submission list, as an index into the result. Present only when the annotation is returned alongside a search result.

    • anno[].session_title string

      Optional session-scheduling metadata: the session's title, used when the tag organizes a meeting agenda.

    • anno[].time string

      Optional session-scheduling metadata: the session's time.

    • anno[].location string

      Optional session-scheduling metadata: the session's location.

    • anno[].session_chair string

      Optional session-scheduling metadata: the session's chair.

  • if search
    • ids array of integers

      Array of submission IDs matching the search, in the order implied by the search.

    • groups array of tag_annotation objects

      Array of search annotations corresponding to the search, sourced from tag annotations, headings, or THEN searches. Often empty.

      + Show child attributes× Hide child attributes
      • groups[].annoid integer

        Unique identifier for this annotation within the tag. (When creating an annotation via POST /taganno, supply a string beginning with n, such as n1, in place of an ID.)

      • groups[].tag string

        The tag this annotation belongs to.

      • groups[].tagval number

        Tag value at which the annotation begins; the annotation labels submissions whose value for the tag is at least this and less than the next annotation's value.

      • groups[].legend string

        Display text (heading) for the group. Absent for a blank separator.

      • groups[].format integer

        Text format code for legend, present only when it is not the default format.

      • groups[].blank boolean

        Present and true when the annotation is a blank separator with no legend.

      • groups[].pos integer

        Position of the annotation in the associated submission list, as an index into the result. Present only when the annotation is returned alongside a search result.

      • groups[].session_title string

        Optional session-scheduling metadata: the session's title, used when the tag organizes a meeting agenda.

      • groups[].time string

        Optional session-scheduling metadata: the session's time.

      • groups[].location string

        Optional session-scheduling metadata: the session's location.

      • groups[].session_chair string

        Optional session-scheduling metadata: the session's chair.

    • search_params string

      URL-encoded string defining all relevant parameters for the search.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/{p}/tagmessages

Retrieve tag edit messages

Return advisory messages about the caller’s tags on submission p, in the standard message_list. These are the warnings HotCRP shows around voting tags—for instance, how many votes remain in an allotment, or that an allotment has been exceeded. The response carries the submission’s pid; the messages themselves are in message_list.

Parameters

  • p integer

    Submission ID

Returns

  • ok boolean
  • pid integer

    Submission ID.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/{p}/votereport

Retrieve vote analysis

Return a human-readable summary of who voted for submission p using a voting tag. vote_report is an HTML fragment listing the voters (with vote counts, for allotment votes); it is empty when there are no votes. Requires permission to see per-user values of the tag.

Parameters

  • tag string

    The voting (or approval) tag to report on.

  • p integer

    Submission ID

Returns

  • ok boolean
  • vote_report string

    HTML summary of the voters, or an empty string.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Review preferences section

A review preference records how much a PC member wants to review a particular submission. HotCRP uses preferences to drive automatic review assignment (the pref autoassigner) and to order the assignment UI.

A preference has two parts:

  • A signed integer preference value: positive means the PC member wants to review the submission (larger is stronger), negative means they would rather not (more negative is stronger), and 0 or absent is neutral.
  • An optional expertise indicator: X (expert), Y (some expertise), or Z (little expertise).

In text the two combine as the value followed by the expertise letter—for example 10X (strong preference, expert) or -5 (mild aversion, no expertise stated).

PC members set their own preferences, for any submission, regardless of whether they can currently see it (so a preference is not lost when a submission later becomes visible). Administrators may read and set another PC member’s preference by naming them in u. Preferences are private: they are visible only to the PC member and to administrators.

These endpoints are also reachable under the aliases pref and reviewpref.

GET/{p}/revpref

Retrieve a review preference

Return a PC member’s review preference for submission p—by default the caller’s own, or another PC member’s when u is given (administrators only).

pref is the numeric preference and value is its text form (number plus any expertise letter); value is an empty string when no preference is set. prefexp gives the expertise indicator on its own when one is set, and topic_score reports how well the submission’s topics match the PC member’s topic interests (present only when the conference uses topics).

Parameters

  • p integer

    Submission ID

  • u string

    PC member whose preference to read (email or user ID); administrators only. Defaults to the caller.

Returns

  • ok boolean
  • value string

    The preference in text form (e.g. 10X), or an empty string if unset.

  • pref integer

    The numeric preference value.

  • prefexp "X" | "Y" | "Z"

    Expertise indicator, when set: X expert, Y some, Z little.

  • topic_score integer

    Topic-interest match score, when the conference uses topics.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/revpref

Set a review preference

Set a PC member’s review preference for submission p, then return it as revpref GET does. By default the change applies to the caller; administrators may set another PC member’s preference with u.

Supply the new preference in pref, in text form: a signed integer, optionally followed by an expertise letter (X, Y, or Z)—for example 10, -5, or 20X. An empty value clears the preference.

Parameters

  • pref string

    New preference in text form (e.g. 10X); empty to clear. Body parameter

  • p integer

    Submission ID

  • u string

    PC member whose preference to set (email or user ID); administrators only. Defaults to the caller.

Returns

  • ok boolean
  • value string

    The stored preference in text form, or an empty string if cleared.

  • pref integer

    The stored numeric preference value.

  • prefexp "X" | "Y" | "Z"

    Expertise indicator, when set.

  • topic_score integer

    Topic-interest match score, when the conference uses topics.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Assignments section

These endpoints perform and compute HotCRP assignments. An assignment is any change expressible through HotCRP’s bulk-assignment interface: review assignments, review preferences, conflicts, tags, decisions, lead and shepherd designations, and more. The exact set of assignment types depends on the conference’s configuration and the calling user’s privileges; /assigners enumerates the types available.

/assign applies an explicit assignment that the caller supplies as JSON or CSV; a user may perform any assignment they have permission to make. /autoassign instead computes an assignment automatically—for example, distributing reviews to balance load across the PC—and is restricted to administrators.

Both endpoints can run in a dry-run mode that parses and checks an assignment, reporting any errors, without touching the database. Assignments are applied atomically: if any part of an assignment is invalid, none of it is performed.

POST/assign

Perform assignments

Apply an explicit set of assignments supplied by the caller, in HotCRP’s bulk-assignment format.

The assignment data can be provided in any of four ways:

  1. As a JSON request body (content type application/json).
  2. As a CSV request body (content type text/csv).
  3. In the assignments parameter, holding JSON or CSV (with a form-encoded request, content type application/x-www-form-urlencoded or multipart/form-data).
  4. In the upload parameter, holding an upload token for a previously-uploaded JSON or CSV file. Use this for assignment files too large to send inline; see the upload API.

JSON assignment data is an array of objects, each with at least pid and action fields (a lone object is also accepted and treated as a one-element array). CSV assignment data is a table whose header includes at least pid and action columns. In both forms the action selects the assignment type and determines which other fields or columns are meaningful; /assigners lists every action and its parameters.

The valid response field reports whether the assignment was free of errors; any errors themselves are described in the standard message_list. For a non-dry-run request, valid is also the commit signal: true means the changes were saved, false means nothing changed.

On success the response describes the assignment that was performed (or, for a dry run, that would be performed). The amount of detail is controlled by the format parameter, ranging from a bare count up to the full list of individual (“atomic”) assignments. An atomic assignment is a single action applied to a single entity, such as adding one tag to one submission or assigning one review.

When the search parameter is supplied, a successful non-dry-run request also returns the result of evaluating that search after the assignment, together with refreshed tag and status information for the affected submissions. This lets a client apply an assignment and update a displayed submission list in a single round trip.

Parameters

  • assignments string

    Assignment data as JSON or CSV, for requests that do not send it as the body. The value is parsed as JSON if it begins with [ or {, and as CSV otherwise. Body parameter

  • upload string

    Upload token for assignment data uploaded earlier via the upload API. The uploaded file may be JSON or CSV.

  • json5 boolean

    If true, JSON assignment data may use JSON5 syntax, including comments, trailing commas, and unquoted keys.

  • dry_run boolean

    If true, parse and validate the assignment and report any errors, but make no database changes. valid still reports whether the assignment would have succeeded.

  • p integer

    If set, restrict the operation to this submission: assignments naming any other submission are silently ignored. Handy for committing one submission’s worth of changes from a larger assignment.

  • format "json" | "csv" | "summary" | "none" default json

    How much detail to include in the response. json (the default) lists each atomic assignment as an object (see assignment_header and assignments); csv returns the same rows as CSV text (see output); summary returns only the distinct actions and affected submissions (assignment_actions, assignment_pids); none returns only assignment_count.

  • forceShow boolean default true

    Whether to override administrator conflicts. Defaults to true; set forceShow=false to respect conflicts instead.

  • search string or search_parameters object

    A search to evaluate after the assignment is applied. When supplied on a successful, non-dry-run request, the response gains the search results (ids, groups, search_params) and refreshed per-submission tag and status information (papers).

Returns

  • ok boolean
  • valid boolean

    True if the assignment parsed and validated with no errors. On a non-dry-run request, true additionally means the changes were committed; false means nothing was changed.

  • dry_run boolean

    Present and true when the request was a dry run.

  • if valid
    • assignment_count integer

      Number of atomic assignments performed (or, for a dry run, that would be performed).

  • if valid and format=json
    • assignment_header array of strings

      Column names describing the fields of each assignments row.

    • assignments array of objects

      The atomic assignments, each an object keyed by the names in assignment_header.

  • if valid and format=summary
    • assignment_actions array of strings

      Distinct action names that were performed.

    • assignment_pids array of integers

      IDs of the submissions affected by the assignment.

  • if valid and format=csv
    • output string

      The atomic assignments rendered as CSV text, including a header row.

    • output_mimetype "text/csv"

      MIME type of output; always text/csv.

    • output_size integer

      Length of output in bytes.

  • if search
    • ids array of integers

      Array of submission IDs matching the search, in the order implied by the search.

    • groups array of tag_annotation objects

      Array of search annotations corresponding to the search, sourced from tag annotations, headings, or THEN searches. Often empty.

      + Show child attributes× Hide child attributes
      • groups[].annoid integer

        Unique identifier for this annotation within the tag. (When creating an annotation via POST /taganno, supply a string beginning with n, such as n1, in place of an ID.)

      • groups[].tag string

        The tag this annotation belongs to.

      • groups[].tagval number

        Tag value at which the annotation begins; the annotation labels submissions whose value for the tag is at least this and less than the next annotation's value.

      • groups[].legend string

        Display text (heading) for the group. Absent for a blank separator.

      • groups[].format integer

        Text format code for legend, present only when it is not the default format.

      • groups[].blank boolean

        Present and true when the annotation is a blank separator with no legend.

      • groups[].pos integer

        Position of the annotation in the associated submission list, as an index into the result. Present only when the annotation is returned alongside a search result.

      • groups[].session_title string

        Optional session-scheduling metadata: the session's title, used when the tag organizes a meeting agenda.

      • groups[].time string

        Optional session-scheduling metadata: the session's time.

      • groups[].location string

        Optional session-scheduling metadata: the session's location.

      • groups[].session_chair string

        Optional session-scheduling metadata: the session's chair.

    • search_params string

      URL-encoded string defining all relevant parameters for the search.

    • papers array of tag_response objects

      Refreshed tag and status information for each submission affected by the assignment, suitable for updating a displayed submission list.

      + Show child attributes× Hide child attributes
      • papers[].pid integer

        Submission ID

      • papers[].tags array of strings

        List of tag names with values

      • papers[].tags_edit_text string

        Textual representation for editing

      • papers[].tags_view_html string

        HTML representation for display

      • papers[].tag_decoration_html string

        HTML representation of badges and emoji

      • papers[].color_classes string

        Space-separated list of tag style classes

      • papers[].tags_conflicted array of strings

        List of tag names with values

      • papers[].color_classes_conflicted string

        Space-separated list of tag style classes

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/assigners

List assignment actions

List every assignment action understood by this HotCRP installation, with the parameters each action accepts. Use this to discover the action values and columns valid in an /assign request. The visible set of actions reflects the calling user’s privileges.

Returns

  • ok boolean
  • assigners array of assignment_action objects

    Available assignment actions

    + Show child attributes× Hide child attributes
    • assigners[].name string
    • assigners[].description string
    • assigners[].group string
    • assigners[].parameters array of view_option objects
      + Show child attributes× Hide child attributes
      • assigners[].parameters[].name string
      • assigners[].parameters[].type string
      • assigners[].parameters[].enum array of strings
      • assigners[].parameters[].lifted boolean
      • assigners[].parameters[].min integer
      • assigners[].parameters[].description string
      • assigners[].parameters[].default any
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/autoassignAdmin only

Compute automatic assignment

Compute an assignment automatically and, unless this is a dry run, perform it. This is an administrator operation.

Select the algorithm with the autoassigner parameter and the submissions to operate on with the q (and optional t) search parameters; /autoassigners lists the available algorithms and their parameters. Most algorithms take further settings through u, disjoint, and param.

The u, disjoint, and param parameters each accept multiple values. Supply them either as a JSON array or by repeating the parameter name with [] appended. For instance, u=%5B1,2%5D (a single u=[1,2]) and u%5B%5D=1&u%5B%5D=2 (separate u[]=1 and u[]=2) both pass the two values 1 and 2.

Autoassignment can be slow, so this endpoint may respond before the computation finishes. In that case the response uses HTTP status 202 Accepted and reports a job identifier (and job_url); poll the /job endpoint with that identifier to follow progress and retrieve the resulting assignment as CSV. When the computation finishes quickly enough, the result is returned directly instead, in the same shape as a completed /job response.

Parameters

  • autoassigner string

    Name of the autoassignment algorithm to run, as listed by /autoassigners.

  • q string

    Search selecting the submissions to assign.

  • t string default alladmin

    The scope of submissions to search, such as s (complete submissions) or all.

  • dry_run boolean

    If true, compute and validate the assignment and report errors, but do not perform it. The computed assignment is still returned as output.

  • minimal_dry_run boolean

    Like dry_run, but skips extra validation passes. For example, an ordinary dry run reports potential conflicts created by the assignment; a minimal dry run does not.

  • u array of strings

    PC members to consider for assignment; defaults to all PC members. Each value is a user search string—a user ID (1), an email (kohler@g.harvard.edu), or a tag (#heavy)—and may be prefixed with - to remove the matching users from the set.

  • disjoint array of strings

    Sets of users that must not both be assigned to the same submission. Each value is a comma-separated list of user search strings (IDs, emails, or tags).

  • param array of strings

    Additional algorithm-specific settings, each formatted NAME=VALUE. See /autoassigners for the settings each algorithm understands.

  • count integer

    Convenience setting for the common count algorithm parameter (for example, the number of reviews per submission); equivalent to passing count=N in param.

Returns

  • ok boolean
  • status "wait" | "run" | "done" | "failed"

    Job status, using the same vocabulary as /job. A successful response carries the computed assignment and reports done; a job that ran but failed reports failed.

  • dry_run boolean

    Present and true when the request was a dry run.

  • if status=wait|run
    • job string

      Identifier of the background job computing the assignment; present when the response is returned before completion.

    • job_url string

      Absolute URL of the /job endpoint for job.

  • if status=done
    • exit_status integer

      Process exit status of the completed computation; 0 on success.

    • assignment_pids array of integers

      IDs of the submissions the computed assignment affects.

    • output string

      The computed assignment as CSV text, ready to be replayed through /assign.

    • output_mimetype "text/csv"

      MIME type of output; always text/csv.

    • output_size integer

      Length of output in bytes.

    • output_at integer

      UNIX time the output was produced.

  • progress string

    Human-readable description of the current computation phase.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/autoassigners

List autoassignment actions

List every autoassignment algorithm understood by this HotCRP installation, with the parameters each one accepts. Use this to discover valid autoassigner values and param settings for /autoassign.

Returns

  • ok boolean
  • autoassigners array of autoassignment_action objects

    Available autoassignment algorithms

    + Show child attributes× Hide child attributes
    • autoassigners[].name string
    • autoassigners[].description string
    • autoassigners[].group string
    • autoassigners[].parameters array of view_option objects
      + Show child attributes× Hide child attributes
      • autoassigners[].parameters[].name string
      • autoassigners[].parameters[].type string
      • autoassigners[].parameters[].enum array of strings
      • autoassigners[].parameters[].lifted boolean
      • autoassigners[].parameters[].min integer
      • autoassigners[].parameters[].description string
      • autoassigners[].parameters[].default any
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Submission administration section

These endpoints set per-submission administrative assignments—the decision, the discussion lead, the shepherd, and the submission manager—one submission at a time, and move a review between rounds. They exist for the HotCRP web application’s convenience; each is a thin wrapper around the assignment machinery, so external integrations changing many submissions should prefer the general-purpose /assign endpoint.

The four assignment roles:

  • Decision—the submission’s accept/reject outcome.
  • Lead—the PC member who leads discussion of the submission.
  • Shepherd—the PC member who oversees the submission toward its final version.
  • Manager—a specific user responsible for administering the submission.

Each role has a matching GET (read the current value) and POST (change it). The POST endpoints require the appropriate administrative permission and report the updated value in the same shape as the corresponding GET. The GET endpoints are more widely readable: PC members and reviewers who may see the value can call them, subject to the conference’s visibility settings.

GET/{p}/decision

Retrieve submission decision

Return the decision recorded for submission p. decision is the decision’s numeric ID: 0 means no decision, a positive ID is an accept-class decision, and a negative ID is a non-accept decision (reject-class or indeterminate). decision_html is its configured name as HTML. editable is present when the caller may change the decision.

Parameters

  • p integer

    Submission ID

Returns

  • ok boolean
  • decision integer

    Decision ID; 0 means no decision.

  • decision_html string

    Decision name, as HTML.

  • editable boolean

    Present when the caller may change the decision.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/decisionAdmin only

Change submission decision

Set the decision for submission p. Supply decision as either a decision ID or a decision name. The caller’s conflicts are overridden. The response reports the new decision as decision GET does.

Parameters

  • decision string

    New decision, given as a decision ID or name. Body parameter

  • p integer

    Submission ID

Returns

  • ok boolean
  • decision integer

    Decision ID; 0 means no decision.

  • decision_html string

    Decision name, as HTML.

  • editable boolean

    Present when the caller may change the decision.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/{p}/lead

Retrieve submission discussion lead

Return the discussion lead of submission p. lead is the lead’s email, or none if unset; lead_html is their name as HTML (None when unset); color_classes carries any style classes implied by the lead’s user tags.

Parameters

  • p integer

    Submission ID

Returns

  • ok boolean
  • lead string

    Discussion lead’s email, or none.

  • lead_html string

    Discussion lead’s name as HTML, or None.

  • color_classes string

    Style classes from the lead’s user tags.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/leadAdmin only

Change submission discussion lead

Set the discussion lead of submission p. Supply lead as a PC member’s email, or none to clear it. The response reports the new lead as lead GET does.

Parameters

  • lead string

    New discussion lead’s email, or none to clear. Body parameter

  • p integer

    Submission ID

Returns

  • ok boolean
  • lead string

    Discussion lead’s email, or none.

  • lead_html string

    Discussion lead’s name as HTML, or None.

  • color_classes string

    Style classes from the lead’s user tags.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/{p}/manager

Retrieve submission administrator

Return the explicit administrator of submission p, if any. manager is their email, or none if unset; manager_html is their name as HTML (None when unset); color_classes carries any style classes implied by the manager’s user tags.

Parameters

  • p integer

    Submission ID

Returns

  • ok boolean
  • manager string

    Manager’s email, or none.

  • manager_html string

    Manager’s name as HTML, or None.

  • color_classes string

    Style classes from the manager’s user tags.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/managerSite admin only

Change submission administrator

Set an explicit administrator for submission p. Supply manager as a PC member’s email, or none to clear it. The response reports the new manager as manager GET does.

Parameters

  • manager string

    New manager’s email, or none to clear. Body parameter

  • p integer

    Submission ID

Returns

  • ok boolean
  • manager string

    Manager’s email, or none.

  • manager_html string

    Manager’s name as HTML, or None.

  • color_classes string

    Style classes from the administrator’s user tags.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/{p}/shepherd

Retrieve submission shepherd

Return the shepherd of submission p. shepherd is their email, or none if unset; shepherd_html is their name as HTML (None when unset); color_classes carries any style classes implied by the shepherd’s user tags.

Parameters

  • p integer

    Submission ID

Returns

  • ok boolean
  • shepherd string

    Shepherd’s email, or none.

  • shepherd_html string

    Shepherd’s name as HTML, or None.

  • color_classes string

    Style classes from the shepherd’s user tags.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/shepherdAdmin only

Change submission shepherd

Set the shepherd of submission p. Supply shepherd as a PC member’s email, or none to clear it. The response reports the new shepherd as shepherd GET does.

Parameters

  • shepherd string

    New shepherd’s email, or none to clear. Body parameter

  • p integer

    Submission ID

Returns

  • ok boolean
  • shepherd string

    Shepherd’s email, or none.

  • shepherd_html string

    Shepherd’s name as HTML, or None.

  • color_classes string

    Style classes from the shepherd’s user tags.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/reviewroundAdmin only

Change a review’s round

Move one review of submission p into a different review round. Restricted to submission administrators. Identify the review with r and the destination round by name in round.

Parameters

  • r integer or string

    Review to move, as a numeric review ID or ordinal.

  • round string

    Name of the destination review round.

  • p integer

    Submission ID

Returns

  • ok boolean
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Reviews section

These endpoints read reviews, manage review ratings and history, and drive the external-review request lifecycle (request, accept, decline, reassign).

Review objects

A review is returned as a JSON review object with an object field equal to "review". Every review object has a stable numeric rid (review ID) and the pid of the submission it belongs to. Beyond that core, a review object mixes three kinds of information, each gated by the caller’s permissions:

  • Metadatartype (review type, see below), round (review round name, if rounds are configured), status (lifecycle state, see below), version (a counter that increases on every edit), and ordinal (a display label like A, B, … assigned once the review becomes visible to authors/PC). Drafts have no ordinal and carry "draft": true. Booleans blind, subreview, and ghost may also appear.
  • Reviewer identityreviewer (display name) and reviewer_email, present only when the caller may see who wrote the review. On anonymous reviews these are omitted even when the review itself is visible.
  • Content—the review-form field values. Each configured review field is keyed by its field UID (an uppercase identifier such as S01 or overAllMerit’s UID), so field values never collide with the core fields above. Score fields render as their symbolic value, text fields as strings. Fields the caller may not see are omitted; their UIDs may be listed in hidden_fields.

Depending on the request, a review object can also include editable, my_review, my_request, review_token, modified_at/modified_at_text, ratings/user_rating, a review-specific message_list, and a format (the default text format for rendering field values).

Review types

rtype is an integer: 1 external, 2 PC, 3 secondary, 4 primary, 5 metareview. It is reported only to callers who may view review metadata.

Review status

status names the review’s position in its lifecycle:

  • empty—assigned but not started
  • acknowledged—the reviewer has accepted the assignment but not entered content
  • draft—content saved but not submitted
  • delivered—submitted (for subreviews, awaiting approval)
  • approved—a subreview approved by its primary reviewer
  • complete—finished and counted

Identifying a review

The r parameter selects a review on submission p. The read endpoints (review, reviewhistory, reviewrating) accept either a numeric review ID (4) or a display ordinal (A). The lifecycle endpoints (acceptreview, declinereview, claimreview) require a numeric review ID. The upload endpoint (review POST) also accepts new (require a freshly-created review) or an empty r (the caller’s own review, created if necessary).

To retrieve many reviews at once, use reviews, which selects reviews by submission search rather than by ID. To create or modify many reviews at once—including from an offline review form spanning several submissions—use reviews POST.

Response formats

The read endpoints review and reviews return JSON review objects by default, but a format parameter can request a plain-text rendering instead:

  • json (the default) returns review objects in HotCRP’s usual JSON envelope.
  • text returns the reviews as text, in the format produced by the “Reviews” download on a submission list.
  • form returns the reviews as offline review forms, the same format produced by the “Review forms” download—and accepted back by review POST and reviews POST. Fetching a form requires only permission to view the review; whether the form can be uploaded again is decided when it is uploaded.

reviews additionally accepts textzip and formzip, which return the same renderings packaged as a ZIP archive with one file per review, named for the review’s ordinal ID (for instance review18A.txt).

A non-json format returns the rendering as the raw response body, without any JSON wrapper: text/plain for text and form, application/zip for the ZIP formats. Errors are still reported as JSON objects with ok set to false, so check the response’s Content-Type or status code. An empty selection yields an empty download, just as format=json yields an empty reviews array.

A rendering has no message_list, so the search diagnostics format=json would report are carried into the download instead: text prefixes them, form includes them as ==-== comment lines, and the ZIP formats collect them in a README-warnings.txt member.

Renderings are conditionally requestable through ETag and If-None-Match. Date-based conditions are ignored, since a rendering depends on more than the reviews’ modification times.

Downloads

The download parameter controls delivery rather than rendering, and works the same way on paper and papers as it does here. download=1 returns the response as a file, and drops HotCRP’s JSON envelope in favor of the bare payload that the matching POST accepts—so a client can download an object, edit it, and upload it again:

  • GET /review with download=1 returns one review object, ready to POST to review.
  • GET /reviews with download=1 returns a bare array of review objects, ready to POST to reviews.

The non-json formats are already bare files, so they are attachments by default; download=0 requests them inline instead, which is useful for reading a review in a browser tab. Conversely format=json is enveloped and inline by default.

Because a bare payload has no message_list, download=1 discards search diagnostics. Errors still arrive in the usual envelope.

GET/{p}/review

Retrieve one review

Return a single review of submission p, selected by r. The review is returned in the review field as a review object. If the review does not exist the response is a 404; if it exists but the caller may not see it, a 403.

Parameters

  • p integer

    Submission ID

  • r integer or string

    Review to return, as a numeric review ID or a display ordinal (A).

  • format "json" | "text" | "form" default json

    How to render the review (see Response formats). json (the default) returns a review object; text returns the review as text and form as an offline review form, each as a text/plain body.

  • download boolean

    True delivers the response as a file. With format=json this also drops the response envelope, returning the bare review object (see Downloads); the other formats are files already, so download=0 makes them inline instead.

  • forceShow boolean default true

    Whether to override administrator conflicts. Defaults to true; set forceShow=false to respect conflicts instead.

Returns

  • ok boolean
  • if format=json and !download
    • review review object

      The requested review object.

      + Show child attributes× Hide child attributes
      • review.object "review"
      • review.pid integer

        Submission ID

      • review.rid integer or string

        Review ID

      • review.rtype integer

        Review type: 1 external, 2 PC, 3 secondary, 4 primary, 5 metareview

      • review.round string
      • review.status "empty" | "acknowledged" | "draft" | "delivered" | "approved" | "complete"
      • review.version integer
      • review.ordinal string
      • review.draft boolean
      • review.blind boolean
      • review.subreview boolean
      • review.ghost boolean
      • review.reviewer string
      • review.reviewer_email string

        Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

      • review.editable boolean
      • review.format integer
      • review.hidden_fields array of strings
      • review.review_token string
      • review.modified_at integer
      • review.modified_at_text string
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/review

Create or modify a review

Create or modify one review of submission p. The review being edited is selected by r:

  • a numeric review ID (4) or display ordinal (A) names an existing review;
  • new requires that a new review be created (the request fails if the reviewer already has a review);
  • an empty or absent r addresses the caller’s own review, creating it if necessary.

The modification is specified in JSON in any of these forms:

  1. In a JSON-formatted request parameter named json.
  2. As a JSON request body (content-type application/json).
  3. As an offline review form in plain text—either the whole request body (with content-type text/plain) or a file upload in a form POST. The text is parsed exactly as an offline form uploaded from the review page; only its sections for submission p are applied (any other sections are ignored).
  4. As a previously-uploaded JSON or text file, named by an upload token in the upload parameter.

In the JSON forms the modification is a review object. Absent fields are left unchanged; fields keyed by their UID set review-form content. Set submitted (or ready) to true to submit the review, or draft to true to save it without submitting. Submission administrators assigning a review on someone’s behalf may name the reviewer with email (plus given_name/family_name/affiliation for a new account), or, for data that does not name one, with the u request parameter.

A newly created review may be given a type with review_type (primary, secondary, metareview, pc, or external). A review defaults to an optional PC review, or external for a non-PC reviewer; requesting a type other than that default requires administrator privilege, and PC review types require a PC reviewer. review_type cannot change the type of an existing review. Creating a review of a specific type this way is equivalent to a review assignment.

The p request parameter is optional for the JSON and text forms: if it is unset, HotCRP uses the pid from the supplied data. If both p and a body pid are present they must match; likewise r and a body rid.

The API also supports form upload using the parameter conventions of the HotCRP web application. These conventions are subject to change, and third-party applications should prefer JSON.

To test a modification without saving, supply a dry_run=1 parameter. This will test the input but make no changes to the database.

Parameters

  • p integer

    Submission to review. Optional when the JSON or text data supplies a pid; if both are present they must match.

  • r integer or string

    Review to create or modify: new, a numeric review ID, a display ordinal, or empty for the caller’s own review.

  • u string

    Reviewer whose review to create or modify; defaults to the caller. Naming another user requires administrator privilege, and must agree with any reviewer named by r or by the data.

  • create_users boolean

    False refuses to create an account for a reviewer who does not have one. Defaults to true, except for offline review forms.

  • disable_users boolean Admin only

    True disables any newly-created users.

  • one of
    • application/json request body review object

      A review object sent as a raw JSON body.

      + Show child attributes× Hide child attributes
      • object "review"
      • pid integer

        Submission ID

      • rid integer or string

        Review ID

      • rtype integer

        Review type: 1 external, 2 PC, 3 secondary, 4 primary, 5 metareview

      • round string
      • status "empty" | "acknowledged" | "draft" | "delivered" | "approved" | "complete"
      • version integer
      • ordinal string
      • draft boolean
      • blind boolean
      • subreview boolean
      • ghost boolean
      • reviewer string
      • reviewer_email string

        Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

      • editable boolean
      • format integer
      • hidden_fields array of strings
      • review_token string
      • modified_at integer
      • modified_at_text string
    • text/plain request body string

      An offline review form, parsed as if uploaded from the review page.

    • json string

      A review object supplied in a json request parameter. Body parameter

    • upload string

      An upload token for a previously-uploaded JSON or text file.

  • dry_run boolean

    True checks input for errors, but does not save changes.

  • override boolean

    Administrators only: bypass deadline and other soft checks.

  • if_vtag_match integer

    Reject the modification unless the review’s current version tag equals this value. 0 matches only a review that does not yet exist, so r=new implies if_vtag_match=0.

  • if_unmodified_since string

    Reject the modification if the review has been modified since this time (a Unix timestamp, or 0).

  • notify boolean Admin only default true

    False disables email notifications.

Returns

  • ok boolean
  • dry_run boolean

    True for dry_run requests.

  • valid boolean

    True if and only if the modification was valid.

    For a non-dry-run request, "valid": true also means the database changes were committed.

  • change_list array of strings

    Names of the review fields the request attempted to modify.

    change_list reflects what the request attempted to change, so successful, failed, and dry-run requests can all return a nonempty list. If the review is new, the change_list begins with "new".

  • conflict boolean

    True when the modification was rejected by an if_vtag_match or if_unmodified_since edit-conflict check.

  • if valid and !dry_run
    • rid integer or string

      Numeric ID of the modified or newly created review.

    • review review object

      The modified review object.

      + Show child attributes× Hide child attributes
      • review.object "review"
      • review.pid integer

        Submission ID

      • review.rid integer or string

        Review ID

      • review.rtype integer

        Review type: 1 external, 2 PC, 3 secondary, 4 primary, 5 metareview

      • review.round string
      • review.status "empty" | "acknowledged" | "draft" | "delivered" | "approved" | "complete"
      • review.version integer
      • review.ordinal string
      • review.draft boolean
      • review.blind boolean
      • review.subreview boolean
      • review.ghost boolean
      • review.reviewer string
      • review.reviewer_email string

        Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

      • review.editable boolean
      • review.format integer
      • review.hidden_fields array of strings
      • review.review_token string
      • review.modified_at integer
      • review.modified_at_text string
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
DELETE/{p}/reviewAdmin only

Delete a review

Delete the review on submission p selected by r (a numeric review ID or a display ordinal; an empty r addresses the caller’s own review). Only administrators may delete reviews.

To test without deleting, supply dry_run=1. The edit-conflict preconditions if_vtag_match and if_unmodified_since behave as for POST /review.

Parameters

  • p integer

    Submission ID

  • r integer or string

    Review to delete: a numeric review ID or display ordinal, or empty for the caller’s own review.

  • dry_run boolean

    True checks the request but does not delete.

  • if_vtag_match integer

    Reject the delete unless the review’s current version tag equals this value.

  • if_unmodified_since string

    Reject the delete if the review has been modified since this time (a Unix timestamp, or 0).

  • forceShow boolean default true

    Whether to override administrator conflicts. Defaults to true; set forceShow=false to respect conflicts instead.

Returns

  • ok boolean
  • dry_run boolean

    True for dry_run requests.

  • valid boolean

    True if the delete was valid; for a non-dry-run request, it was also committed.

  • change_list array of strings

    Always ["delete"].

  • conflict boolean

    True when the delete was rejected by an if_vtag_match or if_unmodified_since edit-conflict check.

  • rid integer or string

    The deleted review’s ID.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/reviews

Retrieve multiple reviews

Return every review the caller can see on a set of submissions, in the reviews array. Select the submissions either with a search (q, optionally narrowed by t) or with a single submission p; supply exactly one of the two. Search diagnostics, if any, are reported in message_list.

The optional rq and u parameters filter which reviews are returned (not which submissions are searched). Supply at most one of them:

  • u returns only reviews written by the user with that email.
  • rq is a review search expression (the same syntax as a re: search), and returns only matching reviews.

reviewer is a search parameter, like q and t: it sets the perspective the submission search uses. It does not restrict which reviews are returned.

Parameters

  • q string

    Search selecting submissions whose reviews to return. Required unless p is given.

  • Search modifiers
    • t string default viewable

      Scope of search; defaults to the submissions the caller can view.

    • reviewer string

      Reviewer whose perspective the submission search uses.

  • p integer

    Return reviews of this single submission instead of running a search.

  • one of
    • rq string

      Review search expression limiting which reviews are returned.

    • u string

      Return only reviews written by this user.

  • format "json" | "text" | "form" | "textzip" | "formzip" default json

    How to render the matching reviews (see Response formats). json (the default) returns review objects; text and form return one text/plain body holding every review; textzip and formzip return an application/zip archive with one file per review.

  • download boolean

    True delivers the response as a file. With format=json this also drops the response envelope, returning a bare array of review objects (see Downloads); the other formats are files already, so download=0 makes them inline instead.

  • forceShow boolean default true

    Whether to override administrator conflicts. Defaults to true; set forceShow=false to respect conflicts instead.

Returns

  • ok boolean
  • if format=json and !download
    • reviews array of review objects

      Matching review objects.

      + Show child attributes× Hide child attributes
      • reviews[].object "review"
      • reviews[].pid integer

        Submission ID

      • reviews[].rid integer or string

        Review ID

      • reviews[].rtype integer

        Review type: 1 external, 2 PC, 3 secondary, 4 primary, 5 metareview

      • reviews[].round string
      • reviews[].status "empty" | "acknowledged" | "draft" | "delivered" | "approved" | "complete"
      • reviews[].version integer
      • reviews[].ordinal string
      • reviews[].draft boolean
      • reviews[].blind boolean
      • reviews[].subreview boolean
      • reviews[].ghost boolean
      • reviews[].reviewer string
      • reviews[].reviewer_email string

        Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

      • reviews[].editable boolean
      • reviews[].format integer
      • reviews[].hidden_fields array of strings
      • reviews[].review_token string
      • reviews[].modified_at integer
      • reviews[].modified_at_text string
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/reviews

Create or modify multiple reviews

Create or modify many reviews in one request. Unlike review POST, this endpoint is not tied to a single submission: each review names its own submission, and the batch may span any number of submissions. The modification may be supplied as:

  1. A JSON array of review objects (as a raw application/json body, in the json form field, or via an upload token). Each object names its submission with pid and, optionally, its review with rid ("rid": "new" requires a freshly-created review). An object may also carry its own if_vtag_match or if_unmodified_since precondition to guard that item’s edit (see review POST).
  2. An offline review form in plain text (a text/plain body, a file upload, or an upload token) containing one or more ==+== Paper sections. Every section is applied to the submission it names; there is no single-submission restriction.

Each review is processed independently and best-effort: one item’s failure does not roll back the others. The response reports one entry per input review, in order, in status_list; the parallel reviews array holds the resulting review object for each committed item (and null for items that were invalid or skipped). A dry_run=1 request validates every item but commits nothing.

The if_vtag_match and if_unmodified_since request parameters set batch-wide default preconditions, applied to every item that does not specify its own. In particular, if_vtag_match=0 requires that every saved review be newly created.

Parameters

  • one of
    • application/json request body array of review objects

      An array of review objects, each naming its submission with pid.

      + Show child attributes× Hide child attributes
      • [].object "review"
      • [].pid integer

        Submission ID

      • [].rid integer or string

        Review ID

      • [].rtype integer

        Review type: 1 external, 2 PC, 3 secondary, 4 primary, 5 metareview

      • [].round string
      • [].status "empty" | "acknowledged" | "draft" | "delivered" | "approved" | "complete"
      • [].version integer
      • [].ordinal string
      • [].draft boolean
      • [].blind boolean
      • [].subreview boolean
      • [].ghost boolean
      • [].reviewer string
      • [].reviewer_email string

        Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

      • [].editable boolean
      • [].format integer
      • [].hidden_fields array of strings
      • [].review_token string
      • [].modified_at integer
      • [].modified_at_text string
    • text/plain request body string

      An offline review form with one or more submission sections.

    • json string

      The review array supplied in a json request parameter. Body parameter

    • upload string

      An upload token for a previously-uploaded JSON or text file.

  • dry_run boolean

    True checks every item for errors, but does not save changes.

  • override boolean

    Administrators only: bypass deadline and other soft checks.

  • if_vtag_match integer

    Batch-wide default version-tag precondition, overridable by a review object’s own if_vtag_match. if_vtag_match=0 requires that every saved review be newly created.

  • if_unmodified_since string

    Batch-wide default edit-conflict precondition (a Unix timestamp, or 0), overridable by a review object’s own if_unmodified_since.

  • notify boolean Admin only default true

    False disables email notifications.

Returns

  • ok boolean
  • dry_run boolean

    True for dry_run requests.

  • status_list array of review_update_status objects

    Per-review results, one entry per input object (same length and order as the input). Entry i reports valid, change_list (beginning with "new" for a created review), the submission’s pid, the review’s rid (when saved), and conflict for an edit-conflict rejection.

    + Show child attributes× Hide child attributes
    • status_list[].valid boolean
    • status_list[].change_list array of strings
    • status_list[].pid integer
    • status_list[].rid integer or string

      Review ID

    • status_list[].conflict boolean

      True when this update was rejected by an edit-conflict check

  • if !dry_run
    • reviews array of review objects

      One entry per input review, in order: the resulting review object, or null for items that were not saved.

      + Show child attributes× Hide child attributes
      • reviews[].object "review"
      • reviews[].pid integer

        Submission ID

      • reviews[].rid integer or string

        Review ID

      • reviews[].rtype integer

        Review type: 1 external, 2 PC, 3 secondary, 4 primary, 5 metareview

      • reviews[].round string
      • reviews[].status "empty" | "acknowledged" | "draft" | "delivered" | "approved" | "complete"
      • reviews[].version integer
      • reviews[].ordinal string
      • reviews[].draft boolean
      • reviews[].blind boolean
      • reviews[].subreview boolean
      • reviews[].ghost boolean
      • reviews[].reviewer string
      • reviews[].reviewer_email string

        Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

      • reviews[].editable boolean
      • reviews[].format integer
      • reviews[].hidden_fields array of strings
      • reviews[].review_token string
      • reviews[].modified_at integer
      • reviews[].modified_at_text string
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/{p}/reviewhistory

Retrieve a review’s edit history

Return the successive versions of one review, newest first, in the versions array. Only the review’s own reviewer or a submission administrator may read its history.

Each entry is either a full review object (object: "review") or, for an incremental edit, a review delta (object: "review_delta") that records only the fields that changed in that version. Set expand=1 to receive every version as a full review object instead of a delta.

Parameters

  • r integer or string

    Review whose history to return, as a numeric review ID or ordinal.

  • p integer

    Submission ID

  • expand boolean

    If true, return each version as a complete review object rather than a delta.

Returns

  • ok boolean
  • pid integer

    Submission ID.

  • rid integer or string

    Review ID.

  • versions array of objects

    Review versions, newest first, each a review object or review delta.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/{p}/reviewrating

Retrieve review ratings

Return the ratings recorded for a review. Ratings let readers flag a review as helpful or as having problems.

ratings is the aggregate of all raters’ flags and is present only when the caller may view ratings. user_rating is the caller’s own rating and is present only when the caller is allowed to rate this review. Each value is a rating (see reviewrating POST for the vocabulary): the string none, a single flag, or an array of flags.

Parameters

  • r integer or string

    Review whose ratings to return.

  • p integer

    Submission ID

Returns

  • ok boolean
  • ratings string or array of strings

    Aggregate rating flags, or none.

  • user_rating string or array of strings

    The caller’s own rating, or none.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/reviewrating

Set a review rating

Record the caller’s rating of a review in user_rating, then return the updated ratings as for reviewrating GET.

A rating is a space-separated list of flags, the string none to clear the caller’s rating, or the equivalent integer bitmask. The flags are good, needswork, short, vague, narrow, disrespectful, and wrong. Administrators may pass clearall to remove every rating on the review.

Parameters

  • r integer or string

    Review to rate.

  • user_rating string

    New rating: a space-separated list of flags, none, or (administrators) clearall. Body parameter

  • p integer

    Submission ID

Returns

  • ok boolean
  • ratings string or array of strings

    Updated aggregate rating flags, or none.

  • user_rating string or array of strings

    The caller’s rating after the change, or none.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/requestreview

Request an external review

Ask a person identified by email to review submission p. Depending on conference policy and the caller’s role, this either assigns the review directly, files a proposal for an administrator to approve, or (for administrators requesting an anonymous reviewer) mints a review token. The action field reports which happened, and message_list carries the human-readable outcome.

If the person has no account yet, supply their name (given_name and family_name, or a combined name) and affiliation so an account can be created. Administrators can set override=1 to bypass conflict and prior-refusal checks that would otherwise block or downgrade the request to a proposal.

Parameters

  • email string

    Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses. Body parameter

  • p integer

    Submission ID

  • given_name string

    Reviewer’s first name (used when creating a new account). Body parameter

  • family_name string

    Reviewer’s last name. Body parameter

  • name string

    Reviewer’s full name, as an alternative to given_name/family_name. Body parameter

  • affiliation string

    Reviewer’s affiliation. Body parameter

  • round string

    Review round to assign the review to.

  • reason string

    Explanation included in the request email. Body parameter

  • override boolean

    Administrators only: bypass conflict and refusal checks. Body parameter

Returns

  • ok boolean
  • action "propose" | "request" | "token"

    What happened: request (review assigned), propose (proposal filed for administrator approval), or token (anonymous review token created).

  • if action=token
    • review_token string

      The review token, present only when action is token.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/acceptreview

Accept a review assignment

Accept the review-assignment invitation identified by r on submission p. This acknowledges the assignment (advancing it out of the empty state) and, if the review had previously been declined, reinstates it. The response’s review_site_relative is a site-relative URL for the review page.

Parameters

  • r integer or string

    Numeric review ID of the assignment to accept.

  • p integer

    Submission ID

Returns

  • ok boolean
  • action "accept"

    Always accept.

  • review_site_relative string

    Site-relative URL of the review.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/declinereview

Decline a review assignment

Decline the review identified by r on submission p, optionally recording a reason. A review that has already been submitted cannot be declined, nor can a primary or secondary review. The response’s review_site_relative is a site-relative URL for the review page.

Parameters

  • r integer or string

    Numeric review ID of the assignment to decline.

  • p integer

    Submission ID

  • reason string

    Optional explanation, shown to the requester. Body parameter

Returns

  • ok boolean
  • action "decline"

    Always decline.

  • review_site_relative string

    Site-relative URL of the review.

  • reason string

    The recorded reason, if any.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/claimreview

Reassign a review to another of your accounts

Move the unsubmitted review r on submission p from its current reviewer to the account identified by email. This is used to consolidate a review onto a different account you are currently signed in to in the same session; reassigning to an account you are not signed into is refused, as is reassigning a review that has already been submitted. The returned review_site_relative URL points at the review under the destination account (with a u/<index>/ prefix when that account differs from the current one).

Parameters

  • r integer or string

    Numeric review ID to reassign.

  • email string

    Email of the destination account; must be one you are signed in to this session.

  • p integer

    Submission ID

Returns

  • ok boolean
  • action "claim"

    Always claim.

  • review_site_relative string

    Site-relative URL of the review under the destination account.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/reviewtoken

List active review tokens

Return the review tokens currently active in the caller’s session, in the token array (encoded form). Review tokens grant the ability to edit specific anonymous reviews.

Returns

  • ok boolean
  • token array of strings

    Encoded review tokens active in the session.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/reviewtoken

Activate or clear review tokens

Set the review tokens active in the caller’s session and return the resulting list as for reviewtoken GET. Pass token as one or more tokens (whitespace/comma separated, or a JSON array of strings); each valid token is activated. Submitting with no usable tokens clears the active tokens.

For security, the session is locked out after five failed token attempts until the user signs out. Per-token results are reported in message_list.

Parameters

  • token string

    Review token(s) to activate, separated by whitespace or commas, or a JSON array. Omit (or pass none) to clear active tokens.

Returns

  • ok boolean
  • token array of strings

    Encoded review tokens active after the change.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Comments section

These endpoints fetch and modify submission comments.

Each comment has a visibility and a topic (which in the UI is called a thread). These values control who can see the comment.

The default comment visibility is "rev", which makes the comment visible to PC and external reviewers. Other values are "admin" (visible only to the submission’s managers and the comment author), "pc" (visible to PC reviewers, but not external reviewers), and "au" (visible to authors and reviewers).

The default comment topic is "rev", the review thread. Comments on the review thread are visible to users who can see reviews; if you can’t see reviews, you can’t see the review thread. Other comment topics are "paper", the submission thread (visible to anyone who can see the submission), and "dec", the decision thread (visible to users who can see the submission’s decision).

Comment objects

A comment is returned as a JSON comment object (the comment schema) with an object field equal to "comment". Every comment object also carries a numeric cid (comment ID) and the pid of the submission it belongs to. Beyond that, the fields present depend on the comment and on what the caller is allowed to see:

  • Placementvisibility and topic (see above), and ordinal (a display label like A1 or cA2, assigned once the comment is visible).
  • Contenttext (the comment body), format (the default text format for rendering it), tags, docs (attachments), and word_count. Content is omitted when the request passes content=false.
  • Authorshipauthor, author_email, by_author (true for a comment written by a submission author), and by_shepherd. On anonymized comments the identity fields are replaced by author_pseudonym/author_pseudonymous, or hidden entirely (author_hidden).
  • Statedraft (true for an unsubmitted response), blind, collapsed, response (the response round name, for response comments), modified_at (and modified_at_text), and review_token.
  • Permissionseditable (the caller may edit this comment), author_editable, and viewer_owned (the caller wrote it).

Identifying a comment

The c parameter selects a comment on submission p. It may be:

  • a numeric comment ID (for example 42);
  • new, to create a comment (POST only);
  • response, to select or create the unnamed response; or
  • a named response selector such as R2response (or, equivalently, set c=response and add a response=R2 parameter).

On POST /{p}/comment, omitting c defaults to new.

GET/{p}/comment

Retrieve comment

Return one comment of submission p, selected by c (see Identifying a comment). The comment is returned in the comment response field as a comment object; if it does not exist or the caller may not see it, an error is returned.

Parameters

  • c string

    The comment to return (a numeric comment ID or a response selector).

  • p integer

    Submission ID

  • response string

    Response-round name, when selecting a named response.

  • content boolean default true

    Set to false to omit comment content (text, docs) from the response, returning only metadata. Defaults to true.

Returns

  • ok boolean
  • comment comment object

    The requested comment.

    + Show child attributes× Hide child attributes
    • comment.object "comment"
    • comment.pid integer

      Submission ID

    • comment.cid integer
    • comment.ordinal string
    • comment.editable boolean
    • comment.viewer_owned boolean
    • comment.visibility "admin" | "pc" | "rev" | "au"
    • comment.topic "paper" | "rev" | "dec"
    • comment.blind boolean
    • comment.draft boolean
    • comment.collapsed boolean
    • comment.response string
    • comment.author_editable boolean
    • comment.by_author boolean
    • comment.by_shepherd boolean
    • comment.format integer
    • comment.review_token string
    • comment.tags string
    • comment.color_classes string

      Space-separated list of tag style classes

    • comment.author string
    • comment.author_email string

      Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

    • comment.author_hidden boolean
    • comment.author_pseudonym string
    • comment.author_pseudonymous boolean
    • comment.modified_at integer
    • comment.modified_at_obscured boolean
    • comment.modified_at_text string
    • comment.text string
    • comment.docs array
    • comment.word_count integer
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/comment

Create or modify comment

Create or modify a comment on submission p. Select the comment with c (see Identifying a comment): a numeric comment ID modifies or deletes an existing comment, new creates an ordinary comment, and response/R2response creates or updates a response.

The modification is specified in JSON in any of these forms:

  • In a json request parameter;
  • As an application/json request body;
  • As an application/zip archive whose data.json (or *-data.json) member is the object—other members may be referenced as attachments;
  • Or via an upload token in the upload request parameter, pointing at a previously-uploaded JSON or ZIP file.

The object’s cid (or response) selects the target comment; its text, visibility, topic, tags, blind, draft, and delete fields carry the update. (A one-element array holding a single object is also accepted.) The dry_run and if_unmodified_since controls are still read from the query string.

Attachments are given as a docs array, each entry either retaining an existing attachment by docid or uploading a new one: inline via content (raw text) or content_base64, or by content_file, which names a file in the ZIP archive or an uploaded file field in a json form request. An omitted docs key keeps the comment’s current attachments.

The API also supports form upload using the parameter conventions of the HotCRP web application (such as a text parameter for the comment body). These conventions are subject to change, and third-party applications should prefer JSON.

Saving with text empty and no attachments is refused for a new comment, but deletes an existing one (it is treated as delete=1).

To test a modification without saving, supply a dry_run=1 parameter. This will test the uploaded JSON but make no changes to the database.

Concurrency

An edit conflict returns "ok": false, "valid": false, and "conflict": true, with the comment field holding the server’s current version so the client can reconcile. Conflicts arise two ways:

  • Editing a response can collide with a concurrent edit automatically.
  • Any comment edit can be guarded explicitly with if_unmodified_since: pass the comment’s last-known modified_at, and the edit is rejected—with a message keyed to if_unmodified_since—if the comment has changed since. Pass if_unmodified_since=0 to require that the comment not already exist.

Attachments

Comment attachments may be uploaded as files (requiring a request body in multipart/form-data encoding), or using the upload API. To upload a single new attachment:

  • Set the attachment:1 body parameter to new
  • Either:
    • Set attachment:1:file as a uploaded file containing the relevant data
    • Or use the upload API to upload the file, and supply the upload token in the attachment:1:upload body parameter

To upload multiple attachments, number them sequentially (attachment:2, attachment:3, and so forth). To delete an existing attachment, supply its docid as an attachment:N parameter, and set attachment:N:delete to 1.

Parameters

  • p integer

    Submission ID

  • one of
    • application/json request body comment object

      A comment object supplied as a raw JSON body (see JSON upload).

      + Show child attributes× Hide child attributes
      • object "comment"
      • pid integer

        Submission ID

      • cid integer
      • ordinal string
      • editable boolean
      • viewer_owned boolean
      • visibility "admin" | "pc" | "rev" | "au"
      • topic "paper" | "rev" | "dec"
      • blind boolean
      • draft boolean
      • collapsed boolean
      • response string
      • author_editable boolean
      • by_author boolean
      • by_shepherd boolean
      • format integer
      • review_token string
      • tags string
      • color_classes string

        Space-separated list of tag style classes

      • author string
      • author_email string

        Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

      • author_hidden boolean
      • author_pseudonym string
      • author_pseudonymous boolean
      • modified_at integer
      • modified_at_obscured boolean
      • modified_at_text string
      • text string
      • docs array
      • word_count integer
    • application/zip request body binary

      A ZIP archive whose data.json is a comment object (see JSON upload).

    • json string

      A comment object supplied in a json request parameter. Body parameter

    • upload string

      An upload token for a previously-uploaded JSON or ZIP comment file.

  • c string default new

    The comment to create, modify, or delete. Defaults to new.

  • text string

    The comment body. Required unless delete=1. Body parameter

  • delete boolean

    Set to 1 to delete the selected comment.

  • visibility "admin" | "pc" | "rev" | "au" default rev

    Body parameter

  • topic "paper" | "rev" | "dec" default rev

    Body parameter

  • tags string

    Space-separated tags for the comment (ordinary comments only). Body parameter

  • response string

    Response-round name, when creating or editing a named response. Body parameter

  • draft boolean

    For responses, set to 1 to save as a draft instead of submitting. Body parameter

  • blind boolean

    Whether the comment is anonymous, where the configuration allows a choice. Body parameter

  • attachment string

    Structured attachment fields, attachment:<n> (see above). Body parameter

  • review_token string

    Review token authorizing the edit, when acting through one. Body parameter

  • if_unmodified_since string

    Reject the edit if the comment has been modified since this time (a Unix timestamp, matching the comment’s modified_at, or 0). See Concurrency.

  • dry_run boolean

    True checks input for errors, but does not save changes.

  • notify boolean Admin only default true

    False disables all email notifications for the change (mention and follower notifications). Ignored unless the caller administers the submission.

Returns

  • ok boolean
  • dry_run boolean

    True for dry_run requests.

  • valid boolean

    True if and only if the modification was valid.

    For a non-dry-run request, "valid": true also means the database changes were committed.

  • change_list array of strings

    Names of the fields the request attempted to change (text, visibility, tags, and/or attachments), or ["delete"] for a delete.

    Creating a comment reports an empty list, since a new comment is not a set of field changes. change_list reflects what the request attempted to change, so successful, failed, and dry-run requests can all return a nonempty list.

  • conflict boolean

    True when the edit was rejected by a concurrency check (see Concurrency).

  • cid integer or string

    The affected comment’s ID: the new ID for a created comment, or the existing ID for an edit. Absent when deleting, or on a dry-run creation.

  • comment comment object

    The saved comment, absent on delete or dry_run.

    + Show child attributes× Hide child attributes
    • comment.object "comment"
    • comment.pid integer

      Submission ID

    • comment.cid integer
    • comment.ordinal string
    • comment.editable boolean
    • comment.viewer_owned boolean
    • comment.visibility "admin" | "pc" | "rev" | "au"
    • comment.topic "paper" | "rev" | "dec"
    • comment.blind boolean
    • comment.draft boolean
    • comment.collapsed boolean
    • comment.response string
    • comment.author_editable boolean
    • comment.by_author boolean
    • comment.by_shepherd boolean
    • comment.format integer
    • comment.review_token string
    • comment.tags string
    • comment.color_classes string

      Space-separated list of tag style classes

    • comment.author string
    • comment.author_email string

      Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

    • comment.author_hidden boolean
    • comment.author_pseudonym string
    • comment.author_pseudonymous boolean
    • comment.modified_at integer
    • comment.modified_at_obscured boolean
    • comment.modified_at_text string
    • comment.text string
    • comment.docs array
    • comment.word_count integer
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
DELETE/{p}/comment

Delete comment

Delete the comment on submission p selected by c (a numeric comment ID or a response selector; see Identifying a comment). c must name an existing comment. This is equivalent to POST /{p}/comment with delete=1, and is subject to the same permission and concurrency rules.

Parameters

  • c string

    The comment to delete (a numeric comment ID or a response selector).

  • p integer

    Submission ID

  • response string

    Response-round name, when selecting a named response.

  • if_unmodified_since string

    Reject the delete if the comment has been modified since this time (a Unix timestamp, matching the comment’s modified_at, or 0).

  • dry_run boolean

    True checks the request but does not delete.

  • notify boolean Admin only default true

    False disables email notifications. Ignored unless the caller administers the submission.

Returns

  • ok boolean
  • dry_run boolean

    True for dry_run requests.

  • valid boolean

    True if the delete was valid; for a non-dry-run request, it was also committed.

  • change_list array of strings

    Always ["delete"].

  • conflict boolean

    True when the delete was rejected by a concurrency check (see Concurrency).

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/comments

Retrieve multiple comments

Retrieve every visible comment on the submissions matching a search.

The search is specified in the q parameter (and other search parameters, such as t). All comments the caller may see, across all matching submissions, are returned as an array of comment objects in the response field comments.

As a shorthand for a single submission, supply its ID in p instead of q; this returns that submission’s visible comments. Supplying both q and p is an error.

Parameters

  • q string

    The search expression.

  • p integer

    A single submission, as an alternative to q.

  • Search modifiers
    • t string default viewable

      The scope of submissions to search, such as s (complete submissions) or all.

  • content boolean default true

    Set to false to omit comment content (text, docs) from each returned comment, returning only metadata. Defaults to true.

  • warn_missing any

Returns

  • ok boolean
  • comments array of comment objects

    The matching comment objects.

    + Show child attributes× Hide child attributes
    • comments[].object "comment"
    • comments[].pid integer

      Submission ID

    • comments[].cid integer
    • comments[].ordinal string
    • comments[].editable boolean
    • comments[].viewer_owned boolean
    • comments[].visibility "admin" | "pc" | "rev" | "au"
    • comments[].topic "paper" | "rev" | "dec"
    • comments[].blind boolean
    • comments[].draft boolean
    • comments[].collapsed boolean
    • comments[].response string
    • comments[].author_editable boolean
    • comments[].by_author boolean
    • comments[].by_shepherd boolean
    • comments[].format integer
    • comments[].review_token string
    • comments[].tags string
    • comments[].color_classes string

      Space-separated list of tag style classes

    • comments[].author string
    • comments[].author_email string

      Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

    • comments[].author_hidden boolean
    • comments[].author_pseudonym string
    • comments[].author_pseudonymous boolean
    • comments[].modified_at integer
    • comments[].modified_at_obscured boolean
    • comments[].modified_at_text string
    • comments[].text string
    • comments[].docs array
    • comments[].word_count integer
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/comments

Create or modify multiple comments

Create, modify, or delete comments on multiple submissions in one request.

Unlike POST /{p}/comment, this endpoint is not scoped to a single submission: each comment object carries its own pid, so a batch may span submissions. There is no site-chair restriction—each comment is authorized independently, exactly as for POST /{p}/comment.

Modify comments independently

The request body is an array of comment objects (the same shape accepted by POST /{p}/comment), supplied as an application/json body, a json request parameter, an application/zip archive whose data.json holds the array, or an upload token. A ZIP or json-form request may carry attachment files shared across items: each object’s docs[].content_file resolves against the one archive.

Each object identifies its submission with pid and its target comment with cid (or response, or neither to create a new comment), plus the text, visibility, topic, tags, delete, … fields carrying the update. A per-object if_unmodified_since guards that item’s edit (the query-string if_unmodified_since is a batch-wide default).

Processing is best-effort: valid items are saved and invalid ones are reported without aborting the batch. The per-item results are returned in the status_list field, and the saved comments in comments—both the same length and order as the input. Messages in message_list carry a landmark field set to the integer index of the item they concern.

Parameters

  • one of
    • application/json request body array of comment objects

      An array of comment objects sent as a raw JSON body.

      + Show child attributes× Hide child attributes
      • [].object "comment"
      • [].pid integer

        Submission ID

      • [].cid integer
      • [].ordinal string
      • [].editable boolean
      • [].viewer_owned boolean
      • [].visibility "admin" | "pc" | "rev" | "au"
      • [].topic "paper" | "rev" | "dec"
      • [].blind boolean
      • [].draft boolean
      • [].collapsed boolean
      • [].response string
      • [].author_editable boolean
      • [].by_author boolean
      • [].by_shepherd boolean
      • [].format integer
      • [].review_token string
      • [].tags string
      • [].color_classes string

        Space-separated list of tag style classes

      • [].author string
      • [].author_email string

        Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

      • [].author_hidden boolean
      • [].author_pseudonym string
      • [].author_pseudonymous boolean
      • [].modified_at integer
      • [].modified_at_obscured boolean
      • [].modified_at_text string
      • [].text string
      • [].docs array
      • [].word_count integer
    • application/zip request body binary

      A ZIP archive whose data.json is an array of comment objects (and any files it references).

    • json string

      Comment objects supplied in a json request parameter. Body parameter

    • upload string

      An upload token for a previously-uploaded JSON or ZIP file.

  • dry_run boolean

    True checks input for errors, but does not save changes.

  • notify boolean default true

    False disables notifications; honored per item only when the caller administers that submission.

  • if_unmodified_since string

    A batch-wide default precondition, overridable by a comment object’s own if_unmodified_since.

Returns

  • ok boolean
  • dry_run boolean

    True for dry_run requests.

  • status_list array of comment_update_status objects

    Per-comment results, one entry per input object (same length and order as the input). Entry i reports valid, change_list, pid, and cid, plus conflict for an edit-conflict rejection.

    + Show child attributes× Hide child attributes
    • status_list[].valid boolean
    • status_list[].change_list array of strings
    • status_list[].pid integer
    • status_list[].cid integer

      The affected comment’s ID, when one was resolved

    • status_list[].conflict boolean

      True when this update was rejected by an if_unmodified_since edit-conflict check

  • comments array of comment objects

    The saved comments, one per input object (null for a failed item); omitted entirely for dry_run.

    + Show child attributes× Hide child attributes
    • comments[].object "comment"
    • comments[].pid integer

      Submission ID

    • comments[].cid integer
    • comments[].ordinal string
    • comments[].editable boolean
    • comments[].viewer_owned boolean
    • comments[].visibility "admin" | "pc" | "rev" | "au"
    • comments[].topic "paper" | "rev" | "dec"
    • comments[].blind boolean
    • comments[].draft boolean
    • comments[].collapsed boolean
    • comments[].response string
    • comments[].author_editable boolean
    • comments[].by_author boolean
    • comments[].by_shepherd boolean
    • comments[].format integer
    • comments[].review_token string
    • comments[].tags string
    • comments[].color_classes string

      Space-separated list of tag style classes

    • comments[].author string
    • comments[].author_email string

      Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses.

    • comments[].author_hidden boolean
    • comments[].author_pseudonym string
    • comments[].author_pseudonymous boolean
    • comments[].modified_at integer
    • comments[].modified_at_obscured boolean
    • comments[].modified_at_text string
    • comments[].text string
    • comments[].docs array
    • comments[].word_count integer
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/mentioncompletion

List mention completions

Return the people the caller may @-mention in a comment, in the format used by HotCRP’s autocompleter. The comment editor calls this when the user types @ to populate the mention dropdown.

Pass the submission in p; the candidate set—authors, reviewers, and PC members—depends on that submission and on what the caller is allowed to see. The list also reflects comment-mention visibility, so it never reveals a participant the caller could not otherwise discover.

Each entry in mentioncompletion is one candidate, given as an autocompleter item. The candidate’s display name appears in either s or sm1 (exactly one is present): s is offered immediately, while sm1 is offered only once the user has typed at least one character. PC members use sm1, so the entire committee is not listed unprompted; authors and other direct participants use s.

Parameters

  • p integer

    Submission whose participants may be mentioned.

Returns

  • ok boolean
  • mentioncompletion array of objects

    Mention candidates, as autocompleter items.

    Each item carries the candidate’s name in s or sm1 (see above) and may also include:

    • au (boolean)—true for the submission’s authors;
    • pri (integer)—match priority; 1 for non-PC candidates, ranking them above PC members;
    • admin (boolean)—true for PC members who administer the submission (or, when no submission is given, site chairs).
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Meeting tracker section

The meeting tracker coordinates a live PC meeting. While it runs, it broadcasts to PC members’ browsers which submission is currently under discussion, advancing through a shared list so everyone stays on the same page. These endpoints back HotCRP’s own meeting-tracker UI; they are not typically used by external integrations.

A tracker is identified by a numeric trackerid and walks an ordered list of submissions (a saved search / “hotlist”). More than one tracker can run at once. Trackers are controlled by track managers—chairs, and PC members who administer the relevant track. A tracker also has a visibility setting (the whole PC, or only holders of a given PC tag) and may hide conflicted submissions.

Polling and real-time updates

Clients keep in sync by polling trackerstatus, which is deliberately cheap: it returns only tracker_status (a compact token of the form <trackerid>@<position>, or off when nothing is running) and tracker_eventid (an integer that increases on every change). A client compares these against what it last saw and fetches full details only when they change. Where a Comet server is configured, its URL is reported as tracker_site and changes are pushed in real time instead of polled.

Tracker status fields

The track and trackerconfig responses report the current state through a common set of fields (each present only when applicable):

  • tracker—the full tracker state object: its trackerid, list position, the submissions in view (each with pid/title and the caller’s relationship to it), and, when several trackers run at once, a ts array of them. Present only when a tracker is running and visible to the caller.
  • tracker_status—the compact status token, as for trackerstatus.
  • tracker_eventid—the change counter, as for trackerstatus.
  • tracker_recent—the time of the most recent tracker update, when recent.
  • tracker_site—the Comet server URL, when one is configured.
  • now—the server’s current time (seconds, with a fractional part), for clock synchronization.
GET/trackerstatus

Poll meeting tracker status

Return a lightweight snapshot of the meeting tracker for change detection. This endpoint requires no authentication, so the poller (and read-only kiosk displays) can call it without a session.

Returns

  • ok boolean
  • tracker_status string

    Compact status token—<trackerid>@<position>, or off when no tracker is running.

  • tracker_eventid integer

    Counter that increases whenever the tracker changes.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/trackTrack manager only

Control the meeting tracker

Start, stop, or advance a tracker. Restricted to track managers. On success the response reports the updated tracker status (above).

The track parameter is the command:

  • stop—stop all trackers (chairs only).
  • <trackerid> <position>—point the tracker <trackerid> (or new to start one) at a list position.
  • <trackerid> stop—stop that one tracker.

The list the tracker walks is supplied in hotlist-info (an encoded submission list, the same form produced elsewhere in the UI). p and tracker_start_at optionally pin a specific submission and start time.

Parameters

  • track string

    Tracker command (see above).

  • hotlist-info string

    The submission list the tracker walks through, as a hotlist string (the same hotlist value returned by /search). Body parameter

  • p integer

    Submission to position the tracker at.

  • tracker_start_at integer

    Tracker start time.

Returns

  • ok boolean
  • tracker object

    Full tracker state, when a tracker is running and visible.

  • if tracker
    • tracker_status string

      Compact status token.

  • tracker_eventid integer

    Tracker change counter.

  • tracker_recent integer

    Time of the most recent tracker update.

  • tracker_site string

    Comet server URL, when configured.

  • if tracker
    • now number

      Server time, for clock synchronization.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/trackerconfigTrack manager only

Configure meeting trackers

Create, modify, or stop trackers and set their display options (name, logo, visibility, conflict hiding). Restricted to track managers. On success the response reports the updated tracker status (above), plus new_trackerid for any tracker newly created.

Trackers are configured as a numbered list of structured parameters tr/<n>/<field>, one group per tracker. The fields are:

  • id—the tracker’s ID, or new to create one.
  • name, logo—display label and logo.
  • visibility, visibility_type—who may see the tracker (the whole PC, or a specific PC tag).
  • hideconflicts—whether to hide conflicted submissions (paired with a has_tr/<n>/hideconflicts presence marker).
  • listinfo—the encoded submission list the tracker walks.
  • p—the submission to position at.
  • stop—stop this tracker.

Set stopall to stop every tracker at once. (A legacy flat parameter form, tr<n>-<field>, is also accepted and translated.)

Parameters

  • stopall boolean

    Stop all trackers. Body parameter

  • tr string

    Structured per-tracker configuration, tr/<n>/<field> (see above). Body parameter

  • has_tr string

    Presence markers for checkbox fields, has_tr/<n>/<field>. Body parameter

Returns

  • ok boolean
  • new_trackerid integer

    ID of a newly created tracker.

  • tracker object

    Full tracker state, when a tracker is running and visible.

  • if tracker
    • tracker_status string

      Compact status token.

  • tracker_eventid integer

    Tracker change counter.

  • tracker_recent integer

    Time of the most recent tracker update.

  • tracker_site string

    Comet server URL, when configured.

  • if tracker
    • now number

      Server time, for clock synchronization.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Users section

These endpoints look up individual users and list the program committee.

User identities are not generally browsable through the API: who you can see depends on your role. PC members can see other PC members; administrators can see more; and a site may optionally allow broader lookup. Accounts are identified by email throughout.

GET/user

Look up a user by email

Look up a single user by email. The lookup is prefix-oriented, which makes it suitable for type-ahead completion: it returns the account whose email is the closest match at or after the query, and match reports whether that email is an exact match for email (rather than merely the next account alphabetically).

When no account is found, the response is {"ok": true, "match": false} with no profile fields. When one is found, its email, given_name, family_name, and affiliation are returned (plus country and orcid when set). Visibility still applies—a caller who may only see PC members will only match PC members.

Give email as a full or nearly-complete address; very short, non-email queries return no match. Supplying a submission p together with potential_conflict=1 adds a potential_conflict description when the looked-up user has a possible conflict with that submission and the caller may see its authors.

Parameters

  • email string

    Email address to look up.

  • p integer

    Submission to check for a potential conflict with the user.

  • potential_conflict boolean

    With p, include a potential_conflict description if one applies.

Returns

  • ok boolean
  • match boolean

    True if an account exactly matching email was found.

  • email string

    The found account’s email.

  • if email
    • given_name string

      First (given) name.

    • family_name string

      Last (family) name.

    • affiliation string

      Affiliation.

    • country string

      Country code, when set.

    • orcid string

      ORCID iD, when set.

  • if email and potential_conflict
    • potential_conflict string

      HTML describing a potential conflict with submission p, when requested and applicable.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/pc

List the program committee

Return the program committee roster in pc, plus related metadata. Each pc entry describes one PC member; the detail included (such as email) depends on the caller’s permissions. sort is last when the roster is ordered by last name, and tags lists the user tags the caller may see.

When the request is made in the context of a submission the caller administers, p carries per-submission information keyed by submission ID—notably which PC members are assignable as reviewers.

Set ui=1 to receive the richer representation HotCRP’s own interface uses.

Parameters

  • ui boolean

    Return the representation used by the HotCRP web interface.

Returns

  • ok boolean
  • pc array of objects

    The PC members.

  • sort string

    last when the roster is sorted by last name.

  • tags array of strings

    User tags visible to the caller.

  • p object

    Per-submission assignment information, when the request has an administered submission in context.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/account

Retrieve account status

Return the status of a user account: its email, whether it is disabled, and whether it is a placeholder (a stub account created on someone’s behalf—for example a requested reviewer who has not yet signed in—that is not yet a fully activated account).

Name the account in email; me or the caller’s own email selects the caller. PC members may query other accounts by email; non-PC callers may query only their own.

Parameters

  • email string

    Account to inspect; me or the caller’s own email for self.

Returns

  • ok boolean
  • email string

    The account’s email.

  • disabled boolean

    Whether the account is disabled.

  • placeholder boolean

    Whether the account is an unactivated placeholder.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/accountSite admin only

Modify an account

Perform an administrative action on the account named by email. Chairs only. Exactly one action applies per request:

  • disable=1—disable the account, blocking sign-in. (You cannot disable your own account.)
  • enable=1—re-enable a disabled account.
  • sendinfo=1—email the account’s sign-in information to its owner.

The response reports the account’s resulting status, as for account GET.

Parameters

  • email string

    Account to modify; me or the caller’s own email for self.

  • disable boolean

    Disable the account.

  • enable boolean

    Re-enable the account.

  • sendinfo boolean

    Email account information to the owner.

Returns

  • ok boolean
  • email string

    The account’s email.

  • disabled boolean

    Whether the account is disabled.

  • placeholder boolean

    Whether the account is an unactivated placeholder.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Account section

These endpoints record small interactions a signed-in user has with their own account in the HotCRP interface: acknowledging a required clickthrough agreement, and dismissing a UI alert.

POST/clickthrough

Accept a clickthrough agreement

Record that the user has accepted a clickthrough agreement—terms that HotCRP can require someone to accept before proceeding, for example before entering reviews. Identify the agreement with clickthrough_id and set accept=1; acceptance is recorded only when accept is true. A successful call returns {"ok": true} with no additional fields.

The acceptance normally applies to the signed-in user. When the caller is acting through a review token rather than a signed-in account, supply the relevant submission in p so the acceptance is attributed to the associated reviewer.

Parameters

  • clickthrough_id string

    Identifier of the agreement being accepted. Body parameter

  • clickthrough_type string

    The agreement’s type. Body parameter

  • clickthrough_time integer

    Time of acceptance, as a UNIX timestamp. Body parameter

  • accept boolean

    Set true to record acceptance; nothing is recorded otherwise. Body parameter

  • p integer

    Submission to attribute the acceptance to when acting through a review token.

Returns

  • ok boolean
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/dismissalert

Dismiss an alert

Dismiss the alert named by alertid for the calling user, so the interface stops showing it. Alerts are the advisory banners HotCRP displays in its own UI.

Dismissing an unknown alert returns a 404; some alerts cannot be dismissed (a permission error), and alerts marked sensitive cannot be dismissed while acting as another user.

Parameters

  • alertid string

    Identifier of the alert to dismiss.

Returns

  • ok boolean
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Notifications section

These endpoints cover reviewing activity—the feed of recent reviews and comments—and the per-submission follow settings that determine who is emailed when that activity happens.

GET/events

Retrieve recent activity

Return a page of recent reviewing activity visible to the caller—newly submitted reviews and comments—most recent first. Available to reviewers.

Results are paged in blocks of up to 10 events. Each request returns events strictly before the from timestamp (a UNIX time, defaulting to now). To fetch the next, older page, pass the response’s to value as the next request’s from; the more flag indicates whether further events exist before to.

Each entry in rows is a pre-rendered HTML activity item used by HotCRP’s feed UI. As with other HTML the API returns, its markup and class names are internal to HotCRP and may change; applications needing structured data should read reviews and comments through their own endpoints.

Parameters

  • from integer

    Return events before this UNIX time. Defaults to now.

Returns

  • ok boolean
  • from integer

    The cutoff time this page was computed from.

  • to integer

    Cutoff for the next (older) page; pass it back as from.

  • rows array of strings

    Recent activity entries, as HTML, newest first.

  • more boolean

    Whether more events exist before to.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/{p}/follow

Set submission follow status

Set whether a user follows submission p. A follower is emailed when reviews or comments are added to the submission. By default the setting applies to the caller; administrators may change another user’s setting with u.

Parameters

  • following boolean

    Whether the user should follow the submission. Body parameter

  • p integer

    Submission ID

  • u string

    User whose setting to change (email or user ID); administrators only. Defaults to the caller.

Returns

  • ok boolean
  • following boolean

    The follow state after the change.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Task management section

The /job endpoint monitors long-running jobs.

GET/job

Monitor job

The /job endpoint monitors the progress of long-running jobs and can return their output upon completion. Jobs represent HotCRP tasks that take too long for a single API request; requests such as /autoassign may start a job and return its unique identifier.

The status response field is "wait" before the job starts, "run" while it is running, "done" after completion, and "failed" when it is known to have failed. The update_at field gives the UNIX timestamp of the most recent job update; if it’s far in the past but status is still "run", the job has likely crashed. Specific jobs may return other response fields, such as a progress string that describes the current phase of job execution.

Some jobs produce output when they complete. When status is "done" and output is present, the response’s output_mimetype and output_size fields describe this output. To fetch the output itself, supply an output parameter. If output=string, the output field contains the output as a string. If output=json, the output field contains the output as parsed JSON. If output=body, then the output is returned as the response body with the proper Content-Type header. /job?output=body understands range requests.

A /job response uses HTTP response status code 202 Accepted for in-progress jobs, and 200 OK for completed or failed jobs. However, if a job’s output is incompatible with the requested format (output=string but the output is not UTF-8 encoded, output=json but the output is not JSON, or output=body but the job failed), then the response uses status code 409 Conflict.

Parameters

  • job string

    Job ID

  • output "string" | "json" | "body"

    Format for job output

Returns

  • ok boolean
  • status "wait" | "run" | "done" | "failed"

    Status of a long-running job. wait before the job starts, run while it is running, done after successful completion, and failed when it is known to have failed.

  • update_at integer

    UNIX time job was last updated

  • if status=done and output
    • output any

      Job output

  • if status=done
    • output_mimetype string

      Output mimetype

    • output_size integer

      Length of output

    • output_at integer

      UNIX time job output was set

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
Additional values may be returned.

Settings section

These endpoints retrieve and modify site settings, and provide supporting information for the settings UI: machine-readable descriptions of every setting, libraries of ready-made submission- and review-field templates, and mail-template expansion.

GET/settingsSite admin only

Retrieve site settings

This endpoint returns a JSON object defining all site settings. The result can be used to examine settings offline, change settings otherwise unavailable through the settings UI, or transfer settings to another site.

The filter and exclude parameters can filter the returned settings to a subset. For example, when exporting one site’s settings for use by another, you might set exclude to #identity OR #deadline; this excludes settings relevant to a conference’s identity (conference_name, site_contact_email, etc.) or deadlines.

Parameters

  • reset boolean
  • filter string

    Search expression defining settings to include

  • exclude string

    Search expression defining settings to exclude

  • download boolean

    If true, download the settings object (without ok wrapper)

Returns

  • ok boolean
  • settings object
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/settingsSite admin only

Modify site settings

This endpoint modifies site settings according to a JSON object. This object may define a full complement of settings or a subset. It may be provided as a request body with type application/json, or as a body parameter with name settings.

The filter and exclude parameters can filter the modifications that are applied; for example, uploading a settings object with filter set to #rf will only change settings relevant to the review form.

For more information on JSON settings, see Help > Advanced settings.

Parameters

  • dry_run boolean

    True checks input for errors, but does not save changes

  • reset boolean
  • filter string

    Search expression defining settings to include

  • exclude string

    Search expression defining settings to exclude

  • settings object

    Settings to change Body parameter

  • filename string

    File name for settings object (for error messages)

Returns

  • ok boolean
  • valid boolean

    True if the modification was valid

  • change_list array of strings

    List of modified top-level settings

  • settings object

    New settings

  • dry_run boolean

    True for dry-run requests

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/settingdescriptionsSite admin only

Describe site settings

Return machine-readable descriptions of the site’s settings. The result is a schema for the JSON objects accepted and returned by /settings: use it to discover the available setting names, learn each setting’s type, and present settings in a user interface.

Each entry in setting_descriptions describes one top-level setting. The set mirrors the settings the caller is allowed to view.

Returns

  • ok boolean
  • setting_descriptions array of setting_description objects

    One descriptor per top-level setting.

    + Show child attributes× Hide child attributes
    • setting_descriptions[].name string

      Setting name: the key used for this setting in /settings JSON.

    • setting_descriptions[].type string

      Value type of the setting, such as string, int, checkbox, object, or oblist (a list of objects).

    • setting_descriptions[].subtype string

      Optional refinement of type.

    • setting_descriptions[].title string

      Human-readable title (formatted text).

    • setting_descriptions[].summary string

      Short one-line summary (formatted text).

    • setting_descriptions[].description string

      Longer explanation of the setting (formatted text).

    • setting_descriptions[].values array

      Example or permitted values for the setting.

    • setting_descriptions[].default_value any

      The setting’s default value, in the same form /settings returns. Present only on top-level descriptors, not on components members.

    • setting_descriptions[].components array of setting_description objects

      For object and oblist settings, descriptors for the member fields, in order. Each member has the same shape as a top-level descriptor (without default_value).

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/submissionfieldlibrarySite admin only

List sample submission fields

Return a library of ready-made submission fields that an administrator can add to the site. HotCRP’s settings UI uses this to offer sample fields (for example, “Supplemental material” or a “Subject area” selector) and to enumerate the submission-field types this installation supports. Chair only.

Returns

  • ok boolean
  • samples array of objects

    Sample submission-field configurations, each a settings object ready to merge into /settings.

  • types array of objects

    The submission-field types available on this site.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/reviewfieldlibrarySite admin only

List sample review fields

Return a library of ready-made review fields, the review-form counterpart of /submissionfieldlibrary. samples holds sample review-field configurations and types enumerates the review-field types this installation supports. Chair only.

Returns

  • ok boolean
  • samples array of objects

    Sample review-field configurations, each a settings object ready to merge into /settings.

  • types array of objects

    The review-field types available on this site.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/mailtext

Expand a mail template

Render a mail template—or arbitrary mail text—using HotCRP’s keyword substitution, returning the resulting subject and body. The web application’s mail composer uses this to preview templates before sending. Available to PC members and administrators.

There are three ways to call it:

  1. Supply a template name to expand a stored mail template. The response contains the expanded subject and body, plus, when the template defines them, a default recipient set (recipients, recipient_description) and a default search collection (t).
  2. Supply template=all to expand every template the caller may use; the results are returned in the templates array.
  3. Supply literal text, subject, and/or body strings to expand arbitrary content instead of a stored template. Each supplied field is returned expanded.

Keyword substitution can be personalized. Identify a recipient with email (and optionally given_name, family_name, and affiliation), a submission with p, and one of its reviews with r; reason fills the %REASON% keyword and width sets the line-wrapping width.

Parameters

  • template string

    Name of the template to expand, or all to expand every available template.

  • p integer

    Submission supplying context for paper-specific keywords.

  • r integer or string

    Review of p supplying context for review-specific keywords.

  • Recipient identity
    • email string

      Recipient email address, for personalized expansion.

    • given_name string

      Recipient given (first) name.

    • family_name string

      Recipient family (last) name.

    • affiliation string

      Recipient affiliation.

  • reason string

    Text substituted for the %REASON% keyword.

  • width integer

    Line-wrapping width; defaults to no wrapping.

  • Literal content
    • text string

      Literal mail text to expand instead of a stored template.

    • subject string

      Literal subject line to expand.

    • body string

      Literal mail body to expand.

Returns

  • ok boolean
  • subject string

    Expanded subject line.

  • body string

    Expanded mail body.

  • recipients string

    Default recipient set for the expanded template.

  • recipient_description string

    Human-readable description of recipients.

  • t string

    Default search collection associated with the template.

  • if text
    • text string

      Expanded text, when text was supplied.

  • if template=all
    • templates array of objects

      Present for template=all; one entry per template, each with name, title, expanded subject and body, and optional recipients, recipient_description, and t.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/namedsearch

List named searches

Return the named (saved) searches available to the caller, in the searches array. PC members only. Each entry has a name and its search string q, and may also carry a display hint, a description, and editable (whether the caller may change it). Per-search diagnostics, if any, appear in message_list.

Returns

  • ok boolean
  • searches array of named_search objects

    The caller’s viewable named searches.

    + Show child attributes× Hide child attributes
    • searches[].name string

      The search’s name.

    • searches[].q string

      The search query string.

    • searches[].display string

      Display options applied when the search is shown, as show:/sort: terms.

    • searches[].description string

      Human-readable description of the search.

    • searches[].editable boolean

      Present and true when the caller may modify or delete the search.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/namedsearch

Save named searches

Create, rename, retarget, or delete named searches. Changes are supplied as a numbered list of structured parameters named_search/<n>/<field>, one group per search; the fields are id (the existing search’s name, or new to create one), name, search (the search string), highlight, description, and delete. On success the updated list is returned exactly as namedsearch GET returns it.

Parameters

  • named_search string

    Structured per-search fields, named_search/<n>/<field> (see above). Body parameter

Returns

  • ok boolean
  • searches array of named_search objects

    The named searches after the change.

    + Show child attributes× Hide child attributes
    • searches[].name string

      The search’s name.

    • searches[].q string

      The search query string.

    • searches[].display string

      Display options applied when the search is shown, as show:/sort: terms.

    • searches[].description string

      Human-readable description of the search.

    • searches[].editable boolean

      Present and true when the caller may modify or delete the search.

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/namedformula

List named formulas

Return the conference’s named formulas in formulas. A named formula gives a reusable name to a formula expression, so it can be referenced from searches, scoring, and graphs. Each entry has a name, its expression, and an id; editable marks formulas the caller may change, and a per-formula message_list reports any problems evaluating the expression.

Returns

  • ok boolean
  • formulas array of named_formula objects

    The conference’s named formulas.

    + Show child attributes× Hide child attributes
    • formulas[].name string

      The formula’s name.

    • formulas[].expression string

      The formula expression.

    • formulas[].id integer

      Internal formula ID.

    • formulas[].editable boolean

      Present and true when the caller may modify or delete the formula.

    • formulas[].message_list array of message objects

      Diagnostics produced when evaluating the expression; present only when the formula has problems.

      + Show child attributes× Hide child attributes
      • formulas[].message_list[].status integer
      • formulas[].message_list[].field string
      • formulas[].message_list[].message string
      • formulas[].message_list[].context array
      • formulas[].message_list[].pos1 integer
      • formulas[].message_list[].pos2 integer
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/namedformula

Save named formulas

Create, edit, or delete named formulas. Available to PC members. Changes are supplied as a numbered list of structured parameters formula/<n>/<field>, one group per formula; the fields are id (the existing formula’s ID, or new), name, expression, and delete. On success the updated list is returned as namedformula GET returns it.

Parameters

  • formula string

    Structured per-formula fields, formula/<n>/<field> (see above). Body parameter

Returns

  • ok boolean
  • formulas array of named_formula objects

    The named formulas after the change.

    + Show child attributes× Hide child attributes
    • formulas[].name string

      The formula’s name.

    • formulas[].expression string

      The formula expression.

    • formulas[].id integer

      Internal formula ID.

    • formulas[].editable boolean

      Present and true when the caller may modify or delete the formula.

    • formulas[].message_list array of message objects

      Diagnostics produced when evaluating the expression; present only when the formula has problems.

      + Show child attributes× Hide child attributes
      • formulas[].message_list[].status integer
      • formulas[].message_list[].field string
      • formulas[].message_list[].message string
      • formulas[].message_list[].context array
      • formulas[].message_list[].pos1 integer
      • formulas[].message_list[].pos2 integer
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer

Session section

These endpoints manage the session that ties a sequence of API calls to a single browser or client: the CSRF token required to modify state, lightweight per-user UI preferences, deferred (“stashed”) user messages, reauthentication for sensitive operations, and a few diagnostic/reporting endpoints used by the HotCRP Javascript client. They are mostly intended for HotCRP’s own front-end code rather than third-party integrations, but they are documented here because understanding them clarifies how HotCRP authenticates and protects write requests.

CSRF tokens and post

HotCRP protects state-changing requests against cross-site request forgery. Browser-driven POST requests (those authenticated with a session cookie rather than a bearer token) must include a CSRF token in the post parameter. The token is obtained from GET /session, where it is returned as the sessioninfo.postvalue field; send that value back as the post query or body parameter on later POST requests in the same session.

CSRF protection does not apply to requests authenticated with an Authorization: bearer token, so external applications using API tokens never need the post parameter. See Authentication.

Session cookies

The session endpoints create a session cookie if one is not already present (this is how a fresh client obtains a CSRF token). Some endpoints in this group are explicitly callable by unauthenticated clients and across origins; where that matters it is noted on the individual endpoint, since such endpoints take care never to leak user information or CSRF tokens to other origins.

GET/whoami

Identify the current user

Report which user the request authenticates as. This is the simplest way to confirm that a set of credentials (a session cookie or an Authorization: bearer token) is valid and to learn whom it identifies.

The response includes the user’s email, given_name, family_name, and affiliation. When the user holds any conference roles, a roles array lists them, drawn from:

  • chair—a conference chair
  • pc—a program committee member; this is also present for chairs
  • sysadmin—a system administrator
  • manager—an administrator of some submissions who is not a full chair
  • author—an author or contact of at least one submission
  • reviewer—assigned at least one review

Returns

  • ok boolean
  • email string

    Email of the signed-in user

  • given_name string

    First (given) name

  • family_name string

    Last (family) name

  • affiliation string

    Affiliation

  • roles array of enums

    Conference roles held by the user

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
GET/session

Retrieve session information and CSRF token

Open a session (setting a session cookie if necessary) and return information about the current client, including the CSRF token needed to authorize cookie-authenticated POST requests.

This endpoint may be called by unauthenticated clients, and—unlike most of the API—it permits cross-origin (CORS) requests. To avoid leaking sensitive data to other origins, a cross-origin or cross-site request receives only {"ok": true}, with no sessioninfo. The full response is returned only for same-origin requests (as determined by the Sec-Fetch-Site request header, or by the absence of an Origin header on clients that do not send Sec-Fetch-Site).

The returned sessioninfo.postvalue is the CSRF token; see CSRF tokens and post above. The email and uid fields are present only when a user is signed in.

Returns

  • ok boolean
  • sessioninfo sessioninfo object

    Session information, omitted for cross-origin requests

    + Show child attributes× Hide child attributes
    • sessioninfo.postvalue string

      CSRF token. Supply this value in the post parameter to authorize cookie-authenticated POST requests.

    • sessioninfo.email string

      Email of the signed-in user; omitted when no user is signed in

    • sessioninfo.uid integer

      User ID of the signed-in user; omitted when no user is signed in

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/session

Update session UI preferences

Update a small set of per-user, per-session UI preferences and return the same session information as GET /session. This endpoint backs the HotCRP Javascript client’s “remember my view” behavior; the preferences it manages are cosmetic (folding state, which columns are shown in paper and user lists, score-sort order) and have no effect on submissions, reviews, or permissions. Unlike GET /session, it requires an authenticated, same-origin request with a valid post CSRF token.

The preferences to change are encoded in the v parameter as a whitespace-separated list of assignments. Each assignment has the form name[.key][=value]:

  • name selects the preference. Recognized names include foldpaper, foldpscollab, foldhomeactivity (folding toggles), pldisplay, pfdisplay, uldisplay (which columns/fields are shown in the paper list, paper form, and user list), and scoresort / ulscoresort (score sort order).
  • .key is an optional sub-selector. For the *display preferences it names the column or field being shown or hidden; for foldpaper it names an individual foldable region.
  • =value is an optional integer. 0 (or an omitted value) means “unfold” or “show”; a nonzero value means “fold” or “hide”.

For example, v=pldisplay.authors=0 foldhomeactivity=1 reveals the authors column in the paper list and folds the home-page activity region.

Parsing is best-effort: every recognized assignment is applied, and any component that is not understood is silently ignored. A successful request returns ok of true whether or not every component was recognized.

Parameters

  • v string

    Whitespace-separated list of preference assignments

Returns

  • ok boolean
  • sessioninfo sessioninfo object

    Updated session information

    + Show child attributes× Hide child attributes
    • sessioninfo.postvalue string

      CSRF token. Supply this value in the post parameter to authorize cookie-authenticated POST requests.

    • sessioninfo.email string

      Email of the signed-in user; omitted when no user is signed in

    • sessioninfo.uid integer

      User ID of the signed-in user; omitted when no user is signed in

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/reauth

Reconfirm the signed-in user’s identity

Reconfirm the credentials of the already-signed-in user. HotCRP requires reauthentication before especially sensitive actions (for example, changing account email or managing security settings); a successful call records a recent-authentication marker in the session so those actions can proceed.

Supply the user’s password. On success the response has ok of true; if the password is wrong, the response is an error (ok is false) whose message_list describes the problem.

The reason parameter is a short tag describing why reauthentication is being requested (HotCRP uses values such as manageemail); it can influence how long the resulting confirmation remains valid. confirm=1 requests an explicit success message in message_list on success. The email and totpcode parameters support alternate verification flows (such as time-based one-time passwords) where those are configured.

Parameters

  • confirm boolean

    If true, include a success message on success

  • reason string

    Short tag describing why reauthentication is requested Body parameter

  • email string

    Email address. Most HotCRP email addresses are ordinary email addresses, but some are markers for anonymous or pseudonymous users (for example anonymous, anonymous1, …). These markers are accepted and returned wherever an email is expected, even though they are not valid email addresses. Body parameter

  • password string

    Account password Body parameter

  • totpcode string

    Time-based one-time password code, if applicable Body parameter

Returns

  • ok boolean
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/stashmessages

Stash messages for later display

Store a list of user-facing messages on the server, keyed by a short identifier, so they can be displayed after a navigation or redirect. This supports the common pattern where a POST handler wants to show a confirmation after redirecting the browser to a new page: the handler stashes the messages, then includes the returned identifier in the redirect URL, and the destination page retrieves and shows them.

The message_list parameter is a JSON-encoded string representing an array of message objects. Each object has an integer status and a string message. status ranges from -5 to 3 (see the message schema); common values are 0 (plain), 1 (warning), 2 (error), and -3 (success). For example:

message_list=[{"status":2,"message":"<0>Submission failed"},{"status":-3,"message":"<0>Draft saved"}]

Message text must carry a HotCRP format sigil. Only plain-text (<0>), Markdown (<1>), and sanitized HTML (<5>) formats are accepted; entries in other formats, or with out-of-range status, are silently dropped. An empty message is allowed and produces a status-only entry.

The response smsg field is the identifier under which the messages were stashed; pass it to the page that should display them. If no usable messages were supplied, smsg is false. To append to an existing stash, supply its identifier in the smsg request parameter (a 10–64 character alphanumeric string); otherwise the server generates a fresh identifier.

Parameters

  • message_list string

    JSON-encoded array of {status, message} objects Body parameter

  • smsg string

    Existing stash identifier to append to Body parameter

Returns

  • ok boolean
  • smsg string or boolean

    Stash identifier, or false if nothing was stashed

  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/oauthregister

OAuth 2.0 dynamic client registration endpoint

Register a new OAuth client and obtain its credentials, following RFC 7591 (OAuth 2.0 Dynamic Client Registration). Like POST /oauthtoken, this is a standards-based endpoint used when HotCRP acts as an OAuth/OpenID Connect identity provider; it does not use HotCRP’s usual {"ok": ...} response envelope. It is available only when the conference enables OAuth clients and dynamic registration; otherwise it returns 404.

The request body is a JSON object (content type application/json). The only required member is redirect_uris, a non-empty array of redirect URI strings; every URI is validated. Optional members include client_name (a human-readable name) and scope (a space-separated scope string). Registration succeeds only when the request matches a dynamic-client template configured for the conference (in particular, the requested redirect_uris must be permitted by that template).

On success the response has HTTP status 201 and a JSON body describing the newly registered client: client_id, client_secret, client_id_issued_at, client_secret_expires_at (Unix timestamps), the accepted redirect_uris, the supported grant_types (authorization_code and refresh_token), and the token_endpoint_auth_method (client_secret_basic). Use the returned client_id and client_secret with POST /oauthtoken. On failure the response has a 4xx status and a body of the form {"error": "invalid_request"} (other values include invalid_redirect_uri and invalid_client_metadata).

POST/oauthtoken

OAuth 2.0 / OpenID Connect token endpoint

Exchange an authorization grant for tokens, following RFC 6749. This is a standards-based OAuth/OpenID Connect token endpoint used when HotCRP acts as an identity provider for a registered client application; it is not a general HotCRP API call and does not use HotCRP’s usual {"ok": ...} response envelope.

The request is form-encoded. Send grant_type=authorization_code with the code returned from the authorization step (plus redirect_uri and, for PKCE clients, code_verifier), or grant_type=refresh_token with a refresh_token. The client authenticates either with HTTP Basic authentication (Authorization: Basic) or by sending client_id and client_secret as body parameters. An optional scope parameter narrows the requested scopes.

On success the response is a standard OAuth token object containing access_token, token_type (Bearer), expires_in, refresh_token, scope, and—when the openid scope was granted—an id_token JWT. On failure the response carries an HTTP 4xx status and a body of the form {"error": "invalid_grant"} (other values include invalid_request, invalid_client, invalid_scope, and unsupported_grant_type).

Parameters

  • grant_type string

    authorization_code or refresh_token Body parameter

  • code string

    Authorization code (for authorization_code grants) Body parameter

  • redirect_uri string

    Redirect URI matching the authorization request Body parameter

  • code_verifier string

    PKCE code verifier Body parameter

  • refresh_token string

    Refresh token (for refresh_token grants) Body parameter

  • client_id string

    Client identifier Body parameter

  • client_secret string

    Client secret Body parameter

  • scope string

    Space-separated requested scopes Body parameter

POST/jserror

Report a client-side Javascript error

Record a Javascript error encountered by the HotCRP front-end in the server error log. This is a diagnostic endpoint used by HotCRP’s own client code; it may be called by unauthenticated clients. It always returns {"ok": true}, even when the report is ignored.

Reports are filtered: errors that appear to originate in browser extensions, or that come from known crawlers, are accepted but not logged.

Parameters

  • error string

    Error message Body parameter

  • url string

    URL where the error occurred Body parameter

  • lineno integer

    Line number Body parameter

  • colno integer

    Column number Body parameter

  • stack string

    Stack trace Body parameter

  • detail string

    Additional detail (truncated when logged) Body parameter

Returns

  • ok boolean
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer
POST/cspreport

Report a Content Security Policy violation

Receive a Content Security Policy violation report and append it to the server’s CSP report log. This endpoint is the target of a report-to/report-uri directive; it is called directly by the browser, may be unauthenticated, and is not intended for manual use.

The request body is JSON sent with content type application/reports+json, application/csp-report, or application/json; it may be a single report object or an array of them. Reports attributed to browser extensions are discarded. A well-formed request returns {"ok": true}. A malformed body returns a 400 error; if the report cannot be persisted (the log is missing, unwritable, or over quota) the response is a 5xx error.

Returns

  • ok boolean
  • message_list array of message objects

    Diagnostic list

    + Show child attributes× Hide child attributes
    • message_list[].status integer
    • message_list[].field string
    • message_list[].message string
    • message_list[].context array
    • message_list[].pos1 integer
    • message_list[].pos2 integer