CiteWise API reference
Build citation quality control into your research workflow. Resolve metadata, inspect provider evidence, propose corrections, render styles, and process large batches through one workspace-aware API.
GET STARTED
Make your first request
API keys are shown once at creation time. Keep them on your server and send them in the X-API-Key header; never expose a key in browser code.
curl https://api.citewise.dev/api/v1/citations/parse \\
-X POST \\
-H "X-API-Key: cw_live_your_key" \\
-H "Content-Type: application/json" \\
-d '{
"reference": "Vaswani A. Attention Is All You Need. 2017.",
"async": false
}'Authentication at a glance
API integrations: use a paid workspace API key in X-API-Key.
Console and web sessions: use a Clerk JWT in Authorization: Bearer ....
Workspace isolation: every resource is scoped to the authenticated workspace.
REQUEST CONVENTIONS
Consistent primitives
All timestamps are UTC ISO-8601 strings. IDs are UUIDs. JSON field names are camelCase.
Content type
JSON or multipartSend application/json for JSON endpoints. Use multipart/form-data for citation import uploads.
Traceability
X-Trace-IdOptional request ID. The response exposes the trace ID for support.
Pagination
page + sizeBatch item pages are zero-indexed; size is capped at 200.
Retries
Retry-AfterHonor this header for rate, concurrency, and system-busy responses.
CITATION API
Verify and enrich references
Parse first, then use the returned citationId for evidence, corrections, and rendering. Every citation endpoint is workspace-scoped.
/api/v1/citations/parseParse and verify a reference
Normalizes input, resolves candidate records across scholarly providers, fuses field-level evidence, stores the citation, and returns a verification report.
Request body
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
| reference | string | required | Raw citation, DOI, URL, or incomplete reference. Maximum 8,000 characters. |
| async | boolean | optional | Reserved for asynchronous processing. Defaults to false; send false for the immediate parse response. |
{
"reference": "Vaswani, A. Attention Is All You Need. 2017.",
"async": false
}Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| citationId | UUID | - | Identifier for follow-up citation endpoints. |
| status | string | - | Verification decision. |
| confidence | number | - | Overall confidence from 0 to 1. |
| citation | CitationDto | - | Full persisted citation, metadata fields, verification details, and APA rendering. |
{
"citationId": "7d9a7d7e-9df7-4c84-9f2a-2f4a7d9c4b11",
"status": "VERIFIED",
"confidence": 0.99,
"citation": {
"id": "7d9a7d7e-9df7-4c84-9f2a-2f4a7d9c4b11",
"status": "VERIFIED",
"confidence": 0.99,
"title": { "fieldName": "title", "value": "Attention Is All You Need", "confidence": 0.99, "algorithm": "PROVIDER_FUSION", "evidence": [] },
"verification": { "rawReference": "Vaswani A. ...", "normalizedReference": "Vaswani A... 2017", "matchScore": 0.99, "candidateMargin": 0.42, "features": {}, "matchedProviders": ["CROSSREF", "OPENALEX"], "contradictions": [], "candidates": [], "providerDiagnostics": [] },
"renderedApa": "Vaswani, A., ... (2017).",
"createdAt": "2026-01-15T10:20:30Z"
}
}The current synchronous contract returns a complete result. The async field is accepted for forward compatibility; use citation jobs for durable asynchronous batch processing.
/api/v1/citationsList recent citations
Returns recent citations for the authenticated workspace, ordered by the workspace history service.
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| [] | CitationSummary[] | - | Each summary contains id, rawReference, status, confidence, renderedApa, and createdAt. |
[
{
"id": "7d9a7d7e-9df7-4c84-9f2a-2f4a7d9c4b11",
"rawReference": "Vaswani A. Attention Is All You Need. 2017.",
"status": "VERIFIED",
"confidence": 0.99,
"renderedApa": "Vaswani, A., ... (2017).",
"createdAt": "2026-01-15T10:20:30Z"
}
]/api/v1/citations/{id}Get a citation
Retrieves the complete stored citation report by ID, including resolved fields, evidence references, candidates, contradictions, and APA rendering.
Path and query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | required | Citation ID returned by parse or list citations. |
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | - | Persisted citation identifier. |
| status | string | - | VERIFIED, PROBABLY_VERIFIED, AMBIGUOUS, CONFLICTING_METADATA, NOT_FOUND, INSUFFICIENT_EVIDENCE, or POSSIBLE_HALLUCINATION. |
| confidence | number | - | Overall confidence from 0 to 1. |
| title ... publisher | FieldDto | null | - | Resolved metadata fields. Each field includes value, confidence, algorithm, and evidence. |
| verification | VerificationDto | - | Normalized input, match scores, provider diagnostics, contradictions, and candidate matches. |
| renderedApa | string | null | - | APA rendering generated during verification. |
| createdAt | ISO-8601 timestamp | - | Creation time in UTC. |
{
"id": "7d9a7d7e-9df7-4c84-9f2a-2f4a7d9c4b11",
"status": "VERIFIED",
"confidence": 0.99,
"title": { "fieldName": "title", "value": "Attention Is All You Need", "confidence": 0.99 },
"verification": { "matchedProviders": ["CROSSREF"], "contradictions": [], "candidates": [] },
"renderedApa": "Vaswani, A., ... (2017).",
"createdAt": "2026-01-15T10:20:30Z"
}/api/v1/citations/{id}/evidenceGet field evidence
Returns provider evidence grouped by metadata field. Use this to show why a field was accepted or investigate a contradiction.
Path and query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | required | Citation ID returned by parse or list citations. |
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| {fieldName} | EvidenceDto[] | - | Dynamic keys such as title, authors, year, doi, or journal map to evidence arrays. |
| source / value | string / unknown | - | Provider identifier and provider-returned value. |
| sourceReliability | number | - | Configured provider reliability, from 0 to 1. |
| extractionConfidence | number | - | Confidence that the value was extracted correctly. |
| contextMatchScore | number | - | How well the provider result matches the submitted reference. |
| weightedScore | number | - | Combined evidence score. |
| createdAt | ISO-8601 timestamp | - | Evidence collection time in UTC. |
{
"title": [
{ "source": "CROSSREF", "value": "Attention Is All You Need", "sourceReliability": 0.98, "extractionConfidence": 1.0, "contextMatchScore": 0.99, "weightedScore": 0.97, "createdAt": "2026-01-15T10:20:30Z" }
],
"doi": []
}/api/v1/citations/{id}/correction-proposalsGenerate correction proposals
Compares the stored citation against its strongest candidates and returns provider-backed changes or unresolved conflicts.
Path and query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | required | Citation ID returned by parse or list citations. |
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| citationId | UUID | - | Citation being evaluated. |
| decision | string | - | PROPOSED, NO_CHANGES, or REVIEW_REQUIRED. |
| changes | CorrectionChangeDto[] | - | Field-level changes with confidence, provenance, sources, and reason. |
| unresolvedConflicts | string[] | - | Conflicts that could not be resolved automatically. |
{
"citationId": "7d9a7d7e-9df7-4c84-9f2a-2f4a7d9c4b11",
"decision": "PROPOSED",
"changes": [{ "field": "doi", "changeType": "RECOVERED", "originalValue": null, "proposedValue": "10.48550/arXiv.1706.03762", "confidence": 0.98, "provenance": "PROVIDER_BACKED", "sources": ["CROSSREF"], "reason": "Proposed value is supported by external scholarly metadata" }],
"unresolvedConflicts": []
}/api/v1/citations/renderRender citation styles
Renders a stored citation or caller-supplied metadata in one or more supported styles. Exactly one of citationId or metadata is required.
Request body
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
| citationId | UUID | - | Stored citation. Mutually exclusive with metadata. |
| metadata | CitationMetadataRequest | - | Inline metadata. Include at least one field; mutually exclusive with citationId. |
| styles | string[] | - | Up to 10 styles. Defaults to ["APA7"]. Supported: APA7, MLA9, CHICAGO_AUTHOR_DATE, IEEE, VANCOUVER, GBT7714. |
{
"citationId": "7d9a7d7e-9df7-4c84-9f2a-2f4a7d9c4b11",
"styles": ["APA7", "MLA9", "IEEE"]
}Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| citationId | UUID | null | - | Stored citation ID, or null when rendering inline metadata. |
| renderings | object | - | Map of canonical style name to rendered citation string. |
{
"citationId": "7d9a7d7e-9df7-4c84-9f2a-2f4a7d9c4b11",
"renderings": { "APA7": "Vaswani, A., ... (2017).", "MLA9": "Vaswani, Ashish, et al. ...", "IEEE": "A. Vaswani et al., ..." }
}For inline rendering, send metadata with fields such as title, authors, year, doi, and publisher. Inline metadata is not persisted.
BATCH JOBS
Process larger workflows
Use durable jobs for many references, progress polling, or deduplication. Job creation returns HTTP 202 and a Location header.
/api/v1/citation-imports/previewPreview a structured import
Parses a multipart BibTeX, RIS, EndNote Tagged Text, or CSL-JSON file and returns counts, warnings, and sample metadata without reserving quota. RIS and EndNote use dedicated tolerant parsers; CSL-JSON uses Jackson; BibTeX uses citeproc-java's jbibtex reader. citeproc-java is used later for CSL rendering.
Request body
Content-Type: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
| file | multipart file | required | A .bib, .ris, .enw, or .json CSL-JSON file, up to 10 MB and 1,000 records. |
| format | string (query) | - | Optional explicit format: BIBTEX, RIS, ENDNOTE, or CSL_JSON. The extension is used by default. |
curl -X POST "https://api.citewise.dev/api/v1/citation-imports/preview?format=RIS" -H "X-API-Key: cw_live_your_key" -F "file=@references.ris"The upload is processed for this request only; no original file is persisted.
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| format | string | - | Detected format: BIBTEX, RIS, ENDNOTE, or CSL_JSON. |
| totalRecords | integer | - | Number of source records found in the file. |
| validRecords | integer | - | Records successfully converted to common CSL metadata. |
| invalidRecords | integer | - | Records that could not be converted and will not enter a job. |
| warningCount | integer | - | Total warnings across all parsed records. |
| records | ImportRecordPreview[] | - | Up to 10 previews with index, sourceKey, title, authors, year, doi, and warnings. |
{
"format": "BIBTEX",
"totalRecords": 2, "validRecords": 2, "invalidRecords": 0, "warningCount": 0,
"records": [{ "index": 1, "sourceKey": "vaswani2017", "title": "Attention Is All You Need", "authors": "Vaswani, Ashish", "year": 2017, "doi": null, "warnings": [] }]
}/api/v1/citation-imports/jobsCreate an import job
Re-uploads a previously previewed structured file and creates a durable verification job. Only valid records are submitted, at least two valid records are required, and quota is reserved at this point.
Request body
Content-Type: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
| file | multipart file | required | The same supported structured file used for preview. |
| styles | string[] (repeated multipart parts) | - | Optional repeated form parts such as styles=APA7&styles=MLA9; defaults to APA7. |
| format | string (query) | - | Optional explicit format override. |
curl -X POST "https://api.citewise.dev/api/v1/citation-imports/jobs?format=RIS" -H "X-API-Key: cw_live_your_key" -F "file=@references.ris" -F "styles=APA7" -F "styles=IEEE"The response is the same 202 job resource returned by /api/v1/citation-jobs. Each item stores its original source record, while the upload itself is not persisted. At least two valid records are required.
Response
202 Accepted| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | - | Job identifier used for polling. |
| type | string | - | VERIFY_AND_CORRECT or DEDUPLICATE. |
| status | string | - | QUEUED, RUNNING, COMPLETED, COMPLETED_WITH_ERRORS, CANCELLED, or FAILED. |
| totalItems / processedItems | integer | - | Total inputs and items that have finished processing. |
| succeededItems / failedItems | integer | - | Successful and failed item counters. |
| cancelRequested | boolean | - | Whether cancellation has been requested. |
| result | object | null | - | Aggregate result when the job completes. |
| errorCode / errorMessage | string | null | - | Job-level failure details, when applicable. |
| createdAt ... updatedAt | ISO-8601 timestamp | - | Job lifecycle timestamps in UTC. |
{
"id": "3f0f7d3c-7033-4b0d-92df-5e8d5ab2e7f6",
"type": "VERIFY_AND_CORRECT",
"status": "QUEUED",
"totalItems": 2, "processedItems": 0, "succeededItems": 0, "failedItems": 0
}/api/v1/citation-jobsCreate a citation job
Queues verification/correction or deduplication work and returns the initial job state. Authenticated batch verification requires a Pro or Team workspace; deduplication requires at least two existing citation IDs.
Request body
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
| type | string | required | VERIFY_AND_CORRECT for references, or DEDUPLICATE for existing citationIds. |
| references | string[] | - | Up to 1,000 references, each up to 8,000 characters. Required for VERIFY_AND_CORRECT. |
| citationIds | UUID[] | - | Up to 1,000 stored citation IDs. Required for DEDUPLICATE. |
| options.styles | string[] | - | Up to 10 render styles. Defaults to ["APA7"]. |
{
"type": "VERIFY_AND_CORRECT",
"references": ["Vaswani A. Attention Is All You Need. 2017.", "Devlin J. BERT: Pre-training of Deep Bidirectional Transformers. 2019."],
"options": { "styles": ["APA7", "IEEE"] }
}Response
202 Accepted| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | - | Job identifier used for polling. |
| type | string | - | VERIFY_AND_CORRECT or DEDUPLICATE. |
| status | string | - | QUEUED, RUNNING, COMPLETED, COMPLETED_WITH_ERRORS, CANCELLED, or FAILED. |
| totalItems / processedItems | integer | - | Total inputs and items that have finished processing. |
| succeededItems / failedItems | integer | - | Successful and failed item counters. |
| cancelRequested | boolean | - | Whether cancellation has been requested. |
| result | object | null | - | Aggregate result when the job completes. |
| errorCode / errorMessage | string | null | - | Job-level failure details, when applicable. |
| createdAt ... updatedAt | ISO-8601 timestamp | - | Job lifecycle timestamps in UTC. |
{
"id": "3f0f7d3c-7033-4b0d-92df-5e8d5ab2e7f6",
"type": "VERIFY_AND_CORRECT",
"status": "QUEUED",
"totalItems": 2, "processedItems": 0, "succeededItems": 0, "failedItems": 0,
"cancelRequested": false, "result": null, "errorCode": null, "errorMessage": null,
"createdAt": "2026-01-15T10:20:30Z", "startedAt": null, "completedAt": null, "updatedAt": "2026-01-15T10:20:30Z"
}/api/v1/citation-jobs/{id}Get job status
Polls the current state and aggregate counters for a job.
Path and query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | required | Job ID returned by create a citation job. |
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | - | Job identifier used for polling. |
| type | string | - | VERIFY_AND_CORRECT or DEDUPLICATE. |
| status | string | - | QUEUED, RUNNING, COMPLETED, COMPLETED_WITH_ERRORS, CANCELLED, or FAILED. |
| totalItems / processedItems | integer | - | Total inputs and items that have finished processing. |
| succeededItems / failedItems | integer | - | Successful and failed item counters. |
| cancelRequested | boolean | - | Whether cancellation has been requested. |
| result | object | null | - | Aggregate result when the job completes. |
| errorCode / errorMessage | string | null | - | Job-level failure details, when applicable. |
| createdAt ... updatedAt | ISO-8601 timestamp | - | Job lifecycle timestamps in UTC. |
{
"id": "3f0f7d3c-7033-4b0d-92df-5e8d5ab2e7f6",
"type": "VERIFY_AND_CORRECT",
"status": "COMPLETED_WITH_ERRORS",
"totalItems": 2, "processedItems": 2, "succeededItems": 1, "failedItems": 1,
"cancelRequested": false, "result": null, "errorCode": null, "errorMessage": null,
"createdAt": "2026-01-15T10:20:30Z", "startedAt": "2026-01-15T10:20:31Z", "completedAt": "2026-01-15T10:21:02Z", "updatedAt": "2026-01-15T10:21:02Z"
}/api/v1/citation-jobs/{id}/itemsList job items
Returns item-level results and failures in item-index order.
Path and query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | required | Job ID returned by create a citation job. |
| page | integer (query) | - | Zero-indexed page number. Defaults to 0. |
| size | integer (query) | - | Page size, defaults to 100 and is clamped to 1-200. |
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| jobId / page / size | UUID / integer / integer | - | Job ID and effective zero-indexed pagination values. Size is clamped to 1-200. |
| totalItems / totalPages | integer | - | Pagination totals. |
| items | CitationJobItemResponse[] | - | Each item includes id, index, status, reference, sourceRecord (for structured imports), inputCitationId, citationId, result, and item-level errors. |
{
"jobId": "3f0f7d3c-7033-4b0d-92df-5e8d5ab2e7f6", "page": 0, "size": 100, "totalItems": 2, "totalPages": 1,
"items": [{ "id": "a3c1...", "index": 0, "status": "SUCCEEDED", "reference": "Vaswani A. ...", "sourceRecord": "TY - JOUR\nTI - ...\nER -", "inputCitationId": null, "citationId": "7d9a...", "result": { "parsed": {}, "correction": {}, "rendered": {} }, "errorCode": null, "errorMessage": null }]
}Optional query parameters are page (default 0) and size (default 100, maximum 200).
/api/v1/citation-jobs/{id}/cancelCancel a job
Requests cancellation of a queued or running job. Terminal jobs are returned unchanged.
Path and query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | required | Job ID returned by create a citation job. |
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | - | Job identifier used for polling. |
| type | string | - | VERIFY_AND_CORRECT or DEDUPLICATE. |
| status | string | - | QUEUED, RUNNING, COMPLETED, COMPLETED_WITH_ERRORS, CANCELLED, or FAILED. |
| totalItems / processedItems | integer | - | Total inputs and items that have finished processing. |
| succeededItems / failedItems | integer | - | Successful and failed item counters. |
| cancelRequested | boolean | - | Whether cancellation has been requested. |
| result | object | null | - | Aggregate result when the job completes. |
| errorCode / errorMessage | string | null | - | Job-level failure details, when applicable. |
| createdAt ... updatedAt | ISO-8601 timestamp | - | Job lifecycle timestamps in UTC. |
{
"id": "3f0f7d3c-7033-4b0d-92df-5e8d5ab2e7f6", "type": "VERIFY_AND_CORRECT", "status": "CANCELLED",
"totalItems": 100, "processedItems": 12, "succeededItems": 12, "failedItems": 0, "cancelRequested": true,
"result": null, "errorCode": null, "errorMessage": null, "createdAt": "2026-01-15T10:20:30Z", "startedAt": "2026-01-15T10:20:31Z", "completedAt": "2026-01-15T10:21:02Z", "updatedAt": "2026-01-15T10:21:02Z"
}WORKSPACE
Manage usage and credentials
These endpoints are workspace-scoped. Console users normally use a Clerk session; API-key access is also accepted by the current backend, while billing checkout still requires an interactive Clerk session.
/api/v1/console/overviewGet workspace overview
Returns the current user, workspace, plan entitlement, monthly reference usage, and admin flag.
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| user | object | - | id, email, displayName, imageUrl, and role. |
| workspace | object | - | id, name, and slug. |
| entitlement | EntitlementSnapshot | - | Plan code, status, monthly allowance, one-time credit balance, throughput, concurrency, and API access. |
| referencesUsed | integer | - | Current monthly reference reservations. |
| admin | boolean | - | Whether the user has admin privileges. |
{
"user": { "id": "...", "email": "researcher@example.com", "displayName": "Ada", "imageUrl": null, "role": "USER" },
"workspace": { "id": "...", "name": "Ada's workspace", "slug": "ada-workspace" },
"entitlement": { "planCode": "FREE", "subscriptionStatus": "ACTIVE", "monthlyReferences": 10, "creditBalance": 100, "requestsPerMinute": 10, "concurrency": 1, "apiAccess": false, "currentPeriodEnd": null, "cancelAtPeriodEnd": false, "hasSubscription": false, "canCancel": false, "canResume": false },
"referencesUsed": 2, "admin": false
}/api/v1/api-keysList API keys
Lists key metadata for the workspace. Secret material is never returned by this endpoint.
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| id / name | UUID / string | - | Key identifier and human-readable name. |
| prefix / last4 | string | - | Safe display prefix and last four secret characters. |
| status | string | - | ACTIVE or REVOKED. |
| createdAt / lastUsedAt / expiresAt | timestamp | null | - | Key lifecycle metadata. |
[
{ "id": "c4c7...", "name": "Production pipeline", "prefix": "cw_live_a1b2c3", "last4": "xYz9", "status": "ACTIVE", "createdAt": "2026-01-15T10:20:30Z", "lastUsedAt": null, "expiresAt": null }
]/api/v1/api-keysCreate an API key
Creates a paid-plan API credential. Store the returned apiKey immediately; it cannot be retrieved later.
Request body
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | required | Human-readable name, trimmed and limited to 100 characters. |
{
"name": "Production pipeline"
}Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| key | ApiKeyView | - | Safe key metadata returned for display. |
| apiKey | string | - | Complete secret. This is the only response that contains it. |
{
"key": { "id": "c4c7...", "name": "Production pipeline", "prefix": "cw_live_a1b2c3", "last4": "xYz9", "status": "ACTIVE", "createdAt": "2026-01-15T10:20:30Z", "lastUsedAt": null, "expiresAt": null },
"apiKey": "cw_live_a1b2c3_your-secret-value"
}API access must be enabled for the workspace. A workspace can have up to 10 active keys. Treat the secret like a password.
/api/v1/api-keys/{id}Revoke an API key
Immediately marks a workspace API key as revoked. Existing requests using it will fail authentication.
Path and query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| id | UUID | required | API key ID returned by list API keys. |
Response
204 No ContentNo response body.
The response has no body. Keep the key ID from the list endpoint for revocation workflows.
BILLING
Manage plans and billing
Billing endpoints are used by the Console. Creem is the system of record for checkout, subscription lifecycle, payment methods, and invoices.
/api/v1/billing/subscriptionGet subscription entitlement
Returns the effective plan and limits for the authenticated workspace, including free-plan defaults and cancellation state.
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| planCode / subscriptionStatus | string | - | Effective plan and current subscription state. |
| monthlyReferences | integer | - | Monthly reference allowance. |
| creditBalance | integer | - | Remaining one-time credits, consumed after the monthly allowance. |
| requestsPerMinute / concurrency | integer | - | Throughput and concurrent execution limits. |
| apiAccess | boolean | - | Whether workspace API keys are enabled. |
| currentPeriodEnd | timestamp | null | - | Current billing period end. |
| cancelAtPeriodEnd | boolean | - | Whether cancellation is scheduled at the end of the current period. |
| currentPeriodStart | timestamp | null | - | Current billing period start. |
| hasSubscription | boolean | - | Whether the workspace has a provider-managed paid subscription. |
| canCancel / canResume | boolean | - | Whether the current subscription state supports the corresponding lifecycle action. |
{
"planCode": "PRO", "subscriptionStatus": "ACTIVE", "monthlyReferences": 500, "creditBalance": 100, "requestsPerMinute": 60, "concurrency": 5, "apiAccess": true,
"currentPeriodEnd": "2026-02-15T00:00:00Z", "cancelAtPeriodEnd": false, "hasSubscription": true, "canCancel": true, "canResume": false
}/api/v1/billing/checkoutCreate a checkout session
Creates a hosted Creem checkout session for a configured subscription or one-time credit pack and returns the URL to open.
Request body
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
| productKey | string | required | Configured product key, such as pro-monthly, team-yearly, starter-pack, research-pack, or lab-pack. |
{
"productKey": "pro-monthly"
}Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| checkoutId | string | - | Provider checkout identifier. |
| checkoutUrl | string | - | Hosted checkout URL. |
{
"checkoutId": "ch_123456",
"checkoutUrl": "https://checkout.creem.io/ch_123456"
}/api/v1/billing/checkout/confirmConfirm a returned checkout
Reconciles a completed hosted checkout using a server-to-server Creem lookup. CiteWise validates checkout status, configured product ID, and workspace metadata before updating entitlements; browser-supplied plan data is never trusted.
Request body
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
| checkoutId | string | required | Checkout ID returned by create checkout. |
{
"checkoutId": "chk_123456"
}Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| hasSubscription | boolean | - | True when a recurring checkout has been linked successfully. |
| planCode / subscriptionStatus | string | - | The reconciled workspace entitlement. |
{
"planCode": "PRO", "subscriptionStatus": "ACTIVE", "hasSubscription": true, "canCancel": true
}/api/v1/billing/subscription/cancelCancel a subscription
Schedules cancellation at the end of the current billing period. Access remains active until then and the request is idempotent. Immediate cancellation is restricted to administrators; regular users should always use scheduled cancellation.
Request body
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
| mode | string (optional) | - | scheduled (default) or immediate. |
{
"mode": "scheduled"
}Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| cancelAtPeriodEnd | boolean | - | True after a scheduled cancellation. |
| currentPeriodEnd | timestamp | null | - | The date through which access remains available. |
{
"planCode": "PRO", "subscriptionStatus": "SCHEDULED_CANCEL", "cancelAtPeriodEnd": true,
"currentPeriodEnd": "2026-02-15T00:00:00Z"
}/api/v1/billing/subscription/resumeResume a subscription
Removes a scheduled cancellation (or resumes a paused subscription) before the current period ends. The operation is idempotent for an already-active subscription.
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| subscriptionStatus | string | - | Usually ACTIVE after a successful resume. |
| cancelAtPeriodEnd | boolean | - | False after cancellation is removed. |
{
"planCode": "PRO", "subscriptionStatus": "ACTIVE", "cancelAtPeriodEnd": false
}/api/v1/billing/portalOpen the billing portal
Generates a short-lived Creem customer portal link for payment methods, invoices, and provider-side subscription management.
Response
200 OK| Field | Type | Required | Description |
|---|---|---|---|
| customerPortalLink | string | - | Hosted Creem customer portal URL. |
{
"customerPortalLink": "https://creem.io/customer-portal/..."
}ERRORS
Handle failures predictably
Every API error uses the same envelope. The code is stable for programmatic handling; message is safe to display; traceId helps support find the request.
{
"timestamp": "2026-01-15T10:20:30Z",
"code": "QUOTA_EXCEEDED",
"message": "monthly reference quota exhausted",
"traceId": "f8c0f4d2a1b84e24"
}| HTTP | Code | Meaning |
|---|---|---|
| 400 | INVALID_REFERENCE / UNSUPPORTED_CITATION_STYLE / FUSION_FAILED | The request body is invalid, a required field is missing, a citation style is unsupported, or evidence fusion could not complete. |
| 400 | INVALID_REQUEST | The request body, path parameter, or required header is malformed. |
| 401 | UNAUTHENTICATED / API_KEY_INVALID / WEBHOOK_SIGNATURE_INVALID | No valid Clerk JWT or X-API-Key was provided, or a signed webhook request failed verification. |
| 403 | FORBIDDEN / SUBSCRIPTION_REQUIRED | The credential is valid but cannot access this workspace or paid-only feature. |
| 404 | CITATION_NOT_FOUND / JOB_NOT_FOUND | The resource does not exist in the authenticated workspace. |
| 405 | METHOD_NOT_ALLOWED | The HTTP method is not supported by this endpoint. |
| 415 | UNSUPPORTED_MEDIA_TYPE | The request Content-Type is not supported. |
| 429 | QUOTA_EXCEEDED / API_KEY_LIMIT_REACHED / RATE_LIMIT_EXCEEDED / CONCURRENCY_LIMIT_EXCEEDED / SYSTEM_BUSY | The workspace allowance, active-key limit, or processing capacity has been reached. Honor Retry-After when present. |
| 502/503 | BILLING_UNAVAILABLE / PROVIDER_UNAVAILABLE / PROVIDER_TIMEOUT | A downstream billing or scholarly provider is unavailable. Retry with backoff. |
| 500 | DATABASE_ERROR / INTERNAL_ERROR | An unexpected server error. Include traceId when contacting support. |
Need help with an integration?
Contact support