Serbices Documentation
Technical documentation for Serbices execution layer
Core Concepts
Execution
An Execution represents one attempt to perform an HTTP request or event emission. Each Execution has:
- A unique Execution ID
- A type (sync, async, or queued)
- A lifecycle with distinct states
- Timestamps for each state transition
- Status information
- Request payload
- Response payload (or error)
Execution Lifecycle
Execution Types
Synchronous Execution
The caller waits for the execution result. Serbices executes immediately and the HTTP response contains the execution result.
Typical use cases:
- User-facing requests
- Read operations
- APIs that require immediate confirmation
Asynchronous Execution
The caller receives an immediate acknowledgement. Execution continues in background. Result is stored and optionally sent via callback.
Typical use cases:
- Non-critical notifications
- Fire-and-forget integrations
- Background processing
Queued Execution
The execution is placed in a queue and executed later by workers. Used to control concurrency and ordering.
Typical use cases:
- Rate-limited APIs
- Sequential processing requirements
- Controlled concurrency
Worker Execution
Internal synchronous execution triggered by a queued task. The worker always calls Serbices in sync.
Typical use cases:
- Executing queued tasks immediately with a final response
- Infrastructure-only flows (serbices-worker)
Queues
Queues in Serbices are execution constraints, not infrastructure. They control how executions are processed.
Serial Queues
One execution at a time, guaranteed ordering
Parallel Queues
Limited concurrency, controlled throughput
Queues are typically defined by integration, connection, external system, or any logical grouping (e.g., moduleSetupId).
Why Queues Exist
- To protect external systems from overload
- To avoid internal resource exhaustion
- To guarantee execution order when required
Callback
A callback is an optional HTTP request triggered after the main execution completes. Callbacks are independent and do not affect the main execution status.
Callbacks are defined as:
callback.onSuccess- Executed when the execution ends as completedcallback.onError- Executed when the execution ends as failed
Payload rules:
- The user-defined callback body is used as the base
- Serbices injects a
serbicesblock with execution context - The original execution payload is not re-sent automatically
- No retries or queueing in this phase
Important: Callback failure does NOT affect the original execution result.
Serbices adds these headers if they are not defined by the caller:
- X-Serbices-Execution-Id
- X-Serbices-Execution-Status
- X-Serbices-Mode
- X-Serbices-Response-Status
Execution ID & Correlation ID
Execution ID
Uniquely identifies a single execution
Correlation ID
Groups multiple related executions
Correlation IDs are used to:
- Trace business flows across multiple executions
- Group retries and related operations
- Audit integrations at a business level
Execution Flows
Synchronous Flow
Caller → Serbices → Target System
↓
Serbices → Caller (with response)The caller waits for the complete execution before receiving a response.
Asynchronous Flow
Caller → Serbices (immediate ack)
↓
Serbices → Target System
↓
Serbices → (optional callback)The caller receives immediate acknowledgement and optionally gets notified via callback.
Queued Flow
Caller → Serbices (queued)
↓
Serbices → Queue
↓
Worker → Target System
↓
Worker → (optional callback)Execution is queued and processed by workers according to queue constraints.
API Reference
Create Execution
/executionsCreates a new execution request. The request body specifies how and where the execution should be performed.
{
"type": "sync | async | queued",
"queue": "optional-queue-name",
"request": {
"method": "POST",
"url": "https://external.api.com/resource",
"headers": {
"Authorization": "Bearer token"
},
"body": {
"example": "data"
},
"timeout_ms": 30000
},
"callback": {
"url": "https://client.app/callback",
"method": "POST",
"headers": {
"Authorization": "Bearer callback-token"
}
},
"correlation_id": "order-12345"
}Field Descriptions
typeExecution type: sync,async, orqueued
queueOptional queue name. Required for queued executions. Defines execution constraints.
requestThe HTTP request to execute. Contains method, URL, headers, body, and timeout.
callbackOptional callback configuration. Serbices will POST execution results to this endpoint.
correlation_idOptional correlation ID for grouping related executions.
Response
For synchronous executions:
{
"execution_id": "exec_abc123",
"status": "completed",
"response": {
"status_code": 200,
"headers": { ... },
"body": { ... }
},
"timestamps": {
"created_at": "2026-01-13T10:00:00Z",
"started_at": "2026-01-13T10:00:00Z",
"completed_at": "2026-01-13T10:00:02Z"
}
}For asynchronous or queued executions:
{
"execution_id": "exec_abc123",
"status": "queued",
"timestamps": {
"created_at": "2026-01-13T10:00:00Z"
}
}Get Execution
/executions/:execution_idRetrieves the full execution record by execution ID.
{
"execution_id": "exec_abc123",
"type": "async",
"queue": "user-notifications",
"status": "completed",
"correlation_id": "order-12345",
"request": {
"method": "POST",
"url": "https://external.api.com/notify",
"headers": { ... },
"body": { ... }
},
"response": {
"status_code": 200,
"headers": { ... },
"body": { ... }
},
"timestamps": {
"created_at": "2026-01-13T10:00:00Z",
"started_at": "2026-01-13T10:00:01Z",
"completed_at": "2026-01-13T10:00:03Z"
}
}Observability
Every execution is stored with complete traceability:
- Full request and response payloads
- Timestamps for each lifecycle transition
- Error details and stack traces
- Correlation IDs for related executions
Query executions by:
- Execution ID
- Correlation ID
- Status
- Queue name
- Time range
Use Cases
Scenario 1: Legacy PHP system calling a fragile third-party API
Problem: PHP monolith needs to call an external API that has strict rate limits (max 10 requests/second). The API breaks if you send too many requests at once.
Solution: The PHP system sends executions to Serbices with type: "queued" and a queue configured for 10 req/s. Serbices handles rate limiting automatically.
Scenario 2: Async notifications from a sync-only service
Problem: A legacy service needs to send notifications after processing an order, but it is synchronous and cannot implement async patterns.
Solution: The service sends an async execution to Serbices and immediately returns. Serbices handles the notification in the background.
Scenario 3: Audit all integration calls
Problem: Company needs to audit all outbound HTTP calls for compliance. Currently, calls are scattered across dozens of services.
Solution: Route all integration traffic through Serbices. Every execution is stored with full traceability, making audits simple.
When to Use Serbices
When to use
- You need to control concurrency or rate limiting for external APIs
- You need async execution but your system is synchronous
- You need full traceability of outbound HTTP requests
- You want to centralize integration logic
- You need guaranteed ordering of requests
When NOT to use
- Event streaming or pub/sub patterns (use Kafka, RabbitMQ)
- Complex multi-step business workflows (use a workflow engine)
- Scheduled recurring jobs (use cron or a scheduler)
- Internal service-to-service calls with no constraints