SSpark ERP

API Reference

A tenant-scoped REST API, documented honestly.

Every application on Spark ERP is reachable through one REST surface under /api/v1 — tenant-scoped, session- or token-authenticated, and the same surface the `erp` CLI itself calls. The examples below are illustrative, drawn from real endpoints used by the CLI and platform — this page is a static reference, not a live, interactive API Explorer.

Authentication

Every request is scoped to a tenant via the X-Tenant-Id header and authenticated with a bearer access token (obtained via an OAuth 2.0 device authorization grant, RFC 8628, or a direct login) or an active session token. This is the exact shape the CLI's own `api()` request helper sends on every call.

Request headers
X-Tenant-Id: 2
Authorization: Bearer <accessToken>
Content-Type: application/json
Obtain a token — device authorization grant
POST /api/v1/auth/device/code       # unauthenticated — starts the flow
POST /api/v1/auth/device/token      # polled until the browser approval completes

# or, for a one-shot flow / CI:
POST /api/v1/auth/login

Pagination, filtering, sorting

List endpoints are paginated by default (page/size, per this platform's own standing convention) — never an unbounded list.

Tenant isolation

X-Tenant-Id scopes every read and write; a token is only valid against the tenant(s) it was issued for.

Correlation IDs

Every response carries an X-Correlation-Id header — join it against server-side logs (`erp logs tail --grep <id>`) to debug a specific call.

Example endpoints

Illustrative request/response pairs — not a live, interactive Explorer. Every path below is a real endpoint referenced in the platform's own CLI source.

GET/api/v1/entities/{entityName}/records

Read records for any entity defined on the tenant — the generic path every entity-backed list view and the CLI's own `erp api get` verification workflow reads through.

Request
curl -H "X-Tenant-Id: 2" -H "Authorization: Bearer $TOKEN" \
  "$BASE_URL/api/v1/entities/employee/records?page=0&size=20"
Response
{
  "content": [
    { "id": 101, "name": "Jordan Lee", "status": "ACTIVE" }
  ],
  "page": 0,
  "size": 20,
  "totalElements": 143
}
GET/api/v1/authoring/plugins

List installed plugins for the current tenant — the real endpoint `erp plugin list` calls.

Request
erp plugin list --tenant 2

# equivalent, via the generic verification command:
erp api get /api/v1/authoring/plugins --tenant 2
Response
[
  { "pluginId": "hcm-employee-information", "version": "1.0.10", "status": "INSTALLED" }
]
POST/api/v1/data-services/{name}/execute

Execute a named Data Service — the platform's read-model abstraction over raw entity queries, used by pages, KPIs and reports.

Request
erp api post /api/v1/data-services/employee-headcount-by-department/execute \
  --body '{"filters":{"status":"ACTIVE"}}' --tenant 2
Response
{
  "data": [
    { "department": "Engineering", "headcount": 48 },
    { "department": "Sales", "headcount": 22 }
  ]
}
GET/api/v1/dev/bundle/manifest

The authoring-bundle manifest a logged-in SDK install syncs against — schemas, catalog, docs, blocks and live entity/theme names, versioned so `erp env sync --check` can detect drift without downloading.

Request
erp env sync --check
Response
{
  "bundleVersion": "2026.09.1",
  "generatedAt": "2026-09-10T08:12:00Z",
  "entityCount": 214,
  "blockCount": 87
}

Call the API from a script, not a browser tool.

The `erp api get/post/put/delete` command authenticates the same way as every example above, against any real endpoint on a logged-in environment — the honest substitute for a hosted, interactive Explorer this site does not run.