API Reference · v1

PowerLab REST API

Read-only access to your PowerLab projects. Pull calculations into a spreadsheet, wire up a client-handoff tool, or back up your designs with a scheduled script.

Base URL

https://powerlab.marinepowerlab.com/api/v1

Authentication

Every request requires a Bearer token. Generate a key from Settings → API Keys. Keys look like plk_… and are shown exactly once at creation.

curl -H "Authorization: Bearer plk_your_key_here" \
  https://powerlab.marinepowerlab.com/api/v1/projects

Invalid or revoked keys return 401 Unauthorized. A valid key whose user isn't on an active Pro plan returns 403 Forbidden.

Rate limits

Per API key, not per user. Limits are advisory headers on every response (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) plus a 429 body when exceeded.

  • Project list: 100/hour
  • Project detail + loads + components: 200/hour each

Code samples

Replace plk_… with your real key. The same pattern works for every endpoint below.

cURLbash
curl -H "Authorization: Bearer plk_your_key_here" \
  https://powerlab.marinepowerlab.com/api/v1/projects
Python (requests)python
import os, requests

key = os.environ['POWERLAB_API_KEY']
res = requests.get(
    'https://powerlab.marinepowerlab.com/api/v1/projects',
    headers={'Authorization': f'Bearer {key}'},
    timeout=15,
)
res.raise_for_status()
for p in res.json()['data']:
    print(p['name'], '—', p['system_voltage'], 'V')
JavaScript (Node / fetch)javascript
const key = process.env.POWERLAB_API_KEY;
const res = await fetch('https://powerlab.marinepowerlab.com/api/v1/projects', {
  headers: { Authorization: `Bearer ${key}` },
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const { data } = await res.json();
for (const project of data) {
  console.log(project.name, '—', project.system_voltage, 'V');
}
Google Sheets (Apps Script)javascript
function importPowerLabProjects() {
  const key = PropertiesService.getScriptProperties().getProperty('POWERLAB_API_KEY');
  const res = UrlFetchApp.fetch(
    'https://powerlab.marinepowerlab.com/api/v1/projects',
    { headers: { Authorization: 'Bearer ' + key } }
  );
  const { data } = JSON.parse(res.getContentText());
  const rows = data.map(p => [p.name, p.vessel_type, p.system_voltage, p.updated_at]);
  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(1, 1, rows.length, rows[0].length).setValues(rows);
}

Endpoints

GET/projects

List your projects, newest first.

Query parameters

  • limit (integer)Default 25, max 100.
  • offset (integer)For pagination.

Response

{
  "data": [
    {
      "id": "uuid",
      "name": "Catalina 36 lithium conversion",
      "vessel_type": "sailboat",
      "system_voltage": 12,
      "location_name": "Vancouver, BC",
      "peak_sun_hours": 4.2,
      "share_token": "…",
      "is_public": false,
      "permit_report_unlocked_at": null,
      "created_at": "2026-04-01T13:00:00.000Z",
      "updated_at": "2026-04-12T18:22:01.000Z"
    }
  ],
  "pagination": { "limit": 25, "offset": 0, "total": 4 }
}
GET/projects/{id}

Full project detail — project row, loads, installed components, and freshly-computed calculations.

Response

{
  "project": { … project columns … },
  "loads": [ …project_loads rows, joined to appliance… ],
  "installed_components": [ … ],
  "calculations": {
    "loads":   { totalDailyWh, totalDailyAh, peakWatts, monthlyKwh, … },
    "battery": { recommendedCapacityAh, batteryConfig, estimatedCost, weightKg, reasoning },
    "solar":   { recommendedSolarWatts, panelCount, panelWattage, chargeControllerAmps, estimatedCost, reasoning }
  }
}
GET/projects/{id}/loads

Machine-readable load list for this project.

Query parameters

  • format (string)Pass format=csv for a CSV stream (otherwise JSON).

Response

{
  "data": [
    {
      "id": "uuid",
      "custom_name": null,
      "watts": 45,
      "quantity": 1,
      "hours_per_day": 16,
      "is_enabled": true,
      "is_critical": true,
      "sort_order": 3,
      "appliance": { "name": "12V Marine Fridge", "category": "Refrigeration" }
    }
  ]
}
GET/projects/{id}/components

Installed-component library for this project: brand/model/serial/warranty dates.

Response

{
  "data": [
    {
      "id": "uuid",
      "component_type": "battery",
      "brand": "Battle Born",
      "model": "BB10012",
      "serial_number": "…",
      "purchase_date": "2024-05-14",
      "warranty_expiry": "2034-05-14",
      "price_paid": 899.00,
      "currency": "CAD",
      "notes": "…",
      "created_at": "…",
      "updated_at": "…"
    }
  ]
}

Common integrations

Google Sheets

Apps Script snippet above. Schedule it on a time-driven trigger to keep your spreadsheet in sync nightly.

Zapier / Make

Use their generic "Webhooks by Zapier" / "HTTP" module with GET + Bearer auth. No dedicated connector yet.

Python / Pandas

pd.read_json on the JSON response or CSV loads endpoint. Good for BoM analysis across multiple projects.

Postman / Bruno

Set collection-level Authorization to Bearer. Import the full base URL and hit each endpoint interactively.

What's NOT here

v1 is read-only on purpose. No write endpoints, no project mutations, no public appliance catalog. Writes live behind the session-authenticated UI. Future additions (webhooks, write endpoints, bulk exports) will be announced in the PowerLab dashboard.