openapi: "3.0.3" info: title: archivmail REST API version: "1" description: | Read-only REST API for external CRM/ERP systems. Authenticate with an API key obtained from the admin panel. All endpoints are GET-only. POST/PUT/PATCH/DELETE return 405. servers: - url: /api/v1 security: - bearerAuth: [] components: securitySchemes: bearerAuth: type: http scheme: bearer description: "API key in format `am_` — obtained once from Admin → API Keys." schemas: Error: type: object properties: error: type: string required: [error] MailSummary: type: object properties: id: type: string description: Unique message ID (UUID) from: type: string to: type: string subject: type: string date: type: string format: date-time size: type: integer description: Raw EML size in bytes has_attachments: type: boolean MailDetail: type: object properties: id: type: string from: type: string to: type: string cc: type: string subject: type: string date: type: string format: date-time size: type: integer body_plain: type: string ocr_status: type: string enum: [pending, done, failed, skipped, disabled] attachments: type: array items: type: object properties: index: type: integer filename: type: string content_type: type: string size: type: integer SearchResponse: type: object properties: mails: type: array items: $ref: "#/components/schemas/MailSummary" total: type: integer page: type: integer pages: type: integer paths: /mails: get: summary: Search / list mails description: | Search the archive. All parameters are optional and combined with AND. **Role `user`:** the `contact` parameter is required. **Role `auditor`:** all parameters are optional. Results are paginated (max 100 per page). parameters: - name: q in: query description: Full-text query schema: type: string - name: contact in: query description: > Match mails where this address appears in From **or** To. Required for `user`-role keys. schema: type: string - name: from in: query description: Filter by sender address (ignored when `contact` is set) schema: type: string - name: to in: query description: Filter by recipient address (ignored when `contact` is set) schema: type: string - name: subject in: query description: Filter by subject (appended to `q`) schema: type: string - name: date_from in: query description: "Start of date range (RFC 3339 or YYYY-MM-DD)" schema: type: string - name: date_to in: query description: "End of date range (RFC 3339 or YYYY-MM-DD, inclusive)" schema: type: string - name: page in: query schema: type: integer default: 1 - name: limit in: query schema: type: integer default: 25 maximum: 100 responses: "200": description: Search results content: application/json: schema: $ref: "#/components/schemas/SearchResponse" "400": description: Missing required parameter (e.g. `contact` for user-role keys) content: application/json: schema: $ref: "#/components/schemas/Error" "401": description: Missing or invalid API key content: application/json: schema: $ref: "#/components/schemas/Error" "429": description: Rate limit exceeded headers: Retry-After: schema: type: integer content: application/json: schema: $ref: "#/components/schemas/Error" /mails/{message_id}: get: summary: Get mail metadata parameters: - name: message_id in: path required: true schema: type: string responses: "200": description: Mail metadata and parsed body content: application/json: schema: $ref: "#/components/schemas/MailDetail" "401": description: Missing or invalid API key content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Mail not found or not accessible content: application/json: schema: $ref: "#/components/schemas/Error" /mails/{message_id}/raw: get: summary: Download original EML parameters: - name: message_id in: path required: true schema: type: string responses: "200": description: Raw EML file content: application/octet-stream: schema: type: string format: binary "401": description: Missing or invalid API key content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Mail not found content: application/json: schema: $ref: "#/components/schemas/Error"