home / skills / openclaw / skills / freshbooks-cli

freshbooks-cli skill

/skills/haseebuchiha/freshbooks-cli

This skill helps you manage FreshBooks invoices, clients, and billing via a CLI, enabling quick actions and secure OAuth2.

npx playbooks add skill openclaw/skills --skill freshbooks-cli

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
4.5 KB
---
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.

Overview

This skill is a CLI tool for managing FreshBooks invoices, clients, and billing from the terminal. It uses FreshBooks OAuth2 for authentication and the official FreshBooks API SDK to create, update, list, archive, and share invoices and clients. All output is JSON for easy scripting and integration.

How this skill works

Authenticate once using the manual OAuth2 flow; tokens are stored locally and auto-refresh before expiry. Use dedicated commands to list, get, create, update, archive, and share invoices and clients; line items are passed as JSON arrays. Commands write JSON to stdout so you can pipe output into jq or other tooling.

When to use it

  • Automating invoice creation and delivery for new or repeat clients
  • Scripting client onboarding workflows from terminal or CI jobs
  • Quickly looking up billing status or invoice details during support
  • Archiving invoices or generating a public share link for a client
  • Integrating FreshBooks calls into shell scripts or small tools

Best practices

  • Always confirm with the user before creating or modifying invoices or billing data
  • Use --manual for auth login; the localhost redirect does not work with FreshBooks
  • Keep client credentials in env vars (FRESHBOOKS_CLIENT_ID and FRESHBOOKS_CLIENT_SECRET) for CI usage
  • Treat money values as strings (e.g., "30000.00") and avoid parseFloat on amounts
  • Pipe output to jq for filtering and to avoid parsing JSON manually

Example use cases

  • Onboard a client: create client, create invoice with JSON lines, then produce a share link
  • Generate a monthly billing script that reads line items from a file and calls invoice create
  • Lookup billing: search clients by organization and retrieve invoice details for reconciliation
  • Archive old or canceled invoices to keep active lists clean while preserving history

FAQ

How do I authenticate if automatic redirect fails?

Use freshbooks auth login --client-id <id> --client-secret <secret> --manual, then paste the code shown in the browser into the CLI.

Where are tokens stored and do they refresh?

Tokens are stored at ~/.config/freshbooks-cli/config.json with 0600 permissions and auto-refresh; re-run auth login if refresh fails.