API Reference

NeNe Corpus exposes a JSON REST API. The live OpenAPI spec is served at /openapi.php on your installation.

Tip: Open https://your-domain.com/openapi.php in a browser or import it into Postman / Insomnia for interactive exploration.

Authentication

Admin endpoints require a Bearer JWT obtained from POST /admin/auth/login.

Authorization: Bearer <jwt>

Consumer endpoints (chat) are public but rate-limited per IP and session.


Admin Auth

POST /admin/auth/login

Authenticate and receive a JWT.

// Request
{ "email": "admin@example.com", "password": "yourpassword" }

// Response 200
{ "token": "eyJ..." }

GET /admin/auth/me

Returns the currently authenticated admin user.

PUT /admin/auth/password

Change admin password (requires current password + new password).

PUT /admin/auth/email

Change admin email address.

POST /admin/auth/password-reset/request

Request a password reset email. Always returns 200 regardless of whether the email exists (enumeration prevention).

{ "email": "admin@example.com" }

POST /admin/auth/password-reset/confirm

Confirm a password reset using the token from the email.

{ "token": "raw-token-from-email", "password": "newpassword" }

Sources

GET /admin/sources

List all uploaded sources.

POST /admin/sources

Upload a new source (PDF, CSV, or plain text).

Content-Type: multipart/form-data
file: <binary>       # for PDF / CSV
source_type: pdf | csv | text
text_content: ...    # for source_type=text

DELETE /admin/sources/{id}

Delete a source and all associated documents and chunks.


Chat (Consumer)

POST /chat/sessions

Create a new chat session.

POST /chat/sessions/{sessionId}/messages

Send a message and receive a sync JSON response with citations.

// Request
{ "message": "Your question here" }

// Response 200
{
  "message": "The answer based on your corpus...",
  "citations": [
    { "document_id": 42, "title": "Product FAQ", "excerpt": "..." }
  ]
}
NeNe Corpus uses sync JSON chat only. SSE / token streaming is intentionally not implemented for Tier A shared hosting compatibility.

Error format

All errors follow RFC 9457 Problem Details:

{
  "type": "not_found",
  "title": "Not Found",
  "status": 404,
  "detail": "Document with ID 99 not found.",
  "instance": "/admin/documents/99"
}