# Billing Export

The billing export script generates a compressed archive of billing data from your Synqly instance.
You email that archive to Synqly for monthly, quarterly, or yearly billing reconciliation.

## Quick Start

The script lives in the [embedded-examples](https://github.com/Synqly/embedded-examples) repo at
`scripts/billing/billing-export.sh`. Run it from the repo root.

You need four values, three of them from your helm chart's `values.yaml`:

- `--url`, your Synqly instance URL.
- `--user`, the admin username, at `global.organizationAdmin.default.credentials`.
- `--org`, your `global.organizationID`.
- The admin password, from the same `credentials` block. The script prompts for it if you do not
supply it another way.


Export last month's billing data:


```bash
./scripts/billing/billing-export.sh \
  --url https://synqly.example.com \
  --user admin \
  --org acme \
  --password-file ~/.synqly-pass
```

To export a different month or a range of months, add `--month` or `--from`/`--to`. See
[Specifying the Time Period](#specifying-the-time-period).

## Requirements

The script needs `curl`, `jq`, `tar`, and `gzip` on your system. If any are missing, it names them
and exits before doing anything else.

## Finding Your Credentials

The admin username and password are configured at `global.organizationAdmin.default.credentials`,
or referenced from Kubernetes Secrets via `global.organizationAdmin.default.secretRef`.

An admin can also be invited by email through `global.organizationAdmin.inviteMembers`, which takes
a comma-separated list of addresses and needs SMTP configured at `global.smtp*`. An invited admin
logs in with their email address, so pass that as `--user`.

Billing data is scoped to the organization you log in to, so run the export once per organization
if your install has more than one.

## Providing Credentials

Provide the password in any of these ways. The script takes the first one it finds:

1. `--password` passes the password directly (appears in shell history).
2. `SYNQLY_PASSWORD` environment variable.
3. `--password-file` reads the password from the first line of a file.
4. Piped input for integration with secret managers:
`vault read -field=password secret/synqly | ./scripts/billing/billing-export.sh ...`
5. Interactive prompt when running in a terminal with no password provided.


## Specifying the Time Period

By default, the script exports the previous calendar month.

### Single Month

Use `--month` to export a single month. The value can be either a `YYYY-MM` format or a month name:


```bash
--month 2026-01
--month january
```

Month names are case-insensitive. When using a month name without a year, the script assumes the
most recent occurrence of that month. For example, running the script in January 2026 with `--month march` will export March 2025, since March 2026 has not yet occurred.

### Month Range

Use `--from` and `--to` together to export multiple months:


```bash
--from 2025-10 --to 2026-01
--from october --to january
```

Both flags must be specified when exporting a range. The range is inclusive of both endpoints.

### Current Month Warning

If your time period includes the current month, the script warns that the data may be incomplete.

## Output Format

The script produces a compressed tar archive named `synqly-billing-export-YYYY-MM-DD-HHMMSS.tar.gz`
containing:

- A CSV file for each exported month, named like `2026-january.csv`
- A `metadata.json` file with export details including the Synqly version, source URL, and list of
included months
- An `export.log` file with timestamps of each operation performed during the export


The CSV files contain one row per integration, plus a subtotal row per account with the integration,
provider type, and connector type columns left empty. A `Deleted` column records whether the
integration was deleted during the billing period.

Use `--output` to specify the destination directory for the archive. The directory must already
exist. The default is the current working directory.

## Sending to Synqly

Email the export archive to `monthlyusagereport@synqly.com`. The subject line should include your
company name and the reporting period. The script prints the address and a suggested subject line
when it finishes.

Example subject line:


```
Acme Corp: 2026-january
```

Or for multi-month reports:


```
Acme Corp: 2025-october to 2026-january
```

Attach the archive with no message body.

## Troubleshooting

### `Required dependencies not found`

Install the tools named in the error message. Most are in the standard package manager.

### `Error: --url is required` or `Error: --user is required`

Both the instance URL and admin username must be provided.

### `Error: Failed to connect to <url>`

The instance did not answer an unauthenticated version check. Check the URL, and whether you need
a VPN to reach it. For an instance with a self-signed certificate, see the `--insecure` flag under
[Security Notes](#security-notes).

### The script exits with status 1 and prints nothing

No password was supplied and the script was run without a terminal, such as from cron or CI. Pass
`--password-file` or set `SYNQLY_PASSWORD`.

### `Error: Password file not found`

The path specified with `--password-file` does not exist or is not readable.

### `Authentication failed: Not Found`

Either `--org` does not match your `global.organizationID`, or `--user` is not a member of that
organization. The lookup returns the same error for both.

### `Authentication failed`

The credentials were rejected by the Synqly instance. Verify that the username and password are
correct.

### `Error: Invalid month: <value>`

The month is neither a `YYYY-MM` value nor a recognized month name.

### `Error: Cannot specify both --month and --from/--to`

Use either `--month` for a single month or `--from`/`--to` for a range, but not both.

### `Error: --from requires --to` or `Error: --to requires --from`

When specifying a range, both endpoints must be provided.

### `Error: --from (X) must not be after --to (Y)`

The range runs backwards. Swap the two values.

### `Error: Output directory does not exist: <dir>`

Create the directory, or drop `--output` to write to the current directory.

### `Error fetching billing data` or `Error: Invalid JSON response from billing API`

The billing endpoint returned an error or a non-JSON body. Check that the admin user has billing
permissions and that the instance is recent enough to expose the billing API.

### `Warning: No data for [month], skipping`

No billing records exist for that month. Expected for new deployments and for months with no
activity.

### `No billing data was exported.`

Every requested month was empty, so the script exits 0 and writes no archive. Check the month and
the `--org` value.

## Security Notes

Credential files should have restrictive permissions (readable only by the user running the script).
Avoid using the `--password` command-line flag in scripts or automation, as its value may be
captured in shell history or process listings.

The `--insecure` flag disables SSL certificate verification. Use this only when connecting to
instances with self-signed certificates in controlled environments, and never in production.

The CSV columns are organization, account, environment, integration name, provider type, connector
type, request and byte counts, and the deleted flag. No customer data, credentials, or API keys are
included.