5.5 KiB
billing-service API and interfaces
This document describes the current billing-service task API plus the
upstream and downstream interfaces it depends on.
If you need the code-level mapping behind these interfaces, read:
Service endpoints
GET /api/ping
Returns the runtime image identity exposed by the running container.
Validation notes:
- release traceability checks this endpoint with
GET, notHEAD accounts.svc.plus/api/pingis the current production validation target for release identity- empty
image,tag,commit, orversionmeans runtime image identity was not injected correctly and should fail deployment validation
Example response:
{
"image": "registry.example.com/billing-service:sha-0123456789abcdef0123456789abcdef01234567",
"tag": "sha-0123456789abcdef0123456789abcdef01234567",
"commit": "0123456789abcdef0123456789abcdef01234567",
"version": "0123456789abcdef0123456789abcdef01234567"
}
GET /healthz
Returns service health derived from the most recent collect-and-rate execution.
Example response:
{
"status": "ok",
"message": ""
}
GET /v1/status
Returns the latest in-memory job result snapshot.
Key fields:
jobstarted_atfinished_atprocessed_sampleswritten_minutesreplayed_minutesstatuserror
POST /v1/jobs/collect-and-rate
Triggers an immediate snapshot pull from xray-exporter, computes minute
deltas, rates chargeable bytes, and writes replay-safe facts into PostgreSQL.
Behavior:
- method must be
POST - returns
200when the run completes without a fatal service error - returns
503when upstream fetch or persistence fails hard enough to mark the run unavailable
POST /v1/jobs/reconcile
Triggers the same execution path as collect-and-rate, but records the job name
as reconcile for operational visibility.
Upstream dependency
xray-exporter
billing-service currently resolves one or more exporter sources and fetches:
GET /v1/snapshots/window?since=<RFC3339>&until=<RFC3339>&limit=<n>&cursor=<token>
Current response shape:
{
"node_id": "jp-xhttp-contabo.svc.plus",
"env": "prod",
"snapshots": [
{
"collected_at": "2026-04-08T12:00:00Z",
"node_id": "jp-xhttp-contabo.svc.plus",
"env": "prod",
"samples": [
{
"uuid": "11111111-1111-1111-1111-111111111111",
"email": "user@example.com",
"inbound_tag": "xhttp-premium",
"uplink_bytes_total": 1024,
"downlink_bytes_total": 2048
}
]
}
],
"has_more": false
}
Required fields:
node_idenvsnapshots[].collected_atsnapshots[].node_idsnapshots[].envsnapshots[].samples[].uuidsnapshots[].samples[].emailsnapshots[].samples[].inbound_tagsnapshots[].samples[].uplink_bytes_totalsnapshots[].samples[].downlink_bytes_total
Target upstream contract
Current production behavior already uses a windowed pull API. The target multi-node design should evolve around the same shape:
- HTTPS transport for remote exporter pulls
- source-specific authentication
- stable catch-up and pagination semantics across multiple exporter nodes
Recommended target path:
GET /v1/snapshots/window?since=<RFC3339>&until=<RFC3339>&limit=<n>&cursor=<token>
Target-state expectations:
- remote pulls use
https://exporter base URLs - TLS verification stays enabled
- each source can be authenticated independently
- responses can be replayed safely from source checkpoints without duplicate billing writes
Downstream reads
User-facing reads do not go through billing-service. The read model is
accounts.svc.plus, backed by PostgreSQL.
Relevant downstream APIs:
GET /api/account/usage/summaryGET /api/account/usage/bucketsGET /api/account/billing/summary
Read-path rules:
billing-servicedoes not expose user-facing usage or billing query APIsaccounts.svc.plusreads PostgreSQL-backed usage and billing factsconsole.svc.plusqueriesaccounts.svc.plus, notbilling-service
Configuration inputs
Runtime environment variables used by the current implementation:
IMAGEEXPORTER_SOURCES_JSONEXPORTER_BASE_URLINTERNAL_SERVICE_TOKENDATABASE_URLLISTEN_ADDRCOLLECT_INTERVALDEFAULT_REGIONSOURCE_REVISIONPRICE_PER_BYTEINITIAL_INCLUDED_QUOTA_BYTESINITIAL_BALANCE
Source configuration rule:
- prefer
EXPORTER_SOURCES_JSONas the main source declaration path EXPORTER_BASE_URLis still supported as the current compatibility path when JSON source configuration is absent- upstream requests use
INTERNAL_SERVICE_TOKENas Bearer authentication
IMAGE rule:
- it must contain the full image reference used to start the container
/api/pingderivesimage,tag,commit, andversionfrom this value- when
IMAGEis missing or malformed, runtime metadata fields should remain empty rather than fabricated
DATABASE_URL rule:
- it must point to the same
accountdatabase thataccounts.svc.plususes - on
jp-xhttp-contabo.svc.plus, the current accounts containers useDB_HOST=stunnel-client,DB_PORT=15432, andDB_NAME=account billing-serviceshould follow that same target so user-facing reads inaccounts.svc.plussee the exact facts written bybilling-service