HTTP API Reference
The ztick HTTP API provides a RESTful interface for managing scheduled jobs and rules. This is an optional interface that runs alongside the native TCP protocol.
OpenAPI Specification
The complete API contract is defined in openapi.json, written in OpenAPI v3.1.1 format. The spec is colocated with the HTTP server that embeds it, and is also served live at GET /openapi.json. You can import it into:
- Swagger Editor — https://editor.swagger.io/ (paste the raw JSON)
- Postman — File → Import → paste
openapi.json - Code generation tools — Generate client SDKs in your language
- API documentation tools — Swagger UI, ReDoc, etc.
Server Configuration
The HTTP API listens on a separate port from the native TCP protocol:
[controller]
listen = "127.0.0.1:5680" # HTTP API port (separate from TCP)Concurrency Model
The HTTP server spawns a dedicated thread per accepted connection, enabling parallel request processing without head-of-line blocking. This concurrency model ( F022):
- Thread-per-connection: Each HTTP request is handled in its own thread, allowing multiple clients to make requests simultaneously
- Atomic connection tracking: An atomic counter tracks active connections, enabling safe shutdown without a global mutex
- Graceful shutdown: On server shutdown, in-flight connections are given up to 5 seconds to complete before the server exits. Any connections that don’t complete within the timeout are forcefully closed
- Throughput scaling: Throughput scales linearly with concurrent clients (tested up to 8 concurrent workers achieving >2000 requests/second)
- Stable latency: Per-request latency remains predictable under concurrent load (p50 latency <5ms at 8 concurrent workers)
Authentication
All API endpoints require Bearer token authentication, configurable via the auth_file:
# Request with token
curl -H "Authorization: Bearer YOUR_TOKEN" http://127.0.0.1:5680/jobsThe /health and /openapi.json endpoints do not require authentication.
Core Endpoints
Jobs (CRUD)
| Method | Endpoint | Purpose |
|---|---|---|
PUT | /jobs/{id} | Create or update a job |
GET | /jobs/{id} | Retrieve a specific job |
DELETE | /jobs/{id} | Delete a job |
GET | /jobs?prefix=<string> | List jobs matching a prefix |
Example: Create a job
curl -X PUT http://127.0.0.1:5680/jobs/deploy.v1 \
-H "Authorization: Bearer token123" \
-H "Content-Type: application/json" \
-d '{
"execution": "2026-04-10T12:00:00Z"
}'Response:
{
"id": "deploy.v1",
"status": "planned",
"execution": 1744286400000000000
}Rules (CRUD)
| Method | Endpoint | Purpose |
|---|---|---|
PUT | /rules/{id} | Create or update a rule |
DELETE | /rules/{id} | Delete a rule |
GET | /rules?prefix=<string> | List rules matching a prefix |
Example: Create a rule
curl -X PUT http://127.0.0.1:5680/rules/notify-slack \
-H "Authorization: Bearer token123" \
-H "Content-Type: application/json" \
-d '{
"pattern": "deploy.",
"runner": {
"type": "direct",
"executable": "/usr/bin/curl",
"args": ["-X", "POST", "https://hooks.slack.com/..."]
}
}'Health & Discovery
| Endpoint | Purpose | Auth Required |
|---|---|---|
GET /health | Server health check | No |
GET /openapi.json | OpenAPI specification as JSON | No |
Example: Check health
curl http://127.0.0.1:5680/healthResponse:
{
"status": "ok"
}Runner Types
The API supports four runner types for rule execution:
Shell Runner
Execute a shell command (requires shell configured in [shell] section):
{
"type": "shell",
"command": "/usr/bin/notify --channel ops"
}Direct Runner
Execute a binary directly without shell invocation (safer, more predictable):
{
"type": "direct",
"executable": "/usr/bin/curl",
"args": ["-s", "http://example.com/webhook"]
}HTTP Runner
Trigger an external webhook via HTTP/HTTPS request:
{
"type": "http",
"method": "POST",
"url": "https://hooks.example.com/webhook"
}Methods: GET, POST, PUT, DELETE
Behavior:
- POST and PUT requests include a JSON body:
{"job_id":"<identifier>","execution":<timestamp_ns>} - GET and DELETE requests send no body
- HTTP 2xx status codes indicate success; all others indicate failure
- TLS is automatically used for
https://URLs - Connection and read timeouts are 30 seconds
Example: POST with webhook
curl -X PUT http://127.0.0.1:5680/rules/notify-deploy \
-H "Authorization: Bearer token123" \
-H "Content-Type: application/json" \
-d '{
"pattern": "deploy.",
"runner": {
"type": "http",
"method": "POST",
"url": "https://hooks.example.com/webhook"
}
}'Example: GET request
{
"type": "http",
"method": "GET",
"url": "https://api.internal/trigger"
}AWF Runner
Execute an AWF (AI Workflow) via the awf CLI. Useful for automating AI agent pipelines on a schedule:
{
"pattern": "code-review.",
"runner": "awf",
"args": ["code-review"]
}With optional input parameters (key=value pairs passed via --input flags):
{
"pattern": "report.",
"runner": "awf",
"args": ["generate-report", "--input", "format=pdf", "--input", "target=main"]
}Spawns awf run <workflow> (or awf run <workflow> --input key1=value1 --input key2=value2 when inputs are provided). Requires the awf CLI binary in $PATH.
Error Responses
All error responses follow this format:
{
"error": "human-readable error message"
}Common HTTP status codes:
| Status | Scenario |
|---|---|
200 OK | Success |
400 Bad Request | Invalid request body (malformed JSON, missing required fields) |
404 Not Found | Job or rule does not exist |
500 Internal Server Error | Server error |
Timestamp Format
Job execution timestamps are specified as ISO 8601 strings in requests:
{
"execution": "2026-04-10T12:00:00Z"
}In responses, timestamps are represented as nanoseconds since Unix epoch:
{
"execution": 1744286400000000000
}See Also
- TCP Protocol Reference — Native binary protocol
- Data Types — Job, Rule, and Runner structures
- Configuration — Server setup