Skip to content

← Back to DWS Receipts

All endpoints are Next.js API routes in app/api/. Authentication uses Supabase session cookies.

Sends SMS OTP to phone number.

Auth: None (public)

Request:

{ "phone": "+12223334444" }

Response:

{ "success": true, "message": "OTP sent successfully" }

Errors: 400 (invalid format), 500 (send failed)


Verifies OTP and creates session.

Auth: None (public)

Request:

{ "phone": "+12223334444", "token": "1234" }

Response:

{
"success": true,
"user": { ... },
"session": { "access_token": "...", "refresh_token": "..." }
}

Errors: 400 (invalid), 401 (wrong code)


Uploads image to temporary storage.

Auth: Required

Request: multipart/form-data with file field

Response:

{ "success": true, "tempFilePath": "user-id/temp_abc123_1234567890.jpg" }

Errors: 400 (invalid file), 401 (unauthorized)


Extracts data from receipt image using AI.

Auth: Required

Request:

{ "tempFilePath": "user-id/temp_abc123_1234567890.jpg" }

Response:

{
"success": true,
"data": {
"date": "2025-01-15",
"amount": 42.99,
"category": "Office Supplies",
"category_id": "uuid"
},
"duplicate": { "isDuplicate": false, "existingReceipts": [] },
"canAutoSubmit": true
}

Creates receipt record and finalizes image storage.

Auth: Required

Request:

{
"receipt_date": "2025-01-15",
"amount": 42.99,
"category_id": "uuid",
"notes": "Office supplies",
"tempFilePath": "user-id/temp_abc123.jpg"
}

Response:

{
"success": true,
"receipt": { "id": "...", "status": "Pending", ... }
}

Fetches user’s receipts with category names.

Auth: Required

Response:

{
"success": true,
"receipts": [
{
"id": "uuid",
"date": "2025-01-15",
"amount": 42.99,
"status": "pending",
"category": "Office Supplies",
"image_url": "https://..."
}
]
}

Updates receipt fields.

Auth: Required (owner or admin)

Request:

{
"id": "receipt-uuid",
"receipt_date": "2025-01-16",
"amount": 50.00,
"category_id": "uuid",
"notes": "Updated notes"
}

Permissions:

  • Employees: Own pending receipts only
  • Admins: Any receipt

Deletes receipt and associated image.

Auth: Required (owner or admin)

Permissions:

  • Employees: Own pending receipts only
  • Admins: Any receipt

Bulk status update (admin only).

Auth: Admin required

Request:

{ "fromStatus": "Approved", "toStatus": "Reimbursed" }

Response:

{
"success": true,
"message": "Successfully updated 15 receipts",
"updatedCount": 15
}

Note: Only supports Approved → Reimbursed transition.


Fetches all receipts with user info and phone numbers.

Auth: Admin required

Query Params:

  • status: Filter by status
  • fromDate: Start date (YYYY-MM-DD)
  • toDate: End date (YYYY-MM-DD)

Response:

{
"success": true,
"receipts": [
{
"id": "uuid",
"employeeName": "John Doe",
"employeeId": "EMP123",
"phone": "+12223334444",
...
}
]
}

Lists all users with profiles.

Auth: Admin required

Query Params:

  • page: Page number (default: 1)
  • perPage: Results per page (default: 50)
  • search: Search name/phone/ID
  • includeDeleted: Include banned users

Creates new user.

Auth: Admin required

Request:

{
"phone": "2223334444",
"full_name": "John Doe",
"role": "employee"
}

Fetches single user details.

Auth: Admin required


Updates user details.

Auth: Admin required

Request:

{
"phone": "3334445555",
"full_name": "Jane Doe",
"role": "admin"
}

Bans user (soft delete).

Auth: Admin required

Note: Cannot ban yourself.


Fetches all categories.

Auth: None required (public data)

Response:

{
"success": true,
"categories": [
{ "id": "uuid", "name": "Parking" },
{ "id": "uuid", "name": "Gas" }
]
}

All errors follow this pattern:

{ "error": "Error message here" }
StatusMeaning
400Bad request / validation error
401Not authenticated
403Not authorized (wrong role)
404Resource not found
409Conflict (duplicate)
500Server error