Sessions API
Complete HTTP API reference for creating, managing, and interacting with CodeSpar sessions, including tool execution and connection management.
Sessions API
Base URL: https://api.codespar.dev
All endpoints require authentication via Bearer token. See Authentication for details on API key types and scopes.
Authorization: Bearer csk_live_your_api_keyProject scoping
Every /v1 endpoint accepts an optional x-codespar-project header that pins the request to a specific project within your organization.
| Header | Required | Description |
|---|---|---|
x-codespar-project | No | Project ID in the form prj_<16chars>. If omitted, requests resolve to the organization's default project (auto-created at signup). Project-scoped API keys ignore this header and always use the key's pinned project. |
# Explicit project
curl -X POST https://api.codespar.dev/v1/sessions \
-H "Authorization: Bearer csk_live_abc123..." \
-H "x-codespar-project: prj_a1b2c3d4e5f6g7h8" \
-H "Content-Type: application/json" \
-d '{"servers": ["stripe"]}'
# Omitted -- falls back to the org's default project
curl -X POST https://api.codespar.dev/v1/sessions \
-H "Authorization: Bearer csk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{"servers": ["stripe"]}'Sessions, triggers, API keys, connections, and events are all scoped to the resolved project. See Projects concept and the Projects API for details.
POST /v1/sessions
Creates a new session connected to the specified MCP servers. Returns the session object with connection status for each server.
Auth required: Yes (scope: sessions:create)
Request body
| Field | Type | Required | Description |
|---|---|---|---|
user_id | string | Yes | End-user identifier on behalf of whom the agent acts |
servers | string[] | Yes* | List of server identifiers (e.g., ["stripe", "mercadopago"]) |
preset | string | No | Named preset: brazilian, mexican, argentinian, colombian, all |
manageConnections | object | No | Connection-management options (see Sessions) |
metadata | object | No | Key-value metadata attached to every tool call |
*Required unless preset is specified. Can be combined with preset to add additional servers.
curl example
curl -X POST https://api.codespar.dev/v1/sessions \
-H "Authorization: Bearer csk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_123",
"servers": ["stripe", "mercadopago"]
}'Response -- 201 Created
{
"id": "ses_abc123def456",
"user_id": "user_123",
"status": "active",
"servers": [
{ "id": "stripe", "name": "Stripe", "status": "connected" },
{ "id": "mercadopago", "name": "Mercado Pago", "status": "connected" }
],
"tool_calls": 0,
"created_at": "2026-04-15T10:30:00Z",
"expires_at": "2026-04-15T11:00:00Z"
}SDK equivalent
const session = await codespar.create("user_123", {
servers: ["stripe", "mercadopago"],
});Sessions expire after 30 minutes of inactivity. The expires_at timestamp is updated with each tool call. If a server fails to connect, the session is still created with the remaining servers -- check the status field on each server entry.
GET /v1/sessions
Lists all sessions for your organization. Supports pagination and filtering by status.
Auth required: Yes (scope: sessions:read)
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
status | string | -- | Filter by status: active, closed, error |
limit | number | 20 | Results per page (max 100) |
offset | number | 0 | Pagination offset |
curl example
curl "https://api.codespar.dev/v1/sessions?status=active&limit=10" \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK
{
"data": [
{
"id": "ses_abc123def456",
"status": "active",
"servers": ["stripe", "mercadopago"],
"tool_calls": 12,
"created_at": "2026-04-15T10:30:00Z",
"expires_at": "2026-04-15T11:00:00Z"
},
{
"id": "ses_def789ghi012",
"status": "active",
"servers": ["correios", "nfe"],
"tool_calls": 3,
"created_at": "2026-04-15T10:15:00Z",
"expires_at": "2026-04-15T10:45:00Z"
}
],
"total": 47,
"limit": 10,
"offset": 0
}GET /v1/sessions/:id
Retrieves details about an existing session, including connected servers, tool call count, and expiry.
Auth required: Yes (scope: sessions:read)
curl example
curl https://api.codespar.dev/v1/sessions/ses_abc123def456 \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK
{
"id": "ses_abc123def456",
"status": "active",
"servers": [
{ "id": "stripe", "name": "Stripe", "status": "connected" },
{ "id": "mercadopago", "name": "Mercado Pago", "status": "connected" }
],
"tool_calls": 12,
"created_at": "2026-04-15T10:30:00Z",
"expires_at": "2026-04-15T11:00:00Z"
}DELETE /v1/sessions/:id
Closes an active session and releases all server connections. Closed sessions cannot be reopened; create a new session instead.
Auth required: Yes (scope: sessions:create)
curl example
curl -X DELETE https://api.codespar.dev/v1/sessions/ses_abc123def456 \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK
{
"id": "ses_abc123def456",
"status": "closed",
"tool_calls": 12,
"closed_at": "2026-04-15T10:45:00Z"
}SDK equivalent
await session.close();Closing a session is idempotent. Calling DELETE on an already-closed session returns 200 OK with the existing closed state.
POST /v1/sessions/:id/execute
Executes a tool call synchronously. The request blocks until the tool completes and the result is available. Use this for operations where the agent needs the response before continuing.
Auth required: Yes (scope: tools:execute)
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Tool name (e.g., codespar_pay, stripe_create_refund) |
arguments | object | Yes | Tool arguments matching the tool's input_schema |
curl example
curl -X POST https://api.codespar.dev/v1/sessions/ses_abc123/execute \
-H "Authorization: Bearer csk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"name": "codespar_pay",
"arguments": {
"method": "pix",
"amount": 9990,
"currency": "BRL",
"description": "Order #1234",
"customer_email": "maria@example.com"
}
}'Response -- 200 OK
{
"tool_call_id": "tc_xyz789abc",
"name": "codespar_pay",
"result": {
"payment_id": "pay_xyz789",
"status": "pending",
"method": "pix",
"provider": "asaas",
"pix_code": "00020126580014br.gov.bcb.pix0136a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"qr_code_url": "https://api.codespar.dev/qr/pay_xyz789.png",
"amount": 9990,
"currency": "BRL",
"expires_at": "2026-04-15T11:00:00Z"
},
"execution_time_ms": 342
}SDK equivalent
const result = await session.execute("codespar_pay", {
method: "pix",
amount: 9990,
currency: "BRL",
});Each call to this endpoint counts as one tool call for billing purposes. If the tool fails (e.g., provider error), it still counts as a tool call.
POST /v1/sessions/:id/send
Sends a natural-language message. The CodeSpar backend runs a Claude tool-use loop using the session's connected servers, calling whichever tools the agent decides it needs, and returns the final response along with every tool call made. Use this for the simplest possible agent integration, with no client-side orchestration.
Auth required: Yes (scope: tools:execute)
Request body
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | Natural-language instruction for the agent |
curl example
curl -X POST https://api.codespar.dev/v1/sessions/ses_abc123/send \
-H "Authorization: Bearer csk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"message": "Charge R$150 via Pix for order #5678 and send a WhatsApp confirmation"
}'Response -- 200 OK
{
"message": "Done. Pix QR code generated and WhatsApp message sent.",
"tool_calls": [
{ "id": "tc_1", "tool_name": "codespar_pay", "status": "success", "duration_ms": 412 },
{ "id": "tc_2", "tool_name": "codespar_notify", "status": "success", "duration_ms": 287 }
],
"iterations": 2
}Streaming variant
Use POST /v1/sessions/:id/send/stream for an SSE stream of StreamEvents (assistant text, tool use, tool result, done) -- see the SDK reference for event shapes.
SDK equivalent
const result = await session.send(
"Charge R$150 via Pix for order #5678 and send a WhatsApp confirmation",
);GET /v1/sessions/:id/connections
Lists OAuth connections for a session created with manageConnections: true. Returns the connection status and authorization URL for each server.
Auth required: Yes (scope: sessions:read)
curl example
curl https://api.codespar.dev/v1/sessions/ses_abc123/connections \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK
{
"connections": [
{
"server": "stripe",
"status": "connected",
"connected_at": "2026-04-15T10:31:00Z"
},
{
"server": "mercadopago",
"status": "pending",
"authUrl": "https://codespar.dev/connect/mercadopago?session=ses_abc123"
}
]
}| Connection status | Description |
|---|---|
pending | User has not yet authenticated. The authUrl field contains the OAuth URL. |
connected | User has authenticated. Tool calls to this server use the user's credentials. |
expired | OAuth token has expired. A new authUrl is provided for re-authentication. |
revoked | User revoked access. A new authUrl is provided. |
SDK equivalent
const connections = await session.connections();POST /v1/sessions/:id/tool-calls
Records a tool call result from an external execution. This is used in advanced workflows where the tool is executed outside of CodeSpar (e.g., by the LLM framework) and the result needs to be recorded for auditing and billing.
Auth required: Yes (scope: tools:execute)
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Tool name that was called |
arguments | object | Yes | Arguments that were passed to the tool |
result | object | Yes | Result returned by the tool |
curl example
curl -X POST https://api.codespar.dev/v1/sessions/ses_abc123/tool-calls \
-H "Authorization: Bearer csk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"name": "codespar_pay",
"arguments": {"method": "pix", "amount": 5000, "currency": "BRL"},
"result": {"payment_id": "pay_ext_001", "status": "completed"}
}'Response -- 201 Created
{
"id": "tc_rec_abc123",
"session_id": "ses_abc123",
"name": "codespar_pay",
"status": "recorded",
"recorded_at": "2026-04-15T10:50:00Z"
}GET /v1/sessions/:id/tool-calls
Lists all tool calls made within a session. Useful for auditing and debugging agent behavior.
Auth required: Yes (scope: sessions:read)
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 50 | Results per page (max 100) |
offset | number | 0 | Pagination offset |
curl example
curl "https://api.codespar.dev/v1/sessions/ses_abc123/tool-calls?limit=5" \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK
{
"data": [
{
"id": "tc_001",
"name": "codespar_discover",
"arguments": { "domain": "payments" },
"status": "completed",
"execution_time_ms": 67,
"created_at": "2026-04-15T10:30:05Z"
},
{
"id": "tc_002",
"name": "codespar_pay",
"arguments": { "method": "pix", "amount": 9990, "currency": "BRL" },
"status": "completed",
"execution_time_ms": 342,
"created_at": "2026-04-15T10:30:12Z"
},
{
"id": "tc_003",
"name": "codespar_notify",
"arguments": { "channel": "whatsapp", "to": "+5511999999999" },
"status": "completed",
"execution_time_ms": 189,
"created_at": "2026-04-15T10:30:15Z"
}
],
"total": 3,
"limit": 5,
"offset": 0
}PATCH /v1/sessions/:id/tool-calls/:tc_id
Updates the status or metadata of a recorded tool call. Used to mark externally-executed tool calls as completed or failed.
Auth required: Yes (scope: tools:execute)
Request body
| Field | Type | Required | Description |
|---|---|---|---|
status | string | No | New status: completed, failed |
result | object | No | Updated result object |
error | object | No | Error details if the tool call failed |
curl example
curl -X PATCH https://api.codespar.dev/v1/sessions/ses_abc123/tool-calls/tc_rec_abc123 \
-H "Authorization: Bearer csk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"status": "completed",
"result": {
"payment_id": "pay_ext_001",
"status": "paid",
"paid_at": "2026-04-15T10:51:00Z"
}
}'Response -- 200 OK
{
"id": "tc_rec_abc123",
"session_id": "ses_abc123",
"name": "codespar_pay",
"status": "completed",
"result": {
"payment_id": "pay_ext_001",
"status": "paid",
"paid_at": "2026-04-15T10:51:00Z"
},
"updated_at": "2026-04-15T10:51:05Z"
}GET /v1/health
Consolidated health check across the six router subsystems: db, vault, embeddings, fx_rates, telemetry, connections. Always returns 200 OK regardless of individual check status — monitors should parse the status field, not the HTTP code.
Auth required: Yes (dual-auth: API key or service key).
curl example
curl https://api.codespar.dev/v1/health \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK
{
"status": "healthy",
"checks": {
"db": { "status": "healthy", "latency_ms": 12 },
"vault": { "status": "healthy", "latency_ms": 8 },
"embeddings": { "status": "healthy", "latency_ms": 41 },
"fx_rates": { "status": "healthy", "stale_seconds": 312 },
"telemetry": { "status": "healthy" },
"connections": { "status": "healthy", "count": 47 }
},
"schema_version": { "current": 64, "expected": 64 },
"observed_at": "2026-05-04T18:30:00Z"
}The top-level status rolls up to healthy, degraded, or down. State transitions emit system.health.degraded and system.health.recovered events to operator webhooks.
GET /health
Unauthenticated liveness probe. No subsystem detail — use /v1/health for that.
curl example
curl https://api.codespar.dev/healthResponse -- 200 OK
{
"status": "ok",
"uptime_ms": 8421305
}GET /v1/tool-calls/:id/payment-status
Polling endpoint for async payment settlement against codespar_charge and codespar_pay tool calls. Returns { status: "pending" } until the provider webhook correlates the call; on settlement, returns the final amount and settlement timestamp.
Auth required: Yes (scope: sessions:read)
curl example
curl https://api.codespar.dev/v1/tool-calls/tc_xyz789/payment-status \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK (settled)
{
"status": "completed",
"idempotency_key": "idem_5f3a...",
"external_reference": "asaas_pay_abc123",
"final_amount_minor": 9990,
"settled_at": "2026-04-15T10:35:12Z"
}Response -- 200 OK (pending)
{
"status": "pending"
}SDK equivalent
const status = await session.paymentStatus("tc_xyz789");GET /v1/tool-calls/:id/payment-status/stream
Server-Sent Events variant of payment-status. Server emits:
| Event | When |
|---|---|
snapshot | Once on connect — the current state |
update | On each status transition |
done | On terminal status, then 5s grace before close |
The server emits a comment-line heartbeat every 15s to keep intermediaries from idling out the connection. The polling sibling stays available — clients pick whichever fits their runtime.
Auth required: Yes (scope: sessions:read)
curl example
curl -N https://api.codespar.dev/v1/tool-calls/tc_xyz789/payment-status/stream \
-H "Authorization: Bearer csk_live_abc123..."Stream output
event: snapshot
data: {"status":"pending"}
event: update
data: {"status":"completed","final_amount_minor":9990,"settled_at":"2026-04-15T10:35:12Z"}
event: done
data: {"status":"completed"}SDK equivalent
await session.paymentStatusStream("tc_xyz789", {
onUpdate: (s) => console.log(s.status),
});GET /v1/tool-calls/:id/verification-status
Polling endpoint for async KYC settlement against codespar_kyc inquiries. Status priority is approved > rejected > review > expired > pending when multiple events have been recorded.
Auth required: Yes (scope: sessions:read)
curl example
curl https://api.codespar.dev/v1/tool-calls/tc_kyc456/verification-status \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK
{
"status": "approved",
"idempotency_key": "idem_kyc_a1b2...",
"external_reference": "persona_inq_xyz",
"settled_at": "2026-04-15T10:36:00Z"
}SDK equivalent
const status = await session.verificationStatus("tc_kyc456");GET /v1/tool-calls/:id/verification-status/stream
SSE variant of verification-status. Same event sequence as the payment-status stream (snapshot, update, done), same 15s heartbeat, same 5s grace before close after terminal state. Polling sibling stays available.
Auth required: Yes (scope: sessions:read)
curl example
curl -N https://api.codespar.dev/v1/tool-calls/tc_kyc456/verification-status/stream \
-H "Authorization: Bearer csk_live_abc123..."SDK equivalent
await session.verificationStatusStream("tc_kyc456", {
onUpdate: (s) => console.log(s.status),
});GET /v1/meta-tools/stats
Per-(provider × canonical_tool) router observability rollup. Reports attempt counts, success counts, and p50 latency for each rail in META_TOOL_CATALOG. Powers the /dashboard/router observability page.
Auth required: Yes — service key only (x-codespar-service-key).
curl example
curl https://api.codespar.dev/v1/meta-tools/stats \
-H "x-codespar-service-key: cssk_internal_abc123..."Response -- 200 OK
{
"rows": [
{
"canonical_tool": "codespar_pay",
"provider_id": "asaas",
"attempts": 1284,
"successes": 1271,
"p50_ms": 412
},
{
"canonical_tool": "codespar_charge",
"provider_id": "mercadopago",
"attempts": 902,
"successes": 897,
"p50_ms": 318
}
]
}GET /v1/meta-tools/stats/hourly
Same shape as /v1/meta-tools/stats but bucketed into the last 24 hourly windows for a single provider+tool pair. Used to render router latency/error sparklines.
Auth required: Yes — service key only.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
provider_id | string | Yes | Provider identifier (e.g., asaas) |
canonical_tool | string | Yes | Canonical meta-tool (e.g., codespar_pay) |
curl example
curl "https://api.codespar.dev/v1/meta-tools/stats/hourly?provider_id=asaas&canonical_tool=codespar_pay" \
-H "x-codespar-service-key: cssk_internal_abc123..."Response -- 200 OK
{
"provider_id": "asaas",
"canonical_tool": "codespar_pay",
"buckets": [
{ "hour": "2026-05-04T18:00:00Z", "attempts": 54, "successes": 53, "p50_ms": 408 },
{ "hour": "2026-05-04T17:00:00Z", "attempts": 61, "successes": 60, "p50_ms": 412 }
]
}POST /v1/connections/hmac-validate
Round-trip validation for the hmac_signed auth_type. The dashboard calls this when an operator pastes a key + secret pair into the connect modal — the backend signs a probe request against the provider and reports whether the credentials produced a valid signature on the wire.
Auth required: Yes (scope: sessions:create)
Request body
| Field | Type | Required | Description |
|---|---|---|---|
server_id | string | Yes | Provider identifier (e.g., foxbit) |
key | string | Yes | Signing key |
secret | string | Yes | Signing secret |
curl example
curl -X POST https://api.codespar.dev/v1/connections/hmac-validate \
-H "Authorization: Bearer csk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"server_id": "foxbit",
"key": "fx_key_abc",
"secret": "fx_secret_xyz"
}'Response -- 200 OK
{
"valid": true,
"probed_endpoint": "GET /rest/v3/me"
}Response -- 200 OK (invalid)
{
"valid": false,
"probed_endpoint": "GET /rest/v3/me",
"provider_status": 401,
"provider_message": "Invalid signature"
}Error responses
All endpoints follow a consistent error format:
{
"error": "error_code",
"message": "Human-readable error description.",
"status": 400
}| Status | Error code | Description | Resolution |
|---|---|---|---|
400 | invalid_request | Missing required fields or invalid values | Check the request body against the schema |
401 | unauthorized | Invalid or missing API key | Verify the Authorization header |
403 | forbidden | API key lacks the required scope | Check key scopes in the dashboard |
404 | not_found | Session or resource not found | Verify the session ID; the session may have been closed |
429 | rate_limited | Too many requests | Wait and retry; check Retry-After header |
429 | quota_exceeded | Monthly tool call quota exceeded | Upgrade your plan or wait for the next billing cycle |
500 | internal_error | Server error | Retry with exponential backoff; contact support if persistent |
503 | server_unavailable | MCP server is temporarily unavailable | The specific provider may be down; retry or use an alternative server |
Rate limit headers
Every response includes rate limit information:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 297
X-RateLimit-Reset: 1713178260Next steps
Last updated on