{"info":{"_postman_id":"219aa612-5fca-466b-a1cf-1c7a94194f38","name":"Expense Tracker API","description":"<html><head></head><body><p>Team-based expense management API with multi-step approval workflows, receipt uploads, commenting, and role-scoped reporting. Built with Laravel 13 + Sanctum.</p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"53937112","collectionId":"219aa612-5fca-466b-a1cf-1c7a94194f38","publishedId":"2sBXitCnJ4","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"publishDate":"2026-04-11T13:28:44.000Z"},"item":[{"name":"Auth","item":[{"name":"Register","id":"978371f0-2329-4186-a723-8c34bbb7a73b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"name\": \"Jane Doe\",\n  \"email\": \"jane@example.com\",\n  \"password\": \"password\",\n  \"password_confirmation\": \"password\",\n  \"team_id\": 1\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/register","description":"<p>Register a new user. <code>team_id</code> is required — users must belong to a team.</p>\n","urlObject":{"path":["api","register"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"3167af72-3c5b-4fd1-95da-50ae93da7ca9","name":"201 Created","originalRequest":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"name\": \"Jane Doe\",\n  \"email\": \"jane@example.com\",\n  \"password\": \"password\",\n  \"password_confirmation\": \"password\",\n  \"team_id\": 1\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/register","description":"Register a new user. `team_id` is required — users must belong to a team."},"status":"Created","code":201,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"user\": {\n    \"id\": 1,\n    \"name\": \"Jane Doe\",\n    \"email\": \"jane@example.com\",\n    \"role\": \"member\",\n    \"team_id\": 1,\n    \"is_active\": true\n  },\n  \"token\": \"1|abc123...\"\n}"}],"_postman_id":"978371f0-2329-4186-a723-8c34bbb7a73b"},{"name":"Login","id":"89fa3aff-2257-49ce-b1a6-c49a1a2a3678","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"jane@example.com\",\n  \"password\": \"password\"\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/login","description":"<p>Login and receive a Bearer token. Returns 401 if credentials are wrong or the account is inactive.</p>\n","urlObject":{"path":["api","login"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"769d569b-6925-4bb1-8597-c7ac9830ff95","name":"200 OK","originalRequest":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"jane@example.com\",\n  \"password\": \"password\"\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/login","description":"Login and receive a Bearer token. Returns 401 if credentials are wrong or the account is inactive."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"user\": {\n    \"id\": 1,\n    \"name\": \"Jane Doe\",\n    \"email\": \"jane@example.com\",\n    \"role\": \"member\",\n    \"team_id\": 1,\n    \"is_active\": true\n  },\n  \"token\": \"2|xyz789...\"\n}"},{"id":"5b1f9d2d-6f14-4db9-9888-ce7d30e7e767","name":"401 Invalid credentials","originalRequest":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"jane@example.com\",\n  \"password\": \"password\"\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/login","description":"Login and receive a Bearer token. Returns 401 if credentials are wrong or the account is inactive."},"status":"Unauthorized","code":401,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Invalid credentials.\"\n}"}],"_postman_id":"89fa3aff-2257-49ce-b1a6-c49a1a2a3678"},{"name":"Logout","id":"3f09815a-9c3f-4eb7-b0f8-6e6b27ffacce","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/logout","description":"<p>Revoke all tokens for the authenticated user.</p>\n","urlObject":{"path":["api","logout"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"5d814a2a-5b61-46c5-ae7c-d410d8b28347","name":"200 OK","originalRequest":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/logout","description":"Revoke all tokens for the authenticated user."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Logged out successfully.\"\n}"}],"_postman_id":"3f09815a-9c3f-4eb7-b0f8-6e6b27ffacce"}],"id":"20ad3f31-646a-43d9-93d3-573d4c7d40dd","_postman_id":"20ad3f31-646a-43d9-93d3-573d4c7d40dd","description":""},{"name":"Categories","item":[{"name":"List Categories","id":"83080b81-b2ae-48b4-bb0b-c772c1661669","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/categories","description":"<p>List all categories. Non-admins see only active categories.</p>\n","urlObject":{"path":["api","categories"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"961b2f9c-ae91-43f6-9a48-b2b200d5c354","name":"200 OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/categories","description":"List all categories. Non-admins see only active categories."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": [\n    { \"id\": 1, \"name\": \"Travel\", \"description\": \"Flights, hotels, transport\", \"is_active\": true },\n    { \"id\": 2, \"name\": \"Meals\", \"description\": \"Business meals\", \"is_active\": true }\n  ]\n}"}],"_postman_id":"83080b81-b2ae-48b4-bb0b-c772c1661669"},{"name":"Create Category","id":"53825c03-ebdd-4034-a7de-465567fa4a22","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"raw","raw":"{\n  \"name\": \"Equipment\",\n  \"description\": \"Hardware, software, peripherals\"\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/categories","description":"<p>Create a new category. Admin only — returns 403 for other roles.</p>\n","urlObject":{"path":["api","categories"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"3d6b3a6c-7dca-439b-9213-27de0c90406a","name":"201 Created","originalRequest":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"raw","raw":"{\n  \"name\": \"Equipment\",\n  \"description\": \"Hardware, software, peripherals\"\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/categories","description":"Create a new category. Admin only — returns 403 for other roles."},"status":"Created","code":201,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": {\n    \"id\": 3,\n    \"name\": \"Equipment\",\n    \"description\": \"Hardware, software, peripherals\",\n    \"is_active\": true\n  }\n}"}],"_postman_id":"53825c03-ebdd-4034-a7de-465567fa4a22"}],"id":"57d4a6bc-9351-4e79-a959-ac6d10705685","_postman_id":"57d4a6bc-9351-4e79-a959-ac6d10705685","description":""},{"name":"Expenses","item":[{"name":"List Expenses","id":"3818eb4e-1193-4a4e-94d4-3450a54c40a8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses","description":"<p>List expenses. Members see their own; managers see their team's; admins see all.</p>\n","urlObject":{"path":["api","expenses"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[{"disabled":true,"description":{"content":"<p>draft | pending | approved | rejected</p>\n","type":"text/plain"},"key":"status","value":"pending"},{"disabled":true,"key":"category_id","value":"1"},{"disabled":true,"key":"date_from","value":"2026-01-01"},{"disabled":true,"key":"date_to","value":"2026-12-31"},{"disabled":true,"key":"amount_min","value":"50"},{"disabled":true,"key":"amount_max","value":"1000"},{"disabled":true,"description":{"content":"<p>Prefix - for descending. Options: amount, date, title, created_at</p>\n","type":"text/plain"},"key":"sort","value":"-amount"},{"disabled":true,"description":{"content":"<p>Max 50</p>\n","type":"text/plain"},"key":"per_page","value":"15"},{"disabled":true,"key":"cursor","value":""}],"variable":[]}},"response":[{"id":"9176f0a5-89b0-4305-b973-b1a8e175d526","name":"200 OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":{"raw":"https://expense-tracker-api-ndhp.onrender.com/api/expenses","host":["https://expense-tracker-api-ndhp.onrender.com"],"path":["api","expenses"],"query":[{"key":"status","value":"pending","description":"draft | pending | approved | rejected","disabled":true},{"key":"category_id","value":"1","disabled":true},{"key":"date_from","value":"2026-01-01","disabled":true},{"key":"date_to","value":"2026-12-31","disabled":true},{"key":"amount_min","value":"50","disabled":true},{"key":"amount_max","value":"1000","disabled":true},{"key":"sort","value":"-amount","description":"Prefix - for descending. Options: amount, date, title, created_at","disabled":true},{"key":"per_page","value":"15","description":"Max 50","disabled":true},{"key":"cursor","value":"","disabled":true}]},"description":"List expenses. Members see their own; managers see their team's; admins see all."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"title\": \"Hotel in London\",\n      \"amount\": \"450.00\",\n      \"date\": \"2026-03-15\",\n      \"status\": \"pending\",\n      \"category\": { \"id\": 1, \"name\": \"Travel\" },\n      \"user\": { \"id\": 2, \"name\": \"Jane Doe\" },\n      \"team\": { \"id\": 1, \"name\": \"Engineering\" }\n    }\n  ],\n  \"meta\": {\n    \"next_cursor\": \"eyJpZCI6MX0=\",\n    \"prev_cursor\": null,\n    \"per_page\": 15\n  }\n}"}],"_postman_id":"3818eb4e-1193-4a4e-94d4-3450a54c40a8"},{"name":"Create Expense","id":"9a178ee0-6f1d-4834-8507-b9756f6304ae","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"raw","raw":"{\n  \"title\": \"Hotel in London\",\n  \"description\": \"3 nights for client meeting\",\n  \"amount\": 450.00,\n  \"category_id\": 1,\n  \"date\": \"2026-03-15\"\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses","description":"<p>Create a draft expense. <code>amount</code> must be greater than 0. <code>date</code> must be today or earlier. The category must be active.</p>\n","urlObject":{"path":["api","expenses"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"8f7b867e-387f-4af6-8b47-9eca46688f90","name":"201 Created","originalRequest":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"raw","raw":"{\n  \"title\": \"Hotel in London\",\n  \"description\": \"3 nights for client meeting\",\n  \"amount\": 450.00,\n  \"category_id\": 1,\n  \"date\": \"2026-03-15\"\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses","description":"Create a draft expense. `amount` must be greater than 0. `date` must be today or earlier. The category must be active."},"status":"Created","code":201,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"title\": \"Hotel in London\",\n    \"amount\": \"450.00\",\n    \"date\": \"2026-03-15\",\n    \"status\": \"draft\",\n    \"category\": { \"id\": 1, \"name\": \"Travel\" },\n    \"user\": { \"id\": 2, \"name\": \"Jane Doe\" },\n    \"receipts\": []\n  }\n}"}],"_postman_id":"9a178ee0-6f1d-4834-8507-b9756f6304ae"},{"name":"Show Expense","id":"b431e2dc-ad88-493d-b3ad-3e9b2818960b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1","description":"<p>Get a single expense with receipts loaded. Returns 403 if not authorized.</p>\n","urlObject":{"path":["api","expenses","1"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"ffd1fe08-7c48-4de0-b623-f1267654475c","name":"200 OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1","description":"Get a single expense with receipts loaded. Returns 403 if not authorized."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"title\": \"Hotel in London\",\n    \"description\": \"3 nights for client meeting\",\n    \"amount\": \"450.00\",\n    \"date\": \"2026-03-15\",\n    \"status\": \"approved\",\n    \"rejection_reason\": null,\n    \"reviewer\": { \"id\": 3, \"name\": \"Admin User\" },\n    \"reviewed_at\": \"2026-03-16T10:00:00Z\",\n    \"category\": { \"id\": 1, \"name\": \"Travel\" },\n    \"user\": { \"id\": 2, \"name\": \"Jane Doe\" },\n    \"team\": { \"id\": 1, \"name\": \"Engineering\" },\n    \"receipts\": [{ \"id\": 1, \"original_name\": \"hotel_receipt.pdf\" }]\n  }\n}"}],"_postman_id":"b431e2dc-ad88-493d-b3ad-3e9b2818960b"},{"name":"Update Expense","id":"30ccc45a-616c-4c75-ad6f-24049b0c8b99","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PUT","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"raw","raw":"{\n  \"title\": \"Hotel in London (updated)\",\n  \"amount\": 480.00\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1","description":"<p>Partial update. Only allowed on Draft or Rejected expenses. Owner only.</p>\n","urlObject":{"path":["api","expenses","1"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"94481e03-e88a-4ded-bc7d-485a66adba9d","name":"200 OK","originalRequest":{"method":"PUT","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"raw","raw":"{\n  \"title\": \"Hotel in London (updated)\",\n  \"amount\": 480.00\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1","description":"Partial update. Only allowed on Draft or Rejected expenses. Owner only."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"title\": \"Hotel in London (updated)\",\n    \"amount\": \"480.00\",\n    \"status\": \"draft\"\n  }\n}"}],"_postman_id":"30ccc45a-616c-4c75-ad6f-24049b0c8b99"},{"name":"Delete Expense","id":"dacc5d6c-5238-4d6f-bad7-b9684e639051","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"DELETE","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1","description":"<p>Delete a draft expense. Soft-deleted — record is preserved. Owner only.</p>\n","urlObject":{"path":["api","expenses","1"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"2347f418-4ab0-423f-a613-b97cbf4c6136","name":"200 OK","originalRequest":{"method":"DELETE","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1","description":"Delete a draft expense. Soft-deleted — record is preserved. Owner only."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Expense deleted.\"\n}"}],"_postman_id":"dacc5d6c-5238-4d6f-bad7-b9684e639051"}],"id":"c4722b77-efab-4020-bdf2-3ff417a25b2c","_postman_id":"c4722b77-efab-4020-bdf2-3ff417a25b2c","description":""},{"name":"Workflow","item":[{"name":"Submit Expense","id":"19d5ec20-0aed-4336-8659-a9d3098354e1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/submit","description":"<p>Submit a Draft or Rejected expense for review. Moves status to Pending. Owner only.</p>\n","urlObject":{"path":["api","expenses","1","submit"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"0c6cd129-3fb7-4be9-9961-f9ccd5cc6b61","name":"200 OK","originalRequest":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/submit","description":"Submit a Draft or Rejected expense for review. Moves status to Pending. Owner only."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"status\": \"pending\",\n    \"rejection_reason\": null\n  }\n}"}],"_postman_id":"19d5ec20-0aed-4336-8659-a9d3098354e1"},{"name":"Approve Expense","id":"074eb582-8f35-4afa-92da-06a42915e9ff","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/approve","description":"<p>Approve a Pending expense. Admin or Manager (same team as expense) only.</p>\n","urlObject":{"path":["api","expenses","1","approve"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"852ac9ec-cec5-4e0c-a204-4aa1b8bb57f3","name":"200 OK","originalRequest":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/approve","description":"Approve a Pending expense. Admin or Manager (same team as expense) only."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"status\": \"approved\",\n    \"reviewer\": { \"id\": 3, \"name\": \"Admin User\" },\n    \"reviewed_at\": \"2026-04-11T09:00:00Z\"\n  }\n}"}],"_postman_id":"074eb582-8f35-4afa-92da-06a42915e9ff"},{"name":"Reject Expense","id":"1c6997d2-6831-4840-8fe0-5cb5fa627ab7","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"raw","raw":"{\n  \"rejection_reason\": \"Missing receipt for hotel stay\"\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/reject","description":"<p>Reject a Pending expense with a reason. Admin or Manager (same team) only.</p>\n","urlObject":{"path":["api","expenses","1","reject"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"948e084c-aab6-43e3-8f3c-6d4512bc46a0","name":"200 OK","originalRequest":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"raw","raw":"{\n  \"rejection_reason\": \"Missing receipt for hotel stay\"\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/reject","description":"Reject a Pending expense with a reason. Admin or Manager (same team) only."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"status\": \"rejected\",\n    \"rejection_reason\": \"Missing receipt for hotel stay\",\n    \"reviewer\": { \"id\": 3, \"name\": \"Admin User\" },\n    \"reviewed_at\": \"2026-04-11T09:05:00Z\"\n  }\n}"}],"_postman_id":"1c6997d2-6831-4840-8fe0-5cb5fa627ab7"}],"id":"91087ad3-16ef-4421-94e2-604a755b227a","_postman_id":"91087ad3-16ef-4421-94e2-604a755b227a","description":""},{"name":"Receipts","item":[{"name":"Upload Receipt","id":"2cc60f67-ae62-4c00-ab6d-3d9862e49bd9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"formdata","formdata":[{"key":"file","type":"file","description":"<p>Accepted: jpg, jpeg, png, pdf. Max: 10MB</p>\n","value":null}]},"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/receipts","description":"<p>Upload a receipt file for an expense. Accepted formats: jpg, jpeg, png, pdf. Max 10MB. Owner only.</p>\n","urlObject":{"path":["api","expenses","1","receipts"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"6ac85f8a-dc0d-4a09-9fc7-f7e202397574","name":"201 Created","originalRequest":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"formdata","formdata":[{"key":"file","type":"file","description":"Accepted: jpg, jpeg, png, pdf. Max: 10MB","value":null}]},"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/receipts","description":"Upload a receipt file for an expense. Accepted formats: jpg, jpeg, png, pdf. Max 10MB. Owner only."},"status":"Created","code":201,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"original_name\": \"hotel_receipt.pdf\",\n    \"mime_type\": \"application/pdf\",\n    \"size\": 204800\n  }\n}"}],"_postman_id":"2cc60f67-ae62-4c00-ab6d-3d9862e49bd9"},{"name":"List Receipts","id":"8fe2b919-b59c-44e2-b179-383ae935727b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/receipts","description":"<p>List all receipts for an expense.</p>\n","urlObject":{"path":["api","expenses","1","receipts"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"186f4a4b-e49c-4dba-b937-208a14402e68","name":"200 OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/receipts","description":"List all receipts for an expense."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"original_name\": \"hotel_receipt.pdf\",\n      \"mime_type\": \"application/pdf\",\n      \"size\": 204800\n    }\n  ]\n}"}],"_postman_id":"8fe2b919-b59c-44e2-b179-383ae935727b"},{"name":"Download Receipt","id":"e9ccec69-4395-4afd-993f-e72a304c2fd0","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/receipts/1/download","description":"<p>Stream-download a receipt file. Response is the file binary.</p>\n","urlObject":{"path":["api","receipts","1","download"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[],"_postman_id":"e9ccec69-4395-4afd-993f-e72a304c2fd0"},{"name":"Delete Receipt","id":"bc83cb22-c1cd-43d9-b8b2-a5f9e5ebe901","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"DELETE","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/receipts/1","description":"<p>Delete a receipt. Removes the file from storage and the database record. Only allowed if the expense is in Draft status. Owner only.</p>\n","urlObject":{"path":["api","receipts","1"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"6ab4d8ec-8c81-4a3b-aae8-574467e47751","name":"200 OK","originalRequest":{"method":"DELETE","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/receipts/1","description":"Delete a receipt. Removes the file from storage and the database record. Only allowed if the expense is in Draft status. Owner only."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Receipt deleted.\"\n}"}],"_postman_id":"bc83cb22-c1cd-43d9-b8b2-a5f9e5ebe901"}],"id":"c2fca8ff-3163-4a83-bf5b-a70076118264","_postman_id":"c2fca8ff-3163-4a83-bf5b-a70076118264","description":""},{"name":"Comments","item":[{"name":"Add Comment","id":"6085cf74-420c-4bce-8465-ea10540dd0d1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"raw","raw":"{\n  \"body\": \"Please attach the original receipt PDF.\"\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/comments","description":"<p>Add a comment to an expense. Max 2000 characters. Auth users who can view the expense can comment.</p>\n","urlObject":{"path":["api","expenses","1","comments"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"1e375c84-e17a-4ddf-b2ff-60e86a9fcaf8","name":"201 Created","originalRequest":{"method":"POST","header":[{"key":"Accept","value":"application/json"},{"key":"Content-Type","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"body":{"mode":"raw","raw":"{\n  \"body\": \"Please attach the original receipt PDF.\"\n}"},"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/comments","description":"Add a comment to an expense. Max 2000 characters. Auth users who can view the expense can comment."},"status":"Created","code":201,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": {\n    \"id\": 1,\n    \"body\": \"Please attach the original receipt PDF.\",\n    \"user\": { \"id\": 3, \"name\": \"Admin User\" },\n    \"created_at\": \"2026-04-11T09:10:00Z\"\n  }\n}"}],"_postman_id":"6085cf74-420c-4bce-8465-ea10540dd0d1"},{"name":"List Comments","id":"b77e8e73-c5ae-4db2-83f3-09bcdeb1b63f","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/comments","description":"<p>List all comments for an expense, newest first.</p>\n","urlObject":{"path":["api","expenses","1","comments"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"9d6fdff0-f870-4c89-9b5a-9087b3febd60","name":"200 OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/expenses/1/comments","description":"List all comments for an expense, newest first."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"body\": \"Please attach the original receipt PDF.\",\n      \"user\": { \"id\": 3, \"name\": \"Admin User\" },\n      \"created_at\": \"2026-04-11T09:10:00Z\"\n    }\n  ]\n}"}],"_postman_id":"b77e8e73-c5ae-4db2-83f3-09bcdeb1b63f"},{"name":"Delete Comment","id":"3e2e2490-eac1-4d73-b7ec-bdfb10b4de8d","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"DELETE","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/comments/1","description":"<p>Delete a comment. The user who created the comment can delete it.</p>\n","urlObject":{"path":["api","comments","1"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"c999f221-cb8e-4411-ae5d-62e112190437","name":"200 OK","originalRequest":{"method":"DELETE","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/comments/1","description":"Delete a comment. The user who created the comment can delete it."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Comment deleted.\"\n}"}],"_postman_id":"3e2e2490-eac1-4d73-b7ec-bdfb10b4de8d"}],"id":"5dc69d2a-4b8b-4e20-93ea-0bf6f43eac00","_postman_id":"5dc69d2a-4b8b-4e20-93ea-0bf6f43eac00","description":""},{"name":"Reports","item":[{"name":"Team Summary","id":"7e08ca44-fbc3-4cd1-a6d1-8bf0b9c9e9b9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/reports/team-summary","description":"<p>Aggregate totals for approved expenses. Admin or Manager only. Managers see their team only.</p>\n","urlObject":{"path":["api","reports","team-summary"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[{"disabled":true,"key":"date_from","value":"2026-01-01"},{"disabled":true,"key":"date_to","value":"2026-12-31"}],"variable":[]}},"response":[{"id":"80861bcc-e483-46d7-b80a-2d474312d20f","name":"200 OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":{"raw":"https://expense-tracker-api-ndhp.onrender.com/api/reports/team-summary","host":["https://expense-tracker-api-ndhp.onrender.com"],"path":["api","reports","team-summary"],"query":[{"key":"date_from","value":"2026-01-01","disabled":true},{"key":"date_to","value":"2026-12-31","disabled":true}]},"description":"Aggregate totals for approved expenses. Admin or Manager only. Managers see their team only."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": {\n    \"total_amount\": \"12450.00\",\n    \"total_count\": 34,\n    \"average_amount\": \"366.18\"\n  }\n}"}],"_postman_id":"7e08ca44-fbc3-4cd1-a6d1-8bf0b9c9e9b9"},{"name":"By Category","id":"43a8e601-7a08-4911-b04e-6510743c7913","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/reports/by-category","description":"<p>Approved expense totals grouped by category, sorted by amount descending. Admin or Manager only.</p>\n","urlObject":{"path":["api","reports","by-category"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[{"disabled":true,"key":"date_from","value":"2026-01-01"},{"disabled":true,"key":"date_to","value":"2026-12-31"}],"variable":[]}},"response":[{"id":"d1a8787a-7208-45ca-9020-387436a0d5f1","name":"200 OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":{"raw":"https://expense-tracker-api-ndhp.onrender.com/api/reports/by-category","host":["https://expense-tracker-api-ndhp.onrender.com"],"path":["api","reports","by-category"],"query":[{"key":"date_from","value":"2026-01-01","disabled":true},{"key":"date_to","value":"2026-12-31","disabled":true}]},"description":"Approved expense totals grouped by category, sorted by amount descending. Admin or Manager only."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": [\n    { \"category_id\": 1, \"category_name\": \"Travel\", \"total_amount\": \"7800.00\", \"total_count\": 18 },\n    { \"category_id\": 2, \"category_name\": \"Meals\", \"total_amount\": \"2300.00\", \"total_count\": 12 }\n  ]\n}"}],"_postman_id":"43a8e601-7a08-4911-b04e-6510743c7913"},{"name":"By Member","id":"b64e2b2e-a9ca-4440-8d13-3a738ee3bd6b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/reports/by-member","description":"<p>Approved expense totals grouped by team member, sorted by amount descending. Admin or Manager only.</p>\n","urlObject":{"path":["api","reports","by-member"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[{"disabled":true,"key":"date_from","value":"2026-01-01"},{"disabled":true,"key":"date_to","value":"2026-12-31"}],"variable":[]}},"response":[{"id":"76ce7f9d-afd1-4184-a95e-0b2611bef509","name":"200 OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":{"raw":"https://expense-tracker-api-ndhp.onrender.com/api/reports/by-member","host":["https://expense-tracker-api-ndhp.onrender.com"],"path":["api","reports","by-member"],"query":[{"key":"date_from","value":"2026-01-01","disabled":true},{"key":"date_to","value":"2026-12-31","disabled":true}]},"description":"Approved expense totals grouped by team member, sorted by amount descending. Admin or Manager only."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"data\": [\n    { \"user_id\": 2, \"user_name\": \"Jane Doe\", \"total_amount\": \"4500.00\", \"total_count\": 10 },\n    { \"user_id\": 4, \"user_name\": \"John Smith\", \"total_amount\": \"3200.00\", \"total_count\": 8 }\n  ]\n}"}],"_postman_id":"b64e2b2e-a9ca-4440-8d13-3a738ee3bd6b"}],"id":"cc55e1e1-b3ff-4c3d-b3dd-597e79821e6e","_postman_id":"cc55e1e1-b3ff-4c3d-b3dd-597e79821e6e","description":""},{"name":"Admin","item":[{"name":"Toggle User Active","id":"0ea14783-fe81-4e6f-a692-23443b40b13a","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/admin/users/2/toggle-active","description":"<p>Activate or deactivate a user account. Admin only. Deactivated users cannot log in.</p>\n","urlObject":{"path":["api","admin","users","2","toggle-active"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"b1d10800-7e4c-4f78-b9e3-a964146c5988","name":"200 OK — Deactivated","originalRequest":{"method":"PATCH","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/admin/users/2/toggle-active","description":"Activate or deactivate a user account. Admin only. Deactivated users cannot log in."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"User deactivated.\",\n  \"user\": { \"id\": 2, \"name\": \"Jane Doe\", \"is_active\": false }\n}"},{"id":"73093c4c-7f74-45a2-b160-a36c59be769c","name":"200 OK — Activated","originalRequest":{"method":"PATCH","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/admin/users/2/toggle-active","description":"Activate or deactivate a user account. Admin only. Deactivated users cannot log in."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"User activated.\",\n  \"user\": { \"id\": 2, \"name\": \"Jane Doe\", \"is_active\": true }\n}"}],"_postman_id":"0ea14783-fe81-4e6f-a692-23443b40b13a"},{"name":"Toggle Team Active","id":"0ba92ac7-ca34-4fa5-8ef3-fedf4ba3140f","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/admin/teams/1/toggle-active","description":"<p>Activate or deactivate a team. Admin only.</p>\n","urlObject":{"path":["api","admin","teams","1","toggle-active"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"eae0d534-9504-4309-a265-20d31df284c4","name":"200 OK","originalRequest":{"method":"PATCH","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/admin/teams/1/toggle-active","description":"Activate or deactivate a team. Admin only."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Team deactivated.\",\n  \"team\": { \"id\": 1, \"name\": \"Engineering\", \"is_active\": false }\n}"}],"_postman_id":"0ba92ac7-ca34-4fa5-8ef3-fedf4ba3140f"},{"name":"Toggle Category Active","id":"fb29a1b7-3169-44f9-93da-edb0980805cb","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/admin/categories/1/toggle-active","description":"<p>Activate or deactivate a category. Admin only. Inactive categories cannot be used in new expenses.</p>\n","urlObject":{"path":["api","admin","categories","1","toggle-active"],"host":["https://expense-tracker-api-ndhp.onrender.com"],"query":[],"variable":[]}},"response":[{"id":"c5295029-7df3-4c42-9882-312297e4dd61","name":"200 OK","originalRequest":{"method":"PATCH","header":[{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer "}],"url":"https://expense-tracker-api-ndhp.onrender.com/api/admin/categories/1/toggle-active","description":"Activate or deactivate a category. Admin only. Inactive categories cannot be used in new expenses."},"status":"OK","code":200,"_postman_previewlanguage":"Text","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Category deactivated.\",\n  \"category\": { \"id\": 1, \"name\": \"Travel\", \"is_active\": false }\n}"}],"_postman_id":"fb29a1b7-3169-44f9-93da-edb0980805cb"}],"id":"c75db2f2-fbe6-487e-905c-8e5da94aaa03","_postman_id":"c75db2f2-fbe6-487e-905c-8e5da94aaa03","description":""}],"event":[{"listen":"prerequest","script":{"id":"c7d1744b-ca80-444d-908b-a72e18680324","type":"text/javascript","packages":{},"requests":{},"exec":[""]}},{"listen":"test","script":{"id":"b0dc79a8-76ef-4279-a13d-1ad0c7ef099a","type":"text/javascript","packages":{},"requests":{},"exec":[""]}}],"variable":[{"key":"base_url","value":"https://expense-tracker-api-ndhp.onrender.com"},{"key":"token","value":"","description":"Paste your Bearer token here after login"}]}