API Reference
Sevro's Connect-RPC API for managing modules, records, connections, webhooks, and workflows.
Sevro exposes a Connect-RPC API. Connect-RPC is gRPC-compatible but works over HTTP/1.1 + JSON, so you can call it with curl or any HTTP client — no special tooling required.
Authentication
All API calls require a Bearer token in the Authorization header:
Authorization: Bearer ply_<your-api-key>API keys are created with sevro bootstrap (first key) or the AuthService.CreateAPIKey RPC (subsequent keys).
Base URL
The API is served at the root of the Sevro server. RPC endpoints follow the Connect-RPC convention:
POST /<package>.<Service>/<Method>For example:
POST /platform.v1.PlatformService/CreateModule
POST /platform.v1.PlatformService/ListRecords
POST /auth.v1.AuthService/CreateAPIKeyContent types
Connect-RPC supports two wire formats:
- JSON (
Content-Type: application/json) — human-readable, use forcurl - Protobuf (
Content-Type: application/proto) — binary, smaller, faster
All examples below use JSON.
PlatformService
Design
CreateModule
curl -X POST http://localhost:8080/platform.v1.PlatformService/CreateModule \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{
"name": "todo",
"entities": [{
"ref": "todo",
"label": "Todo",
"attributes": [
{"ref": "description", "label": "Description", "type": "string", "isRequired": true}
],
"methods": [{
"ref": "new",
"label": "New",
"isConstructor": true,
"parameters": [
{"ref": "description", "label": "Description", "type": "string", "isRequired": true}
],
"actions": [
{"target": "description", "expression": "params.description"}
]
}]
}]
}'Response: {"id": "module-uuid"}
UpdateModule
curl -X POST http://localhost:8080/platform.v1.PlatformService/UpdateModule \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{"id": "module-uuid", "name": "todo", "entities": [...], "workflows": [...]}'GetModule
curl -X POST http://localhost:8080/platform.v1.PlatformService/GetModule \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{"id": "module-uuid"}'ListModules
curl -X POST http://localhost:8080/platform.v1.PlatformService/ListModules \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{"pageSize": 100}'DeleteModule
curl -X POST http://localhost:8080/platform.v1.PlatformService/DeleteModule \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{"id": "module-uuid"}'Runtime
ExecuteMethod
Execute a method on a record (or create via constructor).
# Create a todo (constructor)
curl -X POST http://localhost:8080/platform.v1.PlatformService/ExecuteMethod \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{
"moduleId": "module-uuid",
"entityRef": "todo",
"methodRef": "new",
"arguments": {
"description": "Buy groceries"
}
}'
# Complete a todo (non-constructor — requires recordId)
curl -X POST http://localhost:8080/platform.v1.PlatformService/ExecuteMethod \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{
"moduleId": "module-uuid",
"entityRef": "todo",
"methodRef": "complete",
"recordId": "record-uuid"
}'Response: {"recordId": "record-uuid"}
GetRecord
curl -X POST http://localhost:8080/platform.v1.PlatformService/GetRecord \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{"id": "record-uuid", "moduleId": "module-uuid", "entityRef": "todo"}'Use expand to resolve reference fields:
{
"id": "record-uuid",
"moduleId": "...",
"entityRef": "project",
"expand": "owner_id,tasks"
}ListRecords
curl -X POST http://localhost:8080/platform.v1.PlatformService/ListRecords \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{
"moduleId": "module-uuid",
"entityRef": "todo",
"filter": "record.completed == false",
"pageSize": 50
}'The filter field accepts a CEL expression evaluated against each record. The expand field resolves references (same as GetRecord).
DeleteRecord
curl -X POST http://localhost:8080/platform.v1.PlatformService/DeleteRecord \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{"id": "record-uuid"}'GetRecordHistory
Retrieve the audit trail for a record.
curl -X POST http://localhost:8080/platform.v1.PlatformService/GetRecordHistory \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{"recordId": "record-uuid", "pageSize": 50}'Workflows
ExecuteWorkflow
curl -X POST http://localhost:8080/platform.v1.PlatformService/ExecuteWorkflow \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{
"moduleId": "module-uuid",
"workflowRef": "notify_created",
"input": {
"todo_id": "record-uuid"
}
}'Response: {"executionId": "...", "status": "completed", "output": {...}}
GetWorkflowStatus
curl -X POST http://localhost:8080/platform.v1.PlatformService/GetWorkflowStatus \
-H "Authorization: Bearer ply_..." \
-H "Content-Type: application/json" \
-d '{"executionId": "execution-uuid"}'Connections
| RPC | Description |
|---|---|
CreateConnection | Create a named external service connection with credentials |
UpdateConnection | Update connection config and credentials |
DeleteConnection | Delete a connection |
GetConnection | Get connection metadata (credentials are never returned) |
ListConnections | List all connections |
TestConnection | Test that a connection's credentials are valid |
Webhooks (outbound)
| RPC | Description |
|---|---|
CreateWebhook | Register an outbound webhook for entity events |
UpdateWebhook | Update webhook URL, events, or active status |
DeleteWebhook | Delete a webhook |
GetWebhook | Get webhook details |
ListWebhooks | List all webhooks |
ListWebhookDeliveries | List delivery attempts for a webhook |
Inbound webhooks
| RPC | Description |
|---|---|
CreateInboundWebhook | Register an inbound webhook that maps external POST → method execution |
UpdateInboundWebhook | Update transform expression or active status |
DeleteInboundWebhook | Delete an inbound webhook |
GetInboundWebhook | Get inbound webhook details (secret is not returned) |
ListInboundWebhooks | List all inbound webhooks |
Inbound webhooks also have a dedicated HTTP endpoint:
POST /hooks/{webhookID}This endpoint receives raw POST requests from external services. It verifies the HMAC-SHA256 signature (via X-Sevro-Signature, X-Hub-Signature-256, or X-Webhook-Signature header), evaluates the CEL transform expression against the parsed JSON body, and executes the configured method. No Bearer token required — auth is via the webhook secret.
Example transform:
transform: "{'description': body.event_text, 'source': 'webhook'}"The body variable is the parsed JSON payload from the incoming request. The transform must return a map[string]any of method arguments.
AuthService
| RPC | Description |
|---|---|
CreateAPIKey | Create a new API key (returns raw token once) |
RevokeAPIKey | Revoke an API key by ID |
ListAPIKeys | List all API keys (tokens are never returned) |
CreatePolicy | Create an authorization policy (CEL expression) |
UpdatePolicy | Update a policy's expression |
DeletePolicy | Delete a policy |
AssignPolicy | Assign a policy to a role, method, or entity |
UnassignPolicy | Remove a policy assignment |
ListPolicies | List all policies |
ListPolicyAssignments | List policy assignments |
Error handling
Errors follow the Connect-RPC error format with structured details:
{
"code": "invalid_argument",
"message": "validation failed",
"details": [
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{ "field": "name", "description": "must not be empty" },
{
"field": "entities[0].attributes[1].type",
"description": "must be one of [string, number, boolean, date, datetime, enum, reference]"
}
]
}
]
}Error codes
| Code | HTTP Status | Meaning |
|---|---|---|
invalid_argument | 400 | Input validation failed |
not_found | 404 | Resource not found |
already_exists | 409 | Duplicate resource |
unauthenticated | 401 | Missing or invalid API key |
permission_denied | 403 | Authenticated but not allowed |
internal | 500 | Server error (message is generic) |
Calling from TypeScript
See the TypeScript integration guide for using @connectrpc/connect-web to call the API with full type safety.