PaperFox API
Read your conferences, submissions, reviews, assignments, and registrations from your own scripts and integrations.
The PaperFox API lets chairs and authors read conference data programmatically — sync submissions into a proceedings pipeline, pull review progress into a dashboard, or check the status of your own papers from a script.
Every endpoint lives under /api/v1. The API is read-mostly: everything is
readable, and you can create submissions (see Creating a submission).
Get an API key
- Go to Settings → API Keys.
- Click Create API Key, give it a name, and pick Read only or Read and write.
- Copy the key. It is shown exactly once — store it in a secret manager. If you lose it, revoke the key and create a new one.
Keys look like pfx_live_.... Treat one like a password: it acts with your
roles in every conference you belong to.
Never commit a key, put it in a browser, or paste it into a support ticket. If a key leaks, revoke it immediately from Settings → API Keys — revocation takes effect on the very next request.
Make your first request
Authenticate with a bearer token. Start with /me — it tells you who the key
belongs to and which conferences and roles it can reach.
curl https://www.paperfox.ai/api/v1/me \
-H "Authorization: Bearer $PAPERFOX_API_KEY"{
"user": { "id": "…", "email": "you@paperfox.ai", "name": "Your Name" },
"key": { "prefix": "pfx_live_a1b2", "scopes": ["read"], "conference": null },
"conferences": [
{ "slug": "icai2027", "name": "…", "roles": ["chair"] }
]
}Then list submissions for a conference you chair:
curl "https://www.paperfox.ai/api/v1/submissions?conference=icai2027&status=ACCEPTED" \
-H "Authorization: Bearer $PAPERFOX_API_KEY"What a key can see
A key never grants more than you already have. On every request PaperFox re-derives your roles for the conference in question, so:
- Conference chairs see every submission, review, and registration in the conference.
- Track chairs see submissions and reviews in the tracks they manage.
- Authors see their own submissions (matched across all your verified email addresses).
- Reviewers see their own assignments.
Blind-review rules apply exactly as they do in the web app: on a single- or double-blind track, reviewer identities are hidden from authors, and reviews stay invisible until the chair releases them.
If you revoke someone's chair role, their keys lose that access on the next call — nothing is baked into the key.
Two extra guardrails when creating a key:
- Scopes —
readorread and write. Creating a submission requires the write scope; a read-only key gets a403. - Conference restriction — a key can be limited to a single conference, so a script for one event can't touch another.
Creating a submission
POST /api/v1/submissions creates a paper. It enforces exactly the same rules as
the web form — submission window, late pass, conference quota — and validates
data against the track's submission form. You must be listed among the
authors; you can't submit on someone else's behalf via the API.
An Idempotency-Key header is required. If your connection drops on a slow
create and you retry, the key is what stops you from ending up with two papers.
Send any unique string (a UUID is ideal) and reuse it for retries of that same
request.
curl -X POST https://www.paperfox.ai/api/v1/submissions \
-H "Authorization: Bearer $PAPERFOX_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"conference": "icai2027",
"track": "main",
"authors": [
{ "firstName": "Alex", "lastName": "Sample", "email": "you@paperfox.ai",
"affiliation": "Sample University", "countryRegion": "US",
"isCorresponding": true }
],
"data": {
"title": "A Paper Title",
"abstract": "…",
"keywords": ["one", "two"]
}
}'data holds the track's submission-form fields keyed by field id — including any
the chair defined. If it doesn't satisfy that form you get a 422 listing each
problem in errors[].
File uploads are not supported over the API yet. The default submission
form leaves the file field optional, so this endpoint works as-is for most
tracks. But if a chair has made the file field required, an API request
cannot satisfy it and will keep returning 422 — submit through the web form
for that track. Tell us if you need this and we'll add an upload endpoint.
Retry behavior:
| Situation | Result |
|---|---|
| Same key, same body | The first response is replayed (Idempotent-Replay: true). No second paper. |
| Same key, different body | 409 — that key is pinned to its original request. Use a new key. |
| Same key while the first call is still running | 409 — retry shortly. |
No Idempotency-Key | 400 |
Pagination
List endpoints are cursor-paginated. Pass limit (1–100, default 25) and follow
nextCursor until hasMore is false. Cursors are opaque — don't construct them.
{
"data": [ /* … */ ],
"hasMore": true,
"nextCursor": "eyJ0IjoiMjAyNi0wNy0wNlQwMDowMDowMC4wMDBaIiwiaWQiOiJhYmMifQ"
}curl "https://www.paperfox.ai/api/v1/submissions?conference=icai2027&limit=50&cursor=$NEXT_CURSOR" \
-H "Authorization: Bearer $PAPERFOX_API_KEY"Rate limits
Limits are per user (creating more keys does not raise them).
| Tier | Per minute | Per day |
|---|---|---|
| Default | 120 | 20,000 |
| Elevated | 600 | 100,000 |
Every response carries the current budget:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1783290000
RateLimit: "default";r=87;t=22Exceeding a limit returns 429 with a Retry-After header (in seconds). Honor
it — or back off exponentially with jitter.
Errors
Errors follow RFC 9457 and are
served as application/problem+json. Branch on code, not on the human-readable
detail.
{
"type": "https://paperfox.ai/problems/validation-error",
"title": "Validation Error",
"status": 422,
"detail": "1 field failed validation.",
"code": "validation_error",
"errors": [
{ "param": "conference", "code": "invalid_type", "message": "Required" }
]
}| Status | code | Meaning |
|---|---|---|
| 401 | invalid_api_key | Missing, malformed, revoked, or expired key |
| 403 | forbidden / insufficient_scope | Key lacks the role, scope, or conference |
| 404 | not_found | No such resource — or you have no access to it |
| 422 | validation_error | Bad query parameters (see errors[]) |
| 429 | rate_limited | Slow down; see Retry-After |
A 404 is also what you get for a resource you may not see, so the API never confirms that something exists to someone who shouldn't know.
Versioning
The API is versioned in the path (/api/v1). These changes can happen at any
time and are not breaking, so write tolerant clients:
- new endpoints and new optional query parameters
- new fields in responses — ignore unknown fields
- new enum members — tolerate values you don't recognize
Anything genuinely breaking would ship as /api/v2. If an endpoint is ever
retired, it will carry Deprecation and Sunset headers with at least 12 months'
notice.
Full details in the compatibility policy. Every change is recorded in the changelog.
OpenAPI spec
The full machine-readable contract is published at
/api/v1/openapi.json (OpenAPI 3.1). Import it into
Postman or Insomnia, or generate a typed client from it.
Browse the endpoints in the API Reference.