Interactive API documentation is available at:
| Endpoint | UI |
|---|---|
/api-docs/swagger | Swagger UI |
/api-docs/redoc | ReDoc |
/api-docs/scalar | Scalar |
/api-docs/spec.json | Raw OpenAPI 3.0 JSON |
/api-docs/spec.yaml | Raw OpenAPI 3.0 YAML |
Most /api/v1/* endpoints require Authorization: Bearer <token>. Two exceptions: GET /api/v1/features is public, and the one-time /api/v1/exports/download/{ticket} URL carries its own credential. GET /api/status and POST /api/login are also public.
Authentication Endpoints
POST /api/login— Authenticate and receive a JWT tokenPOST /api/auth/mfa/verify— Complete a login that requires TOTP
Tokens are stateless JWTs; there is no server-side logout endpoint. Discard the token client-side (or revoke the API token that issued it).
API Token Management
GET /api/v1/access-token-list— List all API tokensPOST /api/v1/access-token— Create a new API tokenDELETE /api/v1/access-token/{token}— Revoke an API token
License (Pro)
GET /api/v1/license/status— Active status, edition, account limit and usageGET /api/v1/license/machine-id— This deployment's machine IDPOST /api/v1/license/upload— Install a license (system:root)GET /api/v1/features— Active edition and feature flags
See Licensing & Trials.
Metrics
GET /api/v1/metrics— Prometheus text exposition (requiressystem:metrics)
See Monitoring & Metrics.
Compliance & Audit (Pro/Enterprise)
| Method | Path | Description |
|---|---|---|
GET | /api/v1/audit-log | Query audit records |
GET | /api/v1/audit-log/export | Export a range as JSONL or CSV (raw payload preserved) |
GET | /api/v1/audit-log/verify | Verify the hash chain |
GET | /api/v1/integrity/jobs | Integrity-check history |
POST | /api/v1/integrity/run | Start an integrity check |
GET | /api/v1/compliance/overview | Compliance dashboard sections |
POST | /api/v1/compliance/evidence-pack | Build a ZIP evidence pack for an audit range |
GET/POST | /api/v1/compliance/config | Runtime compliance overrides |
GET | /api/v1/approvals | Dual-control request history |
GET/POST | /api/v1/approvals/config | Dual-control policy |
POST | /api/v1/approvals/{id}/approve | Approve a request |
POST | /api/v1/approvals/{id}/reject | Reject a request |
POST | /api/v1/approvals/{id}/break-glass | Emergency override |
POST | /api/v1/approvals/erasure-requests | GDPR Art. 17 erasure request |
GET | /api/v1/legal-hold | List active hold cases |
POST/DELETE | /api/v1/legal-hold/{account_id} | Place a case / release every active case |
POST/DELETE | /api/v1/legal-hold/batch | Batch hold operations |
GET/POST | /api/v1/siem | SIEM forwarding configuration |
GET | /api/v1/timestamps | Timestamp-anchor history |
Full request and response schemas are in the interactive API documentation, and each area is described in Audit Log & Integrity, Dual Control, Legal Hold, GDPR Erasure Requests, and SIEM Forwarding.
Account Management
GET /api/v1/accounts— List all accountsPOST /api/v1/account— Create an accountGET /api/v1/account/:account_id— Get account detailsPOST /api/v1/account/:account_id— Update account configuration (retention fields rejected)POST /api/v1/account/:account_id/retention— Change retention policy (root only; weakening changes may queue for approval)DELETE /api/v1/account/:account_id— Remove an accountPOST /api/v1/accounts/:account_id/start-download— Start manual downloadPOST /api/v1/accounts/:account_id/cancel-download— Cancel download
Search & Messages
POST /api/v1/search-messages— Full-text search across messagesPOST /api/v1/search-attachment— Search attachmentsGET /api/v1/message-content/:account_id/:envelope_id— Get a message with parsed contentGET /api/v1/download-message/:account_id/:envelope_id— Download raw EMLGET /api/v1/download-attachment/:account_id/:envelope_id— Download an attachmentGET /api/v1/get-thread-messages/:account_id— Reconstruct a threadGET /api/v1/all-contacts— Aggregated contactsPOST /api/v1/delete-messages— Delete explicitly listed messages. Body:{ "<account_id>": ["<envelope_id>", …] }— the key is the account ID, not the mailbox ID; each value is the envelopeidUUID returned bysearch-messagesPOST /api/v1/restore-messages/:account_id— Push archived messages back to their source IMAP server (not an undo of deletion)
Batch deletion
| Method | Path | Description |
|---|---|---|
POST | /api/v1/batch-delete/preview | Count and account breakdown for a filter (including accounts you may not delete from) |
POST | /api/v1/batch-delete | Start an asynchronous deletion job; requires data:delete on every account in scope |
GET | /api/v1/batch-delete | Delete history (your own jobs; system:root sees all) |
GET | /api/v1/batch-delete/:job_id | Job status, progress and per-account counts |
POST | /api/v1/batch-delete/:job_id/cancel | Request cancellation — applied between batches |
Deletion is permanent (there is no trash). The job enumerates the filter once, when it starts, and deletes that point-in-time set in batches of 500; mail arriving afterwards is not touched. Deleted messages are recorded as tombstones, so a later gap-fill or full re-sync does not bring them back. A second job cannot run while one is in progress.
With dual control enabled for message.delete, the request queues instead of starting a job, and records the exact frozen id set (not the filter) that the approver signs.
Preview fields, the per-account permission split, job statuses, tombstones, legal hold and recovery limits are described in Batch Deletion.
Sorting
POST /api/v1/search-messages accepts an optional sort_by (and desc boolean):
| Value | Sorts by |
|---|---|
DATE | The message's Date header |
INTERNAL_DATE | IMAP INTERNALDATE / import timestamp |
INGEST_AT | Bichon's archival (ingest) timestamp |
SIZE | Message size |
RELEVANCE | Full-text relevance score (BM25) |
Behavior details:
- The API default is
DATE, but when the query carries a full-text term and no sort is requested, the server defaults toRELEVANCE— a date-descending default would bury the best match under the newest mail. RELEVANCEis always descending (higher score = more relevant); thedescflag is ignored for it.- An explicit
RELEVANCEwith no text term in the query falls back toDATE— there is no score to order by.
Tags
POST /api/v1/update-tags— Add or remove tags on messagesGET /api/v1/all-tags— All tags with document counts
Saved Searches
GET/POST/api/v1/saved-searches— List / createPATCH/DELETE/api/v1/saved-searches/:id— Rename / delete one
Import & Export
POST /api/v1/import— Import raw EML (Base64-encoded payload)POST /api/v1/upload-import— WebUI file upload pathPOST /api/v1/exports/preview— Preview an export's scope (saved search or ad-hoc filter)POST /api/v1/exports— Start an export job (MBOX of messages, or a ZIP of attachments)GET /api/v1/exports— List export jobsGET /api/v1/exports/:job_id— Export statusPOST /api/v1/exports/:job_id/cancel— Cancel a running jobDELETE /api/v1/exports/:job_id— Delete a job and its artifactGET /api/v1/exports/:job_id/download— Download the artifactPOST /api/v1/exports/:job_id/download-ticket— One-time, 60-second download URLPOST /api/v1/exports/:job_id/verify— Verify the artifact (Pro)
preview and create take either saved_search_id or an ad-hoc filter ({"email": …} / {"attachment": …}), plus an optional label and format ("Mbox" or "Attachments"). See Import & Export.
For the complete API reference with request/response schemas, visit the interactive API documentation on your Bichon instance.