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.