Developers

Build on Mawro with an open REST API

Workspace API keys with scopes, signed webhooks and 38 documented endpoints for employees, organisation data, attendance, leave and payroll, with JSON responses, predictable errors and an OpenAPI 3.1 file you can import anywhere.

  • Base URLhttps://mawro.neuroskill.tech/api/v1
  • AuthenticationAPI key (Bearer mk_live_…) on /ext; user JWT elsewhere
  • VersioningIn the path: /api/v1
  • Rate limits120 / minute per API key by default; 600 / minute per signed-in user

Quickstart

Your first call in three steps

  1. 1Create an API keyAn administrator opens Settings › Integrations › API keys, names the key, ticks only the scopes it needs (for example "Send attendance punches") and can set an expiry. The key is shown once; Mawro keeps only a hash of it.
  2. 2Call the external APISend the key as Authorization: Bearer mk_live_… to the /ext endpoints. A key never sees more than the person who created it, and every call is audited.
  3. 3Subscribe to webhooksAdd an https endpoint under Settings › Integrations › Webhooks and pick events such as employee.hired or payroll.run_approved. Every delivery is signed, so you can check it came from Mawro.

Responses

One envelope, predictable errors

  • Successful responses return the result under data, with a correlation ID and server timestamp under meta.
  • Errors return a stable key, an HTTP status and field-level details you can show to users.
  • Timestamps are ISO-8601 in UTC. Lists are paged or capped; see each endpoint.
  • Quote the correlation ID (also in the X-Correlation-Id header) when you contact support.
200Success
{
  "data": {
    "rows": [
      {
        "id": "7d1c…",
        "displayName": "Ana Santos",
        "employeeNumber": "EMP-000214"
      }
    ],
    "total": 1,
    "page": 1,
    "pageSize": 25
  },
  "meta": {
    "correlationId": "b6f0c2a4-…",
    "timestamp": "2026-10-18T09:15:02.114Z"
  }
}
422Error
{
  "error": {
    "key": "CFG-001",
    "type": "ERROR",
    "message": "Validation failed.",
    "statusCode": 422,
    "correlationId": "b6f0c2a4-…",
    "timestamp": "2026-10-18T09:15:02.114Z",
    "path": "/api/v1/attendance/punches/batch",
    "details": [
      {
        "field": "events[0].eventAt",
        "key": "CFG-001",
        "message": "Must be an ISO-8601 timestamp.",
        "severity": "ERROR"
      }
    ]
  }
}

Webhooks

Events pushed to your systems, signed

Each delivery is a JSON POST of { id, type, createdAt, data } with X-Mawro-Event, X-Mawro-Delivery, X-Mawro-Timestamp and X-Mawro-Signature headers. A 2xx answer within 10 seconds counts as delivered; otherwise Mawro retries up to 8 times with growing gaps, keeps a delivery log you can redeliver from, and pauses an endpoint after 20 failures in a row. Endpoints must be public https addresses; private and internal addresses are refused.

  • employee.hiredAn employment record became active (direct hire or onboarding go-live).
  • employee.updatedA fact on an employee record was written, or the employment status changed.
  • employee.terminatedAn exit was completed and the employment ended.
  • leave.approvedA leave request was approved.
  • attendance.publishedAn attendance period was locked: its figures are final for payroll.
  • payroll.run_approvedA payroll run was approved.
  • onboarding.completedAn onboarding case was completed.
  • offboarding.completedAn exit case was completed.
Node.jsVerify a delivery
import { createHmac, timingSafeEqual } from 'node:crypto';

// Express: app.post('/hooks/mawro', express.raw({ type: '*/*' }), handler)
function fromMawro(req, secret) {
  const ts = req.get('X-Mawro-Timestamp');
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  const expected = 'v1=' + createHmac('sha256', secret)
    .update(ts + '.' + req.body).digest('hex');
  return req.get('X-Mawro-Signature').split(',').some((s) =>
    s.trim().length === expected.length &&
    timingSafeEqual(Buffer.from(s.trim()), Buffer.from(expected)));
}

The signature is HMAC-SHA256 of "timestamp.body" with your endpoint secret (shown once, and rotatable). During a rotation the header can carry two signatures.

See Mawro running on your own processes

Book a 30-minute walkthrough with our team, or start a free trial and invite your HR team today.