Skip to content

Custom integration (any language)

The FastAPI SDK is a convenience layer over three HTTP endpoints — the SDK API. If you run Go, Node, Rails, Laravel or anything else, you can implement the same pattern yourself. This guide documents the endpoints and the caching/reporting pattern that makes the integration fast and robust.

Authentication

All SDK API calls authenticate with your tenant secret key (mas_..., from the tenant's Overview tab):

Authorization: Bearer mas_...

Base URL: https://api.microauth.com. A suspended tenant receives 403 on every SDK API call.

Keys are matched by hash

Your customers send you their API key (map_...). You never forward the raw key to MicroAuth — you always work with its SHA-256 hex digest (sha256("map_...") → 64 lowercase hex chars). The snapshot contains key hashes, and the verify endpoint takes a key_hash query parameter.

The pattern in one diagram

your API process                          MicroAuth
┌──────────────────────────┐
│  in-memory cache         │  every ~30s   GET /sdk/v1/snapshot
│  keys + customers  ◄─────┼───────────────────────────────────►
│                          │  cache miss   GET /sdk/v1/keys/verify
│  per-request:            │───────────────────────────────────►
│   hash key → lookup →    │
│   enforce → count        │  every ~15s   POST /sdk/v1/usage
│  usage counters   ───────┼───────────────────────────────────►
└──────────────────────────┘

Never call MicroAuth on the hot path. Serve requests from the cache; talk to MicroAuth in the background.

1. GET /sdk/v1/snapshot

Returns everything you need to authenticate and enforce limits locally: all active customers with their effective limits, and all active key hashes.

bash
curl https://api.microauth.com/sdk/v1/snapshot \
  -H "Authorization: Bearer mas_..."
json
{
  "generated_at": "2026-08-03T18:00:00Z",
  "billable_status_codes": [200],
  "customers": [
    {
      "id": "c6f7e9a2-...",
      "status": "active",
      "credit_balance_micro": 12500000,
      "month_requests": 48210,
      "effective": {
        "rps": 10,
        "price_per_request_micro": 500,
        "monthly_quota": 1000000,
        "source": "plan",
        "billing_model": "subscription"
      }
    }
  ],
  "keys": [
    {
      "id": "9b1d3f60-...",
      "key_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
      "customer_id": "c6f7e9a2-..."
    }
  ]
}

Notes:

  • effective.monthly_quota is omitted when the customer has no request cap.
  • effective.source is custom, plan or payg — which layer of the limit resolution won.
  • Refresh every ~30 seconds. The endpoint is rate limited to 60 requests/minute per tenant; polling faster returns 429 and buys you nothing.
  • Build two lookup maps from the response: key_hash → key and customer_id → customer.

2. GET /sdk/v1/keys/verify

For keys that aren't in your cached snapshot (e.g. created seconds ago). Resolves one key hash to its customer and limits:

bash
curl "https://api.microauth.com/sdk/v1/keys/verify?key_hash=$(printf '%s' "map_..." | shasum -a 256 | cut -d' ' -f1)" \
  -H "Authorization: Bearer mas_..."

Valid key:

json
{
  "valid": true,
  "key_id": "9b1d3f60-...",
  "billable_status_codes": [200],
  "customer": { "id": "c6f7e9a2-...", "status": "active", "credit_balance_micro": 12500000, "month_requests": 48210, "effective": { "rps": 10, "price_per_request_micro": 500, "source": "plan", "billing_model": "subscription" } }
}

Unknown or revoked key: { "valid": false } (HTTP 200 — the call succeeded, the key didn't).

Guidelines:

  • Only call this on a cache miss, and de-duplicate concurrent misses for the same hash (single-flight), so a burst can't stampede MicroAuth.
  • Negatively cache invalid hashes for ~30 seconds; a flood of garbage keys should be absorbed by your cache, not forwarded.
  • Rate limit: 600 requests/minute per tenant.

3. POST /sdk/v1/usage

Report billable requests in batches. MicroAuth records usage and charges each customer's prepaid balance at their effective per-request price.

bash
curl -X POST https://api.microauth.com/sdk/v1/usage \
  -H "Authorization: Bearer mas_..." \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "key_id": "9b1d3f60-...", "requests": 42, "period_start": "2026-08-03T18:00:00Z" }
    ]
  }'
json
{ "accepted": 1, "rejected": 0 }

Rules and semantics:

  • Only count billable responses — those whose HTTP status is in billable_status_codes from the snapshot (default [200]). Don't charge your customers for your own 500s.
  • Aggregate locally as one counter per key_id per hour, flush every ~15 seconds. period_start is bucketed to the hour server-side, and buckets are summed additively — so multiple workers reporting the same hour is correct by design.
  • Limits: 1–1000 items per call, 1–10,000,000 requests per item, 600 calls/minute per tenant.
  • rejected counts items that couldn't be applied (unknown key, suspended customer, overflow). Rejected items should not be retried blindly — a suspended customer's usage stays rejected.
  • If MicroAuth is unreachable, keep the counters and retry with backoff. Usage reporting is additive per hour bucket, so late reports are fine — but don't re-send items that were already accepted (that would double-charge; dedupe on your side per flush).

Local enforcement checklist

On each incoming request to your API:

  1. Read the key from your header (e.g. X-API-Key); missing → 401.
  2. hash = sha256_hex(key); look it up in the snapshot; miss → verify endpoint (single-flight) → still invalid → 401.
  3. Customer status != "active"403.
  4. billing_model != "none" and credit_balance_micro <= 0402 (account for usage you've counted locally since the last snapshot).
  5. monthly_quota set and month_requests + local count ≥ quota → 429.
  6. Enforce effective.rps per customer (token bucket or fixed window; use Redis if you run many workers) → over → 429 with Retry-After.
  7. Serve the request. If the response status is billable, increment the counter for (key_id, current_hour).

Minimal reference implementation (Python, ~no framework)

python
import hashlib, threading, time, requests

BASE = "https://api.microauth.com"
HEADERS = {"Authorization": "Bearer mas_..."}

snapshot = {"keys": {}, "customers": {}, "billable": {200}}
usage = {}  # (key_id, hour_iso) -> count
lock = threading.Lock()

def sync_loop():
    while True:
        r = requests.get(f"{BASE}/sdk/v1/snapshot", headers=HEADERS, timeout=5)
        if r.ok:
            d = r.json()
            with lock:
                snapshot["keys"] = {k["key_hash"]: k for k in d["keys"]}
                snapshot["customers"] = {c["id"]: c for c in d["customers"]}
                snapshot["billable"] = set(d["billable_status_codes"])
        time.sleep(30)

def report_loop():
    while True:
        time.sleep(15)
        with lock:
            items = [{"key_id": k, "requests": n, "period_start": h}
                     for (k, h), n in usage.items() if n > 0]
            pending = dict(usage); usage.clear()
        if items:
            r = requests.post(f"{BASE}/sdk/v1/usage", headers=HEADERS,
                              json={"items": items}, timeout=5)
            if not r.ok:  # put the counts back and retry next tick
                with lock:
                    for kh, n in pending.items():
                        usage[kh] = usage.get(kh, 0) + n

def authenticate(api_key: str):
    h = hashlib.sha256(api_key.encode()).hexdigest()
    with lock:
        key = snapshot["keys"].get(h)
        cust = snapshot["customers"].get(key["customer_id"]) if key else None
    if not key or not cust:
        return None  # -> 401 (add the verify-endpoint fallback here)
    if cust["status"] != "active":
        return "suspended"  # -> 403
    return key, cust

def record(key_id: str, status: int):
    if status in snapshot["billable"]:
        hour = time.strftime("%Y-%m-%dT%H:00:00Z", time.gmtime())
        with lock:
            usage[(key_id, hour)] = usage.get((key_id, hour), 0) + 1

(Production code should add the verify fallback, negative caching, RPS limiting and graceful-shutdown flushing — exactly what the FastAPI SDK does for you.)

See also

MicroAuth is a product of Zyref, LLC.