System
The server's version, updates, licence and the words for values (vocabulary).
On this page
Get the version and update status
GET/system
This server's version, update channel and update status.
One resource; there's no collection, updated_since or deletion record. update.status is worked out on each read
against the running version: off when this build can't check (update.can_check false: managed, no
release signing key, or a development build), or when daily checks are off (update_checks false) and there's
no result; else available while the last result is newer than version, up_to_date when it isn't,
unknown before any result. So with daily checks off, a Check now's result still shows. A failed check keeps
the last result and sets update.error. A newer release the licence doesn't cover (it came out after the
licence's updates_until, or refuses its key) is not_covered instead of available, worked out on each read,
so adding a licence that covers it makes it available without a new check. Without a licence (the trial, or
read-only) every release is offered.
curl "$NIFTY_URL/api/v1/system" \
-H "Authorization: Bearer $NIFTY_TOKEN"
Response
200 OK Errors: 401 429
{
"data": {
"version": "1.2.0",
"channel": "stable",
"update_checks": true,
"update_checks_managed": true,
"update_checks_managed_by": "desktop",
"plain_http": true,
"update": {
"status": "up_to_date",
"not_covered_reason": "updates_ended",
"latest_released_on": "2027-12-03",
"can_check": true,
"latest_version": "1.3.0",
"notes_url": "https://example.com",
"checked_at": "2026-10-10T09:30:00Z",
"dismissed": true,
"error": "Couldn’t reach releases.niftyware.io."
}
}
}
Change update settings
PATCH/system
Also PUT /system, the same.
Change the update channel, turn daily checks on or off, or dismiss an update.
Only the fields sent change. A channel other than stable or beta, an update_checks that isn't a boolean
(or any update_checks while it's managed), or a dismissed_version that isn't a version like 1.2.3 or
1.2.3-beta.1 (or null) is a 422. Changing channel clears the last result (status unknown); changing it
or turning checks on queues a check.
curl -X PATCH "$NIFTY_URL/api/v1/system" \
-H "Authorization: Bearer $NIFTY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"system":{"channel":"stable","update_checks":true}}'
Request body
| Name | Description |
|---|---|
systemobject | |
system.channelUpdateChannel · optional | stable (the default) gets stable releases; beta gets betas too, and stable releases newer than them. |
system.update_checksboolean · optional | Check daily. |
system.dismissed_versionstring or null · optional | The update the owner has seen; update.dismissed while it's at least latest_version. Null clears it. |
Response
200 OK Errors: 400 401 403 415 422 429
{
"data": {
"version": "1.2.0",
"channel": "stable",
"update_checks": true,
"update_checks_managed": true,
"update_checks_managed_by": "desktop",
"plain_http": true,
"update": {
"status": "up_to_date",
"not_covered_reason": "updates_ended",
"latest_released_on": "2027-12-03",
"can_check": true,
"latest_version": "1.3.0",
"notes_url": "https://example.com",
"checked_at": "2026-10-10T09:30:00Z",
"dismissed": true,
"error": "Couldn’t reach releases.niftyware.io."
}
}
}
Check for an update now
POST/system/update_check
Fetches the channel's signed manifest and answers with the result (a failure is update.error, still a 200).
Works while daily checks are off; a 422 (details.base) when they're managed or update.can_check is false.
Takes no body; ignores Idempotency-Key. Waits up to 30 seconds. Limited to 10 a minute per IP address.
curl -X POST "$NIFTY_URL/api/v1/system/update_check" \
-H "Authorization: Bearer $NIFTY_TOKEN"
Response
200 OK Errors: 401 403 415 422 429
{
"data": {
"version": "1.2.0",
"channel": "stable",
"update_checks": true,
"update_checks_managed": true,
"update_checks_managed_by": "desktop",
"plain_http": true,
"update": {
"status": "up_to_date",
"not_covered_reason": "updates_ended",
"latest_released_on": "2027-12-03",
"can_check": true,
"latest_version": "1.3.0",
"notes_url": "https://example.com",
"checked_at": "2026-10-10T09:30:00Z",
"dismissed": true,
"error": "Couldn’t reach releases.niftyware.io."
}
}
}
Get the licence
GET/licence
The licence, or the free trial, and whether Nifty is read-only.
One resource; there's no collection, updated_since or deletion record. state is licensed when the stored
key is valid, not revoked and covers this version (released on or before its updates_until); else trial
for 14 days from first launch; else read_only. A stored key that doesn't apply keeps its details, with
problem saying why.
curl "$NIFTY_URL/api/v1/licence" \
-H "Authorization: Bearer $NIFTY_TOKEN"
Response
200 OK Errors: 401 429
{
"data": {
"state": "licensed",
"problem": "revoked",
"licensee": {
"name": "Ada Lovelace",
"email": "[email protected]"
},
"key_id": "3F9A-C27B-0E15",
"order_reference": "LS-482913",
"issued_on": "2026-10-10",
"updates_until": "2027-10-10",
"trial_ends_at": "2026-10-10T09:30:00Z",
"trial_days_left": 0,
"released_on": "2026-10-10",
"onboarded": true,
"updated_at": "2026-10-10T09:30:00Z"
}
}
Get the vocabulary
GET/vocabulary
Every fixed list a client shows, with labels.
Types, statuses, labels, colours, icons, appearance choices and upload limits, so a client needn't hard-code them. Every list is in display order. Not paginated; it changes only with a server release.
curl "$NIFTY_URL/api/v1/vocabulary" \
-H "Authorization: Bearer $NIFTY_TOKEN"
Response
200 OK Errors: 401 429
{
"data": {
"relationships": [
{
"key": "spouse",
"label": "direct report",
"group": "family"
}
],
"person_links": [
{
"key": "spouse",
"label": "parent",
"group": "family",
"inverse_key": "spouse",
"inverse_label": "child",
"symmetric": true,
"synonyms": [
"mother",
"father",
"mum",
"mom",
"dad"
]
}
],
"key_date_kinds": [
{
"key": "birthday",
"label": "Work anniversary",
"icon": "cake"
}
],
"social_platforms": [
{
"key": "website",
"label": "LinkedIn"
}
],
"relationship_groups": [
{
"key": "family",
"label": "Family",
"icon": "house"
}
],
"contact_labels": {
"email_addresses": {
"suggestions": [
"Personal",
"Work",
"Other"
],
"default": "string"
},
"phone_numbers": {
"suggestions": [
"Personal",
"Work",
"Other"
],
"default": "string"
},
"social_profiles": {
"suggestions": [
"Personal",
"Work",
"Other"
],
"default": "string"
}
},
"project_statuses": [
{
"key": "planned",
"label": "On hold",
"icon": "circle-pause",
"tone": "neutral",
"open": true
}
],
"task_count_kinds": [
{
"key": "open",
"label": "Won’t do",
"icon": "circle-slash"
}
],
"colors": [
{
"key": "teal",
"label": "Teal"
}
],
"picker_icons": [
"folder"
],
"accents": [
{
"key": "iris",
"label": "Iris"
}
],
"themes": [
{
"key": "system",
"label": "Match device"
}
],
"code_themes": [
{
"key": "match",
"label": "Match theme"
}
],
"ai_provider_kinds": [
{
"key": "openai_compatible",
"label": "OpenAI-compatible"
}
],
"uploads": {
"avatar": {
"content_types": [
"image/jpeg",
"image/png"
],
"max_bytes": 10485760
},
"note_image": {
"content_types": [
"image/jpeg",
"image/png"
],
"max_bytes": 10485760
},
"document": {
"content_types": [
"image/jpeg",
"image/png"
],
"max_bytes": 10485760
}
},
"calendar_sync_frequencies": [
{
"key": "30_minutes",
"label": "30 minutes",
"minutes": 30
}
],
"meeting_providers": [
{
"key": "google_meet",
"label": "Google Meet"
}
],
"calendar_sync_errors": [
{
"key": "not_found",
"label": "the server refused the address"
}
],
"document_link_kinds": [
{
"key": "person",
"label": "Person"
}
],
"calendar_sources": [
{
"key": "google",
"label": "Google Calendar",
"url": "https://calendar.google.com/"
}
],
"limits": {
"tag_name": 50,
"folder_name": 100,
"document_name": 200,
"task_title": 200,
"task_list_name": 100,
"project_name": 100,
"project_text": 100,
"project_url": 2048,
"project_member_role": 100,
"position_title": 100,
"company_name": 100,
"calendar_feed_name": 100,
"calendar_address": 2048
}
}
}
Get open source licences
GET/licences
The open source software in this build, with its licences.
The notices distributed with Nifty, grouped by where the software is used. Each package names its licence
text by licence_id in licences, so a shared text appears once. Not paginated; it changes only with a
server release.
curl "$NIFTY_URL/api/v1/licences" \
-H "Authorization: Bearer $NIFTY_TOKEN"
Response
200 OK Errors: 401 429
{
"data": {
"groups": [
{
"key": "web",
"label": "string",
"packages": [
{
"name": "string",
"version": "string",
"licence": "string",
"url": "string",
"licence_id": "string"
}
]
}
],
"licences": [
{
"id": "string",
"text": "string"
}
]
}
}
Identify a Nifty install
GET/.well-known/nifty
Unauthenticated. Reveals nothing about the owner.
curl "$NIFTY_URL/api/v1/.well-known/nifty" \
-H "Authorization: Bearer $NIFTY_TOKEN"
Response
200 OK
{
"app": "nifty",
"version": "1.2.3",
"min_shell_version": "0.0.0",
"api_versions": [
{
"version": "v1",
"base_url": "https://example.com"
}
]
}