Developer API
A versioned REST API to read and create projects, list .sri files, and get notified the moment a contract is signed. Mint a key from your dashboard's Account → Developer API tab — this page is the endpoint reference.
Authentication
Every request carries your key as a bearer token. Keys are scoped to your own account — you'll only ever see or modify your own projects.
curl https://sriwatt.io/api/v1/projects \ -H "Authorization: Bearer swpk_..."
A missing or invalid key returns 401 with { "error": "unauthorized" }.
Rate limits
Reads are limited to 60 requests/minute per key; writes (POST/PATCH) to 20 requests/minute. Exceeding either returns 429 with { "error": "rate_limit_exceeded" }.
Versioning
Everything lives under /api/v1/. A breaking response-shape change ships as a sibling /api/v2/ rather than mutating this contract — no field is ever removed or repurposed under an existing integration.
Projects
/api/v1/projectsLists your projects, newest first.
Query params: limit (default 50, max 200), cursor (an ISO createdAt to page before).
{
"ok": true,
"projects": [
{
"id": "...", "firstName": "...", "lastName": "...", "email": "...",
"projectType": "on-grid", "projectSizeKw": 250,
"contractStatus": "pending", "quoteStatus": "not_generated",
"location": "...", "createdAt": "...", "updatedAt": "..."
}
],
"nextCursor": "2026-07-01T00:00:00.000Z"
}/api/v1/projects/:idFetches one project (adds phone, lat, lon over the list shape). 404 if it doesn't exist or isn't yours.
/api/v1/projectsCreates a new software-only project and emails the customer their project invite — the same invite the dashboard's New Project flow sends.
Scoped down from the dashboard's New Project wizard: one project per new customer email (an existing email returns 409 — add a second site from the dashboard instead), and software-only (a subscriptionTier other than "software" returns 422 — device-based projects need inventory assignment the dashboard still owns).
curl -X POST https://sriwatt.io/api/v1/projects \
-H "Authorization: Bearer swpk_..." \
-H "Content-Type: application/json" \
-d '{
"firstName": "Asha", "lastName": "Rao", "email": "asha@example.com",
"projectType": "on-grid", "projectSizeKw": 25,
"lat": 23.03, "lon": 72.58
}'
# 201
{ "ok": true, "invited": true, "project": { "id": "...", ... } }Required: firstName, a valid email (no + aliases), projectType (on-grid / off-grid / hybrid), a positive projectSizeKw. Optional: lastName, phone, location, lat/lon, entityType (individual/company), businessType (when entityType is company).
/api/v1/projects/:idUpdates a project's mutable fields. Any subset of:
{
"phone": "+91...", "location": "...", "lat": 23.03, "lon": 72.58,
"projectType": "hybrid", "projectSizeKw": 30,
"quoteStatus": "generated"
}Deliberately not writable here: email (it's the customer's login identity — changing it would orphan their invite) and contractStatus (marking a contract "signed" without a real signature would fabricate one — that stays a dashboard/customer action). 404 if the id doesn't exist or isn't yours.
.sri files
/api/v1/sri-filesLists your empirical module-performance files (summary metadata — status, module identity, measurement period).
Query params: limit (default 50, max 200).
{
"ok": true,
"sriFiles": [
{
"id": "...", "module_brand": "...", "module_model": "...",
"module_power_class_w": 580, "status": "validated",
"period_start": "...", "period_end": "...",
"generation_date": "...", "created_at": "..."
}
]
}Webhooks
Register a URL from the dashboard's Developer API tab to receive a signed POST the moment one of these fires: project.created, contract.signed, quote.generated, sri_file.generated. Leave the event list empty on a subscription to receive all of them.
POST <your URL>
Content-Type: application/json
X-SriWatt-Event: project.created
X-SriWatt-Signature: sha256=<hmac-sha256 of the raw body, hex>
{"type":"project.created","createdAt":"...","data":{"projectId":"...","email":"...","projectType":"on-grid","projectSizeKw":25}}Verify the signature with your subscription's secret (shown once at creation, and always visible in the dashboard afterward — unlike an API key, this secret authenticates calls from SriWatt, so it stays retrievable). Delivery is best-effort with an 8-second timeout and no retry queue in this first version.
Errors
Every non-2xx response is JSON with at least an error code:
{ "error": "invalid_request", "message": "projectSizeKw must be a positive number." }Common codes: unauthorized (401), invalid_request (400), conflict (409), not_found (404), rate_limit_exceeded (429), internal_error (500).
Manage keys and webhook subscriptions from your dashboard's Account → Developer API tab.