# Markovo AI-Native Integration

Markovo exposes the same PDF-to-Markdown capability through the browser, HTTP API, CLI, and MCP. Every successful conversion ends in a stable bundle containing Markdown, assets, provenance, metadata, and quality evidence.

## Capability discovery

Always call `GET https://markovo.net/v1/capabilities` before routing a new file type. At launch only `pdf-to-markdown` is available. Future capabilities may appear as Beta or disabled and must not be treated as generally available.

`GET /v1/catalog` is the only trusted source for plan IDs, prices, Credit grants, pack validity, and billing rules. A client must never calculate a charge from a display price.

## Safe conversion flow

Estimate first:

```bash
curl -X POST https://markovo.net/v1/estimates \
  -H "Authorization: Bearer ${PDF2MD_API_KEY}" \
  -F "file=@input.pdf" \
  -F "capability_id=pdf-to-markdown" \
  -F "mode=fast"
```

After explicit confirmation, submit the returned upload ID with a maximum Credit ceiling:

```bash
curl -X POST https://markovo.net/v1/jobs \
  -H "Authorization: Bearer ${PDF2MD_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"upload_id":"upl_...","max_credits":30}'
```

Poll and download:

```bash
curl https://markovo.net/v1/jobs/{job_id} \
  -H "Authorization: Bearer ${PDF2MD_API_KEY}"

curl -L "https://markovo.net/v1/jobs/{job_id}/download?format=zip" \
  -H "Authorization: Bearer ${PDF2MD_API_KEY}" \
  -o bundle.zip
```

Anonymous estimates return a one-time `job_token`. Send it in `x-markovo-job-token` for confirmation, status, quality, and download requests. Never put that token in a query string. Authenticated jobs are accessible only to the owning organization and project.

`POST /v1/convert` remains a compatibility shortcut and also requires `max_credits`. Paid requests reserve before queueing, settle the actual route on success, and release the reservation on failure or terminal retry.

## Output contract

- `output.md`: readable Markdown.
- `assets/`: extracted or generated assets.
- `metadata.json`: conversion metadata and actual Credit usage.
- `source_map.json`: source-page provenance.
- `quality_report.json`: weak-page and fallback evidence.
- `bundle.zip`: the portable delivery bundle.

Agents should inspect `quality_report.json` before presenting the output as reliable. A successful job does not imply perfect extraction for formulas, scans, complex charts, or unusual layouts.

## Authentication and secrets

Create API keys from `/app#api-keys`. Plaintext is shown only once. Store keys in a secret manager and use the `markovo:convert` scope. The `mk_live_` prefix identifies new Markovo keys; legacy `pdf2md_*` credentials and scopes remain accepted during migration.

Same-origin authentication lives at `/api/auth/*`:

- Google: `https://markovo.net/api/auth/callback/google`
- GitHub: `https://markovo.net/api/auth/callback/github`
- Email verification and password reset: Alibaba Cloud DirectMail SMTP from `support@markovo.net`

Do not send API keys, job tokens, email addresses, filenames, or document contents to analytics. Markovo's product funnel stores only aggregate daily counts by allowlisted event and pathname.

## Pricing and lifecycle

- Free: 100 Credits/month and no rollover.
- Plus: $8/month, 2,000 Credits, one-month rollover capped at 4,000, 7-day result retention.
- Pro: $19/month, 6,000 Credits, one-month rollover capped at 12,000, API keys, two concurrent jobs, webhooks, 30-day retention.
- Credit packs: 2,000/$10, 12,000/$49, 60,000/$199; expire after 365 days.
- Business is waitlist-only; Enterprise is contact sales.

Anonymous and Free results expire after one hour. Source files are deleted when processing completes. The launch runtime rejects work estimated above 12 minutes.

## Errors and retry policy

- `400`: malformed request, invalid PDF, or missing `max_credits`.
- `401`: authentication is required or invalid.
- `402`: estimate exceeds the ceiling or the account lacks Credits.
- `404`: the job is not owned by the requester (ownership failures are intentionally indistinguishable from missing jobs).
- `409`: output is not ready.
- `413`: upload exceeds the byte limit.
- `422`: capability, page, or estimated-runtime limit exceeded.
- `429`: daily limit exceeded.
- `503`: account metering is unavailable.

Retry queue/network failures with backoff. Do not retry invalid input unchanged. Queue processing acknowledges only success; failures retry and enter a DLQ after the configured terminal attempt. Platform retries never consume additional Credits.

## CLI and MCP

```bash
export PDF2MD_BASE_URL="https://markovo.net"
export PDF2MD_API_KEY="mk_live_..."

pdf2md doctor --json
pdf2md convert input.pdf --out runs/input --mode fast
pdf2md usage
pdf2md billing
pdf2md-mcp
```

The legacy executable and environment names are compatibility aliases. Markovo remains the customer-facing brand.

Production should be considered ready only after the domain, OAuth callbacks, Alibaba Cloud SMTP sender, D1 migrations, Container runtime, a real conversion/download, and all Creem Sandbox products have passed the release checklist.
