Back to Skills
    🦞

    freshbooks-cli

    FreshBooks CLI for managing invoices, clients, and billing.

    By @haseebuchiha
    View on GitHub
    SKILL.md
    ---
    name: freshbooks-cli
    description: FreshBooks CLI for managing invoices, clients, and billing. Use when the user mentions freshbooks, invoicing, billing, clients, or accounting.
    metadata: {"openclaw":{"emoji":"💰","requires":{"bins":["freshbooks"]},"install":[{"id":"npm","kind":"node","package":"@haseebuchiha/freshbooks-cli","bins":["freshbooks"],"label":"Install freshbooks-cli (npm)"}]}}
    ---
    
    # freshbooks-cli
    
    CLI tool for managing FreshBooks invoices, clients, and billing. Uses the official `@freshbooks/api` SDK.
    
    ## Install
    
    ```bash
    npm install -g @haseebuchiha/freshbooks-cli
    ```
    
    Requires `.npmrc` with `@haseebuchiha:registry=https://npm.pkg.github.com` for GitHub Package Registry.
    
    ## Setup (once)
    
    Authenticate with FreshBooks OAuth2. You must use the `--manual` flag (localhost redirect does not work with FreshBooks).
    
    ```bash
    freshbooks auth login \
      --client-id "<FRESHBOOKS_CLIENT_ID>" \
      --client-secret "<FRESHBOOKS_CLIENT_SECRET>" \
      --manual
    ```
    
    This opens the browser. Authorize, then copy the code from the page and paste it into the CLI. Tokens are stored at `~/.config/freshbooks-cli/config.json` (0600 permissions) and auto-refresh before expiry.
    
    Verify: `freshbooks auth status`
    
    ## Auth commands
    
    - `freshbooks auth login --client-id <id> --client-secret <secret> --manual` -- authenticate via OAuth2 OOB flow
    - `freshbooks auth logout` -- clear stored tokens and credentials
    - `freshbooks auth status` -- show account ID, token expiry, and auth state
    - `freshbooks auth refresh` -- manually refresh the access token
    
    ## Clients commands
    
    - `freshbooks clients list [-p <page>] [--per-page <n>] [-s <search>]` -- list clients, search by org name
    - `freshbooks clients get <id>` -- get a single client by ID
    - `freshbooks clients create [--fname <name>] [--lname <name>] [--email <email>] [--organization <org>]` -- create a client
    - `freshbooks clients create --data '<json>'` -- create with full JSON payload
    - `freshbooks clients update <id> --data '<json>'` -- update a client
    
    Example: `freshbooks clients create --fname "Taha" --organization "abcg.io"`
    
    ## Invoices commands
    
    - `freshbooks invoices list [-p <page>] [--per-page <n>]` -- list invoices
    - `freshbooks invoices get <id>` -- get a single invoice by ID
    - `freshbooks invoices create --client-id <id> [--lines '<json>']` -- create an invoice with line items
    - `freshbooks invoices create --client-id <id> --data '<json>'` -- create with full JSON payload
    - `freshbooks invoices update <id> --data '<json>'` -- update an invoice
    - `freshbooks invoices archive <id>` -- archive an invoice (no permanent delete in FreshBooks)
    - `freshbooks invoices share-link <id>` -- get a shareable link for an invoice
    
    ### Line items format
    
    Lines are a JSON array. Each line has `name`, `qty`, and `unitCost` (money object):
    
    ```json
    [
      {"name": "Web Services", "qty": 1, "unitCost": {"amount": "15000.00", "code": "USD"}},
      {"name": "App Services", "qty": 1, "unitCost": {"amount": "15000.00", "code": "USD"}}
    ]
    ```
    
    Example (full invoice create):
    
    ```bash
    freshbooks invoices create --client-id 818183 \
      --lines '[{"name":"Web Services","qty":1,"unitCost":{"amount":"15000.00","code":"USD"}},{"name":"App Services","qty":1,"unitCost":{"amount":"15000.00","code":"USD"}}]'
    ```
    
    ## Workflows
    
    ### Onboard a new client and invoice them
    
    1. `freshbooks clients create --fname "Name" --organization "Company"` -- note the returned `id`
    2. `freshbooks invoices create --client-id <id> --lines '[...]'` -- create the invoice
    3. `freshbooks invoices share-link <invoice-id>` -- get shareable link
    
    ### Look up billing for a client
    
    1. `freshbooks clients list -s "company name"` -- find the client ID
    2. `freshbooks invoices list` -- list all invoices (filter by client in output)
    3. `freshbooks invoices get <id>` -- get full invoice details
    
    ## Notes
    
    - All output is JSON to stdout. Pipe to `jq` for filtering: `freshbooks clients list | jq '.clients[].organization'`
    - Money values are `{"amount": "string", "code": "USD"}`. The amount is always a string like `"30000.00"`, never a number. Do not use parseFloat on money.
    - `archive` sets vis_state=1. FreshBooks does not support permanent deletion.
    - Tokens auto-refresh. If refresh fails, re-run `freshbooks auth login --client-id <id> --client-secret <secret> --manual`.
    - Client credentials can also be read from env vars `FRESHBOOKS_CLIENT_ID` and `FRESHBOOKS_CLIENT_SECRET` (takes priority over stored config).
    - Always use `--manual` for auth login. The localhost callback redirect URI does not work with FreshBooks.
    - Confirm with the user before creating invoices or modifying billing data.