Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintfax.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

Live access on mintfax is gated on a single timestamp: account.activated_at. Until that field is set, live operational endpoints refuse to run. Sandbox is never gated.

The activation gate

The activation gate runs on every authenticated request. When a request arrives with an mfx_live_... key on an operational route (POST /faxes, GET /environment/*, GET /faxes/{id}, and so on), mintfax checks the account’s activated_at. If it is null, the request is rejected before it reaches your application handler:
{
  "error": "account_not_activated",
  "message": "Live operations require account activation. Activate via the dashboard.",
  "action": "activate_account",
  "docs": "https://mintfax.com/docs/errors/account-not-activated"
}
HTTP 403. See account_not_activated in the error catalog. Sandbox routes have no activation check. As soon as registration completes, you can send sandbox faxes with the mfx_test_... key returned at signup, manage keys with the mfx_acct_... key, and explore the API freely.

activated_at is set on first successful live credit purchase

activated_at is written atomically in the same database transaction as the first successful live credit purchase. Until that purchase succeeds, the account stays unactivated - even if the user has signed up, verified their email, and added a card. The flow is:
  1. User clicks Activate Live in the dashboard.
  2. Stripe Checkout opens. The session collects the card AND charges for the first credit package.
  3. On a successful charge, mintfax (in one transaction):
    • Records the payment.
    • Credits the live pool.
    • Sets account.activated_at = now().
  4. Once activation completes, subsequent live requests succeed immediately - there is no caching layer to invalidate.
If the Stripe Checkout fails (card declined, user abandons), nothing is set. The account remains unactivated and the user can retry.

Why not stripe_id?

A naive design would treat the presence of stripe_id (a Stripe customer ID) as activation. mintfax does not, because a setup-mode Stripe Checkout writes stripe_id to the account record without funding it. That style of flow saves a card for later use but does not move any money. If stripe_id were the gate, anyone could mark themselves “activated” by adding a card they had no intention of being charged on. We would then accept live fax submissions, place holds, attempt the carrier dispatch, and only discover at capture time that the card cannot actually be charged - too late for a clean failure. Tying activation to a real credit purchase fixes that: the first live fax always succeeds, because we already know the card works (it just charged) and the pool has credits to draw from.

Buy-as-activation: one UX step, four atomic effects

The dashboard’s Activate Live CTA collapses four operations into a single Stripe Checkout session:
EffectResult
Card on fileStripe customer + payment method saved
Initial chargeReal money moves
Credits the live poolavailable increases on the live wallet
Sets activated_atLive operational endpoints unlock
All four happen in the same database transaction in mintfax’s webhook handler when Stripe confirms the successful payment. There is no half-activated state - either every step succeeded and the account is live, or none did and the account is unchanged.

The unactivated phase

Between registration and first live purchase, the account exists in an unactivated state. What works and what does not:
ActionState
Register with POST /account/registerWorks
Receive mfx_test_... and mfx_acct_... at verifyWorks
Send sandbox faxes with mfx_test_...Works
Read sandbox balance and transactionsWorks
Manage keys with mfx_acct_...Works
Create a live environmentWorks (the environment exists; the keys do not yet)
Mint a mfx_live_... keyWorks (the key exists, but every operational call rejects it with account_not_activated)
Send a live faxBlocked - account_not_activated
Read live balance via /environment/balanceBlocked - account_not_activated
A live key on an operational route never gets past authentication while the account is unactivated. AuthenticateApiKey raises account_not_activated during auth itself, so the request never reaches your handler. This is intentional: the system stays consistent (live operations stay strictly off until activation) and the error code is specific enough for a client to act on.

Detecting and handling the gate

If you build automation that may run before activation completes, watch for the error code and surface the dashboard URL to your operator:
curl -X POST https://api.mintfax.com/v1/faxes \
  -H "Authorization: Bearer mfx_live_xyz789wvu654..." \
  -F "to=+15125550100" \
  -F "file=@invoice.pdf"
{
  "error": "account_not_activated",
  "message": "Live operations require account activation. Activate via the dashboard.",
  "action": "activate_account",
  "docs": "https://mintfax.com/docs/errors/account-not-activated"
}
The action field is stable - match on activate_account and prompt your user to complete the dashboard step. Once activation succeeds, the same request will go through without code changes.

Reactivation

There is no deactivation gate in normal operation - once activated_at is set, it stays set. mintfax does not currently expose an environment-level suspension state; if you need to stop API access for an environment, revoke the keys attached to it.
  • Credits - the account-pool credit model
  • Keys - environment vs account keys and prefix routing
  • Errors - account_not_activated and adjacent codes
Last modified on May 13, 2026