Skip to content
Niftyhelp 2026.10.2 Support

Facts

Things you know about a person, such as their children's names or how they take their coffee. Each fact has a fact label (e.g. "Coffee"), shared by everyone; a person's facts follow the labels' order.

On this page

List fact labels

GET/fact_labels

Fact labels, in the owner's order: a person's facts follow it.

curl "$NIFTY_URL/api/v1/fact_labels" \
  -H "Authorization: Bearer $NIFTY_TOKEN"

Query parameters

NameDescription
orderposition | id | name | updated_at · optionalThe field to sort by; ties are broken by id, so the order is stable.
directionasc | desc · optionalasc (ascending) or desc (descending), for order.
updated_sincedate-time · optionalOnly records updated at or after this time (ISO 8601 with Z or a UTC offset), ordered by updated_at, id.
cursorstring · optionalmeta.next_cursor from the previous page.
limitinteger · optionalItems per page, up to 100; a larger number is taken as 100.
counttrue | false · optionaltrue adds meta.total_count: the size of the filtered set (with updated_since too), ignoring cursor and limit. Anything but true or false is a 400.

Response

200 OK Errors: 400 401 429

{
  "data": [
    {
      "id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
      "name": "Coffee",
      "icon": "coffee",
      "position": 1,
      "created_at": "2026-10-10T09:30:00Z",
      "updated_at": "2026-10-10T09:30:00Z"
    }
  ],
  "meta": {
    "next_cursor": "eyJrIjpbIjIwMjYtMTAtMDlUMDg6MzA6MDBaIl19",
    "limit": 1,
    "total_count": 1
  }
}

Add a fact label

POST/fact_labels

Goes last unless position is sent. A name another fact label has, ignoring case and spacing, is a 422.

curl -X POST "$NIFTY_URL/api/v1/fact_labels" \
  -H "Authorization: Bearer $NIFTY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"fact_label":{"name":"Coffee","icon":"coffee"}}'

Headers

NameDescription
Idempotency-Keystring · optionalMakes a POST safe to retry for 24 hours. Needs a bearer token (400 under session auth).

Request body

NameDescription
fact_labelobject
fact_label.namestring · optionalSpaces are squished. Unique ignoring case and spacing.
fact_label.iconstring or null · optionalAn icon from GET /category_choices, or null for none.
fact_label.positioninteger · optional1-based; out-of-range values are clamped. Moves the label there.

Response

201 Created Errors: 400 401 403 409 415 422 429

{
  "data": {
    "id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "name": "Coffee",
    "icon": "coffee",
    "position": 1,
    "created_at": "2026-10-10T09:30:00Z",
    "updated_at": "2026-10-10T09:30:00Z"
  }
}

Get a fact label

GET/fact_labels/{id}

curl "$NIFTY_URL/api/v1/fact_labels/01j9zq3k8m5x2v7c4n6b0t1r9e" \
  -H "Authorization: Bearer $NIFTY_TOKEN"

Path parameters

NameDescription
idULIDA record's ID.

Response

200 OK Errors: 401 404 429

{
  "data": {
    "id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "name": "Coffee",
    "icon": "coffee",
    "position": 1,
    "created_at": "2026-10-10T09:30:00Z",
    "updated_at": "2026-10-10T09:30:00Z"
  }
}

Change or move a fact label

PATCH/fact_labels/{id}

Only the fields sent change. A rename shows on every person's facts, which keep their edited_at and updated_at. A name another fact label has, ignoring case and spacing, is a 422 (name: "already exists"); there's no merge. Sending position moves the label there and renumbers every label 1..n; the others whose position changed get a new updated_at, so re-sync with updated_since after a move.

curl -X PATCH "$NIFTY_URL/api/v1/fact_labels/01j9zq3k8m5x2v7c4n6b0t1r9e" \
  -H "Authorization: Bearer $NIFTY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"fact_label":{"name":"Coffee","icon":"coffee"}}'

Path parameters

NameDescription
idULIDA record's ID.

Request body

NameDescription
fact_labelobject
fact_label.namestring · optionalSpaces are squished. Unique ignoring case and spacing.
fact_label.iconstring or null · optionalAn icon from GET /category_choices, or null for none.
fact_label.positioninteger · optional1-based; out-of-range values are clamped. Moves the label there.

Response

200 OK Errors: 400 401 403 404 415 422 429

{
  "data": {
    "id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "name": "Coffee",
    "icon": "coffee",
    "position": 1,
    "created_at": "2026-10-10T09:30:00Z",
    "updated_at": "2026-10-10T09:30:00Z"
  }
}

Delete a fact label

DELETE/fact_labels/{id}

Permanent, with every fact that has it (GET /fact_label_counts says how many). Writes a fact_label deletion record and a fact one for each of its facts. Other labels keep their positions (gaps are fine).

curl -X DELETE "$NIFTY_URL/api/v1/fact_labels/01j9zq3k8m5x2v7c4n6b0t1r9e" \
  -H "Authorization: Bearer $NIFTY_TOKEN"

Path parameters

NameDescription
idULIDA record's ID.

Response

204 Deleted Errors: 401 403 404 429

Fact counts per fact label

GET/fact_label_counts

How many facts each fact label has, among live people.

Not a record and not paginated: there's nothing to sync, so ask again when facts change. Ordered by fact_label_id; labels with no facts are left out.

curl "$NIFTY_URL/api/v1/fact_label_counts" \
  -H "Authorization: Bearer $NIFTY_TOKEN"

Response

200 OK Errors: 401 429

{
  "data": [
    {
      "fact_label_id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
      "fact_count": 1
    }
  ]
}

List facts

GET/facts

Every live person's facts. With person_id, only that person's (at most one per label), in the order of their fact labels by default. To keep a copy in sync, list them without person_id.

curl "$NIFTY_URL/api/v1/facts" \
  -H "Authorization: Bearer $NIFTY_TOKEN"

Query parameters

NameDescription
person_idULID · optionalOnly this person's facts. An unknown or deleted person's is an empty page.
orderlabel | id | created_at | updated_at · optionalThe field to sort by: label is the fact labels' order. Ties are broken by id, so the order is stable. The default is label with person_id, otherwise id.
directionasc | desc · optionalasc (ascending) or desc (descending), for order.
updated_sincedate-time · optionalOnly records updated at or after this time (ISO 8601 with Z or a UTC offset), ordered by updated_at, id.
cursorstring · optionalmeta.next_cursor from the previous page.
limitinteger · optionalItems per page, up to 100; a larger number is taken as 100.
counttrue | false · optionaltrue adds meta.total_count: the size of the filtered set (with updated_since too), ignoring cursor and limit. Anything but true or false is a 400.

Response

200 OK Errors: 400 401 429

{
  "data": [
    {
      "id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
      "person_id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
      "label_id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
      "text": "Flat white, no sugar",
      "edited_at": "2026-10-10T09:30:00Z",
      "created_at": "2026-10-10T09:30:00Z",
      "updated_at": "2026-10-10T09:30:00Z"
    }
  ],
  "meta": {
    "next_cursor": "eyJrIjpbIjIwMjYtMTAtMDlUMDg6MzA6MDBaIl19",
    "limit": 1,
    "total_count": 1
  }
}

Add a fact

POST/facts

Add a fact to a person, given as person_id (that can be you). Send label_id, or label: a name, found ignoring case and spacing or created last, in the same transaction (a 422 creates neither). Both, or neither, is a 422 on label. A person has at most one fact per label, its text holding everything under it: a label they have a fact under already is a 422 on the field sent ("already has a fact for this person…"). An unknown or deleted person is a 422 on person_id.

curl -X POST "$NIFTY_URL/api/v1/facts" \
  -H "Authorization: Bearer $NIFTY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"fact":{"person_id":"01j9zq3k8m5x2v7c4n6b0t1r9e","label":"Coffee","text":"Flat white, no sugar"}}'

Headers

NameDescription
Idempotency-Keystring · optionalMakes a POST safe to retry for 24 hours. Needs a bearer token (400 under session auth).

Request body

NameDescription
factobject
fact.person_idULID · optionalCreate only, and required there: the person the fact is about.
fact.label_idULID · optionalThe fact label. Send this or label.
fact.labelstring · optionalA fact label's name: found ignoring case and spacing, or created. Send this or label_id.
fact.textstring · optionalPlain text, 1–2,000 characters; may span lines. Leading and trailing space is trimmed.

Response

201 Created Errors: 400 401 403 409 415 422 429

{
  "data": {
    "id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "person_id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "label_id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "text": "Flat white, no sugar",
    "edited_at": "2026-10-10T09:30:00Z",
    "created_at": "2026-10-10T09:30:00Z",
    "updated_at": "2026-10-10T09:30:00Z"
  }
}

Get a fact

GET/facts/{id}

A deleted person's facts are a 404.

curl "$NIFTY_URL/api/v1/facts/01j9zq3k8m5x2v7c4n6b0t1r9e" \
  -H "Authorization: Bearer $NIFTY_TOKEN"

Path parameters

NameDescription
idULIDA record's ID.

Response

200 OK Errors: 401 404 429

{
  "data": {
    "id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "person_id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "label_id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "text": "Flat white, no sugar",
    "edited_at": "2026-10-10T09:30:00Z",
    "created_at": "2026-10-10T09:30:00Z",
    "updated_at": "2026-10-10T09:30:00Z"
  }
}

Change a fact

PATCH/facts/{id}

Only the fields sent change: text, and the label as label_id or label (as on create). A fact can't move to another person, nor onto a label the person has another fact under (a 422, as on create). edited_at changes only when the text or label does.

curl -X PATCH "$NIFTY_URL/api/v1/facts/01j9zq3k8m5x2v7c4n6b0t1r9e" \
  -H "Authorization: Bearer $NIFTY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"fact":{"person_id":"01j9zq3k8m5x2v7c4n6b0t1r9e","label":"Coffee","text":"Flat white, no sugar"}}'

Path parameters

NameDescription
idULIDA record's ID.

Request body

NameDescription
factobject
fact.person_idULID · optionalCreate only, and required there: the person the fact is about.
fact.label_idULID · optionalThe fact label. Send this or label.
fact.labelstring · optionalA fact label's name: found ignoring case and spacing, or created. Send this or label_id.
fact.textstring · optionalPlain text, 1–2,000 characters; may span lines. Leading and trailing space is trimmed.

Response

200 OK Errors: 400 401 403 404 415 422 429

{
  "data": {
    "id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "person_id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "label_id": "01j9zq3k8m5x2v7c4n6b0t1r9e",
    "text": "Flat white, no sugar",
    "edited_at": "2026-10-10T09:30:00Z",
    "created_at": "2026-10-10T09:30:00Z",
    "updated_at": "2026-10-10T09:30:00Z"
  }
}

Delete a fact

DELETE/facts/{id}

Permanent. Writes a fact deletion record.

curl -X DELETE "$NIFTY_URL/api/v1/facts/01j9zq3k8m5x2v7c4n6b0t1r9e" \
  -H "Authorization: Bearer $NIFTY_TOKEN"

Path parameters

NameDescription
idULIDA record's ID.

Response

204 Deleted Errors: 401 403 404 429

Menu

2026.10.2Contact support