Developer Documentation
Integrate Appfora's Legal and Support APIs into your application. Get your API key, make your first call, and ship.
Quick Start
- 1Create an account and scan your repository
- 2Navigate to your product → API Keys → Create key
- 3Copy the key (
af_live_...) — shown only once - 4Pass it as
Authorization: Bearer af_live_...
Working Examples
Complete examples covering connection, every API scope, and cleanup. Replace YOUR_PRODUCT_ID and af_live_YOUR_KEY with your actual values.
import requests
BASE_URL = "https://gateway.appfora.io/api/v1"
PRODUCT = "YOUR_PRODUCT_ID"
API_KEY = "af_live_YOUR_KEY"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# ── legal:read ─────────────────────────────────────────────────────
docs = requests.get(f"{BASE_URL}/{PRODUCT}/api/legal/documents", headers=HEADERS)
print("Legal docs:", docs.json())
single = requests.get(
f"{BASE_URL}/{PRODUCT}/api/legal/documents/privacy-policy", headers=HEADERS)
print("Privacy Policy:", single.json())
config = requests.get(f"{BASE_URL}/{PRODUCT}/api/legal/config", headers=HEADERS)
print("Legal config:", config.json())
# ── legal:generate ─────────────────────────────────────────────────
gen = requests.post(f"{BASE_URL}/{PRODUCT}/api/legal/generate",
headers=HEADERS, json={"trigger": "api"})
print("Generate:", gen.json())
regen = requests.post(f"{BASE_URL}/{PRODUCT}/api/legal/regenerate",
headers=HEADERS, json={"trigger": "api"})
print("Regenerate:", regen.json())
requests.put(f"{BASE_URL}/{PRODUCT}/api/legal/config",
headers=HEADERS,
json={"company_name": "Acme Ltd", "dpo_email": "[email protected]"})
# ── legal:approve ──────────────────────────────────────────────────
drafts = requests.get(
f"{BASE_URL}/{PRODUCT}/api/legal/documents/drafts", headers=HEADERS)
print("Drafts:", drafts.json())
doc_id = "DRAFT_DOC_ID"
requests.put(f"{BASE_URL}/{PRODUCT}/api/legal/documents/{doc_id}/publish",
headers=HEADERS)
requests.put(f"{BASE_URL}/{PRODUCT}/api/legal/documents/{doc_id}/reject",
headers=HEADERS)
# ── support:articles ───────────────────────────────────────────────
articles = requests.get(
f"{BASE_URL}/{PRODUCT}/api/support/articles", headers=HEADERS)
print("Articles:", articles.json())
# ── support:ask ────────────────────────────────────────────────────
answer = requests.post(f"{BASE_URL}/{PRODUCT}/api/support/ask",
headers=HEADERS,
json={"question": "How do I reset my password?"})
print("Answer:", answer.json())
# ── support:regenerate ─────────────────────────────────────────────
requests.post(f"{BASE_URL}/{PRODUCT}/api/support/generate",
headers=HEADERS, json={"trigger": "api"})
# ── support:approve ────────────────────────────────────────────────
requests.post(f"{BASE_URL}/{PRODUCT}/api/support/kb/rebuild",
headers=HEADERS)
requests.put(f"{BASE_URL}/{PRODUCT}/api/support/articles/ART_ID/review",
headers=HEADERS, json={"approved": True})
# ── Cleanup ────────────────────────────────────────────────────────
# Keys are long-lived — there is no "session close" call.
# Revoke from the Appfora dashboard (Products → API Keys → Revoke)
# or rotate via the management API when no longer needed.
# The gateway invalidates the cached session instantly via pub/sub.
print("Done — revoke or rotate the key when no longer needed.")API Endpoints
All endpoints are under https://gateway.appfora.io/api/v1/{product_id}
Legal — Live & Test
/api/legal/documentslegal:read/api/legal/documents/{slug}legal:read/api/legal/configlegal:readLegal — CI / CD
/api/legal/generatelegal:generate/api/legal/regeneratelegal:generate/api/legal/configlegal:generate/api/legal/documents/draftslegal:approve/api/legal/documents/{id}/publishlegal:approve/api/legal/documents/{id}/rejectlegal:approveSupport — Live & Test
/api/support/asksupport:ask/api/support/articlessupport:articlesSupport — CI / CD
/api/support/generatesupport:regenerate/api/support/articles/{id}/reviewsupport:approve/api/support/qa/{id}/feedbacksupport:approve/api/support/kb/rebuildsupport:approveScopes Reference
Assign the minimum scopes needed for each integration.
| Scope | Category | Allows |
|---|---|---|
legal:read | Live & Test | Read generated legal documents (ToS, Privacy, AUP, etc.) |
legal:generate | CI / CD | Regenerate legal documents and update legal config |
legal:approve | CI / CD | List drafts, publish or reject legal document versions |
support:ask | Live & Test | Ask support questions in real-time |
support:articles | Live & Test | Read Help Centre articles and FAQs |
support:regenerate | CI / CD | Regenerate Help Centre FAQ articles from scan data |
support:approve | CI / CD | Approve articles, approve/reject Q&A, rebuild KB |
Error Handling
All errors return:
{ "detail": "Human-readable message" }Rate Limits & Caps
Per-Key Rate Limit
Default 60 req/min, configurable up to 1,000,000. Editable inline from the API Keys page.
Soft Cap
Warning email sent to all org members. Requests continue.
Hard Cap
Returns 429 — all subsequent requests blocked until billing cycle resets or cap is raised.
Retry Strategy
Exponential backoff on 429: wait 1s, 2s, 4s, 8s, then fail.
Ready to Integrate?
Create your account, scan your first repo, and start making API calls in minutes.
Get Started Free