Skip to content
View as MarkdownOpen this guide as plain text

Use the Citation API

Use workspace scoped API keys, durable jobs and prepaid credits to work with documents, sources, writing, Check and files.

Connect to the APILink to Connect to the API

Use https://citation.co/api/v1 for API v1. The existing automation API at /api/automation/v1, MCP and CLI keep their own contracts and credentials.

  1. Open API in settings. Select one workspace and the permissions your application needs.
  2. Create a key and copy its secret immediately. Store it on your server. The secret is only shown when created or rotated.
  3. Send Authorization: Bearer with the key. Call /me to verify the workspace, expiry and permissions.
Verify your key
export CITATION_API_BASE=https://citation.co/api/v1
curl "$CITATION_API_BASE/me" \
  -H "Authorization: Bearer $CITATION_API_KEY"

Permissions and accessLink to Permissions and access

Keys belong to one workspace and expire after 1 to 90 days. Rotation invalidates the previous secret while retaining the connection and its request history. Revocation stops future access. Membership and document roles are checked again when work starts, before changes are saved and before files are downloaded.

ScopeUse
documents:readRead documents and history
documents:writeCreate, update, trash, restore and apply edits
sources:readRead sources, resolve new sources and format references
sources:writeSave and update source records
exports:readExport and download document files
ai:writeUse the Write tools
checks:writeStart Check and review findings
files:writeUpload and import files
sharing:readRead document access
sharing:writeManage document guests, invitations and public links
comments:readRead comments
comments:writeAdd and resolve comments
webhooks:writeManage webhook subscriptions and deliveries

Document operations require documents:read. Source and paid document operations also need sources:read. Applying edits requires documents:write. Only a document owner can manage sharing. An editor can resolve their own comments, and an owner can resolve any comment. API permissions never grant a broader workspace role.

Documents, sources and citationsLink to Documents, sources and citations

MethodPathPurpose
GET, POST/documentsList, search or create
GET, PATCH, DELETE/documents/{id}Read, update or move to trash
POST/documents/{id}/restoreRestore from trash
GET/documents/{id}/historyRead version history
GET, POST/documents/{id}/sourcesRead or save source records
GET, PATCH/documents/{id}/sources/{source_id}Read or update a source
POST/documents/{id}/citationsInsert a citation at an editor position
GET/documents/{id}/bibliographyRender saved references
GET/documents/{id}/citation-checkInspect citation links
GET, PATCH/documents/{id}/writing-contextRead or save a brief, outline, style and document memory
Create a document
curl "$CITATION_API_BASE/documents" \
  -H "Authorization: Bearer $CITATION_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $REQUEST_ID" \
  -d '{"title":"Reading notes","text":"A draft to review.","style":"apa"}'

Read the document before editing. Send its version with PATCH. Use content for Citation editor JSON to preserve marks and citation nodes. Sending text replaces rich content. Change style through the same version checked update. Source updates use the source version returned by its read endpoint. Existing source records are not removed by document edits.

List endpoints return items, has_more and next_cursor. Send next_cursor as after with the same query. The default limit is 20 and the maximum is 50. Document text is returned in pages of up to 20000 characters with next_offset. Bibliography pages use offset and snapshot_id, which detects changed documents or sources.

Durable jobs and safe applicationLink to Durable jobs and safe application

POST pathOperationCredits
/writeWrite using Citation standard model selection1
/sources/resolveFind sources by DOI, ISBN, URL or text query1
/importsImport a draft or PDF source1
/exportsExport a document or bibliography1
/checksReview up to 5000 words5

Paid operations require max_credits. The API rejects a request when its fixed price exceeds that ceiling. An accepted operation returns HTTP 202 with job_id, status and credits. Poll GET /jobs/{job_id} until status is succeeded, failed or cancelled. POST /jobs/{job_id}/cancel requests cancellation. A running provider call may finish before cancellation takes effect.

Request a writing proposal
{
  "document_id": "DOCUMENT_ID",
  "version": 3,
  "intent": "rewrite",
  "message": "Improve clarity and preserve the evidence.",
  "selection": "The exact passage to revise.",
  "source_ids": [],
  "apply": false,
  "max_credits": 1
}

Write supports brief, outline, section, sources, synthesis, argument, style, rewrite, memory, feedback and completion. Source based writing needs selected saved sources with readable excerpts or linked text. Section writing needs a saved outline. AI accepts up to 10000 document words and 12 selected sources. Generated output is limited to 2000 words. Limits are rejected explicitly.

Write and Check return proposals by default. Set apply to true with the starting document version to request supported edits in the same job. result.application reports applied, no_changes, conflict, proposed or not_applied. A version conflict preserves the generated proposal and does not incur a second charge. You can apply a completed writing proposal through POST /jobs/{job_id}/apply with the current version.

Check accepts up to 5000 words and 20 saved sources. GET /jobs/{job_id}/review returns progress and findings. PATCH /jobs/{job_id}/findings/{finding_id} accepts decision: apply or dismiss and a document version. Web similarity findings, changed evidence and suggestions that change meaning require manual review. Sources are never added automatically. Public web similarity does not establish originality across every private or published collection.

Inspect the Check run status, checked_words and source coverage as well as the job status. A partial Check can contain valid results while some text, sources or web checks remain unavailable. Valid partial results use the fixed Check price. An entirely failed review releases its credits. Provider safety limits are separate from product allowances and can delay or limit a review.

Credits and paymentsLink to Credits and payments

Credit purchases are currently unavailable. The package price is 100 credits for $10 USD. Operations that use credits require an existing balance. Credits are whole numbers, belong to the account and are shared across its API keys. Purchased credits never expire. There is no API subscription or automatic refill. Free and Pro product allowances are not used for API operations.

GET /pricing returns the current fixed tariff. GET /balance returns balance, reserved and available. GET /ledger returns purchase, reserve, spend, release, refund and dispute movements. Basic document reads and edits, source records and citation formatting are free. Rate, data size and storage limits still apply.

Credits are reserved atomically when a job is accepted. A valid result settles the charge. A valid empty source search is a completed operation. A job that fails or is cancelled before producing a result releases its reservation. A valid proposal remains chargeable when it cannot be applied. Retrying the same operation does not charge again.

When credit purchases are available, API settings opens Stripe Checkout. Verified payment events add credits once. The return page cannot add credit. Refunds and disputes adjust the related purchase; spent credits can leave a negative balance that must be covered before another paid job starts.

Files and storageLink to Files and storage

Upload DOCX, TXT or PDF bytes to POST /files with Content-Type: application/octet-stream, X-File-Name (URL encoded), X-Content-SHA256 and Idempotency-Key. The SHA256 is the lowercase hexadecimal digest of the file. Import uploads are limited to 4 MB. Send the returned id as file_id to /imports.

DOCX and TXT create drafts using the existing document parser and validation. PDF imports return source metadata and warnings for review. Exports accept docx, pdf, txt, bibtex or ris, a document_id, its version and max_credits. Bibliography formats require saved sources. Export uses one consistent document and source snapshot.

The completed job returns file_id and a download_url. Download with the same authorization header. Files are private and the current workspace and document access are checked again. The existing account storage limit applies to uploads and generated files. DELETE /files/{file_id} removes a file and releases its storage.

Sharing and commentsLink to Sharing and comments

Use /documents/{id}/sharing to read access or set a public link with enabled: true or false. POST /documents/{id}/invitations with email and role creates a private invitation URL. The API returns the URL for your application to deliver; it does not send an email automatically. DELETE the invitation ID to revoke it. PATCH /documents/{id}/members changes an existing document guest to editor, viewer or remove. Workspace membership is outside API v1.

Read or add comments at /documents/{id}/comments. POST /documents/{id}/comments/{comment_id}/resolve resolves an allowed comment. Keep comment bodies below 10000 characters.

Retries, errors and limitsLink to Retries, errors and limits

Every mutation requires Idempotency-Key. Reuse the same key and identical method, path, parameters and body after an uncertain result. Changed input returns 409. A key rotation preserves this history. Generate a new idempotency key for a new intended operation.

Error response
{
  "error": {
    "code": "VERSION_CONFLICT",
    "message": "The document changed. Read its current version before applying changes.",
    "retryable": false,
    "request_id": "REQUEST_UUID"
  }
}
StatusAction
400, 415, 422Correct the request or unsupported content.
401, 403, 404Verify the key, permissions and current access.
402Add API credits.
409Read current data and resolve the conflict.
413Reduce the document or file size.
429Wait for Retry-After seconds.
408, 502, 503Retry only when retryable is true, using the same idempotency key.

Each response carries X-Request-ID. Limits are 120 requests per key per minute and 300 per account. Each account can run two paid jobs and queue 20. Keep a bounded retry budget. The clients retry at most twice by default, preserve mutation keys and do not silently submit extra paid jobs.

The shared editor permits up to 10000 documents per workspace, 1000 sources per document and 2000 editor mutations per key per day. Editor changes and export snapshots support up to 100000 text characters and 1 MB of editor JSON. Citation formatting and exports support up to 200 saved sources. Reading editor JSON is limited to 200 KB; use include_content: false and text pagination for larger reads. Buying credits does not raise these data limits.

Events and webhooksLink to Events and webhooks

GET /events returns document.created, document.updated, source.created, source.updated and job status events. Store the cursor only after your downstream action succeeds. Payloads contain identifiers, not document text.

POST /webhooks accepts a public HTTPS url and an events array. Copy the returned secret at creation. Private addresses and redirects are blocked. GET /webhooks/{id}/deliveries shows attempts and response status. Failed deliveries retry with increasing delay, up to six attempts. Receivers must deduplicate X-Citation-Event-ID.

Verify X-Citation-Signature against HMAC SHA256(secret, timestamp + "." + rawBody). The header uses v1= followed by the hexadecimal digest. Read timestamp from X-Citation-Timestamp, reject timestamps outside a short tolerance, compare signatures in constant time, then parse the body. Return a successful status only after recording the event.

TypeScript and Python clientsLink to TypeScript and Python clients

The repository includes packages/citation-api and packages/citation-python. Both use types generated from the same validation schemas and provide safe retries, pagination, file upload, downloads and job polling. Packages have not been published to a registry. The export examples below require an existing API credit balance.

TypeScript workflow
const api = new Citation(process.env.CITATION_API_KEY, {
  baseUrl: "https://citation.co/api/v1"
});
const draft = await api.createDocument({title: "Reading notes", text: "A draft."});
const job = await api.exportDocument({
  document_id: draft.document_id, version: draft.version,
  format: "docx", max_credits: 1
});
const result = await api.wait(job.job_id);
const bytes = await api.download(result.result.file_id);
Python workflow
api = Citation(api_key, "https://citation.co/api/v1")
draft = api.create_document({"title": "Reading notes", "text": "A draft."})
job = api.export_document({
    "document_id": draft["document_id"], "version": draft["version"],
    "format": "docx", "max_credits": 1
})
result = api.wait(job["job_id"])
content = api.download(result["result"]["file_id"])

The examples/research files in each package demonstrate document creation, a saved source, citation insertion, AI revision, Check and export. Set CITATION_API_KEY and CITATION_API_BASE before running them. Keep returned job IDs after a client timeout so you can resume polling.