Developers

The Staffvelo API and webhooks

Read and add people, request time off, run reports and get every event as a signed webhook — the same rules as the app.

Keys

An admin makes an API key in Settings → API & webhooks: read only, or read and write. A key acts as the admin who made it, so every change goes through the same checks, notifications, workflows and audit log as the app. Only a fingerprint of the key is stored — copy it when it's shown.

curl https://staffvelo.com/api/v1/me   -H "Authorization: Bearer sv_api_…"

Requests and answers are JSON. Errors are { "error": "…" } in plain words, with the usual status codes. Each key may make 600 requests every 10 minutes (then 429).

Endpoints

Base address: https://staffvelo.com/api/v1 (your workspace address works too).

MethodPathWhat it does
GET/meThe workspace and the key's access
GET/eventsThe events you can subscribe to
GET/people?limit&status&emailPeople, newest first (active, left or all) — no pay or ID fields
GET/people/{id}One person
POST/peopleAdd a person: name, email, job_title, department, start_date, send_invite
GET/time-off?status&from&to&limitTime off, newest first
POST/time-offRequest time off: employee_email (or employee_id), type, from, to, note
GET/reports/fieldsWhat Custom reports can show
POST/reports/runRun a report: source, columns, filters, group_by, sort
GET/webhooksYour webhooks
POST/webhooksSubscribe: url (https), event or events — the answer has the signing secret
DELETE/webhooks/{id}Unsubscribe
curl -X POST https://staffvelo.com/api/v1/time-off   -H "Authorization: Bearer sv_api_…" -H "Content-Type: application/json"   -d '{"employee_email":"arta@acme.com","type":"Holiday","from":"2026-12-22","to":"2026-12-31"}'

Webhooks

Add a webhook in Settings or with POST /webhooks. Staffvelo POSTs each event you chose as JSON, from the moment it happens:

{ "id": "8f1c…", "event": "timeoff.approved", "occurred_at": "2026-11-02T09:15:00Z",
  "workspace": { "slug": "acme", "name": "Acme" },
  "data": { "person": { "name": "Arta Berisha", "email": "…", "dept": "Engineering" },
            "manager": { "name": "Amara Okafor" },
            "timeoff": { "type": "Holiday", "from": "2026-12-22", "to": "2026-12-31", "days": 6 } } }

Events: employee.added, employee.left, timeoff.requested, timeoff.approved, timeoff.declined, expense.submitted, card.created, card.moved, request.created — and workflow.webhook from a workflow's “Send to a webhook” step.

Check that it really came from Staffvelo: the X-Staffvelo-Signature header is sha256= and the HMAC-SHA256 of the raw body with your webhook's secret.

const crypto = require("crypto");
const expected = "sha256=" + crypto.createHmac("sha256", process.env.STAFFVELO_WEBHOOK_SECRET).update(rawBody).digest("hex");
const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-staffvelo-signature"] || ""));

Answer with any 2xx within 8 seconds. Only public https addresses can receive webhooks; after 20 failures in a row a webhook switches itself off and admins see why.

AI tools (MCP)

Staffvelo is also an MCP server at https://<your-workspace>.staffvelo.com/mcp: ChatGPT and claude.ai connect with Sign in with Staffvelo (OAuth 2.1), and Claude Code, Cursor or VS Code with a personal access key. It's read-only and each person's AI sees only what they can see. An admin switches it on in Settings → AI agents.

Try every module free for 14 days

No card, no sales call. Your workspace is live in under a minute.