Hubstaff Timesheets and Time Entries API

Create time entries for users, list organization timesheets (aggregate approval records), move timesheets through the open, submitted, approved, and denied statuses, and audit manual time edits via time edit logs.

OpenAPI Specification

hubstaff-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Hubstaff API
  description: 'The Hubstaff API v2 provides programmatic read and write access to Hubstaff''s time tracking,
    timesheet, workforce management, and project management data - organizations, members, teams, projects,
    tasks, clients, activities (10-minute tracked time blocks with activity percentages), daily activity
    aggregates, time entries, timesheets and approvals, time off requests/policies/balances, attendance
    schedules and shifts, screenshots, app and URL usage, invoices, team payments, and webhooks.


    Authentication uses OpenID Connect / OAuth 2.0 through Hubstaff Account (https://account.hubstaff.com).
    For server-side scripts, create a personal access token at https://developer.hubstaff.com/personal_access_tokens
    - the PAT acts as an OAuth refresh token (90-day expiry) that you exchange for short-lived access
    tokens at https://account.hubstaff.com/access_tokens. Send the access token as a Bearer token on every
    request.


    Rate limit: authenticated users are allowed 1,000 requests per hour per application; individual requests
    time out after 30 seconds. All requests must use HTTPS. Collection endpoints use cursor pagination
    via page_start_id and page_limit. This document is a curated OpenAPI 3.0 rendering of the live Swagger
    2.0 definition published at https://api.hubstaff.com/v2/docs, covering the primary resource areas;
    consult the live definition for the complete surface (insights, job sites, budgets, overtime policies,
    integrations, and more).'
  version: '2.0'
  contact:
    name: Hubstaff Developer Portal
    url: https://developer.hubstaff.com/
  termsOfService: https://hubstaff.com/terms
externalDocs:
  description: Hubstaff API v2 reference (interactive)
  url: https://developer.hubstaff.com/docs/hubstaff_v2
servers:
- url: https://api.hubstaff.com
  description: Hubstaff production API (paths include the /v2 prefix)
security:
- oauth2:
  - hubstaff:read
- personalAccessToken: []
tags:
- name: Organizations
  description: Organizations the authenticated user belongs to, plus seat usage.
- name: Members
  description: Organization membership - list, add, and update members and their pay/bill rates.
- name: Invites
  description: Invite users to an organization.
- name: Teams
  description: Teams within an organization and their membership.
- name: Users
  description: The authenticated user and user profiles.
- name: Activities
  description: Tracked time as 10-minute activity blocks and daily aggregates, with keyboard/mouse activity
    percentages.
- name: Time Entries
  description: Create time entries for a user (manual time via the API).
- name: Timesheets
  description: Timesheet approval records - list and update status (open, submitted, approved, denied).
- name: Time Edit Logs
  description: Audit trail of manual time edits.
- name: Projects
  description: Projects within an organization, including budgets and project members.
- name: Tasks
  description: Tasks (to-dos) within projects and organizations.
- name: Clients
  description: Clients that projects are billed to.
- name: Client Invoices
  description: Invoices issued to clients.
- name: Team Payments
  description: Payments made to team members (payroll).
- name: Time Off
  description: Time off requests, policies, and balances.
- name: Attendance
  description: Expected work shifts (schedules), actual clock-in/clock-out shifts, and holidays.
- name: Screenshots
  description: Screenshots captured while tracking time.
- name: App & URL Tracking
  description: Application and URL usage captured while tracking, plus tracking settings.
- name: Webhooks
  description: Webhook subscriptions delivering real-time event notifications (timer.start, timer.stop,
    task.create, shift.late, etc.).
paths:
  /v2/organizations:
    get:
      operationId: getV2Organizations
      tags:
      - Organizations
      summary: List organizations
      description: Returns a collection of organizations the authenticated user is an active member of.
      parameters:
      - name: page_start_id
        in: query
        description: The page start ID.
        schema:
          type: integer
          format: int32
          default: 0
      - name: page_limit
        in: query
        description: The default page size
        schema:
          type: integer
          format: int32
          default: null
      responses:
        '200':
          description: A list of organizations
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '429':
          description: Rate limit exceeded
    post:
      operationId: postV2Organizations
      tags:
      - Organizations
      summary: Create organization
      description: 'Creates a new organization.


        Returns the created organization.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Request payload. See the live Hubstaff API reference (https://api.hubstaff.com/v2/docs)
                for the full schema.
      responses:
        '200':
          description: An organization
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '429':
          description: Rate limit exceeded
  /v2/organizations/{organization_id}:
    get:
      operationId: getV2OrganizationsOrganizationId
      tags:
      - Organizations
      summary: Get organization
      description: Returns the organization with the given ID.
      parameters:
      - name: organization_id
        in: path
        description: Organization ID
        required: true
        schema:
          type: integer
          format: int32
      responses:
        '200':
          description: An organization
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
  /v2/organizations/{organization_id}/seats:
    get:
      operationId: getV2OrganizationsOrganizationIdSeats
      tags:
      - Organizations
      summary: Get organization seats
      description: "Returns billing seat counters for the specified organization.\n\n- Paid seats are\
        \ the total number of seats you are currently paying for.\n- Occupied is the total number of seats\
        \ that are currently filled.\n- Open seats will be filled automatically when new members are added.\n\
        \  Any open seats will be removed automatically when a new billing cycle starts,\n  bringing down\
        \ the number of paid seats to match the number of seats occupied."
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      responses:
        '200':
          description: Organization seats counters
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
  /v2/organizations/{organization_id}/members:
    get:
      operationId: getV2OrganizationsOrganizationIdMembers
      tags:
      - Members
      summary: List organization members
      description: "Returns a collection of members for the given organization.\n\nResults can be filtered\
        \ by search, user IDs, membership role, and date range.\n\n*trackable* - Whether the user can\
        \ track time.  This is one of 3 values\n- *false* -- meaning tracking has been explicitly disabled\
        \ for this user regardless of their role\n- *true* -- meaning they are allowed to track time\n\
        - *viewer* -- meaning they are allowed to track time, however as they are only a project viewer\
        \ (or no\n  memberships) they implicitly can not track on any project\n\n*membership_role* - The\
        \ basic role in this organization\n- *owner* - An owner of the organization.  This member can\
        \ do anything within the organization.\n- *manager* - An manager of the organization.  This member\
        \ can do anything within the organization\n  except things to do with money. (payroll, invoicing,\
        \ account billing)\n- *user* - (By project). A member of the organization where permissions are\
        \ defined by their project memberships\n\n*effective_role* - represents an effective role that\
        \ combines a member's organization role and their project roles\n- *organization_owner* - The\
        \ member is an organization owner\n- *organization_manager* - The member is an organization manager\n\
        - *project_manager* - The member is an organization user and a manager on all projects and teams\n\
        - *project_user* - The member is an organization user and a user on all projects and teams\n-\
        \ *project_viewer* - The member is an organization user and a viewer on all projects and teams\n\
        - *by_project* - The member is an organization user and has mixed roles on their projects and\
        \ team memberships (advanced in the web UI)\n- *unassigned* - The member has no assigned role\
        \ and no project memberships (No role in the web UI)\n\n*profile* - The profile information for\
        \ the user. Only organization owners and managers may see this information.\n- *custom_fields*\
        \ - The custom fields, defined for organization, in format of \"key\": \"value\". The meaning\n\
        \   of keys is defined in organization.member_profile_fields.\n\n**Filtering by dates:**\n\nYou\
        \ can filter members by when they were added to the organization using the `created_at` parameter:\n\
        - Use `created_at[start]` to get members added on or after a specific date\n- Use `created_at[stop]`\
        \ to get members added before a specific date\n- Use both to get members added within a date range\n\
        \nYou can also filter by when membership was last updated using the `updated_at` parameter:\n\
        - Use `updated_at[start]` to get members updated on or after a specific date\n- Use `updated_at[stop]`\
        \ to get members updated before a specific date\n- Use both to get members updated within a date\
        \ range"
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      - name: page_start_id
        in: query
        description: The page start ID.
        schema:
          type: integer
          format: int32
          default: 0
      - name: page_limit
        in: query
        description: The default page size
        schema:
          type: integer
          format: int32
          default: null
      - name: search[email]
        in: query
        description: An email to search for members
        schema:
          type: string
      - name: search[name]
        in: query
        description: A name to search for members
        schema:
          type: string
      - name: include_removed
        in: query
        description: Include members that were removed from the organization
        schema:
          type: boolean
          default: false
      - name: include_profile
        in: query
        description: Include member profile information
        schema:
          type: boolean
          default: false
      - name: include_projects
        in: query
        description: Include project memberships for this member
        schema:
          type: boolean
          default: false
      - name: project_statuses
        in: query
        description: Filter projects by status when include_projects=true
        schema:
          type: array
          items:
            type: string
            enum:
            - active
            - archived
            - deleted
      - name: include_limits
        in: query
        description: Include member limits information
        schema:
          type: boolean
          default: false
      - name: membership_roles
        in: query
        description: Search by membership role
        schema:
          type: array
          items:
            type: string
            enum:
            - owner
            - manager
            - user
            - unassigned
      - name: created_at[start]
        in: query
        description: Start date for created_at filter (inclusive)
        schema:
          type: string
          format: date-time
      - name: created_at[stop]
        in: query
        description: End date for created_at filter (exclusive)
        schema:
          type: string
          format: date-time
      - name: updated_at[start]
        in: query
        description: Start date for updated_at filter (inclusive)
        schema:
          type: string
          format: date-time
      - name: updated_at[stop]
        in: query
        description: End date for updated_at filter (exclusive)
        schema:
          type: string
          format: date-time
      - name: user_ids
        in: query
        description: List of user IDs
        schema:
          type: array
          items:
            type: integer
            format: int32
      - name: include
        in: query
        description: Specify related data to side load.
        schema:
          type: array
          items:
            type: string
            enum:
            - users
            - projects
      responses:
        '200':
          description: A list of members
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
    post:
      operationId: postV2OrganizationsOrganizationIdMembers
      tags:
      - Members
      summary: Create organization member
      description: 'Creates a new user and adds them to the organization as a member.


        Returns the created member.


        Available roles:

        - organization_manager - Organization manager

        - project_manager - Project manager

        - project_user - Project user

        - project_viewer - Project viewer


        Available pay periods:

        - none - Disables automatic payments

        - weekly - Pay users weekly

        - twice_per_month - Pay users twice a month

        - biweekly - Pay users bi-weekly

        - monthly - Pay users monthly'
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Request payload. See the live Hubstaff API reference (https://api.hubstaff.com/v2/docs)
                for the full schema.
      responses:
        '201':
          description: A member
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
  /v2/organizations/{organization_id}/update_members:
    put:
      operationId: putV2OrganizationsOrganizationIdUpdateMembers
      tags:
      - Members
      summary: Update organization members
      description: 'Updates organization members.


        Returns {success: true} on success.


        Only pass in the members you want to change.


        Available roles:

        - user - Member role determined by project membership

        - manager - Organization manager

        - owner - Organization owner

        - remove - Removes user from organization (and all projects/teams)


        Limits: Specify full limits config. Missing limits will be removed. Empty "limits" removes all
        limits.


        Projects: Specify project memberships to change. Available project roles: viewer, user, manager,
        remove.


        Metadata: Only specify keys to change. Non-existent keys are created. Use null to remove a key.


        Key requirements:

        - 2-30 characters

        - Lowercase letters, numbers, and underscores only


        Value requirements:

        - Valid UTF-8 string

        - Maximum 200 characters


        Batch size: Up to 150 members per request. Larger requests are rejected with HTTP 400 and code
        "too_many_members".'
      parameters:
      - name: organization_id
        in: path
        description: Organization ID
        required: true
        schema:
          type: integer
          format: int32
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Request payload. See the live Hubstaff API reference (https://api.hubstaff.com/v2/docs)
                for the full schema.
      responses:
        '200':
          description: Updated successfully
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
  /v2/organizations/{organization_id}/invites:
    get:
      operationId: getV2OrganizationsOrganizationIdInvites
      tags:
      - Invites
      summary: List organization invites
      description: 'Returns a collection of invites for the given organization.


        Results can be filtered by email and status.'
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      - name: page_start_id
        in: query
        description: The page start ID.
        schema:
          type: integer
          format: int32
          default: 0
      - name: page_limit
        in: query
        description: The default page size
        schema:
          type: integer
          format: int32
          default: null
      - name: email
        in: query
        description: An email to search for a pending invitation by
        schema:
          type: string
      - name: status
        in: query
        description: Filter invites by status
        schema:
          type: string
          enum:
          - all
          - pending
          - accepted
          - expired
          default: pending
      - name: include
        in: query
        description: Specify related data to side load.
        schema:
          type: array
          items:
            type: string
            enum:
            - users
            - projects
      responses:
        '200':
          description: A list of invites
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
    post:
      operationId: postV2OrganizationsOrganizationIdInvites
      tags:
      - Invites
      summary: Create invite
      description: 'Creates a new invite.


        Returns the created invite.


        Note: If there is an account for the email in Hubstaff, the invite will be auto accepted.

        Note: There is a rate limit on how many invites you may create.


        Available roles:

        - organization_manager - Invited as an organization manager

        - project_manager - Invited as a project manager

        - project_user - Invited as a project user

        - project_viewer - Invited as a project viewer


        If no project_ids are set, any project_* role will default to project_viewer (no projects assigned).'
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Request payload. See the live Hubstaff API reference (https://api.hubstaff.com/v2/docs)
                for the full schema.
      responses:
        '201':
          description: An invite
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
  /v2/organizations/{organization_id}/teams:
    get:
      operationId: getV2OrganizationsOrganizationIdTeams
      tags:
      - Teams
      summary: List organization teams
      description: Returns a collection of teams for the given organization.
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      - name: page_start_id
        in: query
        description: The page start ID.
        schema:
          type: integer
          format: int32
          default: 0
      - name: page_limit
        in: query
        description: The default page size
        schema:
          type: integer
          format: int32
          default: null
      responses:
        '200':
          description: A list of teams
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
    post:
      operationId: postV2OrganizationsOrganizationIdTeams
      tags:
      - Teams
      summary: Create team
      description: 'Creates a new team.


        Returns the created team.


        Only name is required. Members can optionally be added with roles: viewer, user, or manager.


        Note: When a member lead is set to true, the role is forced to manager.'
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Request payload. See the live Hubstaff API reference (https://api.hubstaff.com/v2/docs)
                for the full schema.
      responses:
        '201':
          description: A team
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
  /v2/teams/{team_id}:
    get:
      operationId: getV2TeamsTeamId
      tags:
      - Teams
      summary: Get team
      description: Returns the team with the given ID.
      parameters:
      - name: team_id
        in: path
        description: Team ID
        required: true
        schema:
          type: integer
          format: int32
      responses:
        '200':
          description: A team
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
  /v2/teams/{team_id}/members:
    get:
      operationId: getV2TeamsTeamIdMembers
      tags:
      - Members
      summary: List team members
      description: 'Returns a collection of members for the given team.


        Membership roles:

        - manager - Can track time, view all data, change settings, and manage membership

        - user - Can track time and view only their own data

        - viewer - Can view reports but cannot make changes'
      parameters:
      - name: team_id
        in: path
        description: Team ID
        required: true
        schema:
          type: integer
          format: int32
      - name: page_start_id
        in: query
        description: The page start ID.
        schema:
          type: integer
          format: int32
          default: 0
      - name: page_limit
        in: query
        description: The default page size
        schema:
          type: integer
          format: int32
          default: null
      - name: include
        in: query
        description: Specify related data to side load.
        schema:
          type: array
          items:
            type: string
            enum:
            - users
      responses:
        '200':
          description: A list of members
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
  /v2/users/me:
    get:
      operationId: getV2UsersMe
      tags:
      - Users
      summary: Get current user
      description: Returns the authenticated user.
      responses:
        '200':
          description: A user
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '429':
          description: Rate limit exceeded
  /v2/users/{user_id}:
    get:
      operationId: getV2UsersUserId
      tags:
      - Users
      summary: Get user
      description: Returns the user with the given ID.
      parameters:
      - name: user_id
        in: path
        description: User ID
        required: true
        schema:
          type: integer
          format: int32
      responses:
        '200':
          description: A user
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
  /v2/organizations/{organization_id}/activities:
    get:
      operationId: getV2OrganizationsOrganizationIdActivities
      tags:
      - Activities
      summary: List organization activities
      description: 'Returns a collection of activities (10-minute time blocks) for the given organization.


        Results can be filtered by user, task, project, and time range (time_slot[start], time_slot[stop]).


        For aggregated daily data, use the daily_activities endpoint instead.


        Note: Data may be delayed up to 20 minutes.

        Note: Date range limit is 7 days. Earliest date is 6 months ago.'
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      - name: page_start_id
        in: query
        description: The page start ID.
        schema:
          type: integer
          format: int32
          default: 0
      - name: page_limit
        in: query
        description: The default page size
        schema:
          type: integer
          format: int32
          default: null
      - name: time_slot[start]
        in: query
        description: Start time (ISO 8601)
        required: true
        schema:
          type: string
          format: date-time
      - name: time_slot[stop]
        in: query
        description: Stop time (ISO 8601, Exclusive)
        required: true
        schema:
          type: string
          format: date-time
      - name: user_ids
        in: query
        description: List of user IDs
        schema:
          type: array
          items:
            type: integer
            format: int32
      - name: task_ids
        in: query
        description: List of task IDs
        schema:
          type: array
          items:
            type: integer
            format: int32
      - name: global_todo_ids
        in: query
        description: List of global todo IDs
        schema:
          type: array
          items:
            type: integer
            format: int32
      - name: project_ids
        in: query
        description: List of project IDs
        schema:
          type: array
          items:
            type: integer
            format: int32
      - name: include
        in: query
        description: Specify related data to side load.
        schema:
          type: array
          items:
            type: string
            enum:
            - users
            - projects
            - tasks
      - name: time_zone
        in: query
        description: The time zone name for the activity
        schema:
          type: string
      responses:
        '200':
          description: A list of activities
        '400':
          description: Invalid parameters
        '401':
          description: Unauthorized
        '403':
          description: API access is only for organizations on an active plan
        '404':
          description: Could not find record
        '429':
          description: Rate limit exceeded
  /v2/organizations/{organization_id}/activities/daily:
    get:
      operationId: getV2OrganizationsOrganizationIdActivitiesDaily
      tags:
      - Activities
      summary: List organization daily activities
      description: 'Returns daily aggregated time tracking data for the given organization.


        Results can be filtered by user_ids[], task_ids[], project_ids[], and date[start]/[stop]. Data
        is aggregated by organization timezone date.


        Note: Date range limit is 31 days. Earliest date is 3 years ago.'
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: integer
          format: int32
      - name: page_start_id
        in: query
        description: The page start ID.
        schema:
          type: integer
          format: int32
          default: 0
      - name: page_limit
        in: query
        description: The default page size
        schema:
          type: integer
          format: int32
          default: null
      - name: date[start]
        in: query
        description: Start date (ISO 8601)
        required: true
        schema:
          type: string
          format: date
      - name: date[stop]
        in: query
        description: Stop date (ISO 8601, Inclusive)
        required: true
        schema:
          type: string
          format: date
      - name: user_ids
        in: query
        description: List of user IDs
        schema:
          type: array
          items:
            type: integer
            format: int32
      - name: task_ids
        in: query
        description: List of task IDs
        schema:
          type: array
          items:
            type: integer
            format: int32
      - name: project_ids
        in: query
        description: List of project IDs
        schema:
          type: array
          items:
            type: integer
            format: int32
      - name: include
        in: query
        description: Specify related data to side load.
        schema:
          type: array
          items:
            type: string
            enum:
            - users
            - projects
            - tasks
      responses:
        '200':
          description: A list of daily activities
        '400':
          description: Inv

# --- truncated at 32 KB (110 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/hubstaff/refs/heads/main/openapi/hubstaff-openapi.yml