API contract types and schemas for CertRev verification engines. MVP is the source of truth.
npm install certrev-api-contractAPI contract types and Zod schemas for CertRev verification engines.
The certrev-mvp repository is the SOURCE OF TRUTH for this contract.
``bashFor MVP (workspace dependency)
pnpm add @certrev/api-contract
Usage
$3
`typescript
import type {
VerificationJob,
TipTapDocument,
ClaimResult,
APAReference,
} from '@certrev/api-contract'const job: VerificationJob = { ... }
`$3
`typescript
import {
VerificationJobSchema,
TipTapDocumentSchema,
CreateJobInputSchema,
} from '@certrev/api-contract'// Validate incoming data
const result = VerificationJobSchema.safeParse(data)
if (!result.success) {
console.error('Invalid job:', result.error)
}
`$3
`typescript
import {
STAGE_LABELS,
ERROR_MESSAGES,
CONTRACT_VERSION,
} from '@certrev/api-contract'// Show progress to users
const label = STAGE_LABELS[job.stage_name] // "Verifying critical claims"
// Show errors to users
const message = ERROR_MESSAGES[error.code] // "Rate limit exceeded..."
`Contract Version
Current version: 2.1.0
Check
CONTRACT_VERSION constant for programmatic access.For Engine Developers
Engines MUST:
1. Poll
verification_jobs table for jobs with status = 'pending' AND matching engine
2. Update jobs with progress using JobProgressUpdate schema
3. Complete jobs with JobCompletion schema
4. Fail jobs with JobFailure schemaSee
schemas.ts for exact shapes.$3
Jobs are assigned to specific engines via the
options.engine field. Each engine should poll only for jobs assigned to it:`sql
-- cr-engine-v2 polls:
SELECT * FROM verification_jobs
WHERE status = 'pending'
AND options->>'engine' = 'cr-engine-v2'
ORDER BY created_at ASC
LIMIT 1-- cr-engine-v3 polls:
SELECT * FROM verification_jobs
WHERE status = 'pending'
AND options->>'engine' = 'cr-engine-v3'
ORDER BY created_at ASC
LIMIT 1
`Available engines:
| Engine ID | Name | Description |
|-----------|------|-------------|
|
cr-engine-v2 | CR Engine V2 | Stable version |
| cr-engine-v3 | CR Engine V3 (BMAD) | Latest with BMAD improvements |Handling legacy jobs: Jobs created before engine routing (without
options.engine) can be handled by any engine or ignored based on your deployment needs.$3
The MVP frontend TipTap editor expects footnotes as marks with this exact structure:
`typescript
// In output_document nodes, add this mark to cited text:
{
type: 'footnote',
attrs: {
footnoteNumbers: [1, 2], // References supporting this claim
claimId: 'uuid' // Links to ClaimResult.id
}
}
`Example: A paragraph with a footnoted claim:
`json
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Studies show this treatment is effective" },
{
"type": "text",
"text": " for patients",
"marks": [{
"type": "footnote",
"attrs": {
"footnoteNumbers": [1, 3],
"claimId": "claim-123"
}
}]
},
{ "type": "text", "text": "." }
]
}
`The frontend renders this as:
"...effective for patients[1,3]."Frontend support:
- TipTap
Footnote extension in src/lib/editor/tiptap-config.ts
- Renders as [1,3]
- DOMPurify whitelist includes sup tag and data-footnote` attributeSee CHANGELOG.md for version history.
What's breaking:
- Removing a field from output
- Changing a field's type
- Renaming a required field
- Adding a required input field
What's NOT breaking:
- Adding optional fields
- Adding new error codes
- Adding new claim types