Proxying API Reference
Synentra acts as a reverse proxy gateway. Any HTTP request prefixed with /proxy/ is intercepted, evaluated, and either forwarded to the upstream service, blocked, or put on hold for human-in-the-loop (HITL) approval.
The proxy supports all HTTP methods – GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, etc. – and forwards the method, headers, and body (when present) to the upstream service.
Throughout this guide the base URL is assumed to be your running server, e.g. http://localhost:7080.
Replace <BASE_URL> in the examples with your actual server address.
URL Format
<method> <BASE_URL>/proxy/<full-upstream-url>
The full absolute URL of the upstream target is embedded in the path:
GET /proxy/https://api.example.com/users/123
Authorization: Bearer <agent-jwt>
Query strings embedded in the target URL are preserved and forwarded correctly.
Supported response codes
| Status | Description |
|---|---|
| Upstream status | Request was allowed and forwarded. Returns upstream response. |
202 Accepted | Request intercepted — HITL review required. Location header set. |
401 Unauthorized | Missing or invalid agent token |
403 Forbidden | Agent is revoked or policy denied the request |
429 Too Many Requests | Rate limit exceeded |
503 Service Unavailable | Circuit breaker open for upstream host |
Request Forwarding (for Allowed Requests)
When a request is allowed, Synentra constructs a new HttpMessage and forwards it.
Headers forwarded:
- All headers from the original request except those listed below.
Headers NOT forwarded:
- The authorization header name is configurable via
SecurityConfiguration.AgentAuth.CustomHeaderName(default:"Synentra-Authorization"). The configured header is excluded from forwarding. Host– The host is set automatically from the target URI.Connection,Content-Length,Transfer-Encoding,Proxy-Connection,TE,Keep-Alive,Upgrade,Trailer– These are managed by the HTTP stack.
Example: Proxying a GET Request
1. Proxying a GET Request
The following example sends a request to https://jsonplaceholder.typicode.com/todos/1 through the Synentra gateway.
- cURL
- JavaScript
- Python
curl -X GET "http://localhost:7080/proxy/https://jsonplaceholder.typicode.com/todos/1" \
-H "Synentra-Authorization: Bearer <your-agent-jwt>"
fetch('http://localhost:7080/proxy/https://jsonplaceholder.typicode.com/todos/1', {
method: 'GET',
headers: {
'Synentra-Authorization': 'Bearer <your-agent-jwt>'
}
})
.then(res => res.json())
.then(console.log);
import requests
response = requests.get(
'http://localhost:7080/proxy/https://jsonplaceholder.typicode.com/todos/1',
headers={'Synentra-Authorization': 'Bearer <your-agent-jwt>'}
)
print(response.json())
If the agent is active, within rate limits, the circuit is closed, and the decision engine allows the request, Synentra forwards the request and returns the upstream response unchanged.
2. Proxying a POST Request with a JSON Body
This example sends a POST request with a JSON payload to create a new resource. The request body is evaluated by the decision engine before forwarding.
- cURL
- JavaScript
- Python
curl -X POST "http://localhost:7080/proxy/https://api.example.com/users" \
-H "Synentra-Authorization: Bearer <your-agent-jwt>" \
-H "Content-Type: application/json" \
-d '{"name": "John Doe", "email": "john@example.com"}'
fetch('http://localhost:7080/proxy/https://api.example.com/users', {
method: 'POST',
headers: {
'Synentra-Authorization': 'Bearer <your-agent-jwt>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'John Doe',
email: 'john@example.com'
})
})
.then(res => res.json())
.then(console.log);
import requests
response = requests.post(
'http://localhost:7080/proxy/https://api.example.com/users',
headers={'Synentra-Authorization': 'Bearer <your-agent-jwt>'},
json={'name': 'John Doe', 'email': 'john@example.com'}
)
print(response.json())
3. HITL Interception (DELETE Request)
If the decision engine returns Hitl (for example, when a DELETE operation is deemed risky), the gateway responds with a 202 Accepted status and a Location header for polling.
- cURL
- JavaScript
- Python
curl -X DELETE "http://localhost:7080/proxy/https://api.example.com/users/all" \
-H "Synentra-Authorization: Bearer <your-agent-jwt>"
Response:
HTTP/1.1 202 Accepted
Location: /hitl/status/abc-123
Request pending approval. Poll /hitl/status/abc-123
fetch('http://localhost:7080/proxy/https://api.example.com/users/all', {
method: 'DELETE',
headers: {
'Synentra-Authorization': 'Bearer <your-agent-jwt>'
}
})
.then(res => {
if (res.status === 202) {
const location = res.headers.get('Location');
console.log(`Request pending approval. Poll ${location}`);
} else {
return res.text();
}
})
.then(console.log);
import requests
response = requests.delete(
'http://localhost:7080/proxy/https://api.example.com/users/all',
headers={'Synentra-Authorization': 'Bearer <your-agent-jwt>'}
)
if response.status_code == 202:
location = response.headers.get('Location')
print(f"Request pending approval. Poll {location}")
else:
print(response.text)
The operator can then approve or deny this request via the HITL endpoints.