Overview
Browser and server clients call LIUV through Google Cloud API Gateway (API key), which forwards to Cloud Run services. First-party web traffic uses Netlify edge functions to attach x-api-key and X-Internal-Token where required.
This page documents the Partner API Phase 1 admin surface implemented by partner-api-service. It is intended for operators and integrations that LIUV provisions (not anonymous public callers).
Base URL
Production gateway host is configured as GCP_BACKEND_URL on Netlify (see deployment). Paths below are shown as rooted at that host.
https://<gateway-host>/v1/admin/partners
From the public website, the same routes are available under the /api prefix (edge proxy strips /api when forwarding):
https://liuv.io/api/v1/admin/partners
Authentication
| Header | Required for | Description |
|---|---|---|
x-api-key |
All gateway routes | Google API Gateway validates this key before invoking Cloud Run. |
X-Internal-Token |
Partner admin API (Phase 1) | Shared secret between LIUV edge/backend and partner-api-service. Not for end users. |
Authorization: Bearer … |
User JWT routes (auth, dashboard APIs) | Standard LIUV session JWT where documented on other endpoints. |
lp_live_… / lp_test_…) are issued by the admin API and stored hashed. Bearer authentication for partner product routes (market, screener, analysis) will be documented in Phase 2.Response format
Successful JSON responses use a common envelope:
{
"success": true,
"data": { },
"error": null,
"code": null
}HTTP status codes follow REST conventions (201 for create, 200 for read/update/delete).
Errors
Failures return the same envelope with success: false, a human-readable error message, and a code (e.g. BAD_REQUEST, NOT_FOUND).
{
"success": false,
"data": null,
"error": "Partner not found",
"code": "NOT_FOUND"
}Partner admin API (Phase 1)
Base path: /v1/admin/partners. Requires x-api-key + X-Internal-Token.
Request body (JSON):
{
"name": "Acme Corp",
"contactEmail": "ops@acme.example",
"tier": "starter",
"scopes": ["market:read", "screener:read"]
}| Field | Type | Notes |
|---|---|---|
name | string | Required. |
contactEmail | string | Required. |
tier | string | starter | growth | professional | enterprise |
scopes | string[] | Optional; defaults to ["market:read"] if omitted or empty. |
Allowed scope values: market:read, screener:read, analysis:read, portfolio:read, ads:write, webhooks:manage, users:read.
Returns an array of partner objects including key metadata (never the secret key material).
Partial update. Omitted fields unchanged. Example:
{
"status": "suspended",
"tier": "growth"
}status: active | suspended
Optional body:
{
"label": "Production",
"testKey": false
}Response data includes apiKey once (lp_live_… or lp_test_…). Store it securely; only a SHA-256 hash is kept server-side.
Roadmap
- — Phase 2+: Partner-facing routes under
/api/v1/partner/…(market, screener, analysis, investor tracker), rate limits, usage reporting. - — Webhooks and advertising APIs per product plan.
OpenAPI definitions for the gateway live in the liuv-backend repo: infra/api-gateway/openapi.yaml.