REST API
In addition to the GraphQL API, the Manager provides REST endpoints for specific operations, primarily for machine user authentication and backend registration.
Base URL
https://manager.example.com/apiAuthentication
REST endpoints use the same authentication methods as GraphQL:
Bearer Token:
Authorization: Bearer <token>Basic Authentication:
Authorization: Basic <base64(username:password)>Endpoints
Validate Machine User
Validates machine user credentials. Used internally by the Proxy for authentication.
Endpoint:
POST /api/validate-machine-userAuthentication: None required (internal use)
Request Body:
{
"username": "machine-user-name",
"token": "bearer-token-or-password"
}Response (Success):
{
"valid": true,
"tenantId": "tenant-uuid",
"machineUserId": "machine-user-uuid"
}Response (Invalid):
{
"valid": false,
"error": "Invalid credentials"
}Example:
curl -X POST https://manager.example.com/api/validate-machine-user \
-H "Content-Type: application/json" \
-d '{
"username": "payment-service",
"token": "muser_abc123..."
}'Check Machine User Auth
Verifies the current machine user authentication status.
Endpoint:
GET /api/machine/checkAuthentication: Bearer Token (Machine User) - Required
Response:
{
"authenticated": true,
"machineUserId": "machine-user-uuid",
"tenantId": "tenant-uuid"
}Example:
curl -X GET https://manager.example.com/api/machine/check \
-H "Authorization: Bearer muser_abc123..."Register Backend
Registers a backend service to receive trigger execution callbacks.
Endpoint:
POST /api/machine/register-backendAuthentication: Bearer Token (Machine User) - Required
Request Body:
{
"name": "Payment Service",
"callbackUrl": "https://payment.example.com/triggers/callback",
"description": "Handles payment processing triggers"
}Response:
{
"id": "backend-uuid",
"name": "Payment Service",
"callbackUrl": "https://payment.example.com/triggers/callback",
"machineUserId": "machine-user-uuid",
"createdAt": "2025-12-01T10:00:00Z"
}Example:
curl -X POST https://manager.example.com/api/machine/register-backend \
-H "Authorization: Bearer muser_abc123..." \
-H "Content-Type: application/json" \
-d '{
"name": "Payment Service",
"callbackUrl": "https://payment.example.com/triggers/callback",
"description": "Handles payment processing triggers"
}'Error Responses
All REST endpoints return standard HTTP status codes:
Success Codes
200 OK- Request successful201 Created- Resource created successfully
Client Error Codes
400 Bad Request- Invalid request format or parameters401 Unauthorized- Missing or invalid authentication403 Forbidden- Insufficient permissions404 Not Found- Resource not found
Server Error Codes
500 Internal Server Error- Server-side error occurred
Error Response Format
{
"error": "Error message",
"code": "ERROR_CODE",
"status": 400
}Example Error:
{
"error": "Invalid machine user credentials",
"code": "INVALID_CREDENTIALS",
"status": 401
}Usage Patterns
Machine User Registration Flow
#!/bin/bash
# 1. Create machine user (via GraphQL)
RESPONSE=$(curl -X POST https://manager.example.com/query \
-H "Authorization: Bearer $USER_PAT" \
-H "Content-Type: application/json" \
-d '{
"query": "mutation { createMachineUserWithCredentials(tenantId: \"'$TENANT_ID'\", input: { name: \"Backend Service\", username: \"backend\", hashedKey: \"__GENERATE_TOKEN__\", enabled: true }) { generatedToken machineUser { id } } }"
}')
MACHINE_TOKEN=$(echo $RESPONSE | jq -r '.data.createMachineUserWithCredentials.generatedToken')
# 2. Verify authentication
curl -X GET https://manager.example.com/api/machine/check \
-H "Authorization: Bearer $MACHINE_TOKEN"
# 3. Register backend for triggers
curl -X POST https://manager.example.com/api/machine/register-backend \
-H "Authorization: Bearer $MACHINE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Backend Service",
"callbackUrl": "https://backend.example.com/triggers/callback"
}'Health Check Integration
Use the check endpoint for health monitoring:
// Health check endpoint
app.get("/health", async (req, res) => {
try {
const response = await fetch(
"https://manager.example.com/api/machine/check",
{
headers: {
Authorization: `Bearer ${process.env.MACHINE_TOKEN}`,
},
}
);
if (response.ok) {
const data = await response.json();
res.json({
status: "healthy",
authenticated: data.authenticated,
});
} else {
res.status(503).json({ status: "unhealthy" });
}
} catch (error) {
res.status(503).json({
status: "unhealthy",
error: error.message,
});
}
});Best Practices
Error Handling
Always handle errors gracefully:
async function validateMachineUser(username, token) {
try {
const response = await fetch(
"https://manager.example.com/api/validate-machine-user",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, token }),
}
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
return data.valid;
} catch (error) {
console.error("Validation failed:", error);
return false;
}
}Retry Logic
Implement retries for transient failures:
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
def create_session_with_retries():
session = requests.Session()
retry = Retry(
total=3,
backoff_factor=1,
status_forcelist=[500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
return session
# Use the session
session = create_session_with_retries()
response = session.get(
'https://manager.example.com/api/machine/check',
headers={'Authorization': f'Bearer {token}'}
)Timeout Configuration
Set appropriate timeouts:
const response = await fetch("https://manager.example.com/api/machine/check", {
headers: { Authorization: `Bearer ${token}` },
signal: AbortSignal.timeout(5000), // 5 second timeout
});Migration from GraphQL
While the GraphQL API provides comprehensive functionality, REST endpoints are provided for specific use cases:
Use REST when:
- Implementing Proxy authentication
- Simple machine user validation needed
- Backend registration for triggers
- Lightweight health checks
Use GraphQL when:
- Managing complex resources
- Querying related data
- Batch operations
- Type-safe API interactions
API Client Examples
Node.js
class ManagerRestClient {
constructor(baseUrl, token) {
this.baseUrl = baseUrl;
this.token = token;
}
async checkAuth() {
const response = await fetch(`${this.baseUrl}/api/machine/check`, {
headers: { Authorization: `Bearer ${this.token}` },
});
return response.json();
}
async registerBackend(name, callbackUrl, description) {
const response = await fetch(
`${this.baseUrl}/api/machine/register-backend`,
{
method: "POST",
headers: {
Authorization: `Bearer ${this.token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ name, callbackUrl, description }),
}
);
return response.json();
}
}
// Usage
const client = new ManagerRestClient("https://manager.example.com", token);
await client.checkAuth();Python
import requests
class ManagerRestClient:
def __init__(self, base_url, token):
self.base_url = base_url
self.token = token
self.headers = {'Authorization': f'Bearer {token}'}
def check_auth(self):
response = requests.get(
f'{self.base_url}/api/machine/check',
headers=self.headers
)
return response.json()
def register_backend(self, name, callback_url, description=''):
response = requests.post(
f'{self.base_url}/api/machine/register-backend',
headers={**self.headers, 'Content-Type': 'application/json'},
json={
'name': name,
'callbackUrl': callback_url,
'description': description
}
)
return response.json()
# Usage
client = ManagerRestClient('https://manager.example.com', token)
client.check_auth()Go
package main
import (
"bytes"
"encoding/json"
"net/http"
)
type ManagerRestClient struct {
BaseURL string
Token string
Client *http.Client
}
func (c *ManagerRestClient) CheckAuth() (map[string]interface{}, error) {
req, _ := http.NewRequest("GET", c.BaseURL+"/api/machine/check", nil)
req.Header.Set("Authorization", "Bearer "+c.Token)
resp, err := c.Client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
return result, nil
}
func (c *ManagerRestClient) RegisterBackend(name, callbackURL, description string) (map[string]interface{}, error) {
body := map[string]string{
"name": name,
"callbackUrl": callbackURL,
"description": description,
}
jsonBody, _ := json.Marshal(body)
req, _ := http.NewRequest("POST", c.BaseURL+"/api/machine/register-backend", bytes.NewBuffer(jsonBody))
req.Header.Set("Authorization", "Bearer "+c.Token)
req.Header.Set("Content-Type", "application/json")
resp, err := c.Client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
return result, nil
}See Also
- GraphQL API Integration - Primary API for resource management
- Backend Registration - Detailed trigger integration guide
- Machine Users - Service account authentication
- API Reference - Complete API documentation