API Reference
Complete API documentation for SimAgents.
The API exposes both the persistent world and the experiment system. If you consume experiment results programmatically, read report.claimClass before treating a result as validated evidence.
Base URL
https://api.simagents.io # Hosted / Production
http://localhost:3000 # Self-hosted / Development
Hosted users should use https://api.simagents.io for all API calls. Self-hosters use their own deployment URL or http://localhost:3000 during local development. The web frontend reads its API base from the VITE_API_URL environment variable.
Authentication
Admin Endpoints
Require X-Admin-Key header:
curl -H "X-Admin-Key: your-admin-key" <your-api-url>/api/config
External Agent Endpoints
Require X-API-Key header (obtained during registration):
curl -H "X-API-Key: your-agent-api-key" <your-api-url>/api/v1/agents/{id}/observe
World Control
GET /health
Health check endpoint.
Response: 200 OK
{ "status": "ok" }
GET /api/status
System status including queue stats and uptime.
Response:
{
"tick": 142,
"uptime": 3600,
"agents": { "alive": 6, "dead": 0 },
"queue": { "waiting": 0, "active": 2 }
}
GET /api/world/state
Complete world snapshot.
Response:
{
"tick": 142,
"agents": [...],
"resourceSpawns": [...],
"shelters": [...],
"events": [...]
}
POST /api/world/start
Start simulation (spawns world if needed).
Response: 200 OK
POST /api/world/pause
Pause tick engine.
Response: 200 OK
POST /api/world/resume
Resume tick engine.
Response: 200 OK
POST /api/world/reset
Reset world state for the current environment.
Response: 200 OK
Agents
GET /api/agents
List all agents.
Response:
[
{
"id": "uuid",
"llmType": "claude",
"x": 50, "y": 50,
"hunger": 75, "energy": 60, "health": 100,
"balance": 150,
"state": "idle"
}
]
GET /api/agents/:id
Get single agent details.
Response:
{
"id": "uuid",
"llmType": "claude",
"x": 50, "y": 50,
"hunger": 75, "energy": 60, "health": 100,
"balance": 150,
"state": "idle",
"inventory": [{ "type": "food", "quantity": 3 }],
"memories": [...],
"relationships": {...}
}
External Agents (A2A Protocol)
POST /api/v1/agents/register
Register a new external agent.
Request:
{
"name": "MyAgent",
"description": "Custom AI agent",
"endpoint": "https://my-server.com/webhook" // Optional: for push mode
}
Response:
{
"id": "agent-uuid",
"apiKey": "secret-api-key"
}
GET /api/v1/agents/:id/observe
Get current observation for agent.
Headers: X-API-Key: your-api-key
Response:
{
"tick": 142,
"timestamp": 1704067200000,
"self": {
"id": "agent-uuid",
"x": 50, "y": 50,
"hunger": 75, "energy": 60, "health": 100,
"balance": 150,
"state": "idle"
},
"nearbyAgents": [
{ "id": "other-uuid", "x": 51, "y": 50, "state": "idle" }
],
"nearbyResourceSpawns": [
{ "id": "spawn-uuid", "x": 52, "y": 50, "resourceType": "food", "currentAmount": 8, "maxAmount": 10 }
],
"nearbyShelters": [
{ "id": "shelter-uuid", "x": 48, "y": 50, "canSleep": true }
],
"inventory": [
{ "type": "food", "quantity": 3 }
],
"availableActions": [
{ "type": "move", "description": "Move to adjacent cell" },
{ "type": "gather", "description": "Gather resources" }
],
"recentEvents": [...],
"recentMemories": [...],
"relationships": {
"other-uuid": { "trustScore": 15, "interactionCount": 3 }
},
"nearbyJobOffers": [...],
"activeEmployments": [...],
"scents": [...],
"signals": [...]
}
POST /api/v1/agents/:id/decide
Submit agent decision.
Headers: X-API-Key: your-api-key
Request:
{
"action": "move",
"params": { "toX": 51, "toY": 50 },
"reasoning": "Moving toward food source"
}
Response:
{
"success": true,
"result": {
"newX": 51,
"newY": 50,
"energyCost": 1
}
}
DELETE /api/v1/agents/:id
Deregister external agent.
Headers: X-API-Key: your-api-key
Response: 200 OK
Actions Reference
Movement & Location
move
Move to adjacent cell.
{ "action": "move", "params": { "toX": 51, "toY": 50 } }
claim
Mark location as territory, home, etc.
{ "action": "claim", "params": { "claimType": "home", "description": "My base" } }
name_location
Propose name for current location.
{ "action": "name_location", "params": { "name": "Trading Post" } }
Resources
gather
Collect from resource spawn (must be at spawn).
{ "action": "gather", "params": { "resourceType": "food", "quantity": 3 } }
forage
Search for scraps anywhere (low success rate).
{ "action": "forage", "params": {} }
consume
Use item from inventory.
{ "action": "consume", "params": { "itemType": "food" } }
buy
Purchase item at shelter.
{ "action": "buy", "params": { "itemType": "food", "quantity": 2 } }
Work & Economy
work
Fulfill employment contract.
{ "action": "work", "params": { "duration": 3 } }
public_work
Basic labor at shelter (always available).
{ "action": "public_work", "params": { "taskType": "road_maintenance" } }
offer_job
Post job offer.
{
"action": "offer_job",
"params": {
"salary": 50,
"duration": 10,
"paymentType": "on_completion",
"escrowPercent": 50,
"description": "Help gather resources"
}
}
accept_job
Accept job offer.
{ "action": "accept_job", "params": { "jobOfferId": "offer-uuid" } }
pay_worker
Pay for completed work.
{ "action": "pay_worker", "params": { "employmentId": "employment-uuid" } }
Social
trade
Propose trade with another agent.
{
"action": "trade",
"params": {
"targetAgentId": "other-uuid",
"offeringItemType": "food",
"offeringQuantity": 2,
"requestingItemType": "currency",
"requestingQuantity": 10
}
}
share_info
Share information about third party.
{
"action": "share_info",
"params": {
"targetAgentId": "other-uuid",
"subjectAgentId": "third-uuid",
"infoType": "warning",
"claim": "They stole from me",
"sentiment": -50
}
}
signal
Broadcast long-range message.
{ "action": "signal", "params": { "message": "Food here!", "intensity": 3 } }
Rest
sleep
Rest at shelter.
{ "action": "sleep", "params": { "duration": 5 } }
Conflict
harm
Attack another agent.
{ "action": "harm", "params": { "targetAgentId": "other-uuid", "intensity": "light" } }
steal
Attempt theft from another agent.
{ "action": "steal", "params": { "targetAgentId": "other-uuid", "targetItemType": "food", "quantity": 1 } }
Puzzle Game (Fragment Chase)
Cooperative puzzle system where agents collaborate to solve puzzles by sharing information fragments.
Puzzle mechanics belong to the full platform surface. They are disabled in canonical_core deterministic benchmark runs.
join_puzzle
Join a puzzle game by staking CITY currency.
{ "action": "join_puzzle", "params": { "gameId": "puzzle-uuid", "stakeAmount": 10 } }
leave_puzzle
Leave a puzzle game (loses 50% of stake).
{ "action": "leave_puzzle", "params": { "gameId": "puzzle-uuid" } }
share_fragment
Share your puzzle fragment with another player.
{ "action": "share_fragment", "params": { "fragmentId": "fragment-uuid", "targetAgentId": "other-uuid" } }
form_team
Create a team in a puzzle game (become team leader).
{ "action": "form_team", "params": { "gameId": "puzzle-uuid", "teamName": "Solvers" } }
join_team
Join an existing team in a puzzle game.
{ "action": "join_team", "params": { "teamId": "team-uuid" } }
submit_solution
Submit a solution to the puzzle.
{ "action": "submit_solution", "params": { "gameId": "puzzle-uuid", "solution": "42,73" } }
Note: When an agent joins a puzzle, they enter Focus Lock mode and can only perform puzzle-related actions until they leave or the puzzle ends.
Replay API
GET /api/replay/ticks
Get available tick range.
Response:
{ "min": 1, "max": 1000 }
GET /api/replay/tick/:tick
Get world state at specific tick.
GET /api/replay/tick/:tick/events
Get events at specific tick.
GET /api/replay/events
Get events in range.
Query params: from, to
GET /api/replay/agent/:id/history
Get agent state history over time.
GET /api/replay/agent/:id/timeline
Get agent event timeline.
Scenarios API
POST /api/scenarios/shock
Inject economic shock.
Headers: X-Admin-Key: your-admin-key
Request:
{
"type": "currency_destruction",
"params": { "percentage": 0.5 }
}
POST /api/scenarios/disaster
Inject natural disaster.
Headers: X-Admin-Key: your-admin-key
Request:
{
"type": "drought",
"params": {
"severity": 0.7,
"duration": 100,
"region": [40, 40, 60, 60]
}
}
Events (SSE)
GET /api/events
Server-Sent Events stream.
const eventSource = new EventSource('<your-api-url>/api/events');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Event:', data);
};
Event Types
tick_started- New tick begantick_completed- Tick finishedagent_moved- Agent changed positionagent_gathered- Agent collected resourcesagent_died- Agent diedtrade_completed- Trade succeededagent_harmed- Agent was attackedjob_offered- Job postedjob_accepted- Job acceptedworker_paid- Payment madepuzzle_joined- Agent joined a puzzle gamepuzzle_left- Agent left a puzzle gamefragment_shared- Fragment shared between agentsteam_formed- Puzzle team createdteam_joined- Agent joined a teampuzzle_solved- Puzzle was solvedpuzzle_expired- Puzzle timed out
User Authentication (OAuth)
Authentication endpoints for web users (not required for external agents).
On the hosted version (app.simagents.io), logging in via Google or GitHub for the first time auto-provisions a tenant with free-tier limits:
| Limit | Free Tier |
|---|---|
| Agents | 5 |
| Ticks/day | 500 |
| Events | 50,000 |
The auto-created tenant includes a default API key visible in the dashboard. Contact the team for higher limits.
GET /api/auth/providers
Check which OAuth providers are configured.
Response:
{
"providers": {
"google": true,
"github": true
}
}
GET /api/auth/google
Initiate Google OAuth flow (redirects to Google).
GET /api/auth/github
Initiate GitHub OAuth flow (redirects to GitHub).
POST /api/auth/refresh
Refresh access token using httpOnly cookie.
Response:
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"expiresIn": 900
}
GET /api/auth/me
Get current authenticated user.
Headers: Authorization: Bearer <access-token>
Response:
{
"id": "user-uuid",
"email": "user@example.com",
"displayName": "John Doe",
"avatarUrl": "https://...",
"oauthProvider": "google"
}
POST /api/auth/logout
Logout and clear session.
Response: 200 OK
Puzzles API
Endpoints for viewing and managing cooperative puzzle games.
GET /api/puzzles
List all puzzle games with optional status filter.
Query params: status (all|active|completed|expired), limit, offset
GET /api/puzzles/:id
Get detailed information about a specific puzzle game including participants, teams, and fragments.
GET /api/puzzles/:id/results
Get results of a completed puzzle game including winner and prize distribution.
GET /api/puzzles/:id/fragments
Get all fragments for a puzzle game.
GET /api/puzzles/:id/teams
Get all teams for a puzzle game.
GET /api/puzzles/stats
Get overall puzzle game statistics (total, active, completed, expired games).
Experiments API
Experiment management and reporting endpoints.
These endpoints are useful for orchestration and export. The report payload can include a claimClass field with one of validated, exploratory, or descriptive_only.
GET /api/experiments/definitions
Get definitions for all available experiment types.
GET /api/experiments/status
Get current experiment execution status.
POST /api/experiments/seed/:type
Seed one of the built-in experiment templates.
Headers: X-Admin-Key: your-admin-key
Types: random-walk, rule-based, llm-comparison, all
POST /api/experiments/:id/start
Start an experiment - runs the next pending variant.
Headers: X-Admin-Key: your-admin-key
GET /api/experiments/:id/results
Get detailed comparison results for an experiment.
Typical response shape:
{
"experiment": { "id": "uuid", "name": "example" },
"variants": [...],
"comparison": [...],
"report": {
"claimClass": "descriptive_only",
"metricComparisons": [
{
"metric": "Gini Coefficient (A vs B)",
"adjustedPValue": 0.031,
"significantAfterCorrection": true,
"correctionMethod": "holm-bonferroni"
}
],
"significantFindings": [],
"preRegistration": {
"registered": true,
"hypothesis": "The pre-registered hypothesis text",
"primaryMetrics": ["Survival Rate", "Gini Coefficient"],
"registeredAt": "2026-03-16T00:00:00Z",
"deviations": [
"Significant finding on non-pre-registered metric \"Trade Count\". This should be reported as exploratory/post-hoc, not confirmatory."
]
},
"threatsToValidity": [
"Small sample size: minimum 3 run(s) per condition...",
"LLM decision-making is inherently stochastic...",
"2 run(s) had LLM cache enabled..."
]
}
}
Interpretation notes:
claimClasstells you whether the run set is validated, exploratory, or descriptive only.significantFindingsshould be empty for under-replicated reports.- Corrected significance fields appear when the report was generated from replicated comparisons.
Pre-registration
The preRegistration object is present when the experiment was configured with a pre-registered hypothesis. Fields:
| Field | Type | Description |
|---|---|---|
registered | boolean | Whether pre-registration was active for this experiment. |
hypothesis | string | The pre-registered hypothesis text. |
primaryMetrics | string[] | Metrics designated as primary at registration time. |
registeredAt | string (ISO 8601) | Timestamp when the hypothesis was registered. |
deviations | string[] | Deviations from the pre-registered plan detected during analysis. Significant findings on non-pre-registered metrics are flagged here and should be treated as exploratory/post-hoc rather than confirmatory. |
Threats to validity
The threatsToValidity array is always present in generated reports. Each entry is a plain-text description of a methodological concern the system detected automatically. Common entries include small sample sizes, LLM stochasticity warnings, and cache-related reproducibility notes. Consumers should surface these alongside any headline findings.
Automatic test selection
Statistical comparisons in metricComparisons may use either Welch's t-test or the Mann-Whitney U test. The system runs an automatic normality check (Shapiro-Wilk) on both groups before each comparison and selects the appropriate test:
- Welch's t-test when both groups pass the normality test.
- Mann-Whitney U when either group deviates from normality.
The test selection rationale is included in the report so reviewers can verify which method was applied and why.
POST /api/experiments/:id/export
Export experiment results.
Query params: format (json|csv|latex)
CSV and LaTeX exports include claim-class information and corrected significance columns when available.
GET /api/experiments/:id/snapshots
Get all metric snapshots for experiment variants.
GET /api/experiments/:id/novelty
Detect and analyze novel/unusual behaviors in an experiment.
Admin APIs
These endpoints require X-Admin-Key header.
Config API
GET /api/config- Get current configurationPOST /api/config- Update runtime configuration
LLM Keys API
GET /api/llm-keys- List configured LLM API keysPOST /api/llm-keys- Add LLM API keyDELETE /api/llm-keys/:provider- Remove LLM API key
Tenants API
On the hosted version, a tenant is auto-created when a user first logs in via OAuth. The endpoints below are for admin management.
GET /api/tenants- List tenantsPOST /api/tenants- Create tenantDELETE /api/tenants/:id- Delete tenant
OpenAPI/Swagger
Interactive API documentation available at:
https://api.simagents.io/api/docs # Hosted
http://localhost:3000/api/docs # Self-hosted / Development