Create a sandbox key
Every account comes with a sandbox: 40 simulated ports that fault on a schedule, so you can build without touching a real charger.
# Settings → API keys → New sandbox key export SALVE_KEY="sk_test_••••••••91c0"
Developers
The same data the console runs on, through a REST API and signed webhooks. Pipe incidents into your helpdesk, push work orders to field partners, or build your own night report.
curl https://api.salve.energy/v1/incidents?status=open \ -H "Authorization: Bearer sk_live_••••••••4f2a"
import { Salve } from '@salve/node'; const salve = new Salve(process.env.SALVE_KEY); const open = await salve.incidents.list({ status: 'open' });
from salve import Salve salve = Salve(api_key=os.environ["SALVE_KEY"]) open_incidents = salve.incidents.list(status="open")
{
"data": [
{
"id": "INC-4812",
"site": "Fulton Market Garage",
"port": "US*SLV*E0233*1",
"code": "EVCommunicationError",
"diagnosis": "Lost link to charging module",
"confidence": 0.94,
"status": "fix_running",
"playbook": "reconnect-ocpp@v3",
"opened_at": "2026-10-25T02:14:07Z"
}
],
"has_more": false
}
Quickstart
Official libraries for Node, Python and Go. Everything else is plain HTTPS and JSON, documented with examples you can paste.
Every account comes with a sandbox: 40 simulated ports that fault on a schedule, so you can build without touching a real charger.
# Settings → API keys → New sandbox key export SALVE_KEY="sk_test_••••••••91c0"
Tell Salve where to send events. Every payload is signed, retried for 72 hours and kept in a replayable log.
curl https://api.salve.energy/v1/webhooks \ -H "Authorization: Bearer $SALVE_KEY" \ -d url="https://ops.example.com/salve" \ -d events="incident.*,workorder.created"
Trigger an approved playbook from your own tools. Salve applies the same guardrails as in the console.
await salve.playbooks.run('unlock-reset@v3', { port: 'US*SLV*E0417*2', reason: 'Driver reported stuck cable' });
Webhooks
Pick an event to see its payload. Every webhook is signed with HMAC-SHA256, retried with backoff and replayable from the console.
{
"type": "incident.opened",
"id": "evt_8Kq2",
"incident": "INC-4812",
"port": "US*SLV*E0233*1",
"code": "EVCommunicationError",
"at": "2026-10-25T02:14:07Z"
}
{
"type": "incident.diagnosed",
"incident": "INC-4812",
"diagnosis": "Lost link to charging module",
"confidence": 0.94,
"planned_fix": "reconnect-ocpp@v3",
"seen_before": 6
}
{
"type": "fix.succeeded",
"incident": "INC-4811",
"playbook": "unlock-reset@v3",
"steps": 4,
"test_session_kwh": 0.5,
"duration_s": 115
}
{
"type": "workorder.created",
"workorder": "INT-2318",
"partner": "Westline Field Ops",
"likely_cause": "Ground fault, DC side",
"parts": ["DC contactor 7731-B"],
"arrive_by": "2026-10-25T10:30:00-07:00"
}
{
"type": "driver.notified",
"incident": "INC-4812",
"channel": "sms",
"language": "en",
"template": "session_paused_restarting"
}
{
"type": "report.ready",
"report": "nevi_q3_2026",
"stations": 38,
"uptime": 0.986,
"url": "https://api.salve.energy/v1/reports/rpt_51"
}
Resources
Documentation, libraries and a sandbox you can break on purpose.
Built to be depended on
99.99%
API uptime, last 12 months
41 ms
median response time
1,200
requests a minute per key
2
US regions, east and west
Forty simulated ports, every event and the full API. Free, no card. Talk to an engineer when you are ready for real chargers.