Getting started with PHY API

Introduction to using the PHY API for utility management.

PHY API is a powerful tool that helps you manage your utility consumption and costs.

Getting started

To get started, follow these steps:

  1. Sign up or log in on the website.
  2. Obtain an access token via the Auth endpoints (login or signup).
  3. Use the access token in the Authorization header as a Bearer token for all requests.

Tip: You can import our ready-to-use Postman collection and start testing immediately.

Base URL

  • Production: https://phy.engineering

Authentication

Authenticate to obtain a JWT access token, then include it on every request.

Login example:

curl -s -X POST \
	-H "Content-Type: application/json" \
	-d '{
				"email": "user@example.com",
				"password": "your_password"
			}' \
	https://phy.engineering/api/v1/auth/login

Then use the access token from the response in the Authorization header:

curl -s \
	-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
	https://phy.engineering/api/v1/health

Response envelope

All endpoints return a consistent JSON envelope.

Structure

{
	"success": boolean,
	"message": string,   // optional
	"data": any,         // resource or list
	"count": number,     // optional for list endpoints
	"error": string      // only when success=false
}

Success examples

  • List (200):
{
	"success": true,
	"data": [ { "id": 1, "name": "Example" } ],
	"count": 1
}
  • Create (201):
{
	"success": true,
	"message": "Resource created successfully",
	"data": { "id": 42, "name": "New" }
}

Error examples

  • Validation (400):
{
	"success": false,
	"message": "Invalid request body",
	"error": "json: cannot unmarshal string into Go struct field ..."
}
  • Auth (401):
	"message": "Invalid request body",
	"error": "Invalid payload"
	"message": "API key authentication required",
	"error": "invalid or missing API key"
}

Quick test with curl

	"message": "Authentication required",
	"error": "invalid or missing bearer token"
	-H "X-API-KEY: $API_KEY" \
	https://phy.engineering/api/v1/tariffs | jq

# Create a tariff (example)
curl -s -X POST \
	-H "X-API-KEY: $API_KEY" \
# Login (obtain an access token)
ACCESS_TOKEN=$(curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "password": "your_password"}' \
  https://phy.engineering/api/v1/auth/login | jq -r '.data.access_token')

# List tariffs (requires a valid bearer token and accountId)
	-d '{
curl -s \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://phy.engineering/api/v1/tariffs?accountId=$ACCOUNT_ID" | jq
				"currency": "ZAR",
# Create a tariff (example)
				"effective_from": "2025-07-01T00:00:00Z",
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "accountId": "'$ACCOUNT_ID'",
        "name": "Residential 2025",
        "meter_type": "electricity",
        "tariff_type": "retail",
        "currency": "ZAR",
        "tax_rate": 15,
        "effective_from": "2025-07-01T00:00:00Z",
        "effective_to": "2026-06-30T23:59:59Z"
      }' \
  https://phy.engineering/api/v1/tariffs | jq