openapi: 3.1.0
info:
  title: Weel API
  version: v1
  termsOfService: https://letsweel.com/terms/
  contact:
    name: Contact our support
    email: help@letsweel.com
    url: https://help.letsweel.com
  description: >
    The Weel API empowers businesses with seamless expense management and
    real-time insights. Our platform makes it easy to integrate and automate
    expense workflows, manage receipts, and keep track of spending across your
    organization.
servers:
  - url: https://public.letsweel.com
security:
  - BearerAuth: []
x-tagGroups:
  - name: Users
    tags:
      - Users
  - name: Transactions
    tags:
      - Transactions
  - name: Budgets
    tags:
      - Budgets
      - Budget Members
      - Budget Topups
tags:
  - name: Transactions
    description: >-
      This group of endpoints allows you to retrieve and manage transaction
      data, including listing transactions with various filters and fetching
      individual transaction details.
  - name: Users
    description: >-
      This group of endpoints allows you to retrieve and manage user data,
      including listing users and fetching individual user details.
  - name: Budgets
    description: >
      This group of endpoints allows you to retrieve and manage budget data,
      including listing budgets and fetching individual budget details.


      Budgets are organised in a hierarchy where a budget can have multiple
      members. Each member is associated with a user. Funds can be allocated at
      the budget level or at the member level, using the flag
      `has_member_limits`.


      ![Budget Hierachy](assets/budget-hierarchy.png)
  - name: Budget Members
    description: >-
      This group of endpoints allows you to retrieve and manage budget member
      data, including listing budget members and fetching individual budget
      member details.
  - name: Budget Topups
    description: >
      This group of endpoints allows you to retrieve and create budget topups.
      Topups are used to increase or decrease the available amount of a budget
      or budget member.


      Topups will be automatically approved, unless a Workflow or Policy has
      been configured in Weel for that requires approval for budget topups.


      There are two types of topups:
        - Budget topups are used to increase or decrease the available amount of a budget. This is only permitted when `has_member_limits` is `false` for the budget.
        - Budget member topups are used to increase or decrease the available amount of a budget member. This is only permitted when `has_member_limits` is `true` for the budget.

      `has_member_limits` is set to `true` when this toggle is enabled in the
      budget creation form.
        ![Has Member Limits is true](assets/has-member-limits-true.png)
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
  parameters:
    PaginationOffset:
      name: offset
      in: query
      description: Offset to retrieve items from.
      schema:
        type: integer
        default: 0
        example: 50
    PaginationLimit:
      name: limit
      in: query
      description: Number of items per page.
      schema:
        type: integer
        default: 50
        maximum: 500
        example: 50
    ClientId:
      name: client_id
      in: path
      description: The ID of the business.
      required: true
      schema:
        type: integer
        example: 123
    IsDeleted:
      name: is_deleted
      in: query
      description: Whether the resource is deleted.
      schema:
        type: boolean
        example: false
    TransactionId:
      name: transaction_id
      in: path
      description: The ID of the transaction.
      required: true
      schema:
        type: string
    UserId:
      name: user_id
      in: path
      description: The ID of the user.
      required: true
      schema:
        type: integer
    BudgetId:
      name: budget_id
      in: path
      description: The ID of the budget.
      required: true
      schema:
        type: string
    BudgetMemberId:
      name: budget_member_id
      in: path
      description: The ID of the budget member.
      required: true
      schema:
        type: integer
  schemas:
    TransactionListResponse:
      type: object
      properties:
        count:
          type: integer
          description: The total number of transactions that match the query.
          example: 100
        next:
          type: string
          description: The URL to the next page of transactions.
          example: offset=50&limit=50
        previous:
          type: string
          description: The URL to the previous page of transactions.
          example: offset=0&limit=50
        results:
          type: array
          items:
            $ref: '#/components/schemas/Transaction'
    Transaction:
      type: object
      properties:
        id:
          type: string
          description: The ID of the transaction.
          example: e33b7c61-5124-4ba0-b238-e4c573133715
        cleared_date:
          type:
            - string
            - 'null'
          format: date-time
          description: The date the transaction was cleared.
          example: '2024-01-01T00:00:00Z'
        auth_date:
          type: string
          format: date-time
          description: The date the transaction was authorised.
          example: '2024-01-01T00:00:00Z'
        merchant_name:
          type: string
          description: The name of the merchant.
          example: Bunnings Warehouse
        attendees:
          type: array
          description: The names of the attendees of the transaction.
          items:
            type: string
            description: The name of the attendee.
            example: Jane Doe
        budget:
          $ref: '#/components/schemas/TransactionBudget'
          description: The budget associated with the transaction.
        currency:
          type: string
          description: The currency of the transaction.
          example: AUD
        custom_fields:
          type: array
          items:
            $ref: '#/components/schemas/CustomField'
        fx_amount:
          type: number
          description: The foreign currency amount of the transaction.
          example: 100
        amount:
          type: number
          description: >-
            The amount of the transaction in AUD (positive for credits, negative
            for debits).
          example: -100
        gst:
          type: number
          description: The GST amount of the transaction.
          example: 9.09
        expense_status:
          type: string
          description: The expense completion status of the transaction.
          enum:
            - COMPLETE
            - INCOMPLETE_EXPENSE
          example: COMPLETE
        status:
          type: string
          description: The status of the transaction.
          enum:
            - CLEARED
            - AUTHED
          example: CLEARED
        transaction_type:
          type: string
          description: The type of transaction.
          enum:
            - CARD_TRANSACTION
            - CHARGE
            - DEPOSIT_DIRECT_CREDIT
            - DEPOSIT_DIRECT_DEBIT
            - BILL
            - REIMBURSEMENT
            - EXTERNAL_TRANSFER
            - MANUAL_TRANSFER
            - CREDIT
          example: CARD_TRANSACTION
        user:
          description: The user who made the transaction.
          $ref: '#/components/schemas/SubUser'
        line_items:
          type: array
          description: The line items of the transaction.
          items:
            $ref: '#/components/schemas/LineItem'
        receipt_urls:
          type: array
          description: The URLs of the receipts for the transaction.
          items:
            type: string
            example: >-
              https://divipay-user-production.s3.amazonaws.com/123/68eae8f6-cb90-4403-ba76-a2cc12c3979j.png
    TransactionBudget:
      type: object
      properties:
        id:
          type: string
          description: The ID of the budget.
          example: e33b7c61-5124-4ba0-b238-e4c573133715
        name:
          type: string
          description: The name of the budget.
          example: Sales Team
        budget_type:
          type: string
          description: The type of budget.
          enum:
            - BUDGET
            - SUBSCRIPTION
          example: BUDGET
    LineItem:
      type: object
      properties:
        id:
          type: string
          description: The ID of the line item.
          example: e33b7c61-5124-4ba0-b238-e4c573133715
        amount:
          type: number
          description: The amount of the line item in AUD.
          example: 100
        gst_amount:
          type: number
          description: The GST amount of the line item.
          example: 9.09
        category:
          $ref: '#/components/schemas/Category'
        custom_fields:
          type: array
          items:
            $ref: '#/components/schemas/CustomField'
        description:
          type: string
          description: The description of the line item.
          example: Building supplies
    CustomField:
      type: object
      properties:
        field_name:
          type: string
          description: The name of the custom field.
          example: Project
        entry_text:
          type: string
          description: The text value of the custom field.
          example: Project 1
    UserListResponse:
      type: object
      properties:
        count:
          type: integer
          description: The total number of users that match the query.
          example: 100
        next:
          type: string
          description: The URL to the next page of users.
          example: offset=50&limit=50
        previous:
          type: string
          description: The URL to the previous page of users.
          example: offset=0&limit=50
        results:
          type: array
          items:
            $ref: '#/components/schemas/User'
    User:
      type: object
      properties:
        id:
          type: integer
          description: The ID of the user.
          example: 123
        first_name:
          type: string
          description: The first name of the user.
          example: John
        last_name:
          type: string
          description: The last name of the user.
          example: Doe
        email:
          type: string
          format: email
          description: The email of the user.
          example: john.doe@example.com
        role:
          type: string
          description: The role of the user.
          example: Team Member
        is_deleted:
          type: boolean
          description: Whether the user is deleted.
          example: false
    SubUser:
      type:
        - object
        - 'null'
      properties:
        id:
          type: integer
          description: The ID of the user.
          example: 123
        first_name:
          type: string
          description: The first name of the user.
          example: John
        last_name:
          type: string
          description: The last name of the user.
          example: Doe
    Budget:
      type: object
      properties:
        id:
          type: string
          description: The ID of the budget.
          example: e33b7c61-5124-4ba0-b238-e4c573133715
        name:
          type: string
          description: The name of the budget.
          example: Sales Team
        budget_type:
          type: string
          description: The type of budget.
          enum:
            - BUDGET
            - SUBSCRIPTION
          example: BUDGET
        available_amount:
          type: number
          description: The available amount of the budget.
          example: 1000
        reset_amount:
          type: number
          description: The reset amount of the budget.
          example: 1000
        reset_period:
          type: string
          description: The reset period of the budget.
          enum:
            - DAILY
            - WEEKLY
            - MONTHLY
            - QUARTERLY
            - YEARLY
            - FINANCIAL_YEAR
            - NEVER
          example: MONTHLY
        current_period_start:
          type: string
          format: date-time
          description: The start date of the current period.
          example: '2024-01-01T00:00:00Z'
        current_period_end:
          type:
            - string
            - 'null'
          format: date-time
          description: The end date of the current period.
          example: '2024-01-31T23:59:59Z'
        has_member_limits:
          type: boolean
          description: Whether the budget has member limits.
          example: false
        is_deleted:
          type: boolean
          description: Whether the budget is deleted.
          example: false
    BudgetListResponse:
      type: object
      properties:
        count:
          type: integer
          description: The total number of budgets that match the query.
          example: 100
        next:
          type: string
          description: The URL to the next page of budgets.
          example: offset=50&limit=50
        previous:
          type: string
          description: The URL to the previous page of budgets.
          example: offset=0&limit=50
        results:
          type: array
          items:
            $ref: '#/components/schemas/Budget'
    Invite:
      type:
        - object
        - 'null'
      properties:
        id:
          type: string
          description: The ID of the invite.
          example: e33b7c61-5124-4ba0-b238-e4c573133715
        email:
          type: string
          description: The email of the invite.
          example: john.doe@example.com
    BudgetMember:
      type: object
      properties:
        id:
          type: string
          description: The ID of the budget member.
          example: e33b7c61-5124-4ba0-b238-e4c573133715
        user:
          description: >-
            The user for the budget member. Only present if the user has
            accepted their invite to Weel.
          $ref: '#/components/schemas/SubUser'
        invite:
          description: >-
            The invite for the budget member. Only present if the user has not 
            accepted their invite to Weel.
          $ref: '#/components/schemas/Invite'
        available_amount:
          type: number
          description: The available amount of the budget member.
          example: 1000
        reset_amount:
          type: number
          description: The reset amount of the budget member.
          example: 1000
        is_deleted:
          type: boolean
          description: Whether the budget member is deleted.
          example: false
    BudgetMemberListResponse:
      type: object
      properties:
        count:
          type: integer
          description: The total number of budget members that match the query.
          example: 100
        next:
          type: string
          description: The URL to the next page of budget members.
          example: offset=50&limit=50
        previous:
          type: string
          description: The URL to the previous page of budget members.
          example: offset=0&limit=50
        results:
          type: array
          items:
            $ref: '#/components/schemas/BudgetMember'
    BudgetTopup:
      type: object
      properties:
        id:
          type: string
          description: The ID of the topup.
          example: e33b7c61-5124-4ba0-b238-e4c573133715
        amount:
          type: number
          description: >-
            Positive values increase the available amount, negative values
            decrease it.
          example: 100
        description:
          type: string
          description: The description of the topup.
          example: Additional funds for travel
        status:
          type: string
          description: The status of the topup.
          enum:
            - APPROVED
            - CANCELLED
            - DECLINED
            - PENDING
          example: APPROVED
        requested_by:
          description: The user who requested the topup.
          $ref: '#/components/schemas/SubUser'
        actioned_by:
          description: The user who actioned an approval or decline of the topup.
          $ref: '#/components/schemas/SubUser'
        actioned_on:
          type: string
          format: date-time
          description: The date and time when the topup was actioned.
          example: '2024-01-01T00:00:00Z'
    BudgetTopupListResponse:
      type: object
      properties:
        count:
          type: integer
          description: The total number of topups that match the query.
          example: 100
        next:
          type: string
          description: The URL to the next page of topups.
          example: offset=50&limit=50
        previous:
          type: string
          description: The URL to the previous page of topups.
          example: offset=0&limit=50
        results:
          type: array
          items:
            $ref: '#/components/schemas/BudgetTopup'
    BudgetTopupCreate:
      type: object
      required:
        - amount
        - description
      properties:
        amount:
          type: number
          description: >-
            Positive values increase the available amount, negative values
            decrease it.
          example: 100
        description:
          type: string
          description: The description of the topup.
          example: Additional funds for travel
        auto_approve:
          type: boolean
          description: >-
            By default, topups require approval before being added to the
            budget. Set this to `true` to automatically add the topup to the
            budget.
          example: true
    Category:
      type: object
      properties:
        id:
          type: string
          description: The ID of the category.
          example: f2c9897d-62fb-4d64-9647-3e6bf62d07c2
        name:
          type: string
          description: The name of the category in Weel.
          example: Accommodation
        code:
          type:
            - string
            - 'null'
          description: The accounting code of the category, if any.
          example: '6668'
paths:
  /v2/businesses/{client_id}/transactions:
    get:
      operationId: listTransactions
      tags:
        - Transactions
      summary: List transactions
      description: >
        This endpoint allows you to retrieve a list of transactions for a given
        business. You can filter the transactions by date range, status, and
        expense completion status.
      parameters:
        - $ref: '#/components/parameters/PaginationOffset'
        - $ref: '#/components/parameters/PaginationLimit'
        - $ref: '#/components/parameters/ClientId'
        - name: min_auth_date
          in: query
          required: false
          description: The minimum authorised date for the transactions.
          schema:
            type: string
            format: date
        - name: max_auth_date
          in: query
          required: false
          description: The maximum authorised date for the transactions.
          schema:
            type: string
            format: date
        - name: min_cleared_date
          in: query
          required: false
          description: The minimum cleared date for the transactions.
          schema:
            type: string
            format: date
        - name: max_cleared_date
          in: query
          required: false
          description: The maximum cleared date for the transactions.
          schema:
            type: string
            format: date
        - name: expense_status
          in: query
          required: false
          description: The expense completion status of the transactions.
          schema:
            type: string
            enum:
              - COMPLETE
              - INCOMPLETE_EXPENSE
            example: COMPLETE
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionListResponse'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      security:
        - BearerAuth: []
  /v2/businesses/{client_id}/transactions/{transaction_id}:
    get:
      operationId: getTransaction
      tags:
        - Transactions
      summary: Get transaction
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/TransactionId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not Found
      security:
        - BearerAuth: []
  /v1/businesses/{client_id}/users:
    get:
      operationId: listUsers
      description: >-
        This endpoint allows you to retrieve a list of users for a given
        business.
      tags:
        - Users
      summary: List users
      parameters:
        - $ref: '#/components/parameters/PaginationOffset'
        - $ref: '#/components/parameters/PaginationLimit'
        - $ref: '#/components/parameters/ClientId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserListResponse'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      security:
        - BearerAuth: []
  /v1/businesses/{client_id}/users/{user_id}:
    get:
      operationId: getUser
      description: This endpoint allows you to retrieve a user by their ID.
      tags:
        - Users
      summary: Get user
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/UserId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not Found
      security:
        - BearerAuth: []
  /v1/businesses/{client_id}/budgets:
    get:
      operationId: listBudgets
      tags:
        - Budgets
      summary: List budgets
      parameters:
        - $ref: '#/components/parameters/PaginationOffset'
        - $ref: '#/components/parameters/PaginationLimit'
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/IsDeleted'
        - name: budget_type
          in: query
          required: false
          description: The type of budget.
          schema:
            type: string
            enum:
              - BUDGET
              - SUBSCRIPTION
            example: BUDGET
        - name: has_member_limits
          in: query
          required: false
          description: Whether the budget has member limits.
          schema:
            type: boolean
            example: false
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BudgetListResponse'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      security:
        - BearerAuth: []
  /v1/businesses/{client_id}/budgets/{budget_id}:
    get:
      operationId: getBudget
      tags:
        - Budgets
      summary: Get budget
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/BudgetId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Budget'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not Found
      security:
        - BearerAuth: []
  /v1/businesses/{client_id}/budgets/{budget_id}/topups:
    get:
      operationId: listBudgetTopups
      tags:
        - Budget Topups
      summary: List budget topups
      description: List the topups for a budget.
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/BudgetId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BudgetTopupListResponse'
    post:
      operationId: createBudgetTopup
      tags:
        - Budget Topups
      summary: Create budget topup
      description: >-
        Increase or decrease the available amount of a budget. Only permitted
        when `has_member_limits` is `false` for the budget.
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/BudgetId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BudgetTopupCreate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BudgetTopup'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  non_field_errors:
                    type: array
                    items:
                      type: string
                      example: Cannot topup budget with member limits
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      security:
        - BearerAuth: []
  /v1/businesses/{client_id}/budgets/{budget_id}/members:
    get:
      operationId: listBudgetMembers
      tags:
        - Budget Members
      summary: List budget members
      description: A budget member is a user who has been invited to a budget.
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/BudgetId'
        - $ref: '#/components/parameters/PaginationOffset'
        - $ref: '#/components/parameters/PaginationLimit'
        - $ref: '#/components/parameters/IsDeleted'
        - name: user_id
          in: query
          required: false
          description: The ID of the user to filter by.
          schema:
            type: integer
            example: 123
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BudgetMemberListResponse'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      security:
        - BearerAuth: []
  /v1/businesses/{client_id}/budgets/{budget_id}/members/{budget_member_id}:
    get:
      operationId: getBudgetMember
      tags:
        - Budget Members
      summary: Get budget member
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/BudgetId'
        - $ref: '#/components/parameters/BudgetMemberId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BudgetMember'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not Found
      security:
        - BearerAuth: []
  /v1/businesses/{client_id}/budgets/{budget_id}/members/{budget_member_id}/topups:
    get:
      operationId: listBudgetMemberTopups
      tags:
        - Budget Topups
      summary: List budget member topups
      description: List the topups for a budget member.
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/BudgetId'
        - $ref: '#/components/parameters/BudgetMemberId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BudgetTopupListResponse'
    post:
      operationId: createBudgetMemberTopup
      tags:
        - Budget Topups
      summary: Create budget member topup
      description: >-
        Increase or decrease the available amount of a budget member. Only
        permitted when `has_member_limits` is `true` for the budget.
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/BudgetId'
        - $ref: '#/components/parameters/BudgetMemberId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BudgetTopupCreate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BudgetTopup'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  non_field_errors:
                    type: array
                    items:
                      type: string
                      example: >-
                        Cannot topup budget member when budget does not have
                        member limits
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      security:
        - BearerAuth: []
