manage-upstreams
Last updated Jul 23, 2026
title: Managing Upstreams description: Create, list, update, and delete upstreams through the dashboard UI and the REST API. group: Configuration order: 3
Managing Upstreams
An upstream is a third-party API you proxy through GuardProxy. Each upstream has its own slug, blocked methods, and path allowlist. You manage them through the dashboard UI or the REST API.
Using the dashboard
The Upstreams page lets you create, edit, and delete upstreams in your browser. Each row shows the proxy endpoint (with a copy button), the blocked methods, and edit/delete actions.
Using the API
All routes are session-authenticated and owner-scoped — you can only ever see or modify the authenticated customer's own upstreams. Authenticate with the session cookie set at sign-in.
| Method | Route | Purpose |
|---|---|---|
GET |
/api/upstreams |
list all upstreams |
POST |
/api/upstreams |
create — 201, or 409 duplicate_slug |
GET |
/api/upstreams/:id |
get one — 404 if not found |
PATCH |
/api/upstreams/:id |
partial update |
DELETE |
/api/upstreams/:id |
delete — 204 |
List upstreams
GET /api/upstreams
Cookie: <session>
{
"upstreams": [
{
"id": "up_abc123",
"slug": "itglue",
"display_name": "ITGlue Production",
"upstream_url": "https://api.itglue.com",
"blocked_methods": ["POST", "PUT", "PATCH", "DELETE"],
"path_allowlist": ["/graphql"],
"proxy_endpoint": "https://cust_abc.guardproxy.dev/itglue",
"created_at": "2026-06-01T12:00:00.000Z",
"updated_at": "2026-06-01T12:00:00.000Z"
}
]
}
Use the returned proxy_endpoint as your base URL — it's the canonical source of truth for routing requests.
Create an upstream
POST /api/upstreams
Content-Type: application/json
Cookie: <session>
{
"slug": "hudu",
"displayName": "Hudu",
"upstreamUrl": "https://hudu.example.com",
"blockedMethods": ["POST", "PUT", "PATCH", "DELETE"],
"pathAllowlist": ["/graphql"]
}
| Field | Required | Rules |
|---|---|---|
slug |
yes | [a-z0-9-], 1–32 chars, lowercased, unique per customer |
displayName |
yes | non-empty |
upstreamUrl |
yes | http(s); private IPs / localhost rejected (SSRF guard) |
blockedMethods |
no | defaults to ["POST","PUT","PATCH","DELETE"] |
pathAllowlist |
no | each entry must start with / |
201returns the new upstream with itsproxy_endpoint.409 duplicate_slug→ that slug already exists for this customer; pick another.400 invalid_*→ validation failed (slug / url / methods / paths).
Update an upstream
PATCH accepts any subset of fields. To widen a path allowlist without touching anything else:
PATCH /api/upstreams/{id}
Content-Type: application/json
{ "pathAllowlist": ["/graphql", "/search"] }
Delete an upstream
DELETE /api/upstreams/{id}
Returns 204 on success. The proxy endpoint stops working immediately.
Validation reference
- slug:
/^[a-z0-9-]{1,32}$/, lowercased before storage. - upstreamUrl: must be
httporhttps; rejected if it resolves to localhost, private IP ranges (10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.0/8,169.254.0.0/16), link-local, CGNAT, the.internalTLD, or cloud metadata endpoints. - blockedMethods: array of
GET|HEAD|OPTIONS|POST|PUT|PATCH|DELETE(case-insensitive; stored uppercase). - pathAllowlist: array of strings matching
/^\/[A-Za-z0-9_./-]*$/(each must start with/).
Account state
GET /api/me returns your user and customer record, including subscription_status and the trial window. The proxy enforces this: an expired or past_due account returns 402, and sustained abuse returns 429.