Quickstart
Goal: your first authenticated APEX call — a retrieval-augmented query against your tenant's corpus — in a few minutes, then the async patterns you will use everywhere else.
0. What you need (from onboarding)
Your platform operator provisions these during tenant onboarding:
| Item | Environment variable (suggested) |
|---|---|
Tenant identifier (e.g. your-tenant) |
APEX_TENANT_ID |
Tenant API key (apex_test_… for development) |
APEX_API_KEY |
| Machine-to-machine client id + secret + token URL + scopes | APEX_CLIENT_ID, APEX_CLIENT_SECRET, APEX_TOKEN_URL |
| Base URLs for your environment | see Environments & Endpoints |
Development base URLs used below: https://zenith.dev.apex.reisiger.org (Zenith), https://vector.dev.apex.reisiger.org (Vector).
1. Mint an access token
See Authentication for the full flow. Short version (curl):
TOKEN=$(curl -s -X POST "$APEX_TOKEN_URL" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=$APEX_CLIENT_ID&client_secret=$APEX_CLIENT_SECRET&scope=apex/your-tenant.read" \
| python -c "import sys,json;print(json.load(sys.stdin)['access_token'])")
2. Confirm your tenant is live
curl -s "https://zenith.dev.apex.reisiger.org/api/v1/your-tenant/config" \
-H "Authorization: Bearer $TOKEN"
A 200 with your tenant's configuration view means you are onboarded. A 404 means the tenant is not configured for Zenith yet — that is the platform's fail-closed behaviour, not a transient error; contact your operator.
3. Your first knowledge query
PowerShell:
$headers = @{ Authorization = "Bearer $token"; 'X-Correlation-ID' = "quickstart:first-query" }
$body = @{ query = 'What are the safety requirements for pressure vessel inspections?'; mode = 'rag' } | ConvertTo-Json
Invoke-RestMethod -Method Post `
-Uri 'https://zenith.dev.apex.reisiger.org/api/v1/your-tenant/query' `
-Headers $headers -ContentType 'application/json' -Body $body
curl:
curl -s -X POST "https://zenith.dev.apex.reisiger.org/api/v1/your-tenant/query" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "X-Correlation-ID: quickstart:first-query" \
-d '{"query": "What are the safety requirements for pressure vessel inspections?", "mode": "rag"}'
Python:
import requests
resp = requests.post(
"https://zenith.dev.apex.reisiger.org/api/v1/your-tenant/query",
headers={"Authorization": f"Bearer {token}", "X-Correlation-ID": "quickstart:first-query"},
json={"query": "What are the safety requirements for pressure vessel inspections?", "mode": "rag"},
timeout=60,
)
resp.raise_for_status()
result = resp.json()
print(result["data"]["answer"])
for source in result["data"]["sources"]:
print(" cited:", source["document_id"], source["relevance_score"])
print("cost (ZAR):", result["cost"]["total_zar"])
Three things to notice in the response:
data.sources— every answer carries citations back to corpus chunks. Surface them; they are your provenance story.data.verification— when enabled for your tenant, answers carry a verification block (confidence, claim checks).cost— per-call cost breakdown in ZAR. Thread yourX-Correlation-IDand reconcile later — see Usage & Cost.
4. Verify a claim (tenant API key style)
Vector authenticates with your tenant API key directly and carries tenant as a query parameter:
curl -s -X POST "https://vector.dev.apex.reisiger.org/verify?tenant_id=your-tenant" \
-H "Authorization: Bearer $APEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"claim": "The company holds ISO 9001 certification.", "context": "supplier due diligence", "depth": "standard"}'
The response contains a verdict (supported / contradicted / insufficient / mixed) and a calibrated confidence between 0 and 1.
5. The async pattern you will use everywhere
Long-running work (corpus ingestion, document jobs, message delivery) follows submit-then-poll:
# Submit — returns immediately with a job/message id
job = requests.post(
"https://zenith.dev.apex.reisiger.org/api/v1/your-tenant/ingest",
headers={"Authorization": f"Bearer {token}"},
json={},
timeout=30,
).json()
# Poll until terminal
import time
while True:
status = requests.get(
f"https://zenith.dev.apex.reisiger.org/api/v1/your-tenant/ingest/{job['job_id']}",
headers={"Authorization": f"Bearer {token}"},
timeout=30,
).json()
if status["status"] in ("completed", "failed"):
break
time.sleep(5)
The same shape applies to Document Operations jobs (GET /v1/jobs/{id}) and Echo message delivery (GET /messages/{tenant}/{message_id}), and Echo can push terminal status to you instead via signed webhooks — see Integration Conventions.
Where next
- Wire your remaining capabilities: Prism rendering, Echo messaging, Document Operations.
- LLM dispatch for your agents: the Forge LLM gateway is Planned (contract pinned) — build behind a flag against its spec.
- Set up your repo per Client-Repo Conventions.