Skip to content

Audit & spend caps

Two features keep AppGantry accounts boring and predictable:

  • The audit feed records the meaningful actions that happened in your organization, with the who, what, when, and from-where.
  • Spend caps put a monthly ceiling on metered usage so a viral build can't produce a surprise invoice.

The audit feed

Every organization gets an audit feed. It is append-only, scoped to one organization, and partitioned by UTC day so it stays fast at any volume.

What it records

State-changing and identity-asserting actions across authentication, organization governance, projects, builds, channels and releases, testers, tokens, webhooks, store connections, storage configuration, and billing. Each row carries:

  • when it happened,
  • what happened (the event type),
  • what kind of thing it happened to, and the identifier of that thing,
  • who did it — a developer, a personal access token, a project access token, or the system itself,
  • the source IP where one applies, and
  • a structured payload of event-specific fields.

For the vocabulary and the categories in full, see Audit events.

What it does not record

  • Tester downloads. Those feed the download meter but are not stored as individual audit rows; on a viral build they would drown everything else.
  • Read-only API calls. The feed is for actions that change state or assert identity, not for every read.
  • Secrets. Tokens, passwords, and secret values never appear in a row, only the fact that one was created, rotated, or revoked.

Retention

Plan Default audit retention
Team 90 days
Business 365 days
Enterprise Not generally available

Export the feed before it ages out if you need to keep it longer.

Reading the feed

In the web app, an organization's Audit page shows one day at a time, with a date picker, and offers a CSV export over a date range. The export is generated by the web app from the audit feed, with four columns — timestamp, event label, data-type label, and IP address. See Exporting.

The same data is available over the API, one UTC day at a time or as a bounded date range. Very large days are capped, and the response tells you when it was truncated so you can narrow the window rather than silently losing rows. See Audit events → Reading the feed.

Audit is not in the interactive API reference

The audit operations are not part of the published OpenAPI document. Audit events is the authoritative description of them.

Spend caps

A viral build multiplied by thousands of testers can move a lot of bytes in a single afternoon. Two things bound that.

The organization's usage view

An organization's Usage page shows current-period consumption against your plan and your remaining balance, so you can see a spike building before it becomes an invoice. It is the first place to look when a number surprises you.

The monthly spend cap

An organization can set a monthly spend cap: a hard ceiling on metered usage for the billing period. It has two parts:

Part Who sets it Visible to you
Your self-limit An organization Admin Yes, and you can change or clear it
The account ceiling AppGantry Yes, read-only

The effective cap is whichever of the two is lower, ignoring whichever is unset. Setting your own limit can only ever reduce your exposure, never raise it beyond the account ceiling.

Reading and changing the cap requires organization Admin, and changing it is a privileged write: it is refused for restricted tokens and it is recorded in the audit feed against the admin who made the change.

Spend caps are an API-level control today

There is no dedicated spend-cap screen in the web app yet. Manage the cap through the API:

Operation Route
Read the current cap GET /api/v1/organizations/{organization_id}/spend-cap
Set or clear the cap PUT /api/v1/organizations/{organization_id}/spend-cap

Organization Admin is required. Request and response shapes are in the interactive API reference.

What happens when the cap is reached

  • New downloads and uploads are blocked with HTTP 402 and error: "spend_cap_exceeded". The block is applied when a signed URL would be minted, so it stops byte movement rather than breaking navigation.
  • Existing artifacts keep accruing storage for the rest of the period. Nothing is deleted automatically; you are still billed for the bytes you are already holding. Shorten retention if you want that number to come down.
  • Metadata reads still work. The build list, tester list, audit feed, and settings are all unaffected. The cap blocks byte movement, not visibility.

Raise or clear the cap, or wait for the next billing period.

Cap behaviour per plan

Plan Cap available Default
Team Pre-paid balance acts as a cap; a monthly cap can be set on top A $0 balance produces 402 prepaid_credit_exhausted
Business Pre-paid balance acts as a cap, and an optional monthly cap can be set on top A $0 balance produces 402 prepaid_credit_exhausted; no monthly cap unless you set one
Enterprise Not generally available Not generally available
BYOSA organizations Not applicable Your cloud provider is the ceiling

What 402 looks like

HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "error": "spend_cap_exceeded",
  "message": "Monthly spend cap reached.",
  "details": {}
}

The envelope is the same flat {error, message, details} shape as every other AppGantry error, and a spend-cap refusal carries no lock_reason — the organization isn't locked, this request was. See Errors → 402, the canonical taxonomy, for the other payment-required cases and for the details.lock_reason values that accompany a billing write lock.

  1. Set a cap at a few times your typical monthly bill: high enough to absorb a busy month, low enough to catch a runaway.
  2. Check the Usage page when you ship something you expect to be popular.
  3. Shorten retention if storage rather than egress is what's growing.
  4. Move to BYOSA if your hosted bill is consistently above the Business platform fee. That removes per-MB risk entirely.

See also