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.

mintfax has three kinds of API key. The prefix is a structural promise: every request is routed based on the prefix the key carries. You pick a key, the routing follows.

The three key kinds

PrefixKindScopeCan send faxesCan manage account
mfx_test_SandboxOne sandbox environmentYes (sandbox)No
mfx_live_LiveOne live environmentYes (live)No
mfx_acct_AccountThe whole account (no environment operations)NoYes

mfx_test_... - sandbox environment key

Operational key scoped to a single sandbox environment. Sends sandbox faxes (no carrier dispatch). Reads that environment’s sandbox fax history, events, webhooks, and credit balance. Cannot touch live data and cannot call /account/*.

mfx_live_... - live environment key

Operational key scoped to a single live environment. Sends real faxes through the carrier. Reads that environment’s live data. Requires the account to be activated - until the first live credit purchase succeeds, a live key returns account_not_activated on operational routes.

mfx_acct_... - account management key

Account-scoped admin key. Reads and manages account-level resources: balances across all pools, the pool-wide transaction ledger, and the list of API keys. Cannot send faxes and cannot call /environment/*. Think of it as the keys-and-money key, not the send-a-fax key.

The prefix is the sandbox/live wall

mintfax follows Stripe’s sk_test_ / sk_live_ pattern, with a third acct kind for the account namespace. Because the gateway routes on prefix, the wall between sandbox and live is structural, not configurational:
A key never spans sandbox and live. Each environment is one type for its life. To send live, use a live key against a live environment. To send sandbox, use a sandbox key against a sandbox environment. There is no environment toggle in the API.
This is the type-homogeneity rule. If you accidentally point a sandbox key at production code, you do not silently send real faxes - the worst case is that nothing happens, because sandbox keys cannot reach live resources by construction.

Registration provisions two keys

POST /account/register/verify returns both a mfx_test_... key and a mfx_acct_... key in the same response. Store both. They have different jobs:
  • Use the sandbox key for your first sandbox fax in dev. It is scoped to the sandbox environment created at registration.
  • Use the acct key when you need to programmatically manage environments, balances, or other keys. For example: listing all your API keys, reading the live and sandbox balances side by side, or creating a new live environment key after you activate.
{
  "account":         { "id": "acct_4HGhJ7K2pNm9XqL3VtR8Wz", "name": "Acme Corp" },
  "user":            { "id": 42, "email": "dev@acme.com" },
  "environment":     { "id": "env_2BcD3eF4gH5iJ6kL7mN8oP", "name": "Sandbox", "type": "sandbox" },
  "api_key":         "mfx_test_abc123def456...",
  "api_key_account": "mfx_acct_qpr456stv789..."
}
Both plain-text keys are shown once only. Save them to a secrets manager or .env file before navigating away.

Creating more keys

Environment keys (test or live)

POST /account/keys with scope_kind=test or scope_kind=live creates an environment-scoped key. Use an mfx_acct_... key to authenticate the call:
curl -X POST https://api.mintfax.com/v1/account/keys \
  -H "Authorization: Bearer mfx_acct_qpr456stv789..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CI pipeline key",
    "scope_kind": "test",
    "environment_id": "env_2BcD3eF4gH5iJ6kL7mN8oP"
  }'
The response includes the plain-text key once. Store it immediately.

Account keys

Subsequent mfx_acct_... keys cannot be created via the API. POST /account/keys with scope_kind=account returns HTTP 403 with acct_key_creation_dashboard_only:
{
  "error": "acct_key_creation_dashboard_only",
  "message": "Account-scoped keys can only be created via the dashboard.",
  "action": "use_dashboard",
  "docs": "https://mintfax.com/docs/errors/acct-key-creation-dashboard-only"
}
Rationale: account keys are admin-equivalent for the account. Restricting their lifecycle to the dashboard adds a human-loop attestation step, so an API-only chain of compromise cannot escalate from a stolen environment key to full account control.

Revocation

Key kindDashboardAPI (DELETE /account/keys/{id} with acct key)
mfx_test_ (sandbox)YesYes
mfx_live_ (live)YesYes
mfx_acct_ (account)YesDashboard only (API returns 403)
Deleting an environment key via the API:
curl -X DELETE https://api.mintfax.com/v1/account/keys/key_8aZqRm4yT3vK7pNxJ2bH9c \
  -H "Authorization: Bearer mfx_acct_qpr456stv789..."
Revocation is effective on the next request - there is no caching layer to wait on. A revoked key returns api_key_invalid.

Which key for which endpoint

The API splits cleanly into two surfaces:
  • Operational (/faxes, /environment/*, /webhooks, /events) - environment keys only.
  • Account (/account/*) - account keys only.
Endpointmfx_test_mfx_live_mfx_acct_
POST /faxesyesyesno
GET /faxes/{id}yesyesno
GET /environment/balanceyesyesno
GET /environment/*yesyesno
GET /accountnonoyes
GET /account/balancenonoyes
GET /account/transactionsnonoyes
GET /account/keysnonoyes
POST /account/keysnonoyes
When a key hits a route it is not scoped for, the API returns HTTP 403 with a specific code: These codes are stable. Match on them programmatically if you need to fall back to a different key in your client.

Worked example: agent registration flow

A coding agent registers, stores both keys, sends a sandbox fax, then later switches to live.
# 1. Start registration. Verification code goes to the email.
curl -X POST https://api.mintfax.com/v1/account/register \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Corp", "email": "dev@acme.com"}'

# 2. Verify with the 6-digit code. Returns BOTH keys.
curl -X POST https://api.mintfax.com/v1/account/register/verify \
  -H "Content-Type: application/json" \
  -d '{"email": "dev@acme.com", "code": "482901"}'
# Response includes:
#   "api_key":         "mfx_test_abc123def456..."   <- sandbox environment
#   "api_key_account": "mfx_acct_qpr456stv789..."   <- account admin

# 3. Store both. The agent persists them to its secrets store.
echo "MINTFAX_TEST_KEY=mfx_test_abc123def456..." >> .env
echo "MINTFAX_ACCT_KEY=mfx_acct_qpr456stv789..." >> .env

# 4. Send a first sandbox fax with the sandbox key.
#    Sandbox accepts only the +1 (500) 555-XXXX magic numbers - see /sandbox.
curl -X POST https://api.mintfax.com/v1/faxes \
  -H "Authorization: Bearer mfx_test_abc123def456..." \
  -F "to=+15005550001" \
  -F "file=@invoice.pdf"

# 5. Later, after activating live in the dashboard, mint a live environment key
#    using the account key.
curl -X POST https://api.mintfax.com/v1/account/keys \
  -H "Authorization: Bearer mfx_acct_qpr456stv789..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "production",
    "scope_kind": "live",
    "environment_id": "env_LiVe9AbC8DeF7GhI6JkL5M"
  }'

# 6. Swap the sandbox key for the new live key in production code.
curl -X POST https://api.mintfax.com/v1/faxes \
  -H "Authorization: Bearer mfx_live_xyz789wvu654..." \
  -F "to=+15125550100" \
  -F "file=@invoice.pdf"
The acct key never sends faxes. The environment keys never read account-level data. The prefix tells the gateway everything it needs to know.
Last modified on May 13, 2026