SOXAgent Documentation
Integrate SOXAgent with your AI agents to govern financial actions with policy enforcement, audit trails, and signed evidence packs.
Base URL: https://soxagent-api.fly.dev
Getting Started
Get up and running in five steps:
- Create an account at app.soxagent.com
- Generate an API key in Settings → API Keys. Copy the key immediately — it's only shown once.
- Register an agent in the Agents tab. Give it an
agent_idthat your code will use in API calls. - Create a policy in the Policies tab. Define action types, approval thresholds, and escalation rules.
- Submit your first authorization using the API. See the Authorization section below.
New accounts include a guided setup wizard that walks you through these steps.
Authentication
Authenticate API requests using your API key. Two header formats are supported:
Authorization: Bearer sk_live_your_key_herex-api-key: sk_live_your_key_hereAPI keys are prefixed by environment: sk_live_ for production and sk_test_ for sandbox. Generate and manage keys in the dashboard at Settings → API Keys. See Environments for details.
Idempotency
All POST requests require an Idempotency-Key header. Use a UUID or unique request identifier. If a request is retried with the same key and body, the original response is replayed without re-execution.
Authorization: Bearer sk_live_abc123...
Content-Type: application/json
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000Rate Limits
API requests are rate-limited to 1,000 requests per minute per tenant. Rate limit headers are included in every response:
X-RateLimit-Limit— requests allowed per windowX-RateLimit-Remaining— requests remainingRetry-After— seconds until limit resets (when exceeded)
Environments
Every SOXAgent workspace has two isolated environments: TEST and LIVE. Policies, authorizations, and evidence are scoped to the environment determined by your API key.
| Environment | Key prefix | Purpose |
|---|---|---|
| test | sk_test_ | Sandbox for development and CI. Evaluate policies without affecting production data or audit trails. |
| live | sk_live_ | Production. Authorizations generate real audit evidence and are included in compliance reporting. |
The environment is determined entirely by the API key used in the request. A sk_test_ key will only evaluate TEST policies and create TEST authorizations. A sk_live_ key will only evaluate LIVE policies and create LIVE authorizations. There is no cross-environment interference.
Recommended workflow
- Create policies in TEST and validate them with
sk_test_keys - Run your agent integration tests against the TEST environment
- Promote policies to LIVE when ready
- Switch your production agents to
sk_live_keys
curl -X POST https://soxagent-api.fly.dev/v1/authorizations \
-H "Authorization: Bearer sk_test_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{ "action": { "type": "refund_approve", "amount": 100 }, "agent": { "agent_id": "my-agent" } }'Execution Reporting
After executing the approved action, report the outcome back to SOXAgent. This closes the audit loop and enables reconciliation.
POST /v1/authorizations/:id/execution
{
"decision_token": "dt_a1b2c3d4...",
"execution_result": {
"status": "succeeded",
"executed_at": "2026-03-18T12:05:00.000Z",
"amount": 150.00,
"currency": "USD",
"external_transaction_id": "txn_stripe_abc123"
}
}| Field | Type | Required | Description |
|---|---|---|---|
| decision_token | string | Yes | Token from the approved authorization |
| execution_result.status | string | Yes | succeeded or failed |
| execution_result.executed_at | string | Yes | ISO 8601 timestamp of execution |
| execution_result.amount | number | No | Actual executed amount (for reconciliation) |
| execution_result.currency | string | No | 3-letter currency code |
| execution_result.external_transaction_id | string | No | External system reference |
| execution_result.error_code | string | No | Error code when status is failed |
| execution_result.error_message | string | No | Error description when status is failed |
{
"request_id": "req_jkl012",
"status": "success",
"data": {
"authorization_id": "aut_7f3k9m2x",
"state": "execution_confirmed",
"execution": {
"status": "succeeded",
"external_transaction_id": "txn_stripe_abc123",
"executed_at": "2026-03-18T12:05:00.000Z"
},
"reconciliation": {
"status": "matched",
"authorized_amount": 150.00,
"executed_amount": 150.00,
"variance": 0
}
}
}Reconciliation compares the authorized amount and currency with the executed values. Status will be matched, mismatched, or failed.
Evidence Packs
Evidence packs are self-contained, cryptographically signed audit bundles for a single authorization. They contain everything an auditor needs to verify the decision chain.
GET /v1/authorizations/:id/evidence
curl https://soxagent-api.fly.dev/v1/authorizations/aut_7f3k9m2x/evidence \
-H "Authorization: Bearer sk_live_abc123..."The response is a comprehensive JSON document containing:
- Authorization metadata — action, agent, decision, timestamps
- Original request — the full submission payload
- Policy snapshot — the exact policy version used for evaluation
- Event chain — hash-chained sequence of all state transitions
- Approval chain — human approvals with timestamps and roles
- Execution & reconciliation — outcome and variance analysis
- Risk assessment — score, tier, and factor decomposition
- Compliance assessment — controls met, unmet, and review-required
- Assertions — continuous assurance check results
- SoD analysis — segregation of duties conflict check
- Agent governance — registration status and control tier
- Verification — integrity score and cryptographic signature
Each evidence pack includes a SHA-256 fingerprint for tamper detection and an Ed25519 digital signature. Public signing keys are available at GET /v1/evidence/public-key (no auth required).
Webhooks
Register webhook endpoints to receive real-time notifications when events occur.
Managing Webhooks
| Method | Endpoint |
|---|---|
| POST | /v1/webhooks |
| GET | /v1/webhooks |
| GET | /v1/webhooks/:id |
| PUT | /v1/webhooks/:id |
| DELETE | /v1/webhooks/:id |
Event Types
- authorization.decided
- approval.requested
- approval.recorded
- execution.confirmed
- execution.failed
- reconciliation.completed
- incident.opened
Signature Verification
Every webhook delivery includes a signature for verification:
X-SOXAgent-Signature— HMAC-SHA256 signatureX-SOXAgent-Timestamp— Unix timestamp of deliveryX-SOXAgent-Event— Event typeX-SOXAgent-Delivery-Id— Unique delivery identifier
Compute the expected signature as:
HMAC-SHA256(webhook_secret, "{timestamp}.{body}")Webhooks have a 10-second timeout. Deliveries are fire-and-forget with no automatic retries.
Error Codes
All error responses use a consistent envelope:
{
"request_id": "req_abc123",
"status": "error",
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description",
"details": {}
}
}| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_REQUEST | Malformed or invalid request body |
| 400 | MISSING_REQUIRED_FIELD | A required field is missing |
| 400 | IDEMPOTENCY_KEY_MISSING | POST request missing Idempotency-Key header |
| 400 | DECISION_TOKEN_INVALID | Decision token is invalid or expired |
| 401 | UNAUTHORIZED | Missing or invalid authentication |
| 403 | POLICY_DENIED | Action denied by policy evaluation |
| 403 | BUDGET_EXCEEDED | Agent monthly budget limit reached |
| 403 | AGENT_PAUSED | Agent is currently paused |
| 403 | SOD_VIOLATION | Segregation of duties conflict detected |
| 404 | NOT_FOUND | Resource not found |
| 409 | DECISION_TOKEN_REUSED | Decision token already consumed |
| 409 | IDEMPOTENCY_CONFLICT | Same key used with different request body |
| 410 | TIMEOUT_EXPIRED | Approval window has expired |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests |
| 500 | INTERNAL_ERROR | Unexpected server error |
Code Examples
curl
# Use sk_test_ keys during development, sk_live_ keys in production
curl -X POST https://soxagent-api.fly.dev/v1/authorizations \
-H "Authorization: Bearer $SOXAGENT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"action": {
"type": "refund_approve",
"amount": 150.00,
"currency": "USD"
},
"agent": {
"agent_id": "support-refund-agent"
}
}'Node.js
const SOXAGENT_API = "https://soxagent-api.fly.dev";
// Use SOXAGENT_TEST_KEY (sk_test_...) in dev, SOXAGENT_API_KEY (sk_live_...) in prod
const API_KEY = process.env.SOXAGENT_API_KEY;
async function authorize(actionType, amount, currency, agentId) {
const res = await fetch(`${SOXAGENT_API}/v1/authorizations`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
action: { type: actionType, amount, currency },
agent: { agent_id: agentId },
}),
});
const json = await res.json();
if (json.status === "success") {
const { decision, decision_token } = json.data;
console.log(`Decision: ${decision}`);
if (decision === "approved") {
// Proceed with the action, then report execution
return { approved: true, token: decision_token };
}
return { approved: false, decision };
}
throw new Error(json.error?.message || `API error: ${res.status}`);
}
// Usage
const result = await authorize("refund_approve", 150, "USD", "support-refund-agent");Python
import os
import uuid
import requests
SOXAGENT_API = "https://soxagent-api.fly.dev"
# Use SOXAGENT_TEST_KEY (sk_test_...) in dev, SOXAGENT_API_KEY (sk_live_...) in prod
API_KEY = os.environ["SOXAGENT_API_KEY"]
def authorize(action_type: str, amount: float, currency: str, agent_id: str):
resp = requests.post(
f"{SOXAGENT_API}/v1/authorizations",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"action": {"type": action_type, "amount": amount, "currency": currency},
"agent": {"agent_id": agent_id},
},
)
resp.raise_for_status()
data = resp.json()
if data["status"] == "success":
decision = data["data"]["decision"]
token = data["data"].get("decision_token")
print(f"Decision: {decision}")
if decision == "approved":
return {"approved": True, "token": token}
return {"approved": False, "decision": decision}
raise Exception(data.get("error", {}).get("message", f"API error: {resp.status_code}"))
# Usage
result = authorize("refund_approve", 150.00, "USD", "support-refund-agent")What's Next
- Dashboard — Monitor authorizations, agent health, risk scores, and compliance posture at app.soxagent.com
- Policy engine — Configure multi-tier approval rules with spending thresholds, escalation routing, and timeout actions
- Agent fleet governance — Register agents, assign owners, set budget limits, and define allowed action scopes
- Compliance frameworks — Map controls to SOX 404 control objectives with coverage gap detection
- Continuous assurance — Automated assertion checks, risk scoring, and maturity assessments
FAQ
What is SOXAgent?
SOXAgent is a financial governance layer for AI agents. Before an agent refunds, pays, approves, or commits spend, SOXAgent evaluates policy, checks approvals and SoD rules, records evidence, and supports ongoing control monitoring.
What's the difference between TEST and LIVE?
TEST is a sandbox for validating policies, approvals, evidence, SoD behavior, and control monitoring. LIVE is for production governance. They are isolated environments inside the same organization.
What's the difference between sk_test_ and sk_live_ keys?
sk_test_ keys work only in TEST. sk_live_ keys work only in LIVE. Use TEST for sandbox validation and LIVE for production traffic.
Does TEST stay isolated from LIVE?
Yes. TEST and LIVE are environment-isolated. Requests, policies, evidence, dashboard data, and runtime policy evaluation stay separate across the two environments.
What happens when a request matches multiple policies?
SOXAgent resolves overlap automatically. The most restrictive result wins first, then more specific rules win over broader ones, with deterministic tiebreaking when needed.
Does SOXAgent support segregation of duties?
Yes. SOXAgent supports SoD role assignments, conflict detection, approval-time blocking, and evidence output for SoD-relevant actions.
What evidence does SOXAgent generate?
Policy snapshots, event history, approvals, decision reasoning, integrity checks, and exportable evidence packs tied to a request lifecycle.
How does SOXAgent help with SOX 404?
SOXAgent is currently SOX 404-first. It helps teams enforce, evidence, and monitor financial-control workflows focused on authorization controls, segregation of duties, and evidence preservation for AI-driven financial actions.
Do humans create transactions in the dashboard?
SOXAgent is primarily a control plane where systems and agents submit requests. Humans configure controls, review approvals, monitor controls, inspect evidence, and investigate outcomes.
Does SOXAgent replace my ERP or finance system?
No. SOXAgent sits in front of important actions and governs whether those actions should proceed and what evidence should be captured. It does not replace your financial system of record.