# Get logged software expenses (subscriptions)

> Eto API reference for `GET /api/v1/finance/software-expenses`. Base URL `https://eto.tools/api/v1/`. Authenticate with the `X-Eto-API-Key` header.

Part of the [Eto API reference](https://eto.tools/dev/docs/). The full reference in one file is at [llms-full.txt](https://eto.tools/dev/docs/llms-full.txt); the machine-readable schema is at [openapi.json](https://eto.tools/dev/docs/openapi.json).

## GET /api/v1/finance/software-expenses

Get logged software expenses (subscriptions)

- Operation ID: `finance_software_expenses`
- Slug: `finance-software-expenses`
- Category: Finance
- Authentication: API key only. Reads or writes data Eto holds for your own account.
- HTML: https://eto.tools/dev/docs/#ep-finance-software-expenses
- Markdown: https://eto.tools/dev/docs/finance/finance-software-expenses.md

Returns the software expenses you logged on the Finance dashboard — the subscriptions under Finance → Settings → Subscriptions (Canva, Printify, Eto, …) — and exactly what they cost inside a date window. The same numbers as the dashboard's "Software Expense" card and its breakdown. Zero Etsy API calls — reads from the Eto database. Instant.

These are ACCOUNT-level, not per shop, so they are NOT included in GET /finance/{shop_id}. To get profit after software, subtract total_cents from the shop's net_profit_cents.

━━━ WHAT YOU GET BACK (always returned) ━━━

start / end — the resolved window (unix seconds)
range — exact window: timezone, local-ISO bounds, label, server time
currency — the currency total_cents is in: your common currency from Finance settings, else the single currency all subscriptions share, else null (mixed)
common_currency — the common currency configured in Finance → Settings, or null
total_cents — everything charged inside the window, converted to `currency`
totals_by_currency — { "USD": 2598, "GBP": 999 } raw sums per native currency
charge_count — number of individual charges inside the window
subscription_count — number of subscriptions logged (all of them, not just active in window)
subscriptions[] — one entry per logged subscription:
  id, name, amount_cents, currency, frequency (weekly | biweekly | monthly | onetime), start_date (YYYY-MM-DD), conversion_rate (native → common), amount_converted_cents, charges_in_range, total_in_range_cents (converted), next_charge_date (YYYY-MM-DD or null), issue (only present when the entry is broken and never bills — e.g. missing amount/date)
scope — reminder that these are account-level costs, not per shop
warnings[] — caveats, e.g. mixed currencies with no common currency set
hint — only when nothing is logged yet, with where to add subscriptions

All amounts are COSTS (money out) returned as POSITIVE cents. Divide by 100 for display.

━━━ HOW CHARGES ARE COUNTED ━━━

Each subscription bills from its start_date on its schedule: weekly every 7 days, biweekly every 14, monthly on the same day each month (clamped to shorter months — the 31st bills on the 30th/28th), onetime exactly once on start_date. A charge is counted when its calendar date falls inside the window. So "this month" for a $12.99 monthly subscription started on the 15th is 1299 cents; "last_7_days" may be 0 if the billing day is not in that week. Identical to the dashboard.

━━━ HOW TO PICK THE DATE WINDOW ━━━

EASIEST — pass period=this_month (the default), today, yesterday, last_7_days, last_30_days or last_month. Or start_date=YYYY-MM-DD & end_date=YYYY-MM-DD (inclusive calendar days). Add timezone=Europe/London to resolve the window in a specific zone — the default is your primary connected shop's timezone, else UTC. Raw unix start/end are accepted too (max 366 days). The response echoes the resolved window in `range`, so you never have to guess which days were counted.

━━━ OPTIONAL ━━━

include=charges — also return charges[]: every individual charge inside the window (date, subscription_id, name, frequency, amount_cents, currency, converted_cents), sorted by date. charges_truncated is true if the list was cut at 2,000 entries (totals are always complete).

━━━ NOTES ━━━

Read-only. Subscriptions are added and edited on the Finance dashboard (eto.tools/dashboard/finances → Settings → Subscriptions).
Only YOUR account's subscriptions are ever returned — there is no id to look up.
An empty subscriptions[] with total_cents 0 is a valid answer: nothing is logged yet (the response carries a hint saying so).

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `period` | query | `string` | no | EASIEST — today, yesterday, last_7_days, last_30_days, this_month, last_month. Resolved server-side. Default: this_month. Default: `this_month`. |
| `start_date` | query | `string` | no | First calendar day "YYYY-MM-DD" (inclusive). |
| `end_date` | query | `string` | no | Last calendar day "YYYY-MM-DD" (inclusive). Defaults to start_date. |
| `timezone` | query | `string` | no | IANA timezone used to resolve period/dates into calendar days (default: your primary connected shop's timezone, else UTC). |
| `include` | query | `string` | no | Set to "charges" to also list every individual charge in the window. |
| `start` | query | `integer` | no | Advanced — unix timestamp, range start (inclusive). Prefer period/start_date. |
| `end` | query | `integer` | no | Advanced — unix timestamp, range end (exclusive). Prefer period/end_date. |

### Request

```bash
# ── This month (default) ──
curl -H "X-Eto-API-Key: eto_your_key" \
  "https://eto.tools/api/v1/finance/software-expenses"

# ── Last month ──
curl -H "X-Eto-API-Key: eto_your_key" \
  "https://eto.tools/api/v1/finance/software-expenses?period=last_month"

# ── A specific window, in your own timezone ──
curl -H "X-Eto-API-Key: eto_your_key" \
  "https://eto.tools/api/v1/finance/software-expenses?start_date=2026-07-01&end_date=2026-07-31&timezone=Europe/London"

# ── This month + every individual charge ──
curl -H "X-Eto-API-Key: eto_your_key" \
  "https://eto.tools/api/v1/finance/software-expenses?period=this_month&include=charges"
```

```python
import requests

url = "https://eto.tools/api/v1/finance/software-expenses"
headers = {"X-Eto-API-Key": "eto_your_key"}

response = requests.get(url, headers=headers, timeout=120)
response.raise_for_status()
print(response.json())
```

```javascript
const url = "https://eto.tools/api/v1/finance/software-expenses";

const response = await fetch(url, {
  method: "GET",
  headers: {
    "X-Eto-API-Key": "eto_your_key",
  },
});
if (!response.ok) throw new Error(`Eto API ${response.status}`);
const data = await response.json();
```

### Response

```json
{
  "start": 1785542400,
  "end": 1788220800,
  "range": {
    "start": 1785542400,
    "end": 1788220800,
    "start_local": "2026-08-01T00:00:00+01:00",
    "end_local": "2026-09-01T00:00:00+01:00",
    "timezone": "Europe/London",
    "label": "this month (month-to-date)",
    "server_now_unix": 1787788800,
    "server_now_utc": "2026-08-23T00:00:00+00:00"
  },
  "currency": "GBP",
  "common_currency": "GBP",
  "total_cents": 2325,
  "totals_by_currency": { "USD": 1299, "GBP": 1299 },
  "charge_count": 2,
  "subscription_count": 3,
  "subscriptions": [
    {
      "id": "sub_1753000000000_ab12",
      "name": "Eto",
      "amount_cents": 1299,
      "currency": "GBP",
      "frequency": "monthly",
      "start_date": "2026-03-05",
      "conversion_rate": 1.0,
      "amount_converted_cents": 1299,
      "charges_in_range": 1,
      "total_in_range_cents": 1299,
      "next_charge_date": "2026-09-05"
    },
    {
      "id": "sub_1751000000000_cd34",
      "name": "Canva Pro",
      "amount_cents": 1299,
      "currency": "USD",
      "frequency": "monthly",
      "start_date": "2026-01-15",
      "conversion_rate": 0.79,
      "amount_converted_cents": 1026,
      "charges_in_range": 1,
      "total_in_range_cents": 1026,
      "next_charge_date": "2026-09-15"
    },
    {
      "id": "sub_1749000000000_ef56",
      "name": "Printify Premium",
      "amount_cents": 2499,
      "currency": "USD",
      "frequency": "monthly",
      "start_date": "2026-08-28",
      "conversion_rate": 0.79,
      "amount_converted_cents": 1974,
      "charges_in_range": 0,
      "total_in_range_cents": 0,
      "next_charge_date": "2026-08-28"
    }
  ],
  "scope": {
    "level": "account",
    "note": "Software expenses are logged per Eto account, not per shop, so they are NOT part of GET /api/v1/finance/{shop_id}. All amounts are costs (money out) returned as positive cents; subtract total_cents from a shop's net_profit_cents to get profit after software.",
    "manage_at": "https://eto.tools/dashboard/finances (Settings → Subscriptions)"
  },
  "warnings": []
}

// ── With include=charges (extra keys) ──
{
  "...": "...",
  "charges": [
    { "date": "2026-08-05", "subscription_id": "sub_1753000000000_ab12", "name": "Eto", "frequency": "monthly", "amount_cents": 1299, "currency": "GBP", "converted_cents": 1299 },
    { "date": "2026-08-15", "subscription_id": "sub_1751000000000_cd34", "name": "Canva Pro", "frequency": "monthly", "amount_cents": 1299, "currency": "USD", "converted_cents": 1026 }
  ],
  "charges_truncated": false
}

// ── Nothing logged yet ──
{
  "...": "...",
  "currency": null,
  "total_cents": 0,
  "subscription_count": 0,
  "subscriptions": [],
  "hint": "No software expenses are logged yet. Add them at eto.tools/dashboard/finances → Settings → Subscriptions and they will appear here."
}
```

### Errors

Failures answer with the shared error body described in the Errors section: `{"error": {"code", "status", "message", "hint", "docs"}}`. Branch on `code`, not on the message.
