A versioned REST API over your workspace. Authenticate with a workspace API token (Settings → Integrations → generate a token) sent as a bearer header:
curl -H "Authorization: Bearer <token>" https://workhubtest.site/api/v1/tasks
Machine-readable spec: /api/v1/openapi.json
(OpenAPI 3.0 — import it into Postman, Insomnia, openapi-generator for SDKs, or Zapier/Make).
· Service status: /status ·
Changelog: /changelog
tasks, projects, contacts, deals (full CRUD);
invoices, members (read-only — confidential HR fields are never returned).
A token is created as read + write or read-only; a read-only token gets 403 insufficient_scope on any write.
Send an Idempotency-Key header on POST to make a retry safe: the same key from the same token within 24 h replays the
first response (Idempotent-Replayed: true) instead of creating a duplicate.
A dependency-free Python client lives in the repository at sdk/python/novuhub_sdk.py (list/get/create/update/delete,
inbound, webhooks, signature verification, rate-limit retries). Any other language: generate one from the OpenAPI spec above.
| Method | Path | What |
|---|---|---|
| GET | /api/v1/<entity>?limit=&offset=&status=&project= | List (paginated, filterable) |
| GET | /api/v1/<entity>/<id> | Fetch one |
| POST | /api/v1/<entity> | Create (JSON body) |
| PATCH | /api/v1/<entity>/<id> | Update fields |
| DEL | /api/v1/<entity>/<id> | Delete |
| POST | /api/v1/inbound | Create a task from an external system ({title, body, source}) |
Register a URL to receive signed JSON when events fire
(task.created, task.updated, task.deleted, and the same for
project.* / contact.*; events:"*" for all).
POST /api/v1/webhooks {"url":"https://you.example/hook","events":"task.created"}
→ returns a "secret" (shown once)
Each delivery includes X-NovuHub-Event and
X-NovuHub-Signature = HMAC-SHA256(body, secret). Verify it before trusting the payload.
GET /api/v1/webhooks ·
DEL /api/v1/webhooks/<id>
Rate limit: 120 requests/minute per token. Responses are JSON; errors carry an error field.