Developer Documentation

Execute business logic through a simple API.

Integrate Astria into your applications using the REST API or the Python and TypeScript SDKs. Execute deterministic business computation without managing execution infrastructure.

Overview

What is Astria?

Astria is the runtime behind Subspace. It executes business logic through a simple API or SDK, providing deterministic and reproducible computation.

The Developer Console lets you manage API keys, usage and billing.

In three points

  • Deterministic — Same model + same inputs = same outputs.
  • Fast — Execute thousands of scenarios in parallel.
  • API-first — REST API and Python/TypeScript SDKs.

Quick Start (5 minutes)

Step 1: Get an API key

  1. Sign in and open the Console → API Keys (or choose a plan)
  2. Generate and activate your API key
  3. Use the X-API-Key header on all REST calls

Step 2: Install an SDK

Choose the SDK that fits your technical stack:

Python (3.10+)

bash
pip install subspacecomputing

PyPI package: subspacecomputing — e.g. 0.1.5 or the latest version on PyPI.

TypeScript/JavaScript (Node.js)

bash
npm install @subspacecomputing/sdk

npm package: @subspacecomputing/sdk — docs synced on 0.1.1; check the latest published version before pinning in production.

Step 3: First call

Choose your language:

python
from subspacecomputing import ASTRIA

# Initialiser le client
client = ASTRIA(api_key="be_live_...")

# Projection simple
result = client.project({
    "scenarios": 1,
    "steps": 12,
    "variables": [
        {
            "name": "capital",
            "init": 1000.0,
            "formula": "capital[t-1] * 1.05"
        }
    ]
})

print(f"Capital final: {'$'}{result['final_values']['capital']:,.2f}")

Result: Capital final: $1,795.86

MCP — Claude & Cursor

Use ASTRIA from Claude Desktop or Cursor via the MCP protocol (Phase 1: stdio transport). Projections and simulations are executed on your Subspace account via the API — not invented by the LLM.

  • Same standard API key as the SDK (be_live_...)
  • Install via npx @subspacecomputing/mcp-server — no separate MCP key
  • astria_* tools: validation, projection, Monte Carlo, runs
Full MCP guide →

SP Models

What is an SP Model?

An SP Model is a declarative JSON format that describes your data projection. You describe what to compute, not how to compute it.

Declarative
Portable
Reproducible
Flexible
Powerful

Basic structure

An SP Model is a declarative JSON format that describes your data projection.

json
{
  "scenarios": 1000,
  "steps": 12,
  "variables": [
    {
      "name": "capital",
      "init": 1000.0,
      "formula": "capital[t-1] * (1 + taux)"
    }
  ]
}

Variable types

1. Deterministic variable

Fixed value with optional evolution via a formula.

json
{
    "name": "capital",
    "init": 1000.0,
    "formula": "capital[t-1] * 1.05"
}

2. Random variable

Statistical distribution with random generation. Available distributions: uniform, normal, lognormal, exponential.

json
{
    "name": "taux",
    "dist": "uniform",
    "params": {"min": 0.03, "max": 0.07},
    "per": "scenario"
}

3. Time Series

Explicit values defined per period.

json
{
    "name": "inflation",
    "values": [0.02, 0.025, 0.03, 0.035, 0.04]
}

Temporal references

In formulas, you can reference values at different periods:

var[t]

Current value

var[t-1]

Previous period

var[0]

Initial value

var[start:end]

Temporal slice (aggregation)

json
{"formula": "capital[t-1] * 1.05"}
{"formula": "capital[t] - capital[0]"}
{"formula": "sum(primes_payees[0:t+1])"}

Functions and operators

Mathematical operators

+, -, *, /, ** (power), % (modulo)

Mathematical functions

abs(x), max(x, y), min(x, y), round(x, n), floor(x, n), ceil(x, n), truncate(x, n), sqrt(x), pow(x, y), exp(x), log(x), ln(x)

Temporal aggregations

sum(array[start:end]), mean(array[start:end]), std(array[start:end]), var(array[start:end])

Advanced options

meta (optional)

Model metadata: seed, name, description. To group several runs under a single projection, use meta.name or meta.projection_id.

  • meta.name: If a projection with this name already exists for your account, it is reused. Otherwise, a new projection is created with this name.
  • meta.projection_id: Explicitly reuses this projection (UUID retrievable via GET /projections or list_projections()). If the ID is invalid or inaccessible, a new projection is created.
  • meta.store_seeds_for_replay: (default false) If true, seeds are stored to replay a scenario via POST /projection-runs/{run_id}/replay/{scenario_id}. Replay quota: Pro 5, Business 100, Enterprise 500/month; max_random_variables limit. Useful when scenarios > 1 and variables with dist.
json
{
  "meta": {
    "seed": 1234567890,
    "name": "Projection Capital 2025",
    "description": "Simulation avec taux variables",
    "projection_id": "00000000-0000-4000-8000-0000000000c3",
    "store_seeds_for_replay": true
  }
}

final_metrics (optional)

Metrics computed only at the end of the simulation.

json
{
  "final_metrics": {
    "capital_final": "capital[t_final]",
    "profit_total": "capital[t_final] - capital[0]",
    "taux_moyen": "mean(taux[0:t_final+1])"
  }
}

Tables & tablevalue()

You can define tables (grids of numeric values) and use them in formulas with the tablevalue(name, ...) function. Two modes are available: inline tables in the spec, or persisted tables (created in the My Tables dashboard) referenced by UUID.

Inline tables (tables)

Defined directly in the payload. Key = name usable in formulas. Value = object with dimensions (1 or 2 axis names) and values (1D or 2D array).

  • 1D table: dimensions: ["age"], values: [0.1, 0.2, 0.3] (one index in tablevalue).
  • 2D table: dimensions: ["pf", "scenarios"], values: [[0.9, 0.1], [0.2, 0.8]] (row 0 = pf=0, columns = scenarios; two indices in tablevalue).
json
{
  "tables": {
    "weight": {
      "dimensions": ["pf", "scenarios"],
      "values": [[0.9, 0.1], [0.2, 0.8]]
    }
  },
  "variables": [
    {
      "name": "w",
      "init": 0,
      "formula": "tablevalue('weight', 0, 1)"
    }
  ]
}

Reference tables (table_refs)

To reuse tables created in the My Tables dashboard (or via the POST /reference-tables API), provide a table_refs object: logical name in the model → table UUID.

json
{
  "table_refs": {
    "weights_portfolio": "00000000-0000-4000-8000-0000000000a1"
  },
  "variables": [
    {
      "name": "alloc",
      "init": 0,
      "formula": "tablevalue('weights_portfolio', 0, 1)"
    }
  ]
}

tablevalue() in formulas

Returns the value of a table at the given indices. The number of indices must match the number of dimensions of the table.

tablevalue('nom', i)

1D table: value at index i

tablevalue('nom', i, j)

2D table: value at position (i, j), order = order of dimensions

Indices are 0-based. You can write tablevalue('weight', 0, 1) (with or without spaces after commas).

json
{"formula": "tablevalue('weight', 0, 1)"}
{"formula": "tablevalue('weights_portfolio', t % 2, 0)"}

API REST

Authentication

Base URL : https://api.subspacecomputing.com

All requests require an API key in the X-API-Key header (except public endpoints).

bash
X-API-Key: be_live_XXXXXXXX...

Team context (optional): X-Team-Id header with the team UUID. The API key can have a default_team_id (portal / key validation). If the user is a member of multiple teams, some endpoints require an explicit context: without X-Team-Id when required, the API responds with 400 and a JSON body where error.reason equals team_context_required.

bash
X-Team-Id: 00000000-0000-4000-8000-0000000000b2

Public endpoints (no API key needed): GET /health, GET /examples, POST /validate

POST /project - Single projection

Runs a single projection (1 scenario) without statistics. scenarios must be exactly 1. With a valid API key, the response contains an optional run_id (UUID) field allowing you to retrieve or track the run via GET /projection-runs/{run_id}.

bash
curl -X POST "https://api.subspacecomputing.com/project" \
  -H "X-API-Key: be_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "scenarios": 1,
    "steps": 12,
    "variables": [
      {
        "name": "capital",
        "init": 1000.0,
        "formula": "capital[t-1] * 1.05"
      }
    ]
  }'

POST /simulate - Simulation Monte Carlo

Runs Monte Carlo simulations (multi-scenario) with full statistics. With a valid API key, the response contains an optional run_id (UUID) field to retrieve the run via GET /projection-runs/{run_id}.

bash
curl -X POST "https://api.subspacecomputing.com/simulate" \
  -H "X-API-Key: be_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "scenarios": 1000,
    "steps": 12,
    "variables": [
      {
        "name": "taux",
        "dist": "uniform",
        "params": {"min": 0.03, "max": 0.07},
        "per": "scenario"
      },
      {
        "name": "capital",
        "init": 1000.0,
        "formula": "capital[t-1] * (1 + taux)"
      }
    ]
  }'

POST /project/batch - Batch projections

Runs multiple individual projections with variable parameters. Available on Business and Unlimited plans only. The response contains run_id (parent run) and run_ids (array of child runs) to track each entity via GET /projection-runs/{run_id}.

bash
curl -X POST "https://api.subspacecomputing.com/project/batch" \
  -H "X-API-Key: be_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "batch_params": [
      {"entity_id": "emp_001", "age": 45, "salary": 60000},
      {"entity_id": "emp_002", "age": 50, "salary": 80000}
    ],
    "template": {
      "scenarios": 1,
      "steps": "65 - batch_params.age",
      "variables": [...]
    },
    "aggregations": [...]
  }'

run_id and run management

run_id in the response: The POST /project, POST /simulate and POST /project/batch endpoints return an optional run_id (UUID) field when the call is made with a valid API key. This run_id lets you retrieve or update the run via GET /projection-runs/{run_id} (see CRUD Projections and Runs below).

run_id in the spec (request): You can pass run_id in the spec body to update an existing run instead of creating a new one. Typical flow: create a run on the portal side → launch the computation with this run_id → the API updates the run (status, result_summary, artefact_id).

Batch: POST /project/batch returns run_id (parent run) and run_ids (array of child runs, one per entity).

meta.name: If you provide meta.name in the spec body, an existing projection with this name is reused to attach the run; otherwise a new projection is created with this name (identification in your dashboard).

meta.projection_id: By passing meta.projection_id (UUID) in the body, you explicitly reuse this projection for the new run. The UUID is retrievable via GET /projections. If the ID is invalid, a new projection is created.

POST /projection-runs/{run_id}/replay/{scenario_id}

Replays a specific scenario of a run whose seeds were stored (meta.store_seeds_for_replay: true during the simulation). The response has the same structure as a SimulateResponse for 1 scenario: final_values, sample_path_s0, statistics, performance.

Prerequisites: run with result_summary.seeds present; scenario_id between 0 and run.scenarios - 1. Auth: X-API-Key header.

bash
curl -X POST "https://api.subspacecomputing.com/projection-runs/{run_id}/replay/0" \
  -H "X-API-Key: be_live_..." \
  -H "Content-Type: application/json"

Errors: 400 (invalid scenario_id or run without seeds), 401 (not authenticated), 404 (run not found).

GET /run-artifacts/{id}

Retrieves a run artifact by its identifier. Authorization follows the parent projection: view right required on the associated projection.

bash
curl -X GET "https://api.subspacecomputing.com/run-artifacts/{artifact_id}" \
  -H "X-API-Key: be_live_..."

SDK Python: get_run_artifact(artifact_id) SDK TypeScript: getRunArtifact(artifactId).

POST /validate - Validate an SP Model

Validates your SP Model without running it. Public endpoint (no API key needed).

bash
curl -X POST "https://api.subspacecomputing.com/validate" \
  -H "Content-Type: application/json" \
  -d '{
    "scenarios": 100,
    "steps": 12,
    "variables": [...]
  }'

Typical response:

json
{
  "valid": true,
  "errors": [],
  "warnings": [],
  "estimated_scenarios": 3,
  "estimated_duration_ms": 0
}

valid indicates whether the model is valid. errors lists the errors (field and message), warnings the possible warnings. The estimated_scenarios and estimated_duration_ms fields give an idea of the cost before running a simulation.

Error handling

200 : Success

400: Validation error (invalid SP Model), missing team context, or another business error documented in the body.

401: Authentication required (API key missing or invalid)

429 : Rate limit exceeded

500 : Server error

For many business or contextual validation errors, the API returns a stable JSON envelope (not just the legacy FastAPI detail):

json
{
  "error": {
    "reason": "team_context_required",
    "message": "…",
    "details": null
  }
}

The error.reason field is the stable key for integrations and the portal (e.g. team_context_required; other authZ examples: model_not_found_or_forbidden, run_restricted_to_owner, edit_restricted_to_owner — see the product / master plan for the frozen catalog).

Quota: Only simulate() and POST /project/batch consume your monthly quota. project() (1 scenario) and validate() do not consume quota.

SDK Python

Installation

Prerequisites: Python 3.10+

bash
pip install subspacecomputing

PyPI package subspacecomputing — e.g. 0.1.5 or the latest version on PyPI.

Initialization

python
from subspacecomputing import ASTRIA

# Initialiser le client (production) — team_id optionnel (X-Team-Id)
client = ASTRIA(api_key="be_live_...", team_id="00000000-0000-4000-8000-0000000000e1")

# Changer le contexte équipe après coup
client.set_team_id("00000000-0000-4000-8000-0000000000e2")

project() - Single projection

Runs a single projection (1 scenario, free). The scenarios parameter must be exactly 1. The response contains run_id (UUID) to retrieve the run later.

python
spec = {
    "scenarios": 1,  # DOIT être 1
    "steps": 12,
    "variables": [
        {
            "name": "capital",
            "init": 1000.0,
            "formula": "capital[t-1] * 1.05"
        }
    ]
}

result = client.project(spec)
print(result['final_values']['capital'])
# Récupérer la run (status, result_summary, etc.)
if result.get('run_id'):
    run = client.get_run(result['run_id'])

simulate() - Simulation Monte Carlo

Runs Monte Carlo simulations (multi-scenario) with full statistics. The response contains run_id to retrieve or track the run.

python
spec = {
    "scenarios": 1000,
    "steps": 12,
    "variables": [
        {
            "name": "taux",
            "dist": "uniform",
            "params": {"min": 0.03, "max": 0.07},
            "per": "scenario"
        },
        {
            "name": "capital",
            "init": 1000.0,
            "formula": "capital[t-1] * (1 + taux)"
        }
    ]
}

result = client.simulate(spec)
print(f"Moyenne: {result['last_mean']['capital']}")
print(f"Médiane: {result['statistics']['capital']['median']}")
# Récupérer la run après simulate (status, result_summary, artefact_id, etc.)
if result.get('run_id'):
    run = client.get_run(result['run_id'])

replay_run() - Replay a scenario

If the run was created with meta.store_seeds_for_replay: true, you can replay a specific scenario with replay_run(run_id, scenario_id). The response is a SimulateResponse for 1 scenario (final_values, sample_path_s0, etc.).

python
result = client.simulate(spec)  # avec meta.store_seeds_for_replay: true
if result.get('run_id'):
    run = client.get_run(result['run_id'])
    # Rejouer le scénario 0
    replay = client.replay_run(result['run_id'], scenario_id=0)
    print("Valeurs finales rejouées:", replay['final_values'][0])

project_batch() - Batch Mode

Runs multiple projections with variable parameters. The response contains run_id (parent run) and run_ids (child runs) to track each entity.

python
template = {
    "scenarios": 1,
    "steps": "65 - batch_params.age",
    "variables": [
        {
            "name": "capital_retraite",
            "init": 0.0,
            "formula": "capital_retraite[t-1] * 1.05 + batch_params.salary * 0.10"
        }
    ]
}

batch_params = [
    {"entity_id": "emp_001", "age": 45, "salary": 60000},
    {"entity_id": "emp_002", "age": 50, "salary": 80000}
]

result = client.project_batch(
    template=template,
    batch_params=batch_params
)

for entity in result['entities']:
    print(f"{entity['_entity_id']}: {entity['final_values'][0]['capital_retraite']}")

Group runs under a projection

By default, each call to project() or simulate() creates a new projection. To attach several runs to a single projection (for example to find them together in your dashboard), use meta.name or meta.projection_id in the spec.

Option A: Group by name (meta.name)

If a projection with this name already exists for your account, it is reused. Otherwise, a new projection is created with this name.

python
spec = {
    "scenarios": 1,
    "steps": 12,
    "meta": {"name": "Capital 2025 - Scénario conservateur"},
    "variables": [
        {"name": "capital", "init": 1000.0, "formula": "capital[t-1] * 1.05"}
    ]
}
result = client.project(spec)
# Les prochains appels avec le même meta.name attacheront leurs runs à la même projection.

Option B: Group by ID (meta.projection_id)

Explicitly reuse a projection whose UUID you have (retrieved via list_projections() or the dashboard). If the ID is invalid, a new projection is created.

python
# Récupérer l'ID d'une projection existante
projections = client.list_projections(limit=10, offset=0)
proj_id = projections["items"][0]["id"]  # ou un ID connu

spec = {
    "scenarios": 1,
    "steps": 12,
    "meta": {"projection_id": proj_id},
    "variables": [
        {"name": "capital", "init": 1000.0, "formula": "capital[t-1] * 1.05"}
    ]
}
result = client.project(spec)
# La run est attachée à la projection proj_id.

validate() - Validate an SP Model

Check your model before launching a simulation. You get a validity indicator, possible errors, warnings and an estimate of the number of scenarios and the duration.

python
validation = client.validate(spec)
if validation.get('valid'):
    print("✅ SP Model valide")
    if validation.get('estimated_scenarios'):
        print(f"   Scénarios estimés: {validation['estimated_scenarios']}")
    if validation.get('warnings'):
        print(f"   Avertissements: {validation['warnings']}")
else:
    print(f"❌ Erreurs: {validation['errors']}")

get_run_artifact() — Run artifact

Equivalent to GET /run-artifacts/{id} (authZ: view right on the parent projection).

python
data = client.get_run_artifact("00000000-0000-4000-8000-0000000000d4")

Error handling

For a 400 with body { "error": { "reason": ... } }, use ValidationError: the reason property on SubspaceError lets you test team_context_required and the other stable codes.

python
from subspacecomputing import (
    ASTRIA,
    SubspaceError,
    QuotaExceededError,
    RateLimitError,
    AuthenticationError,
    ValidationError
)

try:
    result = client.simulate(spec)
except QuotaExceededError:
    print("Quota mensuel dépassé")
except RateLimitError as e:
    print(f"Rate limit: {e}")
except AuthenticationError:
    print("Clé API invalide")
except ValidationError as e:
    if getattr(e, "reason", None) == "team_context_required":
        print("Préciser X-Team-Id ou set_team_id()")
    print(f"Erreur: {e.detail}")

SDK TypeScript

The npm package documented below reflects the same functional surface as the Python SDK and the REST API. Check the version published on npm before pinning a dependency in production. In a browser, avoid exposing the API key: call these endpoints from your backend or a controlled proxy.

Installation

Prerequisites: Node.js 18+

bash
npm install @subspacecomputing/sdk

npm package: @subspacecomputing/sdk — docs synced on 0.1.1 — check the latest version published on npm before pinning in production.

Initialization

typescript
import { ASTRIA } from '@subspacecomputing/sdk';

// new ASTRIA(apiKey, baseUrl?, teamId?)
const client = new ASTRIA('be_live_...', undefined, '00000000-0000-4000-8000-0000000000e1');
// ou : new ASTRIA('be_live_...', 'https://api.subspacecomputing.com', '00000000-0000-4000-8000-0000000000e1');

client.setTeamId('00000000-0000-4000-8000-0000000000e2');

project() - Single projection

Runs a single projection (1 scenario, free). The scenarios parameter must be exactly 1.

typescript
const spec = {
  scenarios: 1,  // DOIT être 1
  steps: 12,
  variables: [
    {
      name: 'capital',
      init: 1000.0,
      formula: 'capital[t-1] * 1.05'
    }
  ]
};

const result = await client.project(spec);
console.log(result.final_values.capital);
// Récupérer la run (status, result_summary, etc.)
if (result.run_id) {
  const run = await client.getRun(result.run_id);
}

simulate() - Simulation Monte Carlo

Runs Monte Carlo simulations (multi-scenario) with full statistics. The response contains run_id to retrieve the run.

typescript
const spec = {
  scenarios: 1000,
  steps: 12,
  variables: [
    {
      name: 'taux',
      dist: 'uniform',
      params: { min: 0.03, max: 0.07 },
      per: 'scenario'
    },
    {
      name: 'capital',
      init: 1000.0,
      formula: 'capital[t-1] * (1 + taux)'
    }
  ]
};

const result = await client.simulate(spec);
console.log(`Moyenne: ${result.last_mean.capital}`);
console.log(`Médiane: ${result.statistics.capital.median}`);
// Récupérer la run après simulate (status, result_summary, artefact_id, etc.)
if (result.run_id) {
  const run = await client.getRun(result.run_id);
}

projectBatch() - Batch Mode

Runs multiple projections with variable parameters. Available on Business and Enterprise plans only. The response contains run_id (parent run) and run_ids (child runs).

typescript
const template = {
  scenarios: 1,
  steps: '65 - batch_params.age',
  variables: [
    {
      name: 'age_actuel',
      init: 'batch_params.age'
    },
    {
      name: 'salaire',
      init: 'batch_params.salary',
      formula: 'salaire[t-1] * 1.03'
    },
    {
      name: 'capital_retraite',
      init: 0.0,
      formula: 'capital_retraite[t-1] * 1.05 + salaire[t] * 0.10'
    }
  ]
};

const batchParams = [
  { entity_id: 'emp_001', age: 45, salary: 60000 },
  { entity_id: 'emp_002', age: 50, salary: 80000 }
];

const aggregations = [
  { name: 'capital_total', formula: 'sum(capital_retraite[t_final])' }
];

const result = await client.projectBatch(template, batchParams, aggregations);

result.entities.forEach(entity => {
  console.log(`${entity._entity_id}: ${entity.final_values[0].capital_retraite}`);
});

Utility methods

validate() - Validate an SP Model

Check your model before launching a simulation. You get a validity indicator, possible errors, warnings and an estimate of the number of scenarios and the duration.

typescript
const validation = await client.validate(spec);
if (validation.valid) {
  console.log('✅ SP Model valide');
  if (validation.estimated_scenarios != null) {
    console.log(`   Scénarios estimés: ${validation.estimated_scenarios}`);
  }
  if (validation.warnings?.length) {
    console.log(`   Avertissements: ${validation.warnings}`);
  }
} else {
  console.log(`❌ Erreurs: ${validation.errors}`);
}

getExamples() - Get examples

Public endpoint (no API key required)

typescript
const examples = await client.getExamples();
console.log(`Available: ${examples.examples.length}`);

getUsage() - Get usage and quotas

typescript
const usage = await client.getUsage();
console.log(`Used: ${usage.quota.used}/${usage.quota.limit}`);
console.log(`Remaining: ${usage.quota.remaining}`);

getPlans() - Get plans

Public endpoint

typescript
const plans = await client.getPlans();
plans.plans.forEach(plan => {
  console.log(`${plan.name}: $${plan.price_monthly}/month`);
});

CRUD Projections and Runs

The responses of project() and simulate() contain a run_id field. You can use getRun(run_id) to retrieve the run (equivalent to GET /projection-runs/{run_id}) and track its status, result_summary, etc.

Projection management

typescript
// Lister les projections
const projections = await client.listProjections(10, 0);

// Obtenir une projection
const projection = await client.getProjection('proj_123');

// Supprimer une projection
await client.deleteProjection('proj_123');

Run management

typescript
// run_id retourné par project() / simulate() → récupérer la run
const result = await client.simulate(spec);
if (result.run_id) {
  const run = await client.getRun(result.run_id);  // GET /projection-runs/{run_id}
}

// Lister les runs d'une projection
const runs = await client.listRuns('proj_123', undefined, 10, 0);

// Obtenir une run par ID
const run = await client.getRun('run_123');

// Supprimer une run
await client.deleteRun('run_123');

getRunArtifact() — Run artifact

Equivalent to GET /run-artifacts/{id} (authZ: view right on the parent projection).

typescript
const artifact = await client.getRunArtifact('00000000-0000-4000-8000-0000000000d4');

Replay (direct API)

The TypeScript SDK does not yet expose replayRun; the POST /projection-runs/{run_id}/replay/{scenario_id} endpoint exists on the API side. While waiting for an npm release that would add the method, call the API with fetch (X-API-Key and, if needed, X-Team-Id headers).

typescript
const res = await fetch(
  `https://api.subspacecomputing.com/projection-runs/${runId}/replay/${scenarioId}`,
  {
    method: 'POST',
    headers: {
      'X-API-Key': apiKey,
      ...(teamId ? { 'X-Team-Id': teamId } : {}),
      'Content-Type': 'application/json',
    },
  }
);
const replay = await res.json();
console.log('final_values', replay.final_values?.[0]);

Helpers

typescript
// Obtenir info rate limit depuis dernière réponse
await client.project(spec);
const rateLimit = client.getRateLimitInfo();
if (rateLimit) {
  console.log(`Limit: ${rateLimit.remaining}/${rateLimit.limit}`);
}

// Obtenir info quota depuis dernière réponse
await client.simulate(spec);
const quota = client.getQuotaInfo();
if (quota) {
  console.log(`Quota: ${quota.used}/${quota.limit}`);
}

Error handling

On a 400, the body may follow the { "error": { "reason", "message" } } envelope. On errors thrown by the SDK, inspect errorReason (e.g. team_context_required) in addition to detail / message.

typescript
import {
  SubspaceError,
  QuotaExceededError,
  RateLimitError,
  AuthenticationError,
  ValidationError
} from '@subspacecomputing/sdk';

try {
  const result = await client.simulate(spec);
} catch (error) {
  if (error instanceof QuotaExceededError) {
    console.error(`Quota dépassé: ${error.message}`);
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limit dépassé: ${error.message}`);
    const retryAfter = error.response?.headers.get('Retry-After');
  } else if (error instanceof AuthenticationError) {
    console.error(`Clé API invalide: ${error.message}`);
  } else if (error instanceof ValidationError) {
    if (error.errorReason === 'team_context_required') {
      console.error('Préciser X-Team-Id ou setTeamId()');
    }
    console.error(`Erreur validation: ${error.detail}`);
  } else if (error instanceof SubspaceError) {
    console.error(`Erreur API: ${error.message}`);
  }
}

Need more details?

Check the complete API reference for all endpoints and parameters.

View API reference →