API Reference
API Reference
The ERPOps API has one public inbound endpoint (the webhook receiver) and a REST API for programmatic access to incidents, connectors, and alerts. API keys are managed in the admin app.
POST /functions/v1/receive-event
The inbound webhook endpoint. Your ERP or middleware POSTs signed integration events to this URL.
Base URL
https://api.erpops.ai/functions/v1/receive-event
Required headers
| Header | Value |
|---|---|
| Content-Type | application/json |
| X-ERPOps-Connector-Id | Your connector UUID (from ERPOps admin) |
| X-ERPOps-Signature | sha256=<hex digest> |
HMAC signature — how to compute
- 1Take the raw request body bytes exactly as they will be sent (do not parse then re-serialize)
- 2Compute HMAC-SHA256 using the connector's secret key (found in ERPOps admin after sign-up)
- 3Hex-encode the digest
- 4Prepend "sha256=" and set as the X-ERPOps-Signature header value
JSON body schema
{
"connector_id": "uuid", // required — must match header
"event_type": "string", // e.g. "integration.failed", "health.degraded"
"timestamp": "ISO-8601", // required — event time in UTC
"severity": "info|warn|error|critical",
"source": "string", // e.g. "PSFT_PAYROLL_BATCH"
"message": "string", // sanitized — no PII
"metadata": { // optional key-value pairs
"exit_code": 1,
"records_processed": 18441,
"records_total": 40000
}
}Code examples
cURL
BODY='{"connector_id":"YOUR_ID","event_type":"integration.failed","timestamp":"2026-04-20T03:00:00Z","severity":"error","source":"PSFT_PAYROLL_BATCH","message":"Exit code 1 at record 18441"}'
SIG=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "YOUR_SECRET" | awk '{print $2}')
curl -X POST https://api.erpops.ai/functions/v1/receive-event \
-H "Content-Type: application/json" \
-H "X-ERPOps-Connector-Id: YOUR_ID" \
-H "X-ERPOps-Signature: sha256=$SIG" \
-d "$BODY"Node.js
import crypto from 'crypto';
const body = JSON.stringify({ connector_id: 'YOUR_ID', event_type: 'integration.failed',
timestamp: new Date().toISOString(), severity: 'error',
source: 'PSFT_PAYROLL_BATCH', message: 'Exit code 1 at record 18441' });
const sig = 'sha256=' + crypto.createHmac('sha256', 'YOUR_SECRET').update(body).digest('hex');
await fetch('https://api.erpops.ai/functions/v1/receive-event', {
method: 'POST',
headers: { 'Content-Type': 'application/json',
'X-ERPOps-Connector-Id': 'YOUR_ID', 'X-ERPOps-Signature': sig },
body,
});Python
import hmac, hashlib, json, requests
from datetime import datetime, timezone
body = json.dumps({"connector_id": "YOUR_ID", "event_type": "integration.failed",
"timestamp": datetime.now(timezone.utc).isoformat(), "severity": "error",
"source": "PSFT_PAYROLL_BATCH", "message": "Exit code 1 at record 18441"})
sig = "sha256=" + hmac.new(b"YOUR_SECRET", body.encode(), hashlib.sha256).hexdigest()
requests.post("https://api.erpops.ai/functions/v1/receive-event",
headers={"Content-Type": "application/json",
"X-ERPOps-Connector-Id": "YOUR_ID", "X-ERPOps-Signature": sig},
data=body)Error codes
| HTTP Status | Meaning & action |
|---|---|
| 401 | Missing or invalid Authorization / HMAC signature |
| 403 | Connector ID not found or does not belong to authenticated tenant |
| 422 | Request body is malformed or missing required fields |
| 429 | Rate limit exceeded — back off and retry after the Retry-After header value |
Rate limits
| Plan | Inbound events | AI queries |
|---|---|---|
| Free | 100 events / day | 100 AI queries / month |
| Professional | 50,000 events / day | 5,000 AI queries / month |
| Enterprise | Unlimited | Unlimited |
Rate-limited responses include a Retry-After header indicating seconds until the limit resets.