Skip to main content

API Reference

Synentra exposes a REST API via ASP.NET Core Minimal APIs.
Interactive API documentation is also available at /open-api when the server is running.

Base URL

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.


Authentication

All requests to management endpoints must include a valid agent JWT (see Tokens).

Set the authorization header
Authorization: Bearer <token>

Tokens

POST /tokens — Exchange credentials for JWT

Exchange an agent's ID and client secret for a JWT token.

curl -X POST "${BASE_URL}/tokens" \
-H "Content-Type: application/json" \
-d '{
"agentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"clientSecret": "my-strong-secret"
}'

Responses

  • 200 OK — Successful authentication.
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresAt": "2025-01-01T13:00:00Z"
}
  • 401 Unauthorized — Invalid credentials.

Agents

Base path: /agents

GET /agents — List agents

Query ParamTypeDefaultDescription
pageint1Page number
pageSizeint25Items per page
curl "${BASE_URL}/agents?page=1&pageSize=25"

Response 200 OK

{
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "billing-agent",
"ownerId": "team-finance",
"status": "Active",
"policyName": "billing-policy",
"trustScore": 0.75
}
],
"page": 1,
"pageSize": 25,
"totalCount": 1
}

POST /agents — Register agent

curl -X POST "${BASE_URL}/agents" \
-H "Content-Type: application/json" \
-d '{
"name": "billing-agent",
"ownerId": "team-finance",
"clientSecret": "my-strong-secret"
}'

Request

{
"name": "billing-agent",
"ownerId": "team-finance",
"clientSecret": "my-strong-secret"
}

Response 201 Created

{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "billing-agent",
"clientSecret": "my-strong-secret"
}

PUT /agents/{agentId}/policy — Assign policy

curl -X PUT "${BASE_URL}/agents/3fa85f64-5717-4562-b3fc-2c963f66afa6/policy" \
-H "Content-Type: application/json" \
-d '{ "policyName": "billing-policy" }'

Response 200 OK


DELETE /agents/{agentId} — Delete agent

curl -X DELETE "${BASE_URL}/agents/3fa85f64-5717-4562-b3fc-2c963f66afa6"

Response 200 OK


POST /agents/{agentId}/lift-quarantine — Lift quarantine

curl -X POST "${BASE_URL}/agents/3fa85f64-5717-4562-b3fc-2c963f66afa6/lift-quarantine"

Response 200 OK


Policies

Base path: /policies

GET /policies — List policies

Query ParamTypeDefault
pageint1
pageSizeint25
curl "${BASE_URL}/policies?page=1&pageSize=25"

Response 200 OK

{
"items": [
{
"name": "billing-policy",
"description": "Governs the billing agent",
"owner": "team-finance",
"default": "Deny",
"ruleCount": 3
}
],
"page": 1,
"pageSize": 25,
"totalCount": 1
}

GET /policies/{name} — Get policy details

curl "${BASE_URL}/policies/billing-policy"

Response 200 OK

{
"name": "billing-policy",
"description": "Governs the billing agent",
"owner": "team-finance",
"default": "Deny",
"rules": [
{
"name": "block-delete",
"priority": 100,
"effect": "Deny",
"conditions": [
{ "field": "input.method", "operator": "eq", "value": "DELETE" }
]
}
]
}

Response 404 Not Found


Proxy

ANY /proxy/{url} — Proxy a request

The proxy endpoint forwards the original HTTP method, headers, and body to the specified upstream URL.

It evaluates policies and may intercept the request for human review.

curl -X GET "${BASE_URL}/proxy/https://api.example.com/resource" \
-H "Authorization: Bearer $TOKEN"
StatusDescription
Upstream statusRequest was allowed and forwarded. Returns upstream response.
202 AcceptedRequest intercepted — HITL review required. Location header set.
401 UnauthorizedMissing or invalid agent token
403 ForbiddenAgent is revoked or policy denied the request
429 Too Many RequestsRate limit exceeded
503 Service UnavailableCircuit breaker open for upstream host

Human-in-the-Loop

Base path: /hitl

GET /hitl — List pending HITL requests

curl "${BASE_URL}/hitl"

Response 200 OK

[
{
"id": "abc-123",
"method": "DELETE",
"url": "https://api.example.com/users/all",
"reason": "High risk score: 0.92",
"agentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"timestamp": "2025-01-01T12:00:00Z",
"expiresAt": "2025-01-01T13:00:00Z"
}
]

GET /hitl/{id} — Get HITL request status

curl "${BASE_URL}/hitl/abc-123"

Response 200 OK

{
"id": "abc-123",
"status": "Pending",
"pending": { ... }
}

Response 404 Not Found


POST /hitl/{id}/approve — Approve request

curl -X POST "${BASE_URL}/hitl/abc-123/approve" \
-H "Content-Type: application/json" \
-d '{ "comment": "Approved by ops team" }'

Response 200 OK — upstream response proxied back.

Response 404 Not Found — expired or not found.


POST /hitl/{id}/deny — Deny request

curl -X POST "${BASE_URL}/hitl/abc-123/deny" \
-H "Content-Type: application/json" \
-d '{ "comment": "Not authorised" }'

Response 200 OK

Response 404 Not Found


Health Check

GET /health

curl "${BASE_URL}/health"

Response 200 OK

{
"status": "Healthy",
"healthCheckDuration": "00:00:00.0123456"
}

Response 503 Service Unavailable — one or more health checks are unhealthy.


OpenAPI / Swagger

Interactive API documentation is available at /open-api when the server is running. The raw specification is at /open-api/synentra/specifications.json.

Was this helpful?