REST API & webhooks
OAuth 2.0, REST endpoints for every resource, 23 HMAC-signed webhook events.
Authorization
We support Authorization Code for user-facing integrations and Client Credentials for backend-to-backend. Tokens are scoped and refreshable.
curl -X POST https://api.pegalio.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "...",
"client_secret": "...",
"scope": "projects:read tasks:write"
}'Base URL
Production: https://api.pegalio.com. Self-host: your own domain. Version header: X-API-Version: 2026-01-01.
Example: create a project
POST /v1/projects
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "Acme Corp Onboarding",
"template_id": "tpl_4phase",
"customer_id": "cust_123",
"go_live_at": "2026-06-01",
"owner_user_id": "usr_456"
}Resources
/v1/tenants— workspaces (Admin only)./v1/users— users and invitations./v1/customers— customer records./v1/projects— projects with all nested resources./v1/phases,/v1/milestones,/v1/tasks/v1/forms,/v1/forms/{id}/responses/v1/templates,/v1/automations/v1/files— presigned upload URLs./v1/audit— the audit log (read-only).
Webhooks
Subscribe in Settings → Webhooks. Specify a URL and events. Every request includes an X-Pegalio-Signature header with HMAC-SHA256.
// Node.js
import crypto from "node:crypto";
const signature = req.headers["x-pegalio-signature"];
const expected = crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(req.rawBody)
.digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).end();
}Every event has an event_id. If your endpoint doesn't return a 2xx within 30 seconds, we retry up to 5 times with exponential backoff. Use event_id to avoid processing the same event twice.
Limits
- Authenticated: 120 req/min per user.
- Batch endpoints: 30 req/min.
- File uploads: 30 per hour.
When you exceed a limit we return 429 with Retry-After, X-RateLimit-Remaining, and X-RateLimit-Reset headers.