Account
Who's signed in, and how the app looks. The password, username, authenticators and API tokens are managed only in the web UI.
On this page
Get the owner and token
GET/me
The owner and the token making the request.
A smoke test for a client and its token. token is null under session auth.
curl "$NIFTY_URL/api/v1/me" \
-H "Authorization: Bearer $NIFTY_TOKEN"
Response
200 OK Errors: 401 429
{
"data": {
"person_id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
"name": "Adam Cooke",
"username": "adam",
"has_password": true,
"welcomed": true,
"time_zone": "London",
"time_zone_iana": "Europe/London",
"today": "2026-10-10",
"token": {
"id": 1,
"name": "Shortcuts on my phone",
"scope": "full",
"created_at": "2026-10-10T09:30:00Z",
"expires_at": "2026-10-10T09:30:00Z",
"last_used_at": "2026-10-10T09:30:00Z"
},
"csrf_token": "string",
"two_factor": true,
"password_sign_in": true
}
}
Get the appearance
GET/appearance
The owner's accent colour and theme.
What the web UI looks like, so an app can match it. One resource; there's no collection.
curl "$NIFTY_URL/api/v1/appearance" \
-H "Authorization: Bearer $NIFTY_TOKEN"
Response
200 OK Errors: 401 429
{
"data": {
"accent": "iris",
"theme": "system",
"code_theme": "match",
"text_size": "small",
"updated_at": "2026-10-10T09:30:00Z"
}
}
Change the appearance
PATCH/appearance
Change the accent colour or theme.
Only the fields sent change. The web UI picks the change up on its next page.
curl -X PATCH "$NIFTY_URL/api/v1/appearance" \
-H "Authorization: Bearer $NIFTY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"appearance":{"accent":"jade","theme":"dark"}}'
Request body
| Name | Description |
|---|---|
appearanceobject | |
appearance.accentAccent · optional | The accent colour. Iris is the default. |
appearance.themeTheme · optional | system follows the device's light or dark setting. The default. |
appearance.code_themeCodeTheme · optional | Code blocks in notes: match follows the theme (the default); light or dark keeps them in that scheme. |
appearance.text_sizeTextSize · optional | The interface's text size; medium is the default. |
Response
200 OK Errors: 400 401 403 415 422 429
{
"data": {
"accent": "iris",
"theme": "system",
"code_theme": "match",
"text_size": "small",
"updated_at": "2026-10-10T09:30:00Z"
}
}
Get the sounds
GET/sounds
Whether sounds play, and the sound for each event.
Synced, so every device the owner uses plays the same ones. One resource; there's no collection.
curl "$NIFTY_URL/api/v1/sounds" \
-H "Authorization: Bearer $NIFTY_TOKEN"
Response
200 OK Errors: 401 429
{
"data": {
"on": true,
"volume": 10,
"task_completed": "pop_in",
"created": "blip_blip",
"deleted": "knock_away",
"calendar_alert": "arpeggio",
"updated_at": "2026-10-10T09:30:00Z"
}
}
Change the sounds
PATCH/sounds
Turn sounds on or off, set their volume, or choose an event's sound (none silences just that event).
Only the fields sent change.
curl -X PATCH "$NIFTY_URL/api/v1/sounds" \
-H "Authorization: Bearer $NIFTY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"sounds":{"on":true,"task_completed":"sparkle"}}'
Request body
| Name | Description |
|---|---|
soundsobject | |
sounds.onboolean · optional | |
sounds.volumeSoundVolume · optional | How loud every sound plays, as a percentage. 100, the default, is full volume. |
sounds.task_completedTaskCompletedSound · optional | Played when a task is ticked off. tap_trio is the default; none is silent. |
sounds.createdCreatedSound · optional | Played when a task, person or project is created. blip_blip is the default; none is silent. |
sounds.deletedDeletedSound · optional | Played when something is deleted, removed, revoked or disconnected. paper_away is the default; none is silent. |
sounds.calendar_alertCalendarAlertSound · optional | For calendar alerts. music_box is the default; none is silent. |
Response
200 OK Errors: 400 401 403 415 422 429
{
"data": {
"on": true,
"volume": 10,
"task_completed": "pop_in",
"created": "blip_blip",
"deleted": "knock_away",
"calendar_alert": "arpeggio",
"updated_at": "2026-10-10T09:30:00Z"
}
}
Get the view choices
GET/views
How the owner has arranged the app's views: orders and sorts, open sections, Wide text, the Calendar's view and the calendars it hides.
Synced, so every device the owner uses shows the same. One resource; there's no collection.
curl "$NIFTY_URL/api/v1/views" \
-H "Authorization: Bearer $NIFTY_TOKEN"
Response
200 OK Errors: 401 429
{
"data": {
"wide_text": true,
"projects_order": "deadline",
"people_arrange": "az",
"people_show": "all",
"calendar_view": "day",
"hidden_calendars": [
"nifty"
],
"places": {}
}
}
Change the view choices
PATCH/views
Only the fields sent change, and in places only the places and fields sent. null puts a choice back to
its default; a place whose choices are all defaults is left out of places.
A value not in its list, a place key not in one of the forms ViewPlace lists, or a choice the place doesn't
offer is a 422 on that field: places[<place>] or places[<place>].task_order.
curl -X PATCH "$NIFTY_URL/api/v1/views" \
-H "Authorization: Bearer $NIFTY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"views":{"wide_text":true,"places":{"today":{"task_order":"start"},"inbox":{"completed_open":null}}}}'
Request body
| Name | Description |
|---|---|
viewsobject | |
views.wide_textboolean or null · optional | |
views.projects_orderProjectsOrder or null · optional | How Projects orders its sections: by deadline (the default), name, or newest first by when each was created or its latest activity. |
views.people_arrangePeopleArrange or null · optional | How People lays out faces: A to Z (az, the default) or under how they relate to you (groups). |
views.people_showPeopleShow or null · optional | Which of People's groups shows: all (the default), a relationship_groups key from the vocabulary, or others, everyone in none. |
views.calendar_viewCalendarView or null · optional | The view the Calendar opens in: day (the default) or week. |
views.hidden_calendarsstring[] or null · optional | The whole set (as HiddenCalendars), replacing the last; one sent twice counts once. Null hides none. |
views.placesobject · optional | The places that change, by key (ViewPlace). A place set to null goes back to its defaults. |
Response
200 OK Errors: 400 401 403 415 422 429
{
"data": {
"wide_text": true,
"projects_order": "deadline",
"people_arrange": "az",
"people_show": "all",
"calendar_view": "day",
"hidden_calendars": [
"nifty"
],
"places": {}
}
}
Bring in a device's view choices
POST/views/import
The same body as PATCH /views, but each choice is taken only where the owner's is still the default, so
it never replaces one. The web UI sends the choices a browser kept itself before they were synced, once.
A new place whose list, person, project or folder no longer exists is left out, and so are new places past
the 2,000 kept (in key order), rather than refusing the rest.
curl -X POST "$NIFTY_URL/api/v1/views/import" \
-H "Authorization: Bearer $NIFTY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"views":{"wide_text":true,"places":{"today":{"task_order":"start"},"inbox":{"completed_open":null}}}}'
Request body
| Name | Description |
|---|---|
viewsobject | |
views.wide_textboolean or null · optional | |
views.projects_orderProjectsOrder or null · optional | How Projects orders its sections: by deadline (the default), name, or newest first by when each was created or its latest activity. |
views.people_arrangePeopleArrange or null · optional | How People lays out faces: A to Z (az, the default) or under how they relate to you (groups). |
views.people_showPeopleShow or null · optional | Which of People's groups shows: all (the default), a relationship_groups key from the vocabulary, or others, everyone in none. |
views.calendar_viewCalendarView or null · optional | The view the Calendar opens in: day (the default) or week. |
views.hidden_calendarsstring[] or null · optional | The whole set (as HiddenCalendars), replacing the last; one sent twice counts once. Null hides none. |
views.placesobject · optional | The places that change, by key (ViewPlace). A place set to null goes back to its defaults. |
Response
200 OK Errors: 400 401 403 415 422 429
{
"data": {
"wide_text": true,
"projects_order": "deadline",
"people_arrange": "az",
"people_show": "all",
"calendar_view": "day",
"hidden_calendars": [
"nifty"
],
"places": {}
}
}