Hubstaff Webhooks API

Subscribe to real-time HTTP event notifications at the organization, project, or user level - timer.start, timer.stop, project.create, task.create, task.assign, schedule and shift events, work breaks, and billing seat snapshots - with an X-Hook-Secret verification and activation handshake and signed deliveries.

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