Cloud API

The fastest way to build an integration is to point your LLM (Claude, ChatGPT, etc.) at the sacli command-line tool and ask it to explore the API. sacli is a 6 MB download with no dependencies. It prints every URL it calls, every header it sends, and every response it receives, giving an LLM everything it needs to replicate the calls in any language.

Prompting Claude Code to explore the SolarAssistant API via sacli
Claude Code exploring the SolarAssistant API

The Cloud API covers site administration (managing sites, members, and access) as well as real-time metrics streamed directly from your devices through the proxy. Client libraries are available for Python and Go.

Primary endpoints

Generate an API token on your user details page and pass it as a Bearer token in the Authorization header on every request:

Generate API token on the user details page

The host for all primary endpoints below is solar-assistant.io. The endpoints below are available to all users on solar-assistant.io.

GET/api/v1/userGet current user

Returns the authenticated user's profile.

Request
curl -H "Authorization: Bearer <token>" https://solar-assistant.io/api/v1/user
Response
{
  "id": 1,
  "email": "me@example.com",
  "first_name": "Alice",
  "last_name": "Smith",
  "phone_number": "+1 555 000 0000",
  "locale": "en"
}
GET/api/v1/sitesList all sites on the account

Returns all sites associated with the authenticated account.

Request
curl -H "Authorization: Bearer <token>" https://solar-assistant.io/api/v1/sites
Response
[
  {
    "id": 19489,
    "name": "my-site",
    "proxy": "us-htz-1",
    "last_seen_at": "2026-05-11T12:00:00Z"
  }
]
GET/api/v1/sites/:idShow site details

Returns full details for a site including its members and organization.

Path parameters
idintegerrequiredSite ID from the list sites response.
Request
curl -H "Authorization: Bearer <token>" https://solar-assistant.io/api/v1/sites/19489
Response
{
  "id": 19489,
  "name": "my-site",
  "proxy": "us-htz-1",
  "last_seen_at": "2026-05-11T12:00:00Z",
  "owner": { "id": 1, "email": "me@example.com", "first_name": "Alice", "last_name": "Smith" },
  "organization": { "id": 7, "name": "Acme", "cloud_host": "acme.solar-assistant.io" },
  "users": [
    { "id": 1, "email": "me@example.com", "first_name": "Alice", "last_name": "Smith", "role": "owner" }
  ]
}
POST/api/v1/sites/registerRegister a site to the account

Claims an unregistered SolarAssistant device and associates it with the authenticated account. If the site is already registered to this account, the existing site is returned.

Body parameters
uidstringrequiredUnique identifier of the device.
namestringDisplay name for the site.
descriptionstringOptional description.
Request
curl -X POST -H "Authorization: Bearer <token>" https://solar-assistant.io/api/v1/sites/register \
  -H "Content-Type: application/json" \
  -d '{"uid": "abc123", "name": "my-site"}'
Response
{
  "id": 19489,
  "name": "my-site",
  "proxy": "us-htz-1",
  "last_seen_at": "2026-05-11T12:00:00Z",
  "owner": { "id": 1, "email": "me@example.com", "first_name": "Alice", "last_name": "Smith" }
}
GET/api/v1/sites/:id/usersList site members

Returns all members of a site with their roles.

Path parameters
idintegerrequiredSite ID from the list sites response.
Request
curl -H "Authorization: Bearer <token>" https://solar-assistant.io/api/v1/sites/<id>/users
Response
[
  {
    "id": 1042,
    "email": "owner@example.com",
    "first_name": "Jane",
    "last_name": "Smith",
    "role": "owner"
  }
]

Roles are owner, admin, or member.

POST/api/v1/sites/:id/usersInvite or update a site member

Invites a user by email. If the email belongs to an existing account they are linked immediately; otherwise they receive an invitation email. Posting with an existing member's email updates their role.

Path parameters
idintegerrequiredSite ID.
Body parameters
emailstringrequiredEmail address of the user to invite.
rolestringrequiredmember, admin, or owner.
first_namestringRequired when inviting a new user (email not yet registered).
last_namestringRequired when inviting a new user.
Request
curl -X POST \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"email":"tech@example.com","role":"admin","first_name":"Bob","last_name":"Jones"}' \
  https://solar-assistant.io/api/v1/sites/<id>/users
Response
{
  "id": 1099,
  "email": "tech@example.com",
  "first_name": "Bob",
  "last_name": "Jones",
  "role": "admin"
}
PATCH/api/v1/sites/:id/users/:user_idUpdate a site member's role

Updates the role of an existing site member. Requires admin or owner access on the site.

Path parameters
idintegerrequiredSite ID.
user_idintegerrequiredID of the member to update.
Body parameters
rolestringrequiredmember, admin, or owner.
Request
curl -X PATCH \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"role":"admin"}' \
  https://solar-assistant.io/api/v1/sites/<id>/users/<user_id>
Response
{
  "id": 1099,
  "email": "tech@example.com",
  "first_name": "Bob",
  "last_name": "Jones",
  "role": "admin"
}
DELETE/api/v1/sites/:id/users/:user_idRemove a site member

Removes a member from the site. The site owner cannot be removed. Requires admin or owner access.

Path parameters
idintegerrequiredSite ID.
user_idintegerrequiredID of the member to remove.
Request
curl -X DELETE \
  -H "Authorization: Bearer <token>" \
  https://solar-assistant.io/api/v1/sites/<id>/users/<user_id>
Response
204 No Content
POST/api/v1/sites/:id/authorizeGenerate site access token

Returns temporary credentials for direct access to a site through the cloud proxy. The token expires after 7 days.

Path parameters
idintegerrequiredSite ID.
Request
curl -X POST -H "Authorization: Bearer <token>" https://solar-assistant.io/api/v1/sites/<id>/authorize
Response
{
  "host": "us-htz-1.solar-assistant.io",
  "site_id": 19489,
  "site_name": "my-site",
  "site_key": "9u10PW2b...",
  "token": "eyJhbGci..."
}

The following endpoint is only available to users that have a registered organization.

GET/api/v1/usersList users

Returns all users.

Query parameters
offsetintegerNumber of records to skip (default 0).
limitintegerMaximum records to return (default 20).
Request
curl -H "Authorization: Bearer <token>" https://solar-assistant.io/api/v1/users
Response
[
  {
    "id": 1,
    "email": "me@example.com",
    "first_name": "Alice",
    "last_name": "Smith",
    "phone_number": "+1 555 000 0000",
    "locale": "en"
  }
]

Proxy pass-through endpoints

Since most sites are connected to a proxy server such as us-htz-1.solar-assistant.io, use the site authorize endpoint to get the host, token, and site_key for a site, then send those as headers on every proxy request. See the regions page for a list of all proxies.

GEThttps://<host>/api/v1/metricsMetrics snapshot

This is the same SolarAssistant device REST API you would call on the local network — all the same paths work the same way. The authorize step is needed to authenticate with the proxy in place of local network access.

Headers
AuthorizationstringrequiredBearer token from the authorize response.
Site-IdintegerrequiredSite ID from the authorize response.
Site-KeystringrequiredSite key from the authorize response.
Request
curl \
  -H "Authorization: Bearer <token>" \
  -H "Site-Id: <site-id>" \
  -H "Site-Key: <site-key>" \
  https://<host>/api/v1/metrics
WSwss://<host>/api/websocketStream metrics via WebSocket

Streams live metrics using the SolarAssistant WebSocket API through the cloud proxy. Connect with the same credentials returned by the authorize endpoint, passing the token as a query parameter and Site-Id / Site-Key as headers.

Query parameters
tokenstringrequiredBearer token from the authorize response.
Headers
Site-IdintegerrequiredSite ID from the authorize response.
Site-KeystringrequiredSite key from the authorize response.
Request
wss://<host>/api/websocket?token=<token>&vsn=2.0.0
Site-Id: <site-id>
Site-Key: <site-key>

After connecting, join the metrics channel using the Phoenix Channel V2 protocol. See the WebSocket API docs for channel events and topic format.