{"openapi":"3.1.0","info":{"title":"TimeTrack API","description":"Time tracking SaaS — Clockify alternative","version":"1.0.0"},"paths":{"/api/v1/api-keys":{"get":{"tags":["api-keys"],"summary":"List Api Keys","description":"List all API keys for the authenticated user (without raw key).","operationId":"list_api_keys_api_v1_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["api-keys"],"summary":"Create Api Key","description":"Create a new API key for the authenticated user.\n\nThe raw key is returned ONLY in this response. Store it securely.\nMax 1 active key per account.\n\nArgs:\n    name: Optional name/label for the key (default: 'Default').\n\nReturns:\n    The full key details INCLUDING raw_key (one-time only).","operationId":"create_api_key_api_v1_api_keys_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/api-keys/{key_id}":{"delete":{"tags":["api-keys"],"summary":"Revoke Api Key","description":"Revoke (soft-delete) an API key. It will no longer work.","operationId":"revoke_api_key_api_v1_api_keys__key_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/api-keys/stats":{"get":{"tags":["api-keys"],"summary":"Get Api Key Stats","description":"Get usage stats for the user's active API key.\n\nOnly works if the user has exactly one active key.","operationId":"get_api_key_stats_api_v1_api_keys_stats_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","description":"Period: 24h, 7d, 30d, 90d","default":"30d","title":"Period"},"description":"Period: 24h, 7d, 30d, 90d"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/api-keys/export":{"get":{"tags":["api-keys"],"summary":"Export Api Key Usage","description":"Export usage logs as CSV for the user's active API key.","operationId":"export_api_key_usage_api_v1_api_keys_export_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","description":"Period: 30d, 90d, all","default":"90d","title":"Period"},"description":"Period: 30d, 90d, all"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/plans":{"get":{"tags":["billing"],"summary":"Get Plans","description":"Return cached pricing plans from Stripe.\n\nPublic endpoint — no authentication required.\nCache TTL is 10 minutes. Falls back to cache if Stripe is unreachable.\nUse ?refresh=true to force a fresh fetch from Stripe.","operationId":"get_plans_api_v1_billing_plans_get","parameters":[{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Refresh"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlansResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/create-checkout-session":{"post":{"tags":["billing"],"summary":"Create Checkout Session","description":"Create a Stripe Checkout Session for the authenticated user's organization.\n\nRequires authentication. Uses the user's org from their token.","operationId":"create_checkout_session_api_v1_billing_create_checkout_session_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutCreateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/billing/create-portal-session":{"post":{"tags":["billing"],"summary":"Create Portal Session","description":"Create a Stripe Billing Portal session for the authenticated user's organization.\n\nRequires authentication. Customer must already exist.","operationId":"create_portal_session_api_v1_billing_create_portal_session_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalCreateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/billing/webhook":{"post":{"tags":["billing"],"summary":"Stripe Webhook","description":"Handle incoming Stripe webhook events.\n\nNo authentication — relies on Stripe webhook signature verification.\nThe raw request body is required for signature verification.","operationId":"stripe_webhook_api_v1_billing_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/billing/subscription":{"get":{"tags":["billing"],"summary":"Get Subscription","description":"Get the current subscription status for the authenticated user's organization.\n\nReturns the plan type, subscription status, and related Stripe info.","operationId":"get_subscription_api_v1_billing_subscription_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/health":{"get":{"tags":["health"],"summary":"Health Check","operationId":"health_check_api_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/ready":{"get":{"tags":["health"],"summary":"Ready Check","operationId":"ready_check_api_v1_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/config":{"get":{"tags":["health"],"summary":"Get Config","description":"Return Auth configuration (Clerk publishable key) for frontend initialization.","operationId":"get_config_api_v1_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/organization":{"get":{"tags":["organization"],"summary":"Get Organization","description":"Get the user's current organization (or first one if multiple).","operationId":"get_organization_api_v1_organization_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["organization"],"summary":"Update Organization","description":"Update organization settings. Admin only.","operationId":"update_organization_api_v1_organization_put","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Update"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["organization"],"summary":"Create Organization","description":"Create a new organization. The creator becomes the owner.\n\nOnly users with 'multiple_orgs' feature can create more than one org.","operationId":"create_organization_api_v1_organization_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Org Data"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/organization/all":{"get":{"tags":["organization"],"summary":"List User Organizations","description":"List ALL organizations this user belongs to.\n\nUsed by frontend to populate team selector dropdown.","operationId":"list_user_organizations_api_v1_organization_all_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/organization/{org_id}/invite":{"post":{"tags":["organization"],"summary":"Invite User","description":"Invite a user to the organization.\n\nAdmin/Manager only. Creates an invitation token sent via email.","operationId":"invite_user_api_v1_organization__org_id__invite_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organization/invitations":{"get":{"tags":["organization"],"summary":"Get My Invitations","description":"Get pending invitations for the current user.","operationId":"get_my_invitations_api_v1_organization_invitations_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/organization/join":{"post":{"tags":["organization"],"summary":"Join Organization","description":"Join an organization using invitation token.","operationId":"join_organization_api_v1_organization_join_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/organization/{org_id}/members":{"get":{"tags":["organization"],"summary":"List Organization Members","description":"List all members of an organization. Admin/Manager only.","operationId":"list_organization_members_api_v1_organization__org_id__members_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organization/{org_id}/members/{member_id}":{"delete":{"tags":["organization"],"summary":"Remove Member","description":"Remove a member from organization. Admin only.","operationId":"remove_member_api_v1_organization__org_id__members__member_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}},{"name":"member_id","in":"path","required":true,"schema":{"type":"string","title":"Member Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/members":{"get":{"tags":["members"],"summary":"List Members","description":"List all members of the current user's organization.","operationId":"list_members_api_v1_members_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/members/invite":{"post":{"tags":["members"],"summary":"Invite Member","description":"Invite a new member to the organization. Admin only.","operationId":"invite_member_api_v1_members_invite_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Invite"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/members/{member_id}/role":{"put":{"tags":["members"],"summary":"Update Role","description":"Change a member's role. Admin only.","operationId":"update_role_api_v1_members__member_id__role_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"member_id","in":"path","required":true,"schema":{"type":"string","title":"Member Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Role Data"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/members/{member_id}":{"delete":{"tags":["members"],"summary":"Remove Member","description":"Remove a member. Admin only.","operationId":"remove_member_api_v1_members__member_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"member_id","in":"path","required":true,"schema":{"type":"string","title":"Member Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/members/{member_id}/status":{"put":{"tags":["members"],"summary":"Update Member Status","description":"Toggle or set a member's active status. Admin only.","operationId":"update_member_status_api_v1_members__member_id__status_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"member_id","in":"path","required":true,"schema":{"type":"string","title":"Member Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Status Data"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/time-entries/active":{"get":{"tags":["time-entries"],"summary":"Get Active Timer","description":"Get the currently active timer for the user.","operationId":"get_active_timer_api_v1_time_entries_active_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["time-entries"],"summary":"Update Active Timer","description":"Update the active timer (assign project/task while running).","operationId":"update_active_timer_api_v1_time_entries_active_put","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/time-entries/recent":{"get":{"tags":["time-entries"],"summary":"Get Recent Entries","description":"Get recent entries for quick continue.","operationId":"get_recent_entries_api_v1_time_entries_recent_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/time-entries/start":{"post":{"tags":["time-entries"],"summary":"Start Timer","description":"Start a new timer.","operationId":"start_timer_api_v1_time_entries_start_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/time-entries/stop":{"post":{"tags":["time-entries"],"summary":"Stop Timer","description":"Stop the active timer.","operationId":"stop_timer_api_v1_time_entries_stop_post","requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/time-entries":{"post":{"tags":["time-entries"],"summary":"Create Manual Entry","description":"Create a manual time entry.","operationId":"create_manual_entry_api_v1_time_entries_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["time-entries"],"summary":"Get Entries","description":"Get paginated entries with filters.","operationId":"get_entries_api_v1_time_entries_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Page Size"}},{"name":"project_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Id"}},{"name":"client_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"}},{"name":"task_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Id"}},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Date"}},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"End Date"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/time-entries/continue/{entry_id}":{"post":{"tags":["time-entries"],"summary":"Continue Entry","description":"Start a new timer reusing a previous entry's details.","operationId":"continue_entry_api_v1_time_entries_continue__entry_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/time-entries/{entry_id}":{"get":{"tags":["time-entries"],"summary":"Get Entry","description":"Get a single time entry by ID.","operationId":"get_entry_api_v1_time_entries__entry_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/time-entries/{entry_id}/history":{"get":{"tags":["time-entries"],"summary":"Get Entry History","description":"Get audit history for a time entry.","operationId":"get_entry_history_api_v1_time_entries__entry_id__history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pomodoro/config":{"get":{"tags":["pomodoro"],"summary":"Get Config","description":"Get the pomodoro configuration for the current user.","operationId":"get_config_api_v1_pomodoro_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["pomodoro"],"summary":"Update Config","description":"Update pomodoro configuration.","operationId":"update_config_api_v1_pomodoro_config_put","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/pomodoro/start":{"post":{"tags":["pomodoro"],"summary":"Start Timer","description":"Start or restart the pomodoro timer.","operationId":"start_timer_api_v1_pomodoro_start_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/pomodoro/pause":{"post":{"tags":["pomodoro"],"summary":"Pause Timer","description":"Pause the running pomodoro timer.","operationId":"pause_timer_api_v1_pomodoro_pause_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/pomodoro/resume":{"post":{"tags":["pomodoro"],"summary":"Resume Timer","description":"Resume a paused pomodoro timer.","operationId":"resume_timer_api_v1_pomodoro_resume_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/pomodoro/complete":{"post":{"tags":["pomodoro"],"summary":"Complete Session","description":"Mark the current pomodoro session as completed and advance phase.","operationId":"complete_session_api_v1_pomodoro_complete_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/pomodoro/stats":{"get":{"tags":["pomodoro"],"summary":"Get Stats","description":"Get pomodoro statistics for today or this week.","operationId":"get_stats_api_v1_pomodoro_stats_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","default":"today","title":"Period"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects":{"get":{"tags":["projects"],"summary":"List Projects","description":"List projects for the user's organization.","operationId":"list_projects_api_v1_projects_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["projects"],"summary":"Create Project","description":"Create a new project.","operationId":"create_project_api_v1_projects_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/projects/{project_id}":{"get":{"tags":["projects"],"summary":"Get Project","description":"Get a single project with its time entries summary.","operationId":"get_project_api_v1_projects__project_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["projects"],"summary":"Update Project","description":"Update a project.","operationId":"update_project_api_v1_projects__project_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["projects"],"summary":"Archive Project","description":"Archive a project (soft delete).","operationId":"archive_project_api_v1_projects__project_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/clients":{"get":{"tags":["clients"],"summary":"List Clients","operationId":"list_clients_api_v1_clients_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["clients"],"summary":"Create Client","operationId":"create_client_api_v1_clients_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/clients/{client_id}":{"get":{"tags":["clients"],"summary":"Get Client","description":"Get a single client by ID.","operationId":"get_client_api_v1_clients__client_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"client_id","in":"path","required":true,"schema":{"type":"string","title":"Client Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["clients"],"summary":"Update Client","operationId":"update_client_api_v1_clients__client_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"client_id","in":"path","required":true,"schema":{"type":"string","title":"Client Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["clients"],"summary":"Delete Client","operationId":"delete_client_api_v1_clients__client_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"client_id","in":"path","required":true,"schema":{"type":"string","title":"Client Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{project_id}/tasks":{"get":{"tags":["tasks"],"summary":"List Tasks","operationId":"list_tasks_api_v1_projects__project_id__tasks_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["tasks"],"summary":"Create Task","operationId":"create_task_api_v1_projects__project_id__tasks_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/tasks/{task_id}":{"put":{"tags":["tasks"],"summary":"Update Task","operationId":"update_task_api_v1_projects_tasks__task_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["tasks"],"summary":"Archive Task","operationId":"archive_task_api_v1_projects_tasks__task_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/timesheets":{"get":{"tags":["timesheets"],"summary":"List Timesheets","description":"List timesheets. If year+week provided, get that week.","operationId":"list_timesheets_api_v1_timesheets_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"year","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Year"}},{"name":"week","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Week"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/timesheets/current":{"get":{"tags":["timesheets"],"summary":"Get Current Timesheet","description":"Get or build the current week's timesheet.","operationId":"get_current_timesheet_api_v1_timesheets_current_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/timesheets/submit":{"post":{"tags":["timesheets"],"summary":"Submit Timesheet","description":"Submit current week's timesheet for approval.","operationId":"submit_timesheet_api_v1_timesheets_submit_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/timesheets/approve/{timesheet_id}":{"post":{"tags":["timesheets"],"summary":"Approve Timesheet","description":"Approve a timesheet. Manager/Admin only.","operationId":"approve_timesheet_api_v1_timesheets_approve__timesheet_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"timesheet_id","in":"path","required":true,"schema":{"type":"string","title":"Timesheet Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/timesheets/reject/{timesheet_id}":{"post":{"tags":["timesheets"],"summary":"Reject Timesheet","description":"Reject a timesheet with reason. Manager/Admin only.","operationId":"reject_timesheet_api_v1_timesheets_reject__timesheet_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"timesheet_id","in":"path","required":true,"schema":{"type":"string","title":"Timesheet Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/dashboard/active-now":{"get":{"tags":["dashboard"],"summary":"Active Now","description":"Get all members with active timers.","operationId":"active_now_api_v1_dashboard_active_now_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/dashboard/today":{"get":{"tags":["dashboard"],"summary":"Today Stats","description":"Get today's hours for the user's organization.","operationId":"today_stats_api_v1_dashboard_today_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/dashboard/week":{"get":{"tags":["dashboard"],"summary":"Week Stats","description":"Get this week's hours.","operationId":"week_stats_api_v1_dashboard_week_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/reports/summary":{"post":{"tags":["reports"],"summary":"Summary Report","description":"Aggregated summary by project/user.","operationId":"summary_report_api_v1_reports_summary_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/reports/detailed":{"post":{"tags":["reports"],"summary":"Detailed Report","description":"List all time entries with filters.","operationId":"detailed_report_api_v1_reports_detailed_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/reports/export/csv":{"post":{"tags":["reports"],"summary":"Export Csv","description":"Export detailed report as CSV download.","operationId":"export_csv_api_v1_reports_export_csv_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/reports/weekly":{"post":{"tags":["reports"],"summary":"Weekly Report","description":"Weekly breakdown — hours per day per member.","operationId":"weekly_report_api_v1_reports_weekly_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/reports/attendance":{"post":{"tags":["reports"],"summary":"Attendance Report","description":"Compare tracked vs expected hours.","operationId":"attendance_report_api_v1_reports_attendance_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/leaves":{"get":{"tags":["leaves"],"summary":"List Leaves","operationId":"list_leaves_api_v1_leaves_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["leaves"],"summary":"Create Leave","operationId":"create_leave_api_v1_leaves_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/leaves/{leave_id}/status":{"put":{"tags":["leaves"],"summary":"Update Leave Status","operationId":"update_leave_status_api_v1_leaves__leave_id__status_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"leave_id","in":"path","required":true,"schema":{"type":"string","title":"Leave Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/holidays":{"get":{"tags":["leaves"],"summary":"List Holidays","operationId":"list_holidays_api_v1_holidays_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"year","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Year"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["leaves"],"summary":"Create Holiday","operationId":"create_holiday_api_v1_holidays_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/teams":{"get":{"tags":["user"],"summary":"List User Teams","description":"List all organizations this user belongs to.","operationId":"list_user_teams_api_v1_user_teams_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/user/active-team":{"put":{"tags":["user"],"summary":"Set Active Team","description":"Set the active team for the current user session.\nThe frontend stores this in localStorage — this endpoint\njust validates that the user belongs to the requested team.","operationId":"set_active_team_api_v1_user_active_team_put","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/time-entries/{entry_id}/location":{"post":{"tags":["geo"],"summary":"Store Location","description":"Store geolocation data on a time entry.\n\nBody: { lat: float, lng: float, accuracy?: float, timestamp?: str }","operationId":"store_location_api_v1_time_entries__entry_id__location_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"CheckoutCreateRequest":{"properties":{"price_id":{"type":"string","title":"Price Id"},"success_url":{"type":"string","title":"Success Url"},"cancel_url":{"type":"string","title":"Cancel Url"}},"type":"object","required":["price_id","success_url","cancel_url"],"title":"CheckoutCreateRequest"},"CheckoutResponse":{"properties":{"session_id":{"type":"string","title":"Session Id"},"url":{"type":"string","title":"Url"}},"type":"object","required":["session_id","url"],"title":"CheckoutResponse"},"ErrorResponse":{"properties":{"detail":{"type":"string","title":"Detail"}},"type":"object","required":["detail"],"title":"ErrorResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"PlansResponse":{"properties":{"plans":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Plans"}},"type":"object","required":["plans"],"title":"PlansResponse"},"PortalCreateRequest":{"properties":{"return_url":{"type":"string","title":"Return Url"}},"type":"object","required":["return_url"],"title":"PortalCreateRequest"},"PortalResponse":{"properties":{"url":{"type":"string","title":"Url"}},"type":"object","required":["url"],"title":"PortalResponse"},"SubscriptionResponse":{"properties":{"plan":{"type":"string","title":"Plan"},"status":{"type":"string","title":"Status"},"customer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Customer Id"},"subscription_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Id"},"period_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period End"}},"type":"object","required":["plan","status"],"title":"SubscriptionResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}