Galaxy Unit Expenses API
The Expenses API from Galaxy Unit — 2 operation(s) for expenses.
The Expenses API from Galaxy Unit — 2 operation(s) for expenses.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/galaxyunit-app:galaxyunit-app-expenses-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Galaxy Unit Expenses API
version: 1.0.0
description: 'REST for AI agents and scripts. A key acts as the member who made it (never above admin) under row-level security. Money is a decimal string. Dates are YYYY-MM-DD in the business time zone (see /me). Errors carry code, field and a hint the agent can act on. Read /for-agents first: https://galaxyunit.app/for-agents'
contact:
url: https://galaxyunit.app/contact
termsOfService: https://galaxyunit.app/terms
servers:
- url: https://app.galaxyunit.app
security:
- apiKey: []
tags:
- name: Expenses
paths:
/api/v1/expenses:
get:
operationId: expensesList
summary: List expenses (newest updated first, cursor pages)
parameters:
- name: q
in: query
description: ILIKE on description, vendor, category
schema:
type: string
maxLength: 100
- name: updated_since
in: query
schema:
type: string
format: date-time
- name: limit
in: query
schema:
type: integer
maximum: 200
default: 50
- name: cursor
in: query
description: next_cursor from the previous page
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: object
properties:
id: {}
job_id: {}
description: {}
amount:
type:
- string
- 'null'
description: Decimal string, e.g. "1234.56"
category: {}
date: {}
vendor: {}
tax_amount:
type:
- string
- 'null'
description: Decimal string, e.g. "1234.56"
currency: {}
receipt_number: {}
kind: {}
notes: {}
version: {}
created_at: {}
updated_at: {}
next_cursor:
type:
- string
- 'null'
'401':
description: Missing or invalid key
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'402':
description: Plan required
content:
application/json:
schema:
type: object
description: Answered with HTTP 402 when a plan is required. Relay message_for_owner and approve_url to the human, then retry the same call.
properties:
code:
const: PLAN_REQUIRED
needed:
type: string
for:
type: string
what_you_get:
type: array
items:
type: string
price:
type:
- object
- 'null'
approve_url:
type: string
trial_url:
type:
- string
- 'null'
message_for_owner:
type: string
retryable:
const: true
'403':
description: Key lacks scope or member lacks role
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'422':
description: Validation error (see field, hint)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'429':
description: Rate limited (Retry-After)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
tags:
- Expenses
post:
operationId: expensesCreate
summary: Create a expense (write scope).
parameters:
- name: Idempotency-Key
in: header
required: true
schema:
type: string
minLength: 8
maxLength: 128
- name: dry_run
in: query
schema:
type: string
enum:
- '1'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
amount:
type: number
exclusiveMinimum: 0
description: Total amount in CAD — must be greater than 0
category:
type: string
description: Category KEY copied EXACTLY from the "Expense category keys" list in the INDUSTRY line of the system prompt — never invent a key; unknown keys fall back to other
description:
type: string
vendor:
type: string
date:
type: string
description: YYYY-MM-DD; default today
required:
- amount
additionalProperties: false
description: Record a business expense. Use for "log/record an expense", "I spent X on Y".
responses:
'202':
description: 'Waiting for the owner: nothing written yet. The owner got an email to approve; poll GET /api/v1/actions/{action_id}.'
content:
application/json:
schema:
$ref: '#/components/schemas/PendingAction'
'401':
description: Missing or invalid key
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'402':
description: Plan required
content:
application/json:
schema:
type: object
description: Answered with HTTP 402 when a plan is required. Relay message_for_owner and approve_url to the human, then retry the same call.
properties:
code:
const: PLAN_REQUIRED
needed:
type: string
for:
type: string
what_you_get:
type: array
items:
type: string
price:
type:
- object
- 'null'
approve_url:
type: string
trial_url:
type:
- string
- 'null'
message_for_owner:
type: string
retryable:
const: true
'403':
description: Key lacks scope or member lacks role
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'404':
description: Named client/job not found in this business
'422':
description: Validation error (see field, hint)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'429':
description: Rate limited (Retry-After)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
tags:
- Expenses
/api/v1/expenses/{id}:
get:
operationId: expensesGet
summary: One expense by id
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
id: {}
job_id: {}
description: {}
amount:
type:
- string
- 'null'
description: Decimal string, e.g. "1234.56"
category: {}
date: {}
vendor: {}
tax_amount:
type:
- string
- 'null'
description: Decimal string, e.g. "1234.56"
currency: {}
receipt_number: {}
kind: {}
notes: {}
version: {}
created_at: {}
updated_at: {}
'401':
description: Missing or invalid key
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'402':
description: Plan required
content:
application/json:
schema:
type: object
description: Answered with HTTP 402 when a plan is required. Relay message_for_owner and approve_url to the human, then retry the same call.
properties:
code:
const: PLAN_REQUIRED
needed:
type: string
for:
type: string
what_you_get:
type: array
items:
type: string
price:
type:
- object
- 'null'
approve_url:
type: string
trial_url:
type:
- string
- 'null'
message_for_owner:
type: string
retryable:
const: true
'403':
description: Key lacks scope or member lacks role
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'404':
description: Not found in this business
'422':
description: Validation error (see field, hint)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
'429':
description: Rate limited (Retry-After)
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
field:
type: string
hint:
type: string
retryable:
type: boolean
required:
- code
- message
- retryable
tags:
- Expenses
components:
schemas:
PendingAction:
type: object
required:
- status
- action_id
properties:
status:
type: string
const: pending_confirmation
action_id:
type: string
format: uuid
expires_at:
type: string
format: date-time
message_for_owner:
type: string
hint:
type: string
securitySchemes:
apiKey:
type: http
scheme: bearer
description: 'Authorization: Bearer gu_live_… — issued in Settings → Integrations by an owner or admin.'