Docs

The v1 CLI: vendors in, certificates in, reminders out.

Add a vendor

certpilot add-vendor "Bob's Concrete LLC" \
  --email don+certpilot@lifeofmorr.com --trade concrete
# {"vendor_id": 1, "name": "Bob's Concrete LLC"}

Import a certificate

certpilot import-cert --vendor 1 --pdf ./coi-bobs.pdf
# {"certificate_id": 3, "needs_human_review": false,
#  "extracted": {"insurers": ["Great American Insurance Co"],
#                "policy_numbers": ["GL-2024-88931"],
#                "effective_date": "2025-01-15",
#                "expiration_date": "2026-01-15",
#                "limit_each_occurrence": 1000000.0,
#                "limit_aggregate": 2000000.0,
#                "coverage_found": ["general_liability", ...]}}

No PDF? Pipe text instead: certpilot import-cert --vendor 1 --name acord.txt < acord.txt. Incomplete extractions print a human-review notice.

Run the reminder engine

certpilot check
# [log] COI expiring in 30 days: Bob's Concrete LLC (GL-2024-88931)
# {"alerts_sent": 1}

Run daily via cron. Alerts are idempotent — re-runs never duplicate. Set CERTPILOT_SMTP_HOST (etc.) to send email instead of logging.

Compliance report

certpilot report
# Bob's Concrete LLC             expiring_soon  certs=2
# {"vendors": 1}

Python package

from certpilot import db, extract, reminders
conn = db.connect("certpilot.db")
db.vendor_status(conn, 1)   # compliant | expiring_soon | expired | no_certs
reminders.run(conn)         # due alerts, delivered once each

Hosted API (self-serve, EXP-1)

Paid plans provision automatically: Stripe checkout completes, a workspace is created, and you claim your API key once with your checkout session id. Send the key as X-API-Key (or Authorization: Bearer). Endpoints: GET /v1/account, GET|POST /v1/vendors, POST /v1/vendors/{id}/certificates (send ACORD-25 text in text for extraction, or explicit fields), GET /v1/vendors/export.csv, GET /v1/report, GET /v1/score (Pro/Scale), POST /v1/check (run the reminder engine for your workspace), GET|POST /v1/keys, DELETE /v1/keys/{id}. Plan caps are enforced in code: over the vendor or seat cap the API answers 402 plan_limit. The hosted API activates when the service deploys — until then the CLI above is the live product.