Skip to main content

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 began
  • tick_completed - Tick finished
  • agent_moved - Agent changed position
  • agent_gathered - Agent collected resources
  • agent_died - Agent died
  • trade_completed - Trade succeeded
  • agent_harmed - Agent was attacked
  • job_offered - Job posted
  • job_accepted - Job accepted
  • worker_paid - Payment made
  • puzzle_joined - Agent joined a puzzle game
  • puzzle_left - Agent left a puzzle game
  • fragment_shared - Fragment shared between agents
  • team_formed - Puzzle team created
  • team_joined - Agent joined a team
  • puzzle_solved - Puzzle was solved
  • puzzle_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:

LimitFree Tier
Agents5
Ticks/day500
Events50,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:

  • claimClass tells you whether the run set is validated, exploratory, or descriptive only.
  • significantFindings should 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:

FieldTypeDescription
registeredbooleanWhether pre-registration was active for this experiment.
hypothesisstringThe pre-registered hypothesis text.
primaryMetricsstring[]Metrics designated as primary at registration time.
registeredAtstring (ISO 8601)Timestamp when the hypothesis was registered.
deviationsstring[]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 configuration
  • POST /api/config - Update runtime configuration

LLM Keys API​

  • GET /api/llm-keys - List configured LLM API keys
  • POST /api/llm-keys - Add LLM API key
  • DELETE /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 tenants
  • POST /api/tenants - Create tenant
  • DELETE /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