NyblitDevelopers

Beta

Build on Nyblit

The Nyblit API lets you read and manage your Tasks from scripts, automations and your own apps. It is a JSON REST API authenticated with personal access tokens.

Quickstart

  1. In Nyblit, open My account → API Access and create a token. Pick only the scopes you need. Copy it — it is shown once. Get a token
  2. Check it works:
curl https://api.nyblit.app/v1/me \
  -H "Authorization: Bearer nyb_pat_…"
  1. List what is on your Today tab (Disposition key in_progress):
curl "https://api.nyblit.app/v1/tasks?disposition=in_progress&limit=20" \
  -H "Authorization: Bearer nyb_pat_…"
  1. Add a task to Today (needs the tasks:write scope):
curl https://api.nyblit.app/v1/tasks \
  -H "Authorization: Bearer nyb_pat_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7c1e9a52-3f0b-4d1e-9b8a-2f6d5c4e3a10" \
  -d '{"title": "Call the bank", "disposition": "in_progress"}'

Tab labels are customisable, so the API always uses the fixed Disposition keys: not_started, in_progress, waiting, on_hold, done.

Authentication and scopes

Send your token in the Authorization header on every request. Tokens in the URL are rejected, because URLs end up in logs. Treat a token like a password: anyone holding it can act as you within its scopes.

  • Tokens always expire. You choose how long when you create one.
  • Revoke a token at any time in My account → API Access; it stops working immediately.
  • Tokens start with nyb_pat_, so secret scanners can spot leaked ones.
  • A token can do what you can do in Nyblit, to your own data. It can't change account security settings or create other tokens.
  • GET /me works with any token and needs no scope. Use it to check a token.
ScopeAllows
tasks:readRead your tasks.
tasks:writeCreate, update and delete your tasks.
projects:readRead your projects.
projects:writeCreate, update and delete your projects.
workflows:readRead your Workflows and Statuses.
workflows:writeCreate, update and delete your Workflows and Statuses.
webhooks:manageManage webhook subscriptions.

During the beta you can read your tasks (with their steps), projects, workflows, statuses and dispositions; create, change, complete, archive and delete tasks; tick, time, add and remove their steps; and create, change and delete projects, workflows and statuses. Webhooks follow.

Making changes

Changes made through the API follow the same rules as the app and sync to every device the account uses.

  • Setting a status_id also sets the task's Workflow and Disposition. Changing workflow_id moves the task to that Workflow's first Status for its Disposition. Changing disposition on its own clears the Status.
  • on_hold_until only applies in Later (on_hold): at that time the task wakes back onto Today. POST /tasks/{id}/later is a shortcut.
  • PATCH changes only the fields you send; send null to clear one.
  • Steps come from the task's Workflow (kind: "status") or, with no Workflow, its own checklist (kind: "subtask"). Tick one with PATCH /tasks/{id}/steps/{step_id} and {"completed": true}; on Today that moves the task on to its next open step. Step minutes add up to the task's time.
  • POST /workflows can create a Workflow and its Statuses in one call. Its Today (in_progress) Statuses become the steps of tasks on it; Not Started has no Statuses. Changing a Status's disposition moves its tasks with it.
  • Deleting a project, Workflow or Status never deletes tasks — they keep their Disposition and just lose it.

Avoiding lost updates

Every task, project, Workflow and Status has a version, also sent as the ETag header. Send it back in If-Match on PATCH, DELETE or an action. If it changed in the meantime (for example in the app), you get 412 precondition_failed with the current ETag — fetch it again, re-apply your change and retry.

curl -X PATCH https://api.nyblit.app/v1/tasks/{id} \
  -H "Authorization: Bearer nyb_pat_…" \
  -H "Content-Type: application/json" \
  -H 'If-Match: "10381"' \
  -d '{"due_date": "2026-10-02"}'

Safe retries

Send an Idempotency-Key (any unique string, such as a UUID) when creating a task, project, Workflow or Status. If the request times out, retry with the same key: you get what the first attempt created (200 with Idempotent-Replayed: true) instead of a duplicate. Use a new key for each new item.

Pagination

Lists return up to limit items (default 50, maximum 100) plus has_more and next_cursor. Pass next_cursor back as cursor to get the next page. Cursors are opaque — do not build them yourself.

{
  "object": "list",
  "data": [ { "object": "task", "id": "…", "title": "Call the bank", … } ],
  "has_more": true,
  "next_cursor": "WyIyMDI2LTA5LTI5…"
}

Unknown query parameters are rejected with 400, so a typo never silently returns everything.

Errors

Errors use RFC 9457 problem details (application/problem+json). Branch on code; show title to people; quote request_id when you contact us.

{
  "type": "https://developers.nyblit.app/errors/insufficient_scope",
  "title": "Token is missing a required scope",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "This endpoint needs the `tasks:read` scope.",
  "request_id": "5f0c…"
}
CodeStatusMeaning
invalid_request400A parameter is missing, malformed or unknown. See errors[].
invalid_token401The token is missing, wrong, expired or revoked.
insufficient_scope403The token works but lacks the scope this endpoint needs.
plan_required403The account’s plan does not include API Access.
access_disabled403Nyblit has turned off API access for this account. Contact support.
task_limit_reached403The account’s plan allows no more active tasks. Complete or archive some first.
not_found404No such endpoint or resource (or it belongs to someone else).
precondition_failed412If-Match did not match: the resource changed since you read it. The body holds the current version.
rate_limited429Too many requests. Wait Retry-After seconds.
internal_error500Our fault. Retry with backoff and quote request_id if it persists.
api_disabled503The API is temporarily switched off. Retry later.

Rate limits

Limits apply per token, per account and (for writes) per day. Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds). When you hit a limit you get 429 with Retry-After — wait that long, then retry. Limits can change, so read the headers rather than hard-coding numbers.

Versioning

The major version is in the URL (/v1). We add fields and endpoints without notice, so ignore fields you do not recognise. Breaking changes ship as a new version, announced in advance with Deprecation and Sunset headers.