Below are the HTTP endpoints exposed by the Leddger AI backend server (default: http://localhost:5000).
Migration Note: The backend has been migrated from Python/FastAPI to Node.js/Express. Authentication has been migrated from Firebase Admin SDK to Supabase JWT verification. All
Authorization: Bearerheaders now expect a Supabase access token (not a Firebase ID token). See Supabase Auth — Backend for details.
- Description: Fetches Google Calendar events from the past 7 days, calculates costs, and applies AI classifications.
- Query Parameters:
google_token(String, required): Google OAuth Access Token (provider token from Supabase session).
- Headers:
Authorization: Bearer <Supabase_Access_Token>(required).
- Response (JSON):
{ "status": "success", "events": [ { "eventId": "event_id_xyz", "title": "Phoenix Database Upgrade Migration", "description": "Postgres schema changes", "startTime": "2026-06-20T10:00:00Z", "endTime": "2026-06-20T11:00:00Z", "durationMinutes": 60, "attendees": [{"email": "dev@example.com", "name": "Developer", "response": "accepted"}], "aiProject": "Project Phoenix", "aiConfidence": 92, "aiReasoning": "Matching database keyword detected.", "cost": 75.0, "requiresHumanReview": false } ] }
- Description: Callback landing URL for GitHub App installation. Exchanges code for token and redirects.
- Query Parameters:
code(String, required)state(String, optional)installation_id(String, optional)
- Description: Fetches the authenticated user's department list from the Supabase
profilestable. - Headers:
Authorization: Bearer <Supabase_Access_Token> - Response:
{ "departments": ["Engineering", "Marketing"] }
- Description: Updates the user's department list in the Supabase
profilestable. - Headers:
Authorization: Bearer <Supabase_Access_Token> - Request Body:
{ "departments": ["Engineering", "Marketing"] }
- Description: Creates a new form draft in the Supabase
form_draftstable. - Headers:
Authorization: Bearer <Supabase_Access_Token> - Request Body:
{ "title": "Team Builder", "config": { ... }, "templateType": "team" } - Response:
{ "draftId": "uuid", "message": "Draft saved" }
- Description: Lists all drafts for the authenticated user from Supabase.
- Headers:
Authorization: Bearer <Supabase_Access_Token> - Response:
{ "drafts": [{ "draft_id": "...", "title": "...", "status": "draft", ... }] }
- Description: Deletes a draft from Supabase.
- Headers:
Authorization: Bearer <Supabase_Access_Token>
- Description: Activates a draft by setting an expiration timestamp.
- Headers:
Authorization: Bearer <Supabase_Access_Token> - Request Body:
{ "expiresAt": "2026-12-31T23:59:59Z" }
- Description: Fetches a draft by ID for public form rendering. Returns 410 if expired, 403 if not yet activated.
- Response:
{ "draft": { "title": "...", "config": { ... } } }
- Description: Submits form data to the Supabase
form_submissionstable and triggers email notification. - Request Body:
{ "field1": "value1", "field2": "value2" }
All endpoints require
Authorization: Bearer <Supabase_Access_Token>. Spreadsheet data is stored in MongoDB.
- Description: Lists all saved spreadsheets for the user (without sheet data).
- Response:
{ "spreadsheets": [{ "_id": "...", "name": "...", "updatedAt": "...", "createdAt": "..." }] }
- Description: Loads a specific spreadsheet with full FortuneSheet data.
- Response:
{ "spreadsheet": { "_id": "...", "name": "...", "sheets": [...], ... } }
- Description: Saves a new spreadsheet. Enforces 20-file limit.
- Request Body:
{ "name": "Q4 Team Roster", "sheets": [...] } - Response (success):
{ "message": "Spreadsheet saved", "spreadsheet": { ... } } - Response (limit reached — 409):
{ "error": "Spreadsheet limit reached", "limit": 20, "message": "..." }
- Description: Updates an existing spreadsheet by ID.
- Request Body:
{ "name": "Updated Name", "sheets": [...] }
- Description: Deletes a spreadsheet from MongoDB.
- Response:
{ "message": "Spreadsheet deleted successfully" }
- Description: Gets the current count and limit info.
- Response:
{ "count": 15, "limit": 20 }
All endpoints require
Authorization: Bearer <Supabase_Access_Token>.
- Description: Fetches all meetings for the user, ordered by creation date (newest first).
- Response:
{ "meetings": [{ "id": "...", "title": "...", "start_time": "...", ... }] }
- Description: Saves a new meeting to Supabase.
- Request Body:
{ "title": "...", "startTime": "...", "endTime": "...", "durationMinutes": 60, "attendees": [...], "aiProject": "...", "aiConfidence": 92, "requiresHumanReview": false }
- Description: Deletes a meeting by UUID.
- Response:
{ "message": "Meeting deleted" }
All endpoints require
Authorization: Bearer <Supabase_Access_Token>.
- Description: Fetches all alerts for the user, ordered by creation date (newest first).
- Response:
{ "alerts": [{ "id": "...", "type": "danger", "title": "...", "description": "...", "resolved": false }] }
- Description: Creates a new alert.
- Request Body:
{ "type": "danger", "title": "...", "description": "..." }
- Description: Marks an alert as resolved.
- Response:
{ "alert": { ... "resolved": true } }
- Description: Deletes an alert.
- Response:
{ "message": "Alert deleted" }
Note: These endpoints are served by the legacy Rust backend (
backend_rs/), not the Node.js server. They are documented for reference but are not part of the current active backend.
- Description: Uploads and ingests a
.txt,.docx, or.pdfdocument. - Request Body (Multipart Form):
file(File, required)scope(String, optional, default:"team")owner_id(String, required)team_id(String, required)chunk_size_tokens(Integer, optional, default:3000)chunk_overlap_tokens(Integer, optional, default:300)
- Description: Ingests multi-turn Slack conversation threads.
- Description: Returns summaries of all ingested documents.
- Description: Retrieves full details and chunks of a specific document.
- Description: Removes the document from the local JSON store.