# pvnode API Plattform

## 2026-08-18 — Built for integrations

Four additions that let a client poll correctly, discover its own entitlements and be set up
without the user copying an id out of the web app. Nothing is removed, and no existing field
changes meaning — all of this is additive.

The [Build Your Own](/en/v2/integrations/build-your-own) guide puts the four together into a
recommended client design.

### `next_poll_at` on the forecast response

Forecasts are computed on demand, not on a schedule, so asking again too early returns the
identical cached payload — and still costs a request. `next_poll_at` names the first moment a
request would return something newer.

```json
"computed_at":  "2026-06-09T08:00:00+02:00",
"next_poll_at": "2026-06-09T12:00:00+02:00"
```

Update slots currently spread evenly across the day from site-local midnight, following how
many updates per day your plan includes — but read the field rather than reproducing that
rule: the distribution is going to change. Treat the value as a recommendation, not a
guarantee: another request can trigger an earlier recomputation. Present on `GET /v2/forecast/{site_id}`; absent
on `/forecast/inline`, which is always computed fresh.
[Details](/en/v2/api/forecast#caching-computed_at-and-next_poll_at)

### `available` alongside `included`

`included` echoes what you requested. `available` lists every include group your **plan** may
request on that endpoint:

```json
"included":  ["default", "strings"],
"available": ["default", "weather", "irradiance", "clearsky", "strings", "variability"]
```

A client can now hide or unlock features without hard-coding plan knowledge, and a plan change
takes effect on the next request with no release and no reconfiguration. Currently
`variability` is the only plan-gated group; the meta-token `all` is deliberately not listed.
Present on the forecast and historical endpoints.
[Details](/en/v2/api/forecast#what-your-plan-allows-available)

### `RequestLimit-*` response headers

Forecast and historical responses — including the **429** — now carry the caller's monthly
quota:

```http
RequestLimit-Limit: 10000
RequestLimit-Used: 4231
RequestLimit-Remaining: 5769
RequestLimit-Reset: 2026-09-01T00:00:00Z
```

`Limit` and `Remaining` are strings and contain the literal `unmetered` on plans without a
cap, so parse defensively. The counter runs per (user, endpoint, month): forecast and
historical have separate budgets, and the figures are account-wide rather than per site.
[Details](/en/v2/api/forecast#request-quota-headers)

### Reading sites is open on every plan

`GET /v2/sites/` and `GET /v2/sites/{site_id}` no longer require a plan with Sites API access:

```bash
GET /v2/sites/
```

Forecast access exists on the free plan and a forecast needs a `site_id`, so a client has to be
able to look that id up. This is what lets an integration offer a **site picker** instead of
asking users to paste an id. The two reads cost no forecast quota and send no `RequestLimit-*`
headers. Creating, updating, deleting and restoring sites still requires Sites API access.
[Details](/en/v2/api/sites#access)
