Schemas
Error
typetitlestatusdetailcodeinstancerequestIddocsUrlValidationError
typetitlestatusdetailcodeinstancerequestIddocsUrlOne entry per field that failed validation.
PaginatedEnvelope
The page of results.
totalTotal rows matching the query (across pages).
limithasMorenextCursorOpaque cursor for the next page; null on the last page.
actor
idActor id. A UUID — unlike the short ids used elsewhere in this API. This is the value returned as createdByActorId, updatedByActorId and actorId on other resources.
typeWhat kind of writer this is: "human" a person, "agent" an autonomous integration, "automation" a workspace rule, "recurringTask" a repeating task rule, "cron" a scheduled maintenance job, "outboxRetry" a retried delivery, "systemDefault" an unattributed server write. Branch on this to tell a person's edit from an automated one.
displayNameName to show for this actor: the person's name, the agent's name, or a label for a server process. A cached convenience copy that can briefly lag a rename, so treat the member or agent record as authoritative when you have it. "Deleted member" once the underlying person has been erased.
memberIdThe person behind this actor, when type is "human" — look it up on /members for name, avatar, role and status. Null for every other type, and null once the person has been erased.
agentIdThe agent behind this actor, when type is "agent". Null for every other type, and null once the agent has been deleted.
tombstonedAtWhen the person or agent behind this actor was permanently erased. The actor survives so past attribution stays intact, but it no longer identifies anyone: memberId and agentId are cleared and displayName becomes a placeholder. Null for every live actor.
annotation
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
typeAnnotation kind: image or video.
fileIdThe file this annotation is drawn on. Required and immutable.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
Where the annotation sits on an image: the shape kind (POINT, RECTANGLE or OVAL) plus x / y / width / height. All four are PERCENTAGES of the file's own dimensions (0–100), not pixels, so an annotation keeps its place at any display size. A POINT needs only x and y. Empty for a bare anchor.
videoTimeSecondsPlayback position in seconds for a video annotation. Null for image annotations.
taskIdThe task that holds this annotation's comment thread. Created automatically when someone comments on the annotation in the Nifty app; null until then.
Messages threaded under this annotation — what the app calls its comments. Populated only when you ask for it with ?expand=messages; also reachable as GET /messages?annotationId=....
annotationExpanded
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
typeAnnotation kind: image or video.
fileIdThe file this annotation is drawn on. Required and immutable.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
Where the annotation sits on an image: the shape kind (POINT, RECTANGLE or OVAL) plus x / y / width / height. All four are PERCENTAGES of the file's own dimensions (0–100), not pixels, so an annotation keeps its place at any display size. A POINT needs only x and y. Empty for a bare anchor.
videoTimeSecondsPlayback position in seconds for a video annotation. Null for image annotations.
taskIdThe task that holds this annotation's comment thread. Created automatically when someone comments on the annotation in the Nifty app; null until then.
Messages threaded under this annotation — what the app calls its comments. Populated only when you ask for it with ?expand=messages; also reachable as GET /messages?annotationId=....
The related File, present only when you pass ?expand=file.
The related Task, present only when you pass ?expand=task.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
annotationCreate
typeAnnotation kind: image or video.
fileIdThe file this annotation is drawn on. Required and immutable.
Where the annotation sits on an image: the shape kind (POINT, RECTANGLE or OVAL) plus x / y / width / height. All four are PERCENTAGES of the file's own dimensions (0–100), not pixels, so an annotation keeps its place at any display size. A POINT needs only x and y. Empty for a bare anchor.
videoTimeSecondsPlayback position in seconds for a video annotation. Null for image annotations.
annotationUpdate
Where the annotation sits on an image: the shape kind (POINT, RECTANGLE or OVAL) plus x / y / width / height. All four are PERCENTAGES of the file's own dimensions (0–100), not pixels, so an annotation keeps its place at any display size. A POINT needs only x and y. Empty for a bare anchor.
videoTimeSecondsPlayback position in seconds for a video annotation. Null for image annotations.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
chat
idUnique identifier for this resource.
createdAtCreation timestamp.
typeChat type: 'group', 'direct' (a 1:1 direct message), or 'project' (a project's general discussion). Create accepts ONLY 'group'.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
nameChat display name. Required for group chats (the only v3-creatable kind); NULL on direct chats and the team self-chat.
descriptionOptional free-text description.
teamIdThe workspace (team) this chat belongs to. Server-set from the caller identity — never client-writable.
projectIdSet only on a project's general-discussion chat; null on group and direct chats. Those chats are not returned by list/get today, so in practice this is always null.
pinnedMessageIdThe message currently pinned in this chat, if any. Read-only.
lastMessageAtTimestamp of the latest message (server-bumped by the message-create afterCommit hook). NULL until the first message. List default-sorts on it.
Who is in this chat. Each entry carries the member id plus whether they own the chat, whether they muted it, and when they joined. Populated only when you ask for it with ?expand=members.
chatExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
typeChat type: 'group', 'direct' (a 1:1 direct message), or 'project' (a project's general discussion). Create accepts ONLY 'group'.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
nameChat display name. Required for group chats (the only v3-creatable kind); NULL on direct chats and the team self-chat.
descriptionOptional free-text description.
teamIdThe workspace (team) this chat belongs to. Server-set from the caller identity — never client-writable.
projectIdSet only on a project's general-discussion chat; null on group and direct chats. Those chats are not returned by list/get today, so in practice this is always null.
pinnedMessageIdThe message currently pinned in this chat, if any. Read-only.
lastMessageAtTimestamp of the latest message (server-bumped by the message-create afterCommit hook). NULL until the first message. List default-sorts on it.
Who is in this chat. Each entry carries the member id plus whether they own the chat, whether they muted it, and when they joined. Populated only when you ask for it with ?expand=members.
The related Project, present only when you pass ?expand=project.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
chatCreate
nameChat display name. Required for group chats (the only v3-creatable kind); NULL on direct chats and the team self-chat.
descriptionOptional free-text description.
typeChat type. Create accepts ONLY a group chat: pass 'group' (the same value reads emit). Direct and project chats are readable but are not created here — post a message with recipientMemberId for a direct message; a project's discussion is provisioned with its project.
memberIdsTeam members to add to the chat, by id — you are always included as its owner. Members are set here, when the chat is created, and cannot be changed afterwards, so send the full roster now. Write-only; read the resulting membership back with ?expand=members.
chatUpdate
nameChat display name. Required for group chats (the only v3-creatable kind); NULL on direct chats and the team self-chat.
descriptionOptional free-text description.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
checkIn
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
nameDisplay name for the check-in. Capped at 100 characters.
notifyTypesHow assignees are reminded: email, message (an in-app message) or notification (a push notification). Every channel you list fires. Usually non-empty, but older records can come back with an empty list — read it, and if you are echoing a record back on an update, drop the key rather than sending the empty array (writes require at least one channel and will reject it).
requestTypeWhat triggers this check-in. schedule runs it on a recurrence and REQUIRES recurringRuleId; manual runs it on demand and must omit recurringRuleId.
formIdThe form holding this check-in's questions. Set once when the check-in is created.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
recurringRuleIdIdentifier of the recurrence rule that triggers this check-in, or null when requestType is manual. Create the rule first with POST /recurring-rules and pass its id here, or send an inline schedule object on the create body instead and one will be created for you.
checkInExpanded
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
nameDisplay name for the check-in. Capped at 100 characters.
notifyTypesHow assignees are reminded: email, message (an in-app message) or notification (a push notification). Every channel you list fires. Usually non-empty, but older records can come back with an empty list — read it, and if you are echoing a record back on an update, drop the key rather than sending the empty array (writes require at least one channel and will reject it).
requestTypeWhat triggers this check-in. schedule runs it on a recurrence and REQUIRES recurringRuleId; manual runs it on demand and must omit recurringRuleId.
formIdThe form holding this check-in's questions. Set once when the check-in is created.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
recurringRuleIdIdentifier of the recurrence rule that triggers this check-in, or null when requestType is manual. Create the rule first with POST /recurring-rules and pass its id here, or send an inline schedule object on the create body instead and one will be created for you.
The related Form, present only when you pass ?expand=form.
The related Recurring Rule, present only when you pass ?expand=recurringRule.
The related Actor, present only when you pass ?expand=createdByActor.
The linked Team Member rows, present only when you pass ?expand=assignees.
The linked Team Member rows, present only when you pass ?expand=subscribers.
The linked Check-in request rows, present only when you pass ?expand=requests.
checkInCreate
nameDisplay name for the check-in. Capped at 100 characters.
notifyTypesHow assignees are reminded: email, message (an in-app message) or notification (a push notification). Every channel you list fires, and at least one is required.
requestTypeWhat triggers this check-in. schedule runs it on a recurrence and REQUIRES recurringRuleId; manual runs it on demand and must omit recurringRuleId.
formIdThe form holding this check-in's questions. Set once when the check-in is created.
recurringRuleIdIdentifier of the recurrence rule that triggers this check-in, or null when requestType is manual. Create the rule first with POST /recurring-rules and pass its id here, or send an inline schedule object on the create body instead and one will be created for you.
Define the recurrence inline instead of pre-creating a rule: send the same timetable object recurringRule.schedule carries and a recurringRule is created in the same transaction and linked, so a failure anywhere rolls both back. This is the one-call alternative to recurringRuleId and mutually exclusive with it. Accepted on create only — change the schedule of an existing check-in by pointing recurringRuleId at another rule.
assigneesTeam members who must answer this check-in. Replaces the whole set on update; use POST /check-ins/{id}/assignees and POST /check-ins/{id}/assignees/remove for a single add or remove.
subscribersTeam members notified when someone answers, without being asked themselves. Replaces the whole set on update; use POST /check-ins/{id}/subscribers and POST /check-ins/{id}/subscribers/remove for a single add or remove.
checkInUpdate
nameDisplay name for the check-in. Capped at 100 characters.
notifyTypesHow assignees are reminded: email, message (an in-app message) or notification (a push notification). Every channel you list fires, and at least one is required.
requestTypeWhat triggers this check-in. schedule runs it on a recurrence and REQUIRES recurringRuleId; manual runs it on demand and must omit recurringRuleId.
recurringRuleIdIdentifier of the recurrence rule that triggers this check-in, or null when requestType is manual. Create the rule first with POST /recurring-rules and pass its id here, or send an inline schedule object on the create body instead and one will be created for you.
assigneesTeam members who must answer this check-in. Replaces the whole set on update; use POST /check-ins/{id}/assignees and POST /check-ins/{id}/assignees/remove for a single add or remove.
subscribersTeam members notified when someone answers, without being asked themselves. Replaces the whole set on update; use POST /check-ins/{id}/subscribers and POST /check-ins/{id}/subscribers/remove for a single add or remove.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
checkInRequest
idUnique identifier for this resource.
createdAtCreation timestamp.
checkInIdThe check-in this request belongs to. Required when creating one, and immutable afterwards — the parent check-in decides both the workspace it lives in and the form that is answered.
updatedAtLast update timestamp.
reminderSentAtWhen the most recent reminder for this request was sent, or null if no reminder has been sent yet. Server-managed (reminders are rate-limited to one every 8 hours) and read-only.
Team members asked to respond to this request. Copied from the parent check-in when the request is created; send an assignees array on the create body to override that. Add or remove members afterwards with POST/DELETE /check-in-requests/:id/assignees, and use ?expand=assignees to read them.
Team members who have submitted an answer to this request. Maintained by the submission flow and read-only — a request is complete once this covers every entry in assignees. Use ?expand=respondedBy to read it.
checkInRequestExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
checkInIdThe check-in this request belongs to. Required when creating one, and immutable afterwards — the parent check-in decides both the workspace it lives in and the form that is answered.
updatedAtLast update timestamp.
reminderSentAtWhen the most recent reminder for this request was sent, or null if no reminder has been sent yet. Server-managed (reminders are rate-limited to one every 8 hours) and read-only.
Team members asked to respond to this request. Copied from the parent check-in when the request is created; send an assignees array on the create body to override that. Add or remove members afterwards with POST/DELETE /check-in-requests/:id/assignees, and use ?expand=assignees to read them.
Team members who have submitted an answer to this request. Maintained by the submission flow and read-only — a request is complete once this covers every entry in assignees. Use ?expand=respondedBy to read it.
The related Check-in, present only when you pass ?expand=checkIn.
checkInRequestCreate
checkInIdThe check-in this request belongs to. Required when creating one, and immutable afterwards — the parent check-in decides both the workspace it lives in and the form that is answered.
assigneesTeam members asked to respond to this request. Copied from the parent check-in when the request is created; send an assignees array on the create body to override that. Add or remove members afterwards with POST/DELETE /check-in-requests/:id/assignees, and use ?expand=assignees to read them.
checklist
idUnique identifier for this resource.
createdAtCreation timestamp.
nameChecklist name — a group of steps on the task.
taskIdTask this checklist belongs to. Required on create; immutable afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
orderFractional rank of the checklist within its task. To reposition, send the midpoint of the two neighbours' ranks.
checklistExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
nameChecklist name — a group of steps on the task.
taskIdTask this checklist belongs to. Required on create; immutable afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
orderFractional rank of the checklist within its task. To reposition, send the midpoint of the two neighbours' ranks.
The related Task, present only when you pass ?expand=task.
The linked Checklist Item rows, present only when you pass ?expand=checklistItems.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
checklistCreate
nameChecklist name — a group of steps on the task.
taskIdTask this checklist belongs to. Required on create; immutable afterwards.
orderFractional rank of the checklist within its task. To reposition, send the midpoint of the two neighbours' ranks.
checklistUpdate
nameChecklist name — a group of steps on the task.
orderFractional rank of the checklist within its task. To reposition, send the midpoint of the two neighbours' ranks.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
checklistItem
idUnique identifier for this resource.
createdAtCreation timestamp.
nameThe item text — a single completable checkbox line (no assignee, dates, or comments).
completedWhether the item is checked off. Defaults to false.
checklistIdChecklist this item belongs to. Required on create; immutable afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
orderFractional rank of the item within its checklist. To reposition, send the midpoint of the two neighbours' ranks.
checklistItemExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
nameThe item text — a single completable checkbox line (no assignee, dates, or comments).
completedWhether the item is checked off. Defaults to false.
checklistIdChecklist this item belongs to. Required on create; immutable afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
orderFractional rank of the item within its checklist. To reposition, send the midpoint of the two neighbours' ranks.
The related Checklist, present only when you pass ?expand=checklist.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
checklistItemCreate
nameThe item text — a single completable checkbox line (no assignee, dates, or comments).
checklistIdChecklist this item belongs to. Required on create; immutable afterwards.
orderFractional rank of the item within its checklist. To reposition, send the midpoint of the two neighbours' ranks.
completedWhether the item is checked off. Defaults to false.
checklistItemUpdate
nameThe item text — a single completable checkbox line (no assignee, dates, or comments).
orderFractional rank of the item within its checklist. To reposition, send the midpoint of the two neighbours' ranks.
completedWhether the item is checked off. Defaults to false.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
customField
idUnique identifier for this resource.
createdAtCreation timestamp.
nameField name, for example "Priority" or "T-shirt size".
typeWhat kind of value this field holds. It decides how you format the string you send: checkbox takes "true" / "false", user takes a member id, dropdown takes one of the field's option values, and the rest take the value written out (a number, a date, a URL).
associationsThe kinds of thing this field can be attached to.
inLibraryWhether this definition comes from the reusable field library rather than being bound to one workspace. Library definitions are not returned by this API today, so it is always false here.
teamIdThe workspace (team) this field definition belongs to.
updatedAtLast update timestamp.
descriptionOptional help text for this field.
currencyISO currency code for a currency field. Null for every other type.
The selectable choices, for a dropdown field. Fetch them with ?expand=options and send one of the returned values when setting the field.
Roles this field is hidden from. Read-only here — fetch it with ?expand=hiddenFor; visibility is managed in the Nifty app.
document
idUnique identifier for this resource.
createdAtCreation timestamp.
nameDocument display name. Required on create; editable.
archivedWhether the document is archived. Archived documents stay in the project but are hidden from default views. Independent of deletion — an archived document is not deleted, and a deleted document is not archived.
accessTypeWho can see this document. public (the default) — everyone in the project. limited — only the document's own member list, which starts out as JUST THE RESOLVED AUTHOR: when an agent or integration creates a limited document, the author it resolves to is the one who can reach it, not the caller. private — a legacy state the API cannot set; those documents are readable and filterable but cannot be created here. Choose this when you create the document — it cannot be changed afterwards through the API (change it in the Nifty app instead). A child document always inherits its parent's access type.
typeWhere the document lives: nifty (a native Nifty document — everything the API creates), or google / dropbox / microsoft for a document linked from that provider. Read-only.
lockedWhether the document is locked against edits.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
description1–3 sentence summary of what this document is for (max 2,000 chars; null = none). Surfaced in list results so agents can discover a project's knowledge without fetching bodies. Set it when creating a document; keep it short — it is metadata, not a second body.
subtypeWhat kind of file a linked Google/Microsoft document is: document, spreadsheet or presentation. Null for native Nifty documents. Read-only.
projectIdThe project this document belongs to. Required on create — a document always lives in a project — and immutable afterwards.
authorIdThe team member credited as the document's author — a member id, so resolve it with ?expand=author or GET /members/{id}. When an agent or integration creates a document it resolves to a person (the project owner), and is null only if no person can be resolved. Read-only.
parentDocumentIdThe document this one is nested under — a parent in the same project. Set once at creation and immutable thereafter.
folderIdThe folder this document sits in — a document folder in the same project. Omit or send null to place it at the project root. The folder path is derived by the server. Set once at creation; moving a document between folders is not part of the update surface yet.
externalIdThe provider's own id for a Google/Microsoft-linked document. Null for Nifty-native documents (everything created through this API). Read-only.
externalEmbedUrlEmbed URL for a document linked from another provider. Null for Nifty-native documents (everything created through this API). Read-only.
documentExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
nameDocument display name. Required on create; editable.
archivedWhether the document is archived. Archived documents stay in the project but are hidden from default views. Independent of deletion — an archived document is not deleted, and a deleted document is not archived.
accessTypeWho can see this document. public (the default) — everyone in the project. limited — only the document's own member list, which starts out as JUST THE RESOLVED AUTHOR: when an agent or integration creates a limited document, the author it resolves to is the one who can reach it, not the caller. private — a legacy state the API cannot set; those documents are readable and filterable but cannot be created here. Choose this when you create the document — it cannot be changed afterwards through the API (change it in the Nifty app instead). A child document always inherits its parent's access type.
typeWhere the document lives: nifty (a native Nifty document — everything the API creates), or google / dropbox / microsoft for a document linked from that provider. Read-only.
lockedWhether the document is locked against edits.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
description1–3 sentence summary of what this document is for (max 2,000 chars; null = none). Surfaced in list results so agents can discover a project's knowledge without fetching bodies. Set it when creating a document; keep it short — it is metadata, not a second body.
subtypeWhat kind of file a linked Google/Microsoft document is: document, spreadsheet or presentation. Null for native Nifty documents. Read-only.
projectIdThe project this document belongs to. Required on create — a document always lives in a project — and immutable afterwards.
authorIdThe team member credited as the document's author — a member id, so resolve it with ?expand=author or GET /members/{id}. When an agent or integration creates a document it resolves to a person (the project owner), and is null only if no person can be resolved. Read-only.
parentDocumentIdThe document this one is nested under — a parent in the same project. Set once at creation and immutable thereafter.
folderIdThe folder this document sits in — a document folder in the same project. Omit or send null to place it at the project root. The folder path is derived by the server. Set once at creation; moving a document between folders is not part of the update surface yet.
externalIdThe provider's own id for a Google/Microsoft-linked document. Null for Nifty-native documents (everything created through this API). Read-only.
externalEmbedUrlEmbed URL for a document linked from another provider. Null for Nifty-native documents (everything created through this API). Read-only.
The related Project, present only when you pass ?expand=project.
The related Team Member, present only when you pass ?expand=author.
The related Document, present only when you pass ?expand=parentDocument.
The related Team Member, present only when you pass ?expand=deletedBy.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
The linked Label rows, present only when you pass ?expand=labels.
documentCreate
nameDocument display name. Required on create; editable.
projectIdThe project this document belongs to. Required on create — a document always lives in a project — and immutable afterwards.
description1–3 sentence summary of what this document is for (max 2,000 chars; null = none). Surfaced in list results so agents can discover a project's knowledge without fetching bodies. Set it when creating a document; keep it short — it is metadata, not a second body.
parentDocumentIdThe document this one is nested under — a parent in the same project. Set once at creation and immutable thereafter.
folderIdThe folder this document sits in — a document folder in the same project. Omit or send null to place it at the project root. The folder path is derived by the server. Set once at creation; moving a document between folders is not part of the update surface yet.
accessTypeWho can see this document. public (the default) — everyone in the project. limited — only the document's own member list, which starts out as JUST THE RESOLVED AUTHOR: when an agent or integration creates a limited document, the author it resolves to is the one who can reach it, not the caller. private — a legacy state the API cannot set; those documents are readable and filterable but cannot be created here. Choose this when you create the document — it cannot be changed afterwards through the API (change it in the Nifty app instead). A child document always inherits its parent's access type.
contentInitial document body, as Markdown. Supports headings, lists, tables, code blocks and Nifty mention syntax. Create-only: the body of an existing document is EXTENDED with the append operation and read back with the content operation — it can never be replaced or deleted, and it is not returned by list or get.
lockedWhether the document is locked against edits.
archivedWhether the document is archived. Archived documents stay in the project but are hidden from default views. Independent of deletion — an archived document is not deleted, and a deleted document is not archived.
documentUpdate
nameDocument display name. Required on create; editable.
description1–3 sentence summary of what this document is for (max 2,000 chars; null = none). Surfaced in list results so agents can discover a project's knowledge without fetching bodies. Set it when creating a document; keep it short — it is metadata, not a second body.
lockedWhether the document is locked against edits.
archivedWhether the document is archived. Archived documents stay in the project but are hidden from default views. Independent of deletion — an archived document is not deleted, and a deleted document is not archived.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
favorite
idUnique identifier for this resource.
createdAtCreation timestamp.
nameThe label shown in the sidebar. It is a snapshot you supply, NOT a live mirror — rename the project and the favorite keeps the old label until you update it yourself.
typeWhat kind of thing is favorited, and therefore what resourceId must point at: project (a project id, plus projectId), document (a document id), file (a file id), fileFolder / documentFolder (a folder id), projectEmbed (an embed id, plus projectId). personalNotes, personalTasks and createdByMe are standing personal views rather than a specific item — they take no resourceId. Set once: re-pointing a favorite means deleting it and creating another.
memberIdThe team member this favorite belongs to. Set by the server from whoever is calling — you only ever see your own.
updatedAtLast update timestamp.
orderRank within the sidebar. Omit it on create to append at the end (the server assigns the next rank); supply one to place it explicitly. Settable on update for drag-and-drop reordering — pick a value between the two neighbours you are dropping between.
resourceIdThe id of the favorited item. Required for every type except the three standing personal views (personalNotes, personalTasks, createdByMe), which take none. Set once — a favorite cannot be re-pointed.
projectIdThe project a project or projectEmbed favorite lives in. Required on create for those two types and ignored for the rest. Set once — a favorite cannot be re-pointed.
favoriteFolderIdFolder grouping this favorite. Null = top-level (not in any folder). Mutable — favorites move between folders.
favoriteExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
nameThe label shown in the sidebar. It is a snapshot you supply, NOT a live mirror — rename the project and the favorite keeps the old label until you update it yourself.
typeWhat kind of thing is favorited, and therefore what resourceId must point at: project (a project id, plus projectId), document (a document id), file (a file id), fileFolder / documentFolder (a folder id), projectEmbed (an embed id, plus projectId). personalNotes, personalTasks and createdByMe are standing personal views rather than a specific item — they take no resourceId. Set once: re-pointing a favorite means deleting it and creating another.
memberIdThe team member this favorite belongs to. Set by the server from whoever is calling — you only ever see your own.
updatedAtLast update timestamp.
orderRank within the sidebar. Omit it on create to append at the end (the server assigns the next rank); supply one to place it explicitly. Settable on update for drag-and-drop reordering — pick a value between the two neighbours you are dropping between.
resourceIdThe id of the favorited item. Required for every type except the three standing personal views (personalNotes, personalTasks, createdByMe), which take none. Set once — a favorite cannot be re-pointed.
projectIdThe project a project or projectEmbed favorite lives in. Required on create for those two types and ignored for the rest. Set once — a favorite cannot be re-pointed.
favoriteFolderIdFolder grouping this favorite. Null = top-level (not in any folder). Mutable — favorites move between folders.
The related Team Member, present only when you pass ?expand=member.
The related Favorite Folder, present only when you pass ?expand=favoriteFolder.
The related Project, present only when you pass ?expand=project.
favoriteCreate
nameThe label shown in the sidebar. It is a snapshot you supply, NOT a live mirror — rename the project and the favorite keeps the old label until you update it yourself.
typeWhat kind of thing is favorited, and therefore what resourceId must point at: project (a project id, plus projectId), document (a document id), file (a file id), fileFolder / documentFolder (a folder id), projectEmbed (an embed id, plus projectId). personalNotes, personalTasks and createdByMe are standing personal views rather than a specific item — they take no resourceId. Set once: re-pointing a favorite means deleting it and creating another.
orderRank within the sidebar. Omit it on create to append at the end (the server assigns the next rank); supply one to place it explicitly. Settable on update for drag-and-drop reordering — pick a value between the two neighbours you are dropping between.
resourceIdThe id of the favorited item. Required for every type except the three standing personal views (personalNotes, personalTasks, createdByMe), which take none. Set once — a favorite cannot be re-pointed.
projectIdThe project a project or projectEmbed favorite lives in. Required for those two types, ignored for the rest.
favoriteFolderIdFolder grouping this favorite. Null = top-level (not in any folder). Mutable — favorites move between folders.
favoriteUpdate
nameThe label shown in the sidebar. It is a snapshot you supply, NOT a live mirror — rename the project and the favorite keeps the old label until you update it yourself.
orderRank within the sidebar. Omit it on create to append at the end (the server assigns the next rank); supply one to place it explicitly. Settable on update for drag-and-drop reordering — pick a value between the two neighbours you are dropping between.
favoriteFolderIdFolder grouping this favorite. Null = top-level (not in any folder). Mutable — favorites move between folders.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
favoriteFolder
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp
nameFolder name shown in the sidebar. Capped at 30 characters, which is easy to hit.
orderRank within the sidebar. Omit it and the server appends the folder at the end.
createdByIdTeam member who created this folder. A member id — resolve it with GET /members/{id}.
updatedAtLast update timestamp
updatedByIdTeam member who last updated this folder. A member id — resolve it with GET /members/{id}.
favoriteFolderExpanded
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp
nameFolder name shown in the sidebar. Capped at 30 characters, which is easy to hit.
orderRank within the sidebar. Omit it and the server appends the folder at the end.
createdByIdTeam member who created this folder. A member id — resolve it with GET /members/{id}.
updatedAtLast update timestamp
updatedByIdTeam member who last updated this folder. A member id — resolve it with GET /members/{id}.
The related Team Member, present only when you pass ?expand=createdBy.
The related Team Member, present only when you pass ?expand=updatedBy.
favoriteFolderCreate
nameFolder name shown in the sidebar. Capped at 30 characters, which is easy to hit.
orderRank within the sidebar. Omit it and the server appends the folder at the end.
favoriteFolderUpdate
nameFolder name shown in the sidebar. Capped at 30 characters, which is easy to hit.
orderRank within the sidebar. Omit it and the server appends the folder at the end.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
file
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
nameFile name, WITH its extension — there is no content-type field on a file, so the extension in this name is how a consumer tells a PDF from a PNG. 1–255 characters after trimming; a blank name is rejected.
sizeSize of the uploaded file in bytes. Required on create — pass the byte count of what you uploaded. Maximum 2,147,483,646 (2 GB) per file, and the upload also has to fit your team's remaining storage quota; exceeding either is rejected.
urlTime-limited download URL for the stored file. Read-only — set the bytes at creation with uploadKey; they never move afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
processedFalse until server-side post-processing (thumbnail generation, virus scanning) finishes — thumbnail and download may be null until then. Typically a few seconds.
downloadAlternate time-limited download URL for the same bytes as url. Read-only.
thumbnailPreview-image URL for image and video files; null for everything else, and null until processed becomes true. Read-only.
folderStackThe folder path this file sits in, from the project root down to its direct parent. Derived by the server from folderId.
Team members subscribed to this file — they are notified when it changes. Populated only when you ask for it with ?expand=subscribers; add and remove them with POST / DELETE /files/{id}/subscribers.
Labels attached to this file. Populated only when you ask for it with ?expand=labels; add and remove them with POST / DELETE /files/{id}/labels.
uploaderIdThe team member who uploaded the file — a member id, so resolve it with ?expand=uploader or GET /members/{id}. Null when uploaded by an agent or an integration — see createdByActorType.
projectIdAttach the file to this project. At least one of projectId, taskId, documentId, messageId or folderId is required on create. Fixed at upload.
taskIdAttach the file to this task. At least one of projectId, taskId, documentId, messageId or folderId is required on create. Fixed at upload.
documentIdAttach the file to this document. At least one of projectId, taskId, documentId, messageId or folderId is required on create. Fixed at upload.
messageIdAttach the file to this message. At least one of projectId, taskId, documentId, messageId or folderId is required on create. Fixed at upload.
folderIdPlace the file in this folder. At least one of projectId, taskId, documentId, messageId or folderId is required on create. A file's project / task / document / message parent is fixed at upload; only its folder can be changed afterwards.
annotationTaskIdThe task that holds this file's annotation thread, created when the file is opened in annotation mode. Read-only.
fileExpanded
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
nameFile name, WITH its extension — there is no content-type field on a file, so the extension in this name is how a consumer tells a PDF from a PNG. 1–255 characters after trimming; a blank name is rejected.
sizeSize of the uploaded file in bytes. Required on create — pass the byte count of what you uploaded. Maximum 2,147,483,646 (2 GB) per file, and the upload also has to fit your team's remaining storage quota; exceeding either is rejected.
urlTime-limited download URL for the stored file. Read-only — set the bytes at creation with uploadKey; they never move afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
processedFalse until server-side post-processing (thumbnail generation, virus scanning) finishes — thumbnail and download may be null until then. Typically a few seconds.
downloadAlternate time-limited download URL for the same bytes as url. Read-only.
thumbnailPreview-image URL for image and video files; null for everything else, and null until processed becomes true. Read-only.
folderStackThe folder path this file sits in, from the project root down to its direct parent. Derived by the server from folderId.
Team members subscribed to this file — they are notified when it changes. Populated only when you ask for it with ?expand=subscribers; add and remove them with POST / DELETE /files/{id}/subscribers.
Labels attached to this file. Populated only when you ask for it with ?expand=labels; add and remove them with POST / DELETE /files/{id}/labels.
uploaderIdThe team member who uploaded the file — a member id, so resolve it with ?expand=uploader or GET /members/{id}. Null when uploaded by an agent or an integration — see createdByActorType.
projectIdAttach the file to this project. At least one of projectId, taskId, documentId, messageId or folderId is required on create. Fixed at upload.
taskIdAttach the file to this task. At least one of projectId, taskId, documentId, messageId or folderId is required on create. Fixed at upload.
documentIdAttach the file to this document. At least one of projectId, taskId, documentId, messageId or folderId is required on create. Fixed at upload.
messageIdAttach the file to this message. At least one of projectId, taskId, documentId, messageId or folderId is required on create. Fixed at upload.
folderIdPlace the file in this folder. At least one of projectId, taskId, documentId, messageId or folderId is required on create. A file's project / task / document / message parent is fixed at upload; only its folder can be changed afterwards.
annotationTaskIdThe task that holds this file's annotation thread, created when the file is opened in annotation mode. Read-only.
The related Team Member, present only when you pass ?expand=uploader.
The related Team Member, present only when you pass ?expand=deletedBy.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
The related Project, present only when you pass ?expand=project.
The related Task, present only when you pass ?expand=task.
The related Document, present only when you pass ?expand=document.
The related Message, present only when you pass ?expand=message.
The related Task, present only when you pass ?expand=annotationTask.
The linked Annotation rows, present only when you pass ?expand=annotations.
fileCreate
nameFile name, WITH its extension — there is no content-type field, so the extension is how a consumer tells a PDF from a PNG.
sizeSize of the uploaded file in bytes. Required — pass the byte count of what you uploaded. Maximum 2 GB per file, and the upload also has to fit your team's remaining storage quota.
uploadKeyStorage key of the already-uploaded bytes: call the createUploadUrl operation, PUT the bytes to the presigned URL it returns, then pass its uploadKey here verbatim. Create REGISTERS metadata; it does not upload bytes.
projectIdAttach the file to this project (one context per file).
taskIdAttach the file to this task (one context per file).
documentIdAttach the file to this document (one context per file).
messageIdAttach the file to this message (one context per file).
folderIdPlace the file in this folder. A file's project / task / document / message parent is fixed at upload; only its folder can be changed afterwards.
Decision Table
| Variant | Matching Criteria |
|---|---|
| type = object · requires: projectId | |
| type = object · requires: taskId | |
| type = object · requires: documentId | |
| type = object · requires: messageId | |
| type = object · requires: folderId |
projectIdAttach the file to this project (one context per file).
nameFile name, WITH its extension — there is no content-type field, so the extension is how a consumer tells a PDF from a PNG.
sizeSize of the uploaded file in bytes. Required — pass the byte count of what you uploaded. Maximum 2 GB per file, and the upload also has to fit your team's remaining storage quota.
uploadKeyStorage key of the already-uploaded bytes: call the createUploadUrl operation, PUT the bytes to the presigned URL it returns, then pass its uploadKey here verbatim. Create REGISTERS metadata; it does not upload bytes.
taskIdAttach the file to this task (one context per file).
documentIdAttach the file to this document (one context per file).
messageIdAttach the file to this message (one context per file).
folderIdPlace the file in this folder. A file's project / task / document / message parent is fixed at upload; only its folder can be changed afterwards.
fileUpdate
nameFile name, WITH its extension — there is no content-type field, so the extension is how a consumer tells a PDF from a PNG.
sizeSize of the uploaded file in bytes. Required — pass the byte count of what you uploaded. Maximum 2 GB per file, and the upload also has to fit your team's remaining storage quota.
folderIdPlace the file in this folder. A file's project / task / document / message parent is fixed at upload; only its folder can be changed afterwards.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
form
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
nameThe form's name, shown to respondents as its title. Set it with meta.title.
automationWhat Nifty does when the form is submitted: task creates a task, doc a document, message a chat message, checkin a check-in response. null for a plain form that just records answers. When it is task, both targetStatusId and targetListId are required in the same request.
targetStatusIdThe board column a task automation files its new task into. Required whenever automation is task.
targetListIdThe list a task automation files its new task into. Required whenever automation is task.
The form's display metadata. title is the form's name, shown to respondents (also surfaced read-only as name); description is the blurb under it.
What a respondent sees after submitting: a heading, body text, an optional image, an optional redirect, and an optional auto-reply email. Stored verbatim, so its keys are snake_case unlike the rest of this API.
multiSubmitWhether one respondent may submit the form more than once. Defaults to false.
docAccessTypeWho can see the document a doc automation creates: public (the whole team), limited (invited members), private (the author only). Defaults to public.
urlThe public link respondents open to fill this form in. Null until the form has been shared.
projectIdAn optional project to associate this form with. It does not affect who can see the form — forms are visible across the whole workspace.
createdByIdTeam member who created this form — a member id, so resolve it with GET /members/{id}. Read-only, set from the caller. Null for creates that have no member behind them.
The form's questions, in the order respondents see them. This is a full replacement: any existing field missing from the array is deleted, along with its options and any answers already submitted to it — include each field's id to keep it. Omit the key entirely to leave the questions untouched. Cannot be an empty array (a form keeps at least one question), and cannot exceed 200 fields.
formExpanded
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
nameThe form's name, shown to respondents as its title. Set it with meta.title.
automationWhat Nifty does when the form is submitted: task creates a task, doc a document, message a chat message, checkin a check-in response. null for a plain form that just records answers. When it is task, both targetStatusId and targetListId are required in the same request.
targetStatusIdThe board column a task automation files its new task into. Required whenever automation is task.
targetListIdThe list a task automation files its new task into. Required whenever automation is task.
The form's display metadata. title is the form's name, shown to respondents (also surfaced read-only as name); description is the blurb under it.
What a respondent sees after submitting: a heading, body text, an optional image, an optional redirect, and an optional auto-reply email. Stored verbatim, so its keys are snake_case unlike the rest of this API.
multiSubmitWhether one respondent may submit the form more than once. Defaults to false.
docAccessTypeWho can see the document a doc automation creates: public (the whole team), limited (invited members), private (the author only). Defaults to public.
urlThe public link respondents open to fill this form in. Null until the form has been shared.
projectIdAn optional project to associate this form with. It does not affect who can see the form — forms are visible across the whole workspace.
createdByIdTeam member who created this form — a member id, so resolve it with GET /members/{id}. Read-only, set from the caller. Null for creates that have no member behind them.
The form's questions, in the order respondents see them. This is a full replacement: any existing field missing from the array is deleted, along with its options and any answers already submitted to it — include each field's id to keep it. Omit the key entirely to leave the questions untouched. Cannot be an empty array (a form keeps at least one question), and cannot exceed 200 fields.
The related Project, present only when you pass ?expand=project.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
The related Team Member, present only when you pass ?expand=deletedBy.
goal
idUnique identifier for this resource.
createdAtCreation timestamp.
nameGoal name
accessTypeWho can see this goal: public (the whole team), limited (the team members listed in members), private (the owner only).
goalSourceTypeWhat feeds the goal's task set: customField, manual, label, assigneeLabel, assignee.
trackMetricTypeHow progress is measured: taskCount, trackedTime, customFieldValue, storyPoints.
targetTypeTarget mode: dynamic (the target tracks the live total of the goal task set) or static (a fixed targetValue).
targetValueThe fixed numeric target. Used only when targetType is static; when targetType is dynamic it is recomputed by the server from the goal task set and anything you send is overwritten.
progressTotalPersisted denominator of the progress rollup (float).
progressCompletedPersisted numerator of the progress rollup (float).
endAtTarget completion date (ISO 8601). Required on create; a goal always has a date it is aiming at.
teamIdThe workspace (team) this goal belongs to.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
descriptionOptional longer description
goalSourceValueThe id goalSourceType points at: for label a label id; for customField a custom-field id; for assignee and assigneeLabel a team-member id. Not used when goalSourceType is manual (send the task ids in tasks instead).
goalSourceOptionNarrows goalSourceValue when goalSourceType is custom_field: the id of the dropdown option to match. Ignored for every other source type.
trackMetricValueThe id trackMetricType points at — for custom_field_value, the custom-field id whose values are summed. Not used by the other metric types.
completedAtWhen this goal was completed, or null while it is open. Entirely server-derived: it is stamped the moment progressCompleted reaches progressTotal and cleared again if progress falls back below. There is no manual complete or reopen — finish the tracked work, or lower a static targetValue.
ownerIdThe team member who owns this goal — for a private goal, the only member who can see it. Defaults to the caller on create; send another team member id to hand it over.
goalGroupIdGoal group this goal is filed under (nullable — ON DELETE SET NULL). Writable: an id files the goal under that group; explicit null unlinks; omitted leaves it unchanged.
goalExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
nameGoal name
accessTypeWho can see this goal: public (the whole team), limited (the team members listed in members), private (the owner only).
goalSourceTypeWhat feeds the goal's task set: customField, manual, label, assigneeLabel, assignee.
trackMetricTypeHow progress is measured: taskCount, trackedTime, customFieldValue, storyPoints.
targetTypeTarget mode: dynamic (the target tracks the live total of the goal task set) or static (a fixed targetValue).
targetValueThe fixed numeric target. Used only when targetType is static; when targetType is dynamic it is recomputed by the server from the goal task set and anything you send is overwritten.
progressTotalPersisted denominator of the progress rollup (float).
progressCompletedPersisted numerator of the progress rollup (float).
endAtTarget completion date (ISO 8601). Required on create; a goal always has a date it is aiming at.
teamIdThe workspace (team) this goal belongs to.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
descriptionOptional longer description
goalSourceValueThe id goalSourceType points at: for label a label id; for customField a custom-field id; for assignee and assigneeLabel a team-member id. Not used when goalSourceType is manual (send the task ids in tasks instead).
goalSourceOptionNarrows goalSourceValue when goalSourceType is custom_field: the id of the dropdown option to match. Ignored for every other source type.
trackMetricValueThe id trackMetricType points at — for custom_field_value, the custom-field id whose values are summed. Not used by the other metric types.
completedAtWhen this goal was completed, or null while it is open. Entirely server-derived: it is stamped the moment progressCompleted reaches progressTotal and cleared again if progress falls back below. There is no manual complete or reopen — finish the tracked work, or lower a static targetValue.
ownerIdThe team member who owns this goal — for a private goal, the only member who can see it. Defaults to the caller on create; send another team member id to hand it over.
goalGroupIdGoal group this goal is filed under (nullable — ON DELETE SET NULL). Writable: an id files the goal under that group; explicit null unlinks; omitted leaves it unchanged.
The related Team Member, present only when you pass ?expand=owner.
The related Goal Group, present only when you pass ?expand=goalGroup.
The linked Team Member rows, present only when you pass ?expand=members.
The linked Task rows, present only when you pass ?expand=tasks.
The linked List rows, present only when you pass ?expand=lists.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
goalCreate
nameGoal name
endAtTarget completion date (ISO 8601). Required on create; a goal always has a date it is aiming at.
descriptionOptional longer description
accessTypeWho can see this goal: public (the whole team), limited (the team members listed in members), private (the owner only).
goalGroupIdGoal group this goal is filed under (nullable — ON DELETE SET NULL). Writable: an id files the goal under that group; explicit null unlinks; omitted leaves it unchanged.
membersTeam members this goal is shared with (this is who accessType: limited means). Set when the goal is created; ignored on update. Read them back with ?expand=members.
goalSourceTypeWhat feeds the goal's task set: customField, manual, label, assigneeLabel, assignee.
goalSourceValueThe id goalSourceType points at: for label a label id; for customField a custom-field id; for assignee and assigneeLabel a team-member id. Not used when goalSourceType is manual (send the task ids in tasks instead).
goalSourceOptionNarrows goalSourceValue when goalSourceType is custom_field: the id of the dropdown option to match. Ignored for every other source type.
tasksTasks linked to this goal, for goals whose goalSourceType is manual. Set when the goal is created; ignored on update. Read them back with ?expand=tasks.
listsLists whose tasks feed this goal. Set when the goal is created; ignored on update. Read them back with ?expand=lists.
trackMetricTypeHow progress is measured: taskCount, trackedTime, customFieldValue, storyPoints.
trackMetricValueThe id trackMetricType points at — for custom_field_value, the custom-field id whose values are summed. Not used by the other metric types.
targetTypeTarget mode: dynamic (the target tracks the live total of the goal task set) or static (a fixed targetValue).
targetValueThe fixed numeric target. Used only when targetType is static; when targetType is dynamic it is recomputed by the server from the goal task set and anything you send is overwritten.
ownerIdThe team member who owns this goal — for a private goal, the only member who can see it. Defaults to the caller on create; send another team member id to hand it over.
goalUpdate
nameGoal name
descriptionOptional longer description
accessTypeWho can see this goal: public (the whole team), limited (the team members listed in members), private (the owner only).
endAtTarget completion date (ISO 8601). Required on create; a goal always has a date it is aiming at.
goalGroupIdGoal group this goal is filed under (nullable — ON DELETE SET NULL). Writable: an id files the goal under that group; explicit null unlinks; omitted leaves it unchanged.
goalSourceTypeWhat feeds the goal's task set: customField, manual, label, assigneeLabel, assignee.
goalSourceValueThe id goalSourceType points at: for label a label id; for customField a custom-field id; for assignee and assigneeLabel a team-member id. Not used when goalSourceType is manual (send the task ids in tasks instead).
goalSourceOptionNarrows goalSourceValue when goalSourceType is custom_field: the id of the dropdown option to match. Ignored for every other source type.
trackMetricTypeHow progress is measured: taskCount, trackedTime, customFieldValue, storyPoints.
trackMetricValueThe id trackMetricType points at — for custom_field_value, the custom-field id whose values are summed. Not used by the other metric types.
targetTypeTarget mode: dynamic (the target tracks the live total of the goal task set) or static (a fixed targetValue).
targetValueThe fixed numeric target. Used only when targetType is static; when targetType is dynamic it is recomputed by the server from the goal task set and anything you send is overwritten.
ownerIdThe team member who owns this goal — for a private goal, the only member who can see it. Defaults to the caller on create; send another team member id to hand it over.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
goalGroup
idUnique identifier for this resource.
createdAtCreation timestamp.
nameDisplay name for this goal group. 1–100 characters; a blank name is rejected.
descriptionFree-text description of the group. Send null or "" to clear it; it always reads back as a string, empty when unset.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
goalGroupExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
nameDisplay name for this goal group. 1–100 characters; a blank name is rejected.
descriptionFree-text description of the group. Send null or "" to clear it; it always reads back as a string, empty when unset.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
The linked Goal rows, present only when you pass ?expand=goals.
The related Actor, present only when you pass ?expand=createdByActor.
goalGroupCreate
nameDisplay name for this goal group. 1–100 characters; a blank name is rejected.
descriptionFree-text description of the group. Send null or "" to clear it; it always reads back as a string, empty when unset.
goalGroupUpdate
nameDisplay name for this goal group. 1–100 characters; a blank name is rejected.
descriptionFree-text description of the group. Send null or "" to clear it; it always reads back as a string, empty when unset.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
label
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
nameThe label text. Send at least one of name or color when creating a label — an empty body is rejected. Names are unique per workspace among live labels: reusing one returns 409.
colorHex color, #RGB or #RRGGBB. Omit it and the server assigns a random palette color, so a label always has one. Stored lowercase and expanded to 6 digits, so #00A99B reads back as #00a99b. Send at least one of name or color when creating a label.
defaultTrue for the labels Nifty seeds into a workspace. Server-managed, and those labels are protected: renaming or deleting one returns 403.
typeWhat the label is for: others for an ordinary tag, member for the labels used to group people. Defaults to others, and cannot be changed afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdTeam member who moved this label to the trash. A member id — resolve it with GET /members/{id}.
labelExpanded
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
nameThe label text. Send at least one of name or color when creating a label — an empty body is rejected. Names are unique per workspace among live labels: reusing one returns 409.
colorHex color, #RGB or #RRGGBB. Omit it and the server assigns a random palette color, so a label always has one. Stored lowercase and expanded to 6 digits, so #00A99B reads back as #00a99b. Send at least one of name or color when creating a label.
defaultTrue for the labels Nifty seeds into a workspace. Server-managed, and those labels are protected: renaming or deleting one returns 403.
typeWhat the label is for: others for an ordinary tag, member for the labels used to group people. Defaults to others, and cannot be changed afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdTeam member who moved this label to the trash. A member id — resolve it with GET /members/{id}.
The related Actor, present only when you pass ?expand=createdByActor.
The related Team Member, present only when you pass ?expand=deletedBy.
labelCreate
nameThe label text. Send at least one of name or color when creating a label — an empty body is rejected. Names are unique per workspace among live labels: reusing one returns 409.
color^#([0-9A-Fa-f]{3}|[0…Hex color, #RGB or #RRGGBB. Omit it and the server assigns a random palette color, so a label always has one. Stored lowercase and expanded to 6 digits, so #00A99B reads back as #00a99b. Send at least one of name or color when creating a label.
typeWhat the label is for: others for an ordinary tag, member for the labels used to group people. Defaults to others, and cannot be changed afterwards.
Decision Table
| Variant | Matching Criteria |
|---|---|
| type = object · requires: name | |
| type = object · requires: color |
nameThe label text. Send at least one of name or color when creating a label — an empty body is rejected. Names are unique per workspace among live labels: reusing one returns 409.
color^#([0-9A-Fa-f]{3}|[0…Hex color, #RGB or #RRGGBB. Omit it and the server assigns a random palette color, so a label always has one. Stored lowercase and expanded to 6 digits, so #00A99B reads back as #00a99b. Send at least one of name or color when creating a label.
typeWhat the label is for: others for an ordinary tag, member for the labels used to group people. Defaults to others, and cannot be changed afterwards.
labelUpdate
nameThe label text. Send at least one of name or color when creating a label — an empty body is rejected. Names are unique per workspace among live labels: reusing one returns 409.
color^#([0-9A-Fa-f]{3}|[0…Hex color, #RGB or #RRGGBB. Omit it and the server assigns a random palette color, so a label always has one. Stored lowercase and expanded to 6 digits, so #00A99B reads back as #00a99b. Send at least one of name or color when creating a label.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
list
idUnique identifier for this resource.
createdAtCreation timestamp.
projectIdProject this list belongs to (scope). Immutable after creation.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
archivedWhether this list is archived (hidden from the active timeline but preserved). Regular field, NOT a soft-delete.
nameList name. Trimmed; obvious spam is rejected with 400. Null only on lists created before this API existed.
descriptionList description
startStart date (ISO 8601). Required together with end whenever isMilestone is true — including when flipping it true with a PATCH. end must be at least 2 days after start; use a task with a due date for single-day work. Forced to null when isMilestone is false.
endEnd date (ISO 8601). Required together with start whenever isMilestone is true — including when flipping it true with a PATCH. Must be at least 2 days after start; use a task with a due date for single-day work. Forced to null when isMilestone is false.
orderSort order within the project timeline. Server-defaulted to MAX(order)+100 when omitted on create.
colorHex color, #RGB or #RRGGBB. Stored lowercase and expanded to 6 digits, so #0A9 reads back as #00aa99. Omitted on create → the server assigns a random palette color, so a list always has one.
isMilestonefalse (the default) = a flat list of tasks. true = a date-spanning milestone shown on the roadmap; it requires start and end at least 2 days apart.
dependencyIdId of the list that must finish before this one starts (timeline dependency). The target must belong to the same project, otherwise the request is rejected with 400.
statusIdWhen set, this list also appears as a column on the project board, backed by the given status. Cannot be changed after creation.
listExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
projectIdProject this list belongs to (scope). Immutable after creation.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
archivedWhether this list is archived (hidden from the active timeline but preserved). Regular field, NOT a soft-delete.
nameList name. Trimmed; obvious spam is rejected with 400. Null only on lists created before this API existed.
descriptionList description
startStart date (ISO 8601). Required together with end whenever isMilestone is true — including when flipping it true with a PATCH. end must be at least 2 days after start; use a task with a due date for single-day work. Forced to null when isMilestone is false.
endEnd date (ISO 8601). Required together with start whenever isMilestone is true — including when flipping it true with a PATCH. Must be at least 2 days after start; use a task with a due date for single-day work. Forced to null when isMilestone is false.
orderSort order within the project timeline. Server-defaulted to MAX(order)+100 when omitted on create.
colorHex color, #RGB or #RRGGBB. Stored lowercase and expanded to 6 digits, so #0A9 reads back as #00aa99. Omitted on create → the server assigns a random palette color, so a list always has one.
isMilestonefalse (the default) = a flat list of tasks. true = a date-spanning milestone shown on the roadmap; it requires start and end at least 2 days apart.
dependencyIdId of the list that must finish before this one starts (timeline dependency). The target must belong to the same project, otherwise the request is rejected with 400.
statusIdWhen set, this list also appears as a column on the project board, backed by the given status. Cannot be changed after creation.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
The related Project, present only when you pass ?expand=project.
The related List, present only when you pass ?expand=dependency.
The related Recurring Rule, present only when you pass ?expand=recurringRule.
The related Status, present only when you pass ?expand=status.
The linked Team Member rows, present only when you pass ?expand=assignees.
The linked Role rows, present only when you pass ?expand=hiddenFor.
The linked Goal rows, present only when you pass ?expand=goals.
The linked attachedCustomField rows, present only when you pass ?expand=customFields.
The linked Task rows, present only when you pass ?expand=tasks.
listCreate
nameList name. Trimmed; obvious spam is rejected with 400.
projectIdProject this list belongs to (scope). Immutable after creation.
descriptionList description
startStart date (ISO 8601). Required together with end whenever isMilestone is true — including when flipping it true with a PATCH. end must be at least 2 days after start; use a task with a due date for single-day work. Forced to null when isMilestone is false.
endEnd date (ISO 8601). Required together with start whenever isMilestone is true — including when flipping it true with a PATCH. Must be at least 2 days after start; use a task with a due date for single-day work. Forced to null when isMilestone is false.
orderSort order within the project timeline. Server-defaulted to MAX(order)+100 when omitted on create.
color^#([0-9A-Fa-f]{3}|[0…Hex color, #RGB or #RRGGBB. Stored lowercase and expanded to 6 digits, so #0A9 reads back as #00aa99. Omitted on create → the server assigns a random palette color, so a list always has one.
archivedWhether this list is archived (hidden from the active timeline but preserved). Regular field, NOT a soft-delete.
isMilestonefalse (the default) = a flat list of tasks. true = a date-spanning milestone shown on the roadmap; it requires start and end at least 2 days apart.
dependencyIdId of the list that must finish before this one starts (timeline dependency). The target must belong to the same project, otherwise the request is rejected with 400.
statusIdWhen set, this list also appears as a column on the project board, backed by the given status. Cannot be changed after creation.
assigneesTeam members assigned to this list. Replaces the whole set on update; use POST/DELETE /lists/{id}/assignees for a single add/remove.
hiddenForRoles this list is hidden from. Replaces the whole set on update; use POST /lists/{id}/hidden-for and POST /lists/{id}/hidden-for/remove for a single add/remove. Every id must be a role in the same workspace.
goalsGoals this list contributes toward. Replaces the whole set on update; use POST/DELETE /lists/{id}/goals for a single add/remove.
Set custom-field values on this list. Each entry is { customFieldId, value } and value is always a string — send "" to clear one. Max 50 entries per request. Read them back with ?expand=customFields.
listUpdate
nameList name. Trimmed; obvious spam is rejected with 400.
descriptionList description
startStart date (ISO 8601). Required together with end whenever isMilestone is true — including when flipping it true with a PATCH. end must be at least 2 days after start; use a task with a due date for single-day work. Forced to null when isMilestone is false.
endEnd date (ISO 8601). Required together with start whenever isMilestone is true — including when flipping it true with a PATCH. Must be at least 2 days after start; use a task with a due date for single-day work. Forced to null when isMilestone is false.
orderSort order within the project timeline. Server-defaulted to MAX(order)+100 when omitted on create.
color^#([0-9A-Fa-f]{3}|[0…Hex color, #RGB or #RRGGBB. Stored lowercase and expanded to 6 digits, so #0A9 reads back as #00aa99. Omitted on create → the server assigns a random palette color, so a list always has one.
archivedWhether this list is archived (hidden from the active timeline but preserved). Regular field, NOT a soft-delete.
isMilestonefalse (the default) = a flat list of tasks. true = a date-spanning milestone shown on the roadmap; it requires start and end at least 2 days apart.
dependencyIdId of the list that must finish before this one starts (timeline dependency). The target must belong to the same project, otherwise the request is rejected with 400.
assigneesTeam members assigned to this list. Replaces the whole set on update; use POST/DELETE /lists/{id}/assignees for a single add/remove.
hiddenForRoles this list is hidden from. Replaces the whole set on update; use POST /lists/{id}/hidden-for and POST /lists/{id}/hidden-for/remove for a single add/remove. Every id must be a role in the same workspace.
goalsGoals this list contributes toward. Replaces the whole set on update; use POST/DELETE /lists/{id}/goals for a single add/remove.
Set custom-field values on this list. Each entry is { customFieldId, value } and value is always a string — send "" to clear one. Max 50 entries per request. Read them back with ?expand=customFields.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
member
idTeam-member id (primary key)
userIdThe global user-account id behind this member. Not resolvable through this API — id is what every other resource references.
nameMember's display name
emailMember's email address.
avatarAvatar image URL.
initialsTwo-letter initials, shown when there is no avatar.
colorHex tint used for this member's avatar placeholder.
onlineWhether the member was connected at the moment this response was built. Point-in-time only; it is not pushed to you.
tzIanaIANA timezone, for example "America/Los_Angeles".
pendingTrue while the member has been invited but has not accepted yet. An active member has pending: false and removed: false.
removedTrue once the member has been removed from the team. Members are removed, not soft-deleted: there is no purgeAt and no restore window, though inviting the same email again reactivates the original record.
roleIdThe member's role, which decides what they may do. Changing it re-roles the member and can cascade permission changes across the workspace; it requires the editRole permission. A role name (for example manager) is accepted in place of an id.
themeThe colour theme this member sees in the Nifty app. Writable only on your own member record — writing another member's returns 403 whatever your role.
storyPointsCapacityHow many story points this member is expected to carry in a sprint. Writable only on your own member record.
memberExpanded
idTeam-member id (primary key)
userIdThe global user-account id behind this member. Not resolvable through this API — id is what every other resource references.
nameMember's display name
emailMember's email address.
avatarAvatar image URL.
initialsTwo-letter initials, shown when there is no avatar.
colorHex tint used for this member's avatar placeholder.
onlineWhether the member was connected at the moment this response was built. Point-in-time only; it is not pushed to you.
tzIanaIANA timezone, for example "America/Los_Angeles".
pendingTrue while the member has been invited but has not accepted yet. An active member has pending: false and removed: false.
removedTrue once the member has been removed from the team. Members are removed, not soft-deleted: there is no purgeAt and no restore window, though inviting the same email again reactivates the original record.
roleIdThe member's role, which decides what they may do. Changing it re-roles the member and can cascade permission changes across the workspace; it requires the editRole permission. A role name (for example manager) is accepted in place of an id.
themeThe colour theme this member sees in the Nifty app. Writable only on your own member record — writing another member's returns 403 whatever your role.
storyPointsCapacityHow many story points this member is expected to carry in a sprint. Writable only on your own member record.
The linked attachedCustomField rows, present only when you pass ?expand=customFields.
memberCreate
emailMember's email address.
nameThe invited person's display name. Defaults to the email address when omitted.
roleIdThe member's role, which decides what they may do. Changing it re-roles the member and can cascade permission changes across the workspace; it requires the editRole permission. A role name (for example manager) is accepted in place of an id.
projectIdOptionally add the invited member to this project at invite time.
memberUpdate
roleIdThe member's role, which decides what they may do. Changing it re-roles the member and can cascade permission changes across the workspace; it requires the editRole permission. A role name (for example manager) is accepted in place of an id.
themeThe colour theme this member sees in the Nifty app. Writable only on your own member record — writing another member's returns 403 whatever your role.
storyPointsCapacityHow many story points this member is expected to carry in a sprint. Writable only on your own member record.
Set custom-field values on this member. Each entry is { customFieldId, value } and value is always a string — send "" to clear one. Only on update: an invite rejects it with a 400. Read them back with ?expand=customFields.
message
idUnique identifier for this resource.
createdAtCreation timestamp.
teamIdTeam this message belongs to. Read-only — resolved from your credentials and from the message's parent context.
typeMessage kind: "text" | "gif" | "document" | "audio". Defaults to "text" when omitted on create; the non-text kinds require their own payload (url / sharedDocumentId / audioDuration), so only pass an explicit type for those. Fixed at creation — it cannot be changed afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
textMessage body, up to 655,350 characters. Supports Markdown formatting, plus embedded mention tags (<@memberId> person, <?taskId> task, <#projectId> project, <??statusId> status, <^listId> list, <~labelId> label, <$portfolioId> portfolio, <!discussionId> discussion). Token glyphs are the literal wire ref format. Nullable for non-text messages.
urlExternal URL for type=gif messages.
subtypeNon-null on the system/lifecycle messages the server generates (task assigned, label applied, member joined a chat). Null on messages a person or an agent wrote. Read-only — you cannot create a system message through the API. A few values are not self-explanatory: hello is the welcome message posted in a new chat, tieTask / untieTask record a dependency being added or removed between two tasks, and moveSubtask records a subtask being re-parented.
isEditedTrue when the text has been edited at least once. Server-managed by the edit path.
hideLinkPreviewWhen true, link previews are not rendered for URLs in this message.
botNameDisplay name shown for a message mirrored in from a connected app (for example a Slack channel). Null for messages written by a person or an agent. Read-only — set by the mirroring integration, never by an API client.
botAvatarAvatar URL shown for a message mirrored in from a connected app. Null for messages written by a person or an agent. Read-only — set by the mirroring integration, never by an API client.
audioDurationAudio playback duration in seconds — populated for type=audio messages.
Every edit made to this message, oldest first. Each entry carries timestamp and the editor: id is the team member who made the edit, or null when an agent or an integration did — in which case actorId identifies it. Server-managed.
authorIdThe team member who wrote this message — a member id, so resolve it with ?expand=author or GET /members/{id}. Null for system and app-mirrored messages — use createdByActorType to tell an agent-written message from a human one.
chatIdThe chat this message belongs to (group, direct, or a project discussion). Exactly one parent context per message.
taskIdThe task this message comments on. Exactly one parent context per message.
documentIdThe document this message comments on. Exactly one parent context per message.
fileIdThe file this message comments on. Exactly one parent context per message — fileId and annotationId may be sent together (a comment on an annotation drawn on a file).
annotationIdThe annotation this message is threaded under. Exactly one parent context per message — fileId and annotationId may be sent together (a comment on an annotation drawn on a file).
parentMessageIdThe message this one replies to. Exactly one parent context per message.
sharedDocumentIdA document shared into a chat message. Distinct from documentId, which marks a comment ON a document. Read-only — share a document from the Nifty app.
Resolved mentions found in text, as a read-only sidecar: each entry is { glyph (the raw <@id> token, still present in text), type (what the mention refers to — only member today), id, name (the display name, or null if the referenced member is deleted or not visible to you) }. Read text for the message; read mentions to show WHO is referenced without losing the ids. Absent when text has no mentions. Server-computed.
repliesCountHow many replies this message has in its thread — 0 when it has none. Named repliesCount because replies is the expandable thread relation on this resource. Server-computed. ⚠️ A reply hidden from your ROLE is excluded from ?expand=replies but is still counted here, so this can exceed the length of the array you receive.
repliersThe distinct TeamMembers who replied in this message's thread, as ids — [] when there is no thread. TeamMember shortids, NOT actor UUIDs: resolve one with GET /members/{id}. Server-computed, and carries the same role-redaction caveat as repliesCount.
messageExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
teamIdTeam this message belongs to. Read-only — resolved from your credentials and from the message's parent context.
typeMessage kind: "text" | "gif" | "document" | "audio". Defaults to "text" when omitted on create; the non-text kinds require their own payload (url / sharedDocumentId / audioDuration), so only pass an explicit type for those. Fixed at creation — it cannot be changed afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
textMessage body, up to 655,350 characters. Supports Markdown formatting, plus embedded mention tags (<@memberId> person, <?taskId> task, <#projectId> project, <??statusId> status, <^listId> list, <~labelId> label, <$portfolioId> portfolio, <!discussionId> discussion). Token glyphs are the literal wire ref format. Nullable for non-text messages.
urlExternal URL for type=gif messages.
subtypeNon-null on the system/lifecycle messages the server generates (task assigned, label applied, member joined a chat). Null on messages a person or an agent wrote. Read-only — you cannot create a system message through the API. A few values are not self-explanatory: hello is the welcome message posted in a new chat, tieTask / untieTask record a dependency being added or removed between two tasks, and moveSubtask records a subtask being re-parented.
isEditedTrue when the text has been edited at least once. Server-managed by the edit path.
hideLinkPreviewWhen true, link previews are not rendered for URLs in this message.
botNameDisplay name shown for a message mirrored in from a connected app (for example a Slack channel). Null for messages written by a person or an agent. Read-only — set by the mirroring integration, never by an API client.
botAvatarAvatar URL shown for a message mirrored in from a connected app. Null for messages written by a person or an agent. Read-only — set by the mirroring integration, never by an API client.
audioDurationAudio playback duration in seconds — populated for type=audio messages.
Every edit made to this message, oldest first. Each entry carries timestamp and the editor: id is the team member who made the edit, or null when an agent or an integration did — in which case actorId identifies it. Server-managed.
authorIdThe team member who wrote this message — a member id, so resolve it with ?expand=author or GET /members/{id}. Null for system and app-mirrored messages — use createdByActorType to tell an agent-written message from a human one.
chatIdThe chat this message belongs to (group, direct, or a project discussion). Exactly one parent context per message.
taskIdThe task this message comments on. Exactly one parent context per message.
documentIdThe document this message comments on. Exactly one parent context per message.
fileIdThe file this message comments on. Exactly one parent context per message — fileId and annotationId may be sent together (a comment on an annotation drawn on a file).
annotationIdThe annotation this message is threaded under. Exactly one parent context per message — fileId and annotationId may be sent together (a comment on an annotation drawn on a file).
parentMessageIdThe message this one replies to. Exactly one parent context per message.
sharedDocumentIdA document shared into a chat message. Distinct from documentId, which marks a comment ON a document. Read-only — share a document from the Nifty app.
Resolved mentions found in text, as a read-only sidecar: each entry is { glyph (the raw <@id> token, still present in text), type (what the mention refers to — only member today), id, name (the display name, or null if the referenced member is deleted or not visible to you) }. Read text for the message; read mentions to show WHO is referenced without losing the ids. Absent when text has no mentions. Server-computed.
repliesCountHow many replies this message has in its thread — 0 when it has none. Named repliesCount because replies is the expandable thread relation on this resource. Server-computed. ⚠️ A reply hidden from your ROLE is excluded from ?expand=replies but is still counted here, so this can exceed the length of the array you receive.
repliersThe distinct TeamMembers who replied in this message's thread, as ids — [] when there is no thread. TeamMember shortids, NOT actor UUIDs: resolve one with GET /members/{id}. Server-computed, and carries the same role-redaction caveat as repliesCount.
The related Team Member, present only when you pass ?expand=author.
The related Team Member, present only when you pass ?expand=deletedBy.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
The related Chat, present only when you pass ?expand=chat.
The related Task, present only when you pass ?expand=task.
The related Document, present only when you pass ?expand=document.
The related File, present only when you pass ?expand=file.
The related Annotation, present only when you pass ?expand=annotation.
The related Message, present only when you pass ?expand=parentMessage.
The related Document, present only when you pass ?expand=sharedDocument.
The linked Team Member rows, present only when you pass ?expand=tagged.
The linked Team Member rows, present only when you pass ?expand=seenBy.
The linked Role rows, present only when you pass ?expand=hiddenFor.
The linked File rows, present only when you pass ?expand=files.
The linked Message rows, present only when you pass ?expand=replies.
messageCreated
idUnique identifier for this resource.
createdAtCreation timestamp.
teamIdTeam this message belongs to. Read-only — resolved from your credentials and from the message's parent context.
typeMessage kind: "text" | "gif" | "document" | "audio". Defaults to "text" when omitted on create; the non-text kinds require their own payload (url / sharedDocumentId / audioDuration), so only pass an explicit type for those. Fixed at creation — it cannot be changed afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
textMessage body, up to 655,350 characters. Supports Markdown formatting, plus embedded mention tags (<@memberId> person, <?taskId> task, <#projectId> project, <??statusId> status, <^listId> list, <~labelId> label, <$portfolioId> portfolio, <!discussionId> discussion). Token glyphs are the literal wire ref format. Nullable for non-text messages.
urlExternal URL for type=gif messages.
subtypeNon-null on the system/lifecycle messages the server generates (task assigned, label applied, member joined a chat). Null on messages a person or an agent wrote. Read-only — you cannot create a system message through the API. A few values are not self-explanatory: hello is the welcome message posted in a new chat, tieTask / untieTask record a dependency being added or removed between two tasks, and moveSubtask records a subtask being re-parented.
isEditedTrue when the text has been edited at least once. Server-managed by the edit path.
hideLinkPreviewWhen true, link previews are not rendered for URLs in this message.
botNameDisplay name shown for a message mirrored in from a connected app (for example a Slack channel). Null for messages written by a person or an agent. Read-only — set by the mirroring integration, never by an API client.
botAvatarAvatar URL shown for a message mirrored in from a connected app. Null for messages written by a person or an agent. Read-only — set by the mirroring integration, never by an API client.
audioDurationAudio playback duration in seconds — populated for type=audio messages.
Every edit made to this message, oldest first. Each entry carries timestamp and the editor: id is the team member who made the edit, or null when an agent or an integration did — in which case actorId identifies it. Server-managed.
authorIdThe team member who wrote this message — a member id, so resolve it with ?expand=author or GET /members/{id}. Null for system and app-mirrored messages — use createdByActorType to tell an agent-written message from a human one.
chatIdThe chat this message belongs to (group, direct, or a project discussion). Exactly one parent context per message.
taskIdThe task this message comments on. Exactly one parent context per message.
documentIdThe document this message comments on. Exactly one parent context per message.
fileIdThe file this message comments on. Exactly one parent context per message — fileId and annotationId may be sent together (a comment on an annotation drawn on a file).
annotationIdThe annotation this message is threaded under. Exactly one parent context per message — fileId and annotationId may be sent together (a comment on an annotation drawn on a file).
parentMessageIdThe message this one replies to. Exactly one parent context per message.
sharedDocumentIdA document shared into a chat message. Distinct from documentId, which marks a comment ON a document. Read-only — share a document from the Nifty app.
Resolved mentions found in text, as a read-only sidecar: each entry is { glyph (the raw <@id> token, still present in text), type (what the mention refers to — only member today), id, name (the display name, or null if the referenced member is deleted or not visible to you) }. Read text for the message; read mentions to show WHO is referenced without losing the ids. Absent when text has no mentions. Server-computed.
repliesCountHow many replies this message has in its thread — 0 when it has none. Named repliesCount because replies is the expandable thread relation on this resource. Server-computed. ⚠️ A reply hidden from your ROLE is excluded from ?expand=replies but is still counted here, so this can exceed the length of the array you receive.
repliersThe distinct TeamMembers who replied in this message's thread, as ids — [] when there is no thread. TeamMember shortids, NOT actor UUIDs: resolve one with GET /members/{id}. Server-computed, and carries the same role-redaction caveat as repliesCount.
createdDM idempotency signal (create-response only): true if recipientMemberId minted a new direct chat, false if an existing 1:1 was reused. Absent for non-DM creates.
messageCreate
textMessage body. Supports Markdown formatting, plus embedded mention tags (<@memberId> person, <?taskId> task, <#projectId> project, <??statusId> status, <^listId> list, <~labelId> label, <$portfolioId> portfolio, <!discussionId> discussion). Nullable for non-text messages (gif, audio).
urlExternal URL — used for type=gif messages (GIF source URL). Null otherwise.
typeMessage kind: "text" | "gif" | "document" | "audio". Defaults to "text" when omitted on create; the non-text kinds require their own payload (url / sharedDocumentId / audioDuration), so only pass an explicit type for those. Fixed at creation — it cannot be changed afterwards.
hideLinkPreviewWhen true, link previews are not rendered for URLs in this message.
audioDurationAudio playback duration in seconds — populated for type=audio messages.
chatIdThe chat this message belongs to (group, direct, or a project discussion). Exactly one parent context per message.
taskIdThe task this message comments on. Exactly one parent context per message.
documentIdThe document this message comments on. Exactly one parent context per message.
fileIdThe file this message comments on. Exactly one parent context per message — fileId and annotationId may be sent together (a comment on an annotation drawn on a file).
annotationIdThe annotation this message is threaded under. Exactly one parent context per message — fileId and annotationId may be sent together (a comment on an annotation drawn on a file).
parentMessageIdThe message this one replies to. Exactly one parent context per message.
recipientMemberIdSend a direct message: provide this instead of chatId, taskId or the other parent contexts. The 1:1 chat is created if it does not exist. Create-only, and must differ from the caller.
taggedTeam members to @-mention on this message, by id. Accepted when the message is created; the mention list of an existing message is not editable, so it is not part of the update body. Read them back with ?expand=tagged.
filesExisting files attached to this message, by id. Writable on create and on update: on update the array you send becomes the COMPLETE set, so a file dropped from it is detached (the file itself is not deleted). Omit the key to leave it untouched. Read them back with ?expand=files.
Decision Table
| Variant | Matching Criteria |
|---|---|
| type = object · requires: chatId | |
| type = object · requires: taskId | |
| type = object · requires: documentId | |
| type = object · requires: fileId | |
| type = object · requires: annotationId | |
| type = object · requires: parentMessageId | |
| type = object · requires: recipientMemberId |
chatIdThe chat this message belongs to (group, direct, or a project discussion). Exactly one parent context per message.
textMessage body. Supports Markdown formatting, plus embedded mention tags (<@memberId> person, <?taskId> task, <#projectId> project, <??statusId> status, <^listId> list, <~labelId> label, <$portfolioId> portfolio, <!discussionId> discussion). Nullable for non-text messages (gif, audio).
urlExternal URL — used for type=gif messages (GIF source URL). Null otherwise.
typeMessage kind: "text" | "gif" | "document" | "audio". Defaults to "text" when omitted on create; the non-text kinds require their own payload (url / sharedDocumentId / audioDuration), so only pass an explicit type for those. Fixed at creation — it cannot be changed afterwards.
hideLinkPreviewWhen true, link previews are not rendered for URLs in this message.
audioDurationAudio playback duration in seconds — populated for type=audio messages.
taskIdThe task this message comments on. Exactly one parent context per message.
documentIdThe document this message comments on. Exactly one parent context per message.
fileIdThe file this message comments on. Exactly one parent context per message — fileId and annotationId may be sent together (a comment on an annotation drawn on a file).
annotationIdThe annotation this message is threaded under. Exactly one parent context per message — fileId and annotationId may be sent together (a comment on an annotation drawn on a file).
parentMessageIdThe message this one replies to. Exactly one parent context per message.
recipientMemberIdSend a direct message: provide this instead of chatId, taskId or the other parent contexts. The 1:1 chat is created if it does not exist. Create-only, and must differ from the caller.
taggedTeam members to @-mention on this message, by id. Accepted when the message is created; the mention list of an existing message is not editable, so it is not part of the update body. Read them back with ?expand=tagged.
filesExisting files attached to this message, by id. Writable on create and on update: on update the array you send becomes the COMPLETE set, so a file dropped from it is detached (the file itself is not deleted). Omit the key to leave it untouched. Read them back with ?expand=files.
messageUpdate
textMessage body. Supports Markdown formatting, plus embedded mention tags (<@memberId> person, <?taskId> task, <#projectId> project, <??statusId> status, <^listId> list, <~labelId> label, <$portfolioId> portfolio, <!discussionId> discussion). Nullable for non-text messages (gif, audio).
hideLinkPreviewWhen true, link previews are not rendered for URLs in this message.
filesExisting files attached to this message, by id. Writable on create and on update: on update the array you send becomes the COMPLETE set, so a file dropped from it is detached (the file itself is not deleted). Omit the key to leave it untouched. Read them back with ?expand=files.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
portfolio
idUnique identifier for this resource.
createdAtCreation timestamp.
nameDisplay name. Maximum 100 characters.
initialsUp to 3 characters shown when the portfolio has no icon. Derived from name when omitted on create.
colorPrimary brand colour as a 6-digit hex value, e.g. #00A99B. Assigned from the Nifty palette when omitted on create.
secondaryColorSecondary brand colour as a 6-digit hex value. Derived from color; values sent by a client are ignored.
isGeneralTrue for the team's General portfolio. Every team has exactly one: projects created without a portfolioId land there, and it cannot be deleted.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
iconIcon image URL for the portfolio.
orderSort order of this portfolio within the team. Auto-assigned on create; send a new value to reorder.
ownerIdTeam member designated as the portfolio owner. Set with PATCH — on create the owner is always the caller (or the team owner for a non-member caller), so it is not part of the create body.
portfolioExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
nameDisplay name. Maximum 100 characters.
initialsUp to 3 characters shown when the portfolio has no icon. Derived from name when omitted on create.
colorPrimary brand colour as a 6-digit hex value, e.g. #00A99B. Assigned from the Nifty palette when omitted on create.
secondaryColorSecondary brand colour as a 6-digit hex value. Derived from color; values sent by a client are ignored.
isGeneralTrue for the team's General portfolio. Every team has exactly one: projects created without a portfolioId land there, and it cannot be deleted.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
iconIcon image URL for the portfolio.
orderSort order of this portfolio within the team. Auto-assigned on create; send a new value to reorder.
ownerIdTeam member designated as the portfolio owner. Set with PATCH — on create the owner is always the caller (or the team owner for a non-member caller), so it is not part of the create body.
The related Team Member, present only when you pass ?expand=owner.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
The related Team Member, present only when you pass ?expand=deletedBy.
The linked Team Member rows, present only when you pass ?expand=members.
portfolioCreate
nameDisplay name. Maximum 100 characters.
iconIcon image URL for the portfolio.
initialsUp to 3 characters shown when the portfolio has no icon. Derived from name when omitted on create.
colorPrimary brand colour as a 6-digit hex value, e.g. #00A99B. Assigned from the Nifty palette when omitted on create.
orderSort order of this portfolio within the team. Auto-assigned on create; send a new value to reorder.
membersTeam member ids belonging to this portfolio. Send members in the create or update body to REPLACE the whole roster; use POST / DELETE /portfolios/{id}/members to add or remove individuals without touching the rest. Read the materialized rows with ?expand=members.
portfolioUpdate
nameDisplay name. Maximum 100 characters.
iconIcon image URL for the portfolio.
initialsUp to 3 characters shown when the portfolio has no icon. Derived from name when omitted on create.
colorPrimary brand colour as a 6-digit hex value, e.g. #00A99B. Assigned from the Nifty palette when omitted on create.
ownerIdTeam member designated as the portfolio owner. Set with PATCH — on create the owner is always the caller (or the team owner for a non-member caller), so it is not part of the create body.
orderSort order of this portfolio within the team. Auto-assigned on create; send a new value to reorder.
membersTeam member ids belonging to this portfolio. Send members in the create or update body to REPLACE the whole roster; use POST / DELETE /portfolios/{id}/members to add or remove individuals without touching the rest. Read the materialized rows with ?expand=members.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
presenceStatus
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
nameName of the status, shown to the team.
appearsOnlineWhether the member is shown as online to their team while this status is active. This is an intent you set, not a live presence reading.
muteNotificationsWhether the member's notifications are silenced while this status is active.
isDefaultTrue for the templates Nifty seeds into every workspace. Server-managed: you cannot promote or demote a template through the API.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
emojiA single emoji shown beside the status.
defaultDurationMsHow long the status stays on before it expires by itself, in milliseconds — 3600000 is one hour. Omit it (or send null) for a status that never auto-expires.
presenceStatusExpanded
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
nameName of the status, shown to the team.
appearsOnlineWhether the member is shown as online to their team while this status is active. This is an intent you set, not a live presence reading.
muteNotificationsWhether the member's notifications are silenced while this status is active.
isDefaultTrue for the templates Nifty seeds into every workspace. Server-managed: you cannot promote or demote a template through the API.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
emojiA single emoji shown beside the status.
defaultDurationMsHow long the status stays on before it expires by itself, in milliseconds — 3600000 is one hour. Omit it (or send null) for a status that never auto-expires.
The related Actor, present only when you pass ?expand=createdByActor.
presenceStatusCreate
nameName of the status, shown to the team.
appearsOnlineWhether the member is shown as online to their team while this status is active. This is an intent you set, not a live presence reading.
emojiA single emoji shown beside the status.
muteNotificationsWhether the member's notifications are silenced while this status is active.
defaultDurationMsHow long the status stays on before it expires by itself, in milliseconds — 3600000 is one hour. Omit it (or send null) for a status that never auto-expires.
presenceStatusUpdate
nameName of the status, shown to the team.
appearsOnlineWhether the member is shown as online to their team while this status is active. This is an intent you set, not a live presence reading.
emojiA single emoji shown beside the status.
muteNotificationsWhether the member's notifications are silenced while this status is active.
defaultDurationMsHow long the status stays on before it expires by itself, in milliseconds — 3600000 is one hour. Omit it (or send null) for a status that never auto-expires.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
project
idUnique identifier for this resource.
createdAtCreation timestamp.
nameDisplay name. Must be unique among the projects in the same portfolio. Maximum 100 characters.
initialsUp to 3 characters shown when the project has no icon. Derived from name when omitted.
colorPrimary brand colour as a 6-digit hex value, e.g. #00A99B. Assigned from the Nifty palette when omitted.
secondaryColorSecondary brand colour as a 6-digit hex value. Derived from color when omitted.
accessTypeVisibility: limited (default — members only) or public (team-wide; all team members are added automatically). A project has exactly these two levels.
modulesFeature tabs the project exposes. SELECT only the ones this project needs — OMITTING the field enables ALL 8, which clutters a focused project. Options: tasks (the task board), milestones (dated roadmap of lists), calendar (calendar of dated items), documents (collaborative docs), files (file storage), discussion (threaded project discussions), forms (intake/survey forms), home (project overview). e.g. a content calendar → [tasks, calendar, files]; a bug tracker → [tasks]; a knowledge base → [documents, files]. Set once at create; immutable afterwards.
autoMilestonesWhen true, monthly lists are created automatically for this project. Applied at create time.
hideUsersFromGuestsHide member list from guest role
subtaskStatusEnabledEnable per-subtask status tracking
queryAllFilesQuery files across all tasks
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
archivedArchived projects are hidden from default project lists. Archiving does NOT cascade — tasks and lists inside the project stay active. Set it with PATCH; a project cannot be created already archived.
niceIdShort project key used in task references — a project with the key PRJ has tasks that read PRJ-14. Server-generated.
descriptionOptional project description. Supports Markdown formatting.
iconIcon image URL for the project. Objects use icon; people use avatar.
portfolioIdThe portfolio this project is grouped under. Defaults to the team's General portfolio when omitted on create. Immutable after create.
defaultTasksViewDefault task board view: table, calendar, swimlane, kanban, timeline or report.
hiddenListColumnsColumns hidden on the list view. Each entry is either a built-in column key (name, assignee, dueDate, status, list, labels, estimate) or the id of a custom field attached to the project.
listColumnsOrderList-view columns in display order, using the same vocabulary as hiddenListColumns — built-in column keys and/or attached custom-field ids.
customFieldsOrderProject-level custom-field ids in display order.
taskCustomFieldsOrderTask-level custom-field ids in display order.
listCustomFieldsOrderList-level custom-field ids in display order.
projectFolderIdThe project folder this project is filed under, within its portfolio. null = unfiled.
ownerIdThe team member who owns this project. Change it with the project transfer operation — it is not settable on create or update. Null only while a project has no owner (a workspace-imported project, or one whose owner has been removed from the team).
discussionChatIdId of the project's discussion chat, or null if it has none. Fetch its messages with GET /messages?chatId=<this>. Reading those messages requires chat membership — access to the project alone is not enough. Discussion-chat messages only: this is NOT a union of the project's task, document and file comments.
defaultStatusIdThe project's first status column, where a new task lands by default. Pass it as statusId when creating a task — a task with no status is invisible on the board. null until the project has a status. Not returned on create/update responses; read it with GET /projects/{id}.
projectExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
nameDisplay name. Must be unique among the projects in the same portfolio. Maximum 100 characters.
initialsUp to 3 characters shown when the project has no icon. Derived from name when omitted.
colorPrimary brand colour as a 6-digit hex value, e.g. #00A99B. Assigned from the Nifty palette when omitted.
secondaryColorSecondary brand colour as a 6-digit hex value. Derived from color when omitted.
accessTypeVisibility: limited (default — members only) or public (team-wide; all team members are added automatically). A project has exactly these two levels.
modulesFeature tabs the project exposes. SELECT only the ones this project needs — OMITTING the field enables ALL 8, which clutters a focused project. Options: tasks (the task board), milestones (dated roadmap of lists), calendar (calendar of dated items), documents (collaborative docs), files (file storage), discussion (threaded project discussions), forms (intake/survey forms), home (project overview). e.g. a content calendar → [tasks, calendar, files]; a bug tracker → [tasks]; a knowledge base → [documents, files]. Set once at create; immutable afterwards.
autoMilestonesWhen true, monthly lists are created automatically for this project. Applied at create time.
hideUsersFromGuestsHide member list from guest role
subtaskStatusEnabledEnable per-subtask status tracking
queryAllFilesQuery files across all tasks
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdMember who soft-deleted this resource (server-stamped). A member id — resolve it with GET /members/{id}.
archivedArchived projects are hidden from default project lists. Archiving does NOT cascade — tasks and lists inside the project stay active. Set it with PATCH; a project cannot be created already archived.
niceIdShort project key used in task references — a project with the key PRJ has tasks that read PRJ-14. Server-generated.
descriptionOptional project description. Supports Markdown formatting.
iconIcon image URL for the project. Objects use icon; people use avatar.
portfolioIdThe portfolio this project is grouped under. Defaults to the team's General portfolio when omitted on create. Immutable after create.
defaultTasksViewDefault task board view: table, calendar, swimlane, kanban, timeline or report.
hiddenListColumnsColumns hidden on the list view. Each entry is either a built-in column key (name, assignee, dueDate, status, list, labels, estimate) or the id of a custom field attached to the project.
listColumnsOrderList-view columns in display order, using the same vocabulary as hiddenListColumns — built-in column keys and/or attached custom-field ids.
customFieldsOrderProject-level custom-field ids in display order.
taskCustomFieldsOrderTask-level custom-field ids in display order.
listCustomFieldsOrderList-level custom-field ids in display order.
projectFolderIdThe project folder this project is filed under, within its portfolio. null = unfiled.
ownerIdThe team member who owns this project. Change it with the project transfer operation — it is not settable on create or update. Null only while a project has no owner (a workspace-imported project, or one whose owner has been removed from the team).
discussionChatIdId of the project's discussion chat, or null if it has none. Fetch its messages with GET /messages?chatId=<this>. Reading those messages requires chat membership — access to the project alone is not enough. Discussion-chat messages only: this is NOT a union of the project's task, document and file comments.
defaultStatusIdThe project's first status column, where a new task lands by default. Pass it as statusId when creating a task — a task with no status is invisible on the board. null until the project has a status. Not returned on create/update responses; read it with GET /projects/{id}.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
The related Team Member, present only when you pass ?expand=deletedBy.
The linked Team Member rows, present only when you pass ?expand=members.
The related Portfolio, present only when you pass ?expand=portfolio.
The linked Chat rows, present only when you pass ?expand=discussionChat.
The linked attachedCustomField rows, present only when you pass ?expand=customFields.
projectCreate
nameDisplay name. Must be unique among the projects in the same portfolio. Maximum 100 characters.
descriptionOptional project description. Supports Markdown formatting.
iconIcon image URL for the project. Objects use icon; people use avatar.
initialsUp to 3 characters shown when the project has no icon. Derived from name when omitted.
color^#[0-9A-Fa-f]{6}$Primary brand colour as a 6-digit hex value, e.g. #00A99B. Assigned from the Nifty palette when omitted.
secondaryColor^#[0-9A-Fa-f]{6}$Secondary brand colour as a 6-digit hex value. Derived from color when omitted.
portfolioIdThe portfolio this project is grouped under. Defaults to the team's General portfolio when omitted on create. Immutable after create.
accessTypeVisibility: limited (default — only invited members) or public (all team members auto-added). Omit for limited; pass public explicitly to make the project team-wide.
modulesFeature tabs the project exposes. Omitting the field enables all eight. Options: tasks (the task board), milestones (dated roadmap of lists), calendar (calendar of dated items), documents (collaborative docs), files (file storage), discussion (threaded project discussions), forms (intake/survey forms), home (project overview). e.g. a content calendar → [tasks, calendar, files]; a bug tracker → [tasks]; a knowledge base → [documents, files]; a client project → [tasks, milestones, files, discussion].
defaultTasksViewDefault task board view: table | calendar | swimlane | kanban | timeline | report.
hiddenListColumnsColumns hidden on the list view. Each entry is either a built-in column key (name, assignee, dueDate, status, list, labels, estimate) or the id of a custom field attached to the project.
listColumnsOrderList-view columns in display order, using the same vocabulary as hiddenListColumns — built-in column keys and/or attached custom-field ids.
customFieldsOrderProject-level custom-field ids in display order.
taskCustomFieldsOrderTask-level custom-field ids in display order.
listCustomFieldsOrderList-level custom-field ids in display order.
autoMilestonesWhen true, monthly lists are created automatically for this project. Applied at create time.
hideUsersFromGuestsHide member list from guest role
subtaskStatusEnabledEnable per-subtask status tracking
queryAllFilesQuery files across all tasks
membersTeam member ids on this project. REPLACE semantics — the array you send in the create or update body becomes the complete roster: ids you omit are removed, ids you add are invited. Omit the key to leave the roster untouched. Read the materialized rows with ?expand=members.
projectFolderIdThe project folder this project is filed under, within its portfolio. null = unfiled.
Custom-field values on this project. READ: ?expand=customFields returns the values attached to this project. WRITE: include customFields: [{ customFieldId, value }] in the create/update body to set values — each one is checked against its field definition before the write commits (value is always a string; max 50 entries per request; "" clears). Field definitions live on the read-only customField resource.
projectUpdate
nameDisplay name. Must be unique among the projects in the same portfolio. Maximum 100 characters.
descriptionOptional project description. Supports Markdown formatting.
iconIcon image URL for the project. Objects use icon; people use avatar.
initialsUp to 3 characters shown when the project has no icon. Derived from name when omitted.
color^#[0-9A-Fa-f]{6}$Primary brand colour as a 6-digit hex value, e.g. #00A99B. Assigned from the Nifty palette when omitted.
secondaryColor^#[0-9A-Fa-f]{6}$Secondary brand colour as a 6-digit hex value. Derived from color when omitted.
archivedArchived projects are hidden from default project lists. Archiving does NOT cascade — tasks and lists inside the project stay active. Set it with PATCH; a project cannot be created already archived.
accessTypeVisibility: limited (default — only invited members) or public (all team members auto-added). Omit for limited; pass public explicitly to make the project team-wide.
defaultTasksViewDefault task board view: table | calendar | swimlane | kanban | timeline | report.
hiddenListColumnsColumns hidden on the list view. Each entry is either a built-in column key (name, assignee, dueDate, status, list, labels, estimate) or the id of a custom field attached to the project.
listColumnsOrderList-view columns in display order, using the same vocabulary as hiddenListColumns — built-in column keys and/or attached custom-field ids.
customFieldsOrderProject-level custom-field ids in display order.
taskCustomFieldsOrderTask-level custom-field ids in display order.
listCustomFieldsOrderList-level custom-field ids in display order.
autoMilestonesWhen true, monthly lists are created automatically for this project. Applied at create time.
hideUsersFromGuestsHide member list from guest role
subtaskStatusEnabledEnable per-subtask status tracking
queryAllFilesQuery files across all tasks
membersTeam member ids on this project. REPLACE semantics — the array you send in the create or update body becomes the complete roster: ids you omit are removed, ids you add are invited. Omit the key to leave the roster untouched. Read the materialized rows with ?expand=members.
projectFolderIdThe project folder this project is filed under, within its portfolio. null = unfiled.
Custom-field values on this project. READ: ?expand=customFields returns the values attached to this project. WRITE: include customFields: [{ customFieldId, value }] in the create/update body to set values — each one is checked against its field definition before the write commits (value is always a string; max 50 entries per request; "" clears). Field definitions live on the read-only customField resource.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
projectActivity
idUnique identifier for this resource.
createdAtWhen the event happened.
projectIdThe project this activity belongs to.
typeWhat happened: projectCreated, usersJoined, usersLeft, listCreated, listMilestoneCreated, listUnlocked, taskCompleted, fileUploaded or docCreated. This value determines which of the reference ids below is set.
taskIdThe task this activity references. Set for taskCompleted; null otherwise.
listIdThe list this activity references. Set for listCreated, listMilestoneCreated and listUnlocked; null otherwise.
documentIdThe document this activity references. Set for docCreated; null otherwise.
fileIdThe file this activity references. Set for fileUploaded; null otherwise.
memberIdThe team member who joined or left. Set for usersJoined and usersLeft; null otherwise.
triggeredByIdThe team member who triggered this event, or null when it was triggered by an automation, an agent or a scheduled job. A member id — resolve it with GET /members/{id}.
projectActivityExpanded
idUnique identifier for this resource.
createdAtWhen the event happened.
projectIdThe project this activity belongs to.
typeWhat happened: projectCreated, usersJoined, usersLeft, listCreated, listMilestoneCreated, listUnlocked, taskCompleted, fileUploaded or docCreated. This value determines which of the reference ids below is set.
taskIdThe task this activity references. Set for taskCompleted; null otherwise.
listIdThe list this activity references. Set for listCreated, listMilestoneCreated and listUnlocked; null otherwise.
documentIdThe document this activity references. Set for docCreated; null otherwise.
fileIdThe file this activity references. Set for fileUploaded; null otherwise.
memberIdThe team member who joined or left. Set for usersJoined and usersLeft; null otherwise.
triggeredByIdThe team member who triggered this event, or null when it was triggered by an automation, an agent or a scheduled job. A member id — resolve it with GET /members/{id}.
The related Project, present only when you pass ?expand=project.
The related Task, present only when you pass ?expand=task.
The related List, present only when you pass ?expand=list.
The related Document, present only when you pass ?expand=document.
The related File, present only when you pass ?expand=file.
The related Team Member, present only when you pass ?expand=triggeredBy.
projectDashboard
idUnique identifier for this resource.
createdAtCreation timestamp.
nameDisplay name for the dashboard. Maximum 100 characters.
projectIdThe project this dashboard belongs to. Set once on create; a dashboard cannot move between projects.
isSharedWhen true the dashboard is visible to all project members; when false it is private to whoever created it. Setting isDefault: true forces isShared: true.
isDefaultThe project's default dashboard. Setting it to true also forces isShared: true and clears isDefault on the project's previous default — a project has at most one.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
Ordered widget cards owned by this dashboard. REPLACE semantics — the array you send becomes the complete widget set: omit the key to leave the widgets untouched, send [] to remove all of them, and re-send every widget you want to keep (any you leave out are deleted). Each widget's position comes from its index in the array.
projectDashboardExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
nameDisplay name for the dashboard. Maximum 100 characters.
projectIdThe project this dashboard belongs to. Set once on create; a dashboard cannot move between projects.
isSharedWhen true the dashboard is visible to all project members; when false it is private to whoever created it. Setting isDefault: true forces isShared: true.
isDefaultThe project's default dashboard. Setting it to true also forces isShared: true and clears isDefault on the project's previous default — a project has at most one.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
Ordered widget cards owned by this dashboard. REPLACE semantics — the array you send becomes the complete widget set: omit the key to leave the widgets untouched, send [] to remove all of them, and re-send every widget you want to keep (any you leave out are deleted). Each widget's position comes from its index in the array.
The related Project, present only when you pass ?expand=project.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
projectDashboardCreate
nameDisplay name for the dashboard. Maximum 100 characters.
projectIdThe project this dashboard belongs to. Set once on create; a dashboard cannot move between projects.
isSharedWhen true the dashboard is visible to all project members; when false it is private to whoever created it. Setting isDefault: true forces isShared: true.
isDefaultThe project's default dashboard. Setting it to true also forces isShared: true and clears isDefault on the project's previous default — a project has at most one.
Ordered widget cards owned by this dashboard. REPLACE semantics — the array you send becomes the complete widget set: omit the key to leave the widgets untouched, send [] to remove all of them, and re-send every widget you want to keep (any you leave out are deleted). Each widget's position comes from its index in the array.
projectDashboardUpdate
nameDisplay name for the dashboard. Maximum 100 characters.
isSharedWhen true the dashboard is visible to all project members; when false it is private to whoever created it. Setting isDefault: true forces isShared: true.
isDefaultThe project's default dashboard. Setting it to true also forces isShared: true and clears isDefault on the project's previous default — a project has at most one.
Ordered widget cards owned by this dashboard. REPLACE semantics — the array you send becomes the complete widget set: omit the key to leave the widgets untouched, send [] to remove all of them, and re-send every widget you want to keep (any you leave out are deleted). Each widget's position comes from its index in the array.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
projectFolder
idUnique identifier for this resource.
createdAtCreation timestamp.
nameFolder display name. Maximum 30 characters.
portfolioIdThe portfolio that contains this project folder. Required on create and immutable after — a folder cannot be moved between portfolios.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
orderSort order of this project folder within its portfolio. Server-assigned on create; send a new value to reorder.
projectFolderExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
nameFolder display name. Maximum 30 characters.
portfolioIdThe portfolio that contains this project folder. Required on create and immutable after — a folder cannot be moved between portfolios.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
orderSort order of this project folder within its portfolio. Server-assigned on create; send a new value to reorder.
The related Portfolio, present only when you pass ?expand=portfolio.
The linked Project rows, present only when you pass ?expand=projects.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
projectFolderCreate
nameFolder display name. Maximum 30 characters.
portfolioIdThe portfolio that contains this project folder. Required on create and immutable after — a folder cannot be moved between portfolios.
orderSort order of this project folder within its portfolio. Server-assigned on create; send a new value to reorder.
projectFolderUpdate
nameFolder display name. Maximum 30 characters.
orderSort order of this project folder within its portfolio. Server-assigned on create; send a new value to reorder.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
recurringRule
idUnique identifier for this resource.
createdAtCreation timestamp.
typeWhat makes this rule fire. date — a cron or schedule timetable. status — the anchored task moving into triggerStatusId. completion — the anchored task being completed. Set once when the rule is created; it cannot be changed afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
cronStandard 5-field cron for date rules — minute, hour, day-of-month, month, day-of-week (no seconds field). It must resolve to a SINGLE minute and a SINGLE hour: ranges, lists and steps in those two positions are rejected. Occurrences are computed in the timezone reported by tzIana.
Recurrence timetable for date rules, as an alternative to cron. Send one or the other — if both are present, cron wins and schedule is ignored.
Restricts what each spawned task copies from the anchored task. Omit it (or send null) and everything is copied — this is an allowlist, not a set of extras. Allowed entries: description, embedUrl, startAt, dueAt, labels, fields (custom-field values), subtasks.
Shifts dates on each spawned task, relative to the date it is spawned on: [{ "type": "dueAt", "offset": 3 }] gives every new task a due date 3 days out. offset is a whole number of days and may be negative.
endWhen the recurrence stops (ISO 8601 timestamp). It must fall after the next occurrence. Once passed, the rule stops spawning: nextRecurrenceAt and sourceTaskId are both cleared.
weekParityThins a date recurrence out to every other ISO week. off (the default) fires every matching week; skipEvenWeeks fires only in odd ISO weeks; skipOddWeeks fires only in even ones.
recurOnDateOnlyFor date rules: when true the rule fires strictly on its timetable, instead of also spawning early if the anchored task is completed ahead of schedule.
triggerStatusIdFor status rules: the status whose arrival fires the rule — the next task is spawned when the anchored task moves into it. Required on a status rule and rejected on any other type. Set once when the rule is created.
onCompleteRead-only: true on completion rules, false on every other type. Derived from type — it is not part of the create body.
sourceTaskIdThe task this rule is anchored to. Required when the rule is created, and server-managed afterwards: each time the rule spawns, the engine repoints it at the newly created task, and it becomes null once end has passed — so a read can return a different task than you sent, or none.
nextRecurrenceAtNext occurrence (server-computed from cron/schedule + the author timezone snapshot). THE engine cursor — the nifty-crons poll selects rules by it; NEVER client-writable (a stale/forged value kills or force-spawns the rule).
targetStatusIdThe status each spawned task is placed into — taken from the anchored task when the rule was created.
tzIanaThe author's IANA timezone (e.g. 'America/New_York'), snapshotted server-side at create/update — the timezone the engine spawns occurrences in. Read-only display field; never client-writable.
tzOffsetThe author's UTC offset in MINUTES EAST of UTC at the time the rule was saved, matching tzIana (New York in winter is -300). Recorded by the server; never writable.
recurringRuleExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
typeWhat makes this rule fire. date — a cron or schedule timetable. status — the anchored task moving into triggerStatusId. completion — the anchored task being completed. Set once when the rule is created; it cannot be changed afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
cronStandard 5-field cron for date rules — minute, hour, day-of-month, month, day-of-week (no seconds field). It must resolve to a SINGLE minute and a SINGLE hour: ranges, lists and steps in those two positions are rejected. Occurrences are computed in the timezone reported by tzIana.
Recurrence timetable for date rules, as an alternative to cron. Send one or the other — if both are present, cron wins and schedule is ignored.
Restricts what each spawned task copies from the anchored task. Omit it (or send null) and everything is copied — this is an allowlist, not a set of extras. Allowed entries: description, embedUrl, startAt, dueAt, labels, fields (custom-field values), subtasks.
Shifts dates on each spawned task, relative to the date it is spawned on: [{ "type": "dueAt", "offset": 3 }] gives every new task a due date 3 days out. offset is a whole number of days and may be negative.
endWhen the recurrence stops (ISO 8601 timestamp). It must fall after the next occurrence. Once passed, the rule stops spawning: nextRecurrenceAt and sourceTaskId are both cleared.
weekParityThins a date recurrence out to every other ISO week. off (the default) fires every matching week; skipEvenWeeks fires only in odd ISO weeks; skipOddWeeks fires only in even ones.
recurOnDateOnlyFor date rules: when true the rule fires strictly on its timetable, instead of also spawning early if the anchored task is completed ahead of schedule.
triggerStatusIdFor status rules: the status whose arrival fires the rule — the next task is spawned when the anchored task moves into it. Required on a status rule and rejected on any other type. Set once when the rule is created.
onCompleteRead-only: true on completion rules, false on every other type. Derived from type — it is not part of the create body.
sourceTaskIdThe task this rule is anchored to. Required when the rule is created, and server-managed afterwards: each time the rule spawns, the engine repoints it at the newly created task, and it becomes null once end has passed — so a read can return a different task than you sent, or none.
nextRecurrenceAtNext occurrence (server-computed from cron/schedule + the author timezone snapshot). THE engine cursor — the nifty-crons poll selects rules by it; NEVER client-writable (a stale/forged value kills or force-spawns the rule).
targetStatusIdThe status each spawned task is placed into — taken from the anchored task when the rule was created.
tzIanaThe author's IANA timezone (e.g. 'America/New_York'), snapshotted server-side at create/update — the timezone the engine spawns occurrences in. Read-only display field; never client-writable.
tzOffsetThe author's UTC offset in MINUTES EAST of UTC at the time the rule was saved, matching tzIana (New York in winter is -300). Recorded by the server; never writable.
The related Task, present only when you pass ?expand=sourceTask.
The related Status, present only when you pass ?expand=targetStatus.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
recurringRuleCreate
typeWhat makes this rule fire. date — a cron or schedule timetable. status — the anchored task moving into triggerStatusId. completion — the anchored task being completed. Set once when the rule is created; it cannot be changed afterwards.
sourceTaskIdThe task this rule is anchored to. Required when the rule is created, and server-managed afterwards: each time the rule spawns, the engine repoints it at the newly created task, and it becomes null once end has passed — so a read can return a different task than you sent, or none.
cronStandard 5-field cron for date rules — minute, hour, day-of-month, month, day-of-week (no seconds field). It must resolve to a SINGLE minute and a SINGLE hour: ranges, lists and steps in those two positions are rejected. Occurrences are computed in the timezone reported by tzIana.
Recurrence timetable for date rules, as an alternative to cron. Send one or the other — if both are present, cron wins and schedule is ignored.
cloneFieldsRestricts what each spawned task copies from the anchored task. Omit it (or send null) and everything is copied — this is an allowlist, not a set of extras. Allowed entries: description, embedUrl, startAt, dueAt, labels, fields (custom-field values), subtasks.
Shifts dates on each spawned task, relative to the date it is spawned on: [{ "type": "dueAt", "offset": 3 }] gives every new task a due date 3 days out. offset is a whole number of days and may be negative.
endWhen the recurrence stops (ISO 8601 timestamp). It must fall after the next occurrence. Once passed, the rule stops spawning: nextRecurrenceAt and sourceTaskId are both cleared.
weekParityThins a date recurrence out to every other ISO week. off (the default) fires every matching week; skipEvenWeeks fires only in odd ISO weeks; skipOddWeeks fires only in even ones.
recurOnDateOnlyFor date rules: when true the rule fires strictly on its timetable, instead of also spawning early if the anchored task is completed ahead of schedule.
triggerStatusIdFor status rules: the status whose arrival fires the rule — the next task is spawned when the anchored task moves into it. Required on a status rule and rejected on any other type. Set once when the rule is created.
recurringRuleUpdate
cronStandard 5-field cron for date rules — minute, hour, day-of-month, month, day-of-week (no seconds field). It must resolve to a SINGLE minute and a SINGLE hour: ranges, lists and steps in those two positions are rejected. Occurrences are computed in the timezone reported by tzIana.
Recurrence timetable for date rules, as an alternative to cron. Send one or the other — if both are present, cron wins and schedule is ignored.
cloneFieldsRestricts what each spawned task copies from the anchored task. Omit it (or send null) and everything is copied — this is an allowlist, not a set of extras. Allowed entries: description, embedUrl, startAt, dueAt, labels, fields (custom-field values), subtasks.
Shifts dates on each spawned task, relative to the date it is spawned on: [{ "type": "dueAt", "offset": 3 }] gives every new task a due date 3 days out. offset is a whole number of days and may be negative.
endWhen the recurrence stops (ISO 8601 timestamp). It must fall after the next occurrence. Once passed, the rule stops spawning: nextRecurrenceAt and sourceTaskId are both cleared.
weekParityThins a date recurrence out to every other ISO week. off (the default) fires every matching week; skipEvenWeeks fires only in odd ISO weeks; skipOddWeeks fires only in even ones.
recurOnDateOnlyFor date rules: when true the rule fires strictly on its timetable, instead of also spawning early if the anchored task is completed ahead of schedule.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
reminder
idUnique identifier for this resource.
createdAtCreation timestamp.
dateWhen the reminder fires, as an ISO 8601 instant (not a calendar date). Must be at least five minutes in the future. This is the only updatable field.
typeReminder kind. custom is the only kind you can create — omit this field and you get it. overdue reminders also exist but Nifty creates them from task due dates; they are read-only and cannot be created, changed, or deleted through the API.
taskIdThe task this reminder is attached to. Required on create; immutable afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
createdByIdThe team member who created this reminder — also its notification recipient, since reminders are personal. Server-set; a member id, so resolve it with GET /members/{id}.
reminderExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
dateWhen the reminder fires, as an ISO 8601 instant (not a calendar date). Must be at least five minutes in the future. This is the only updatable field.
typeReminder kind. custom is the only kind you can create — omit this field and you get it. overdue reminders also exist but Nifty creates them from task due dates; they are read-only and cannot be created, changed, or deleted through the API.
taskIdThe task this reminder is attached to. Required on create; immutable afterwards.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
createdByIdThe team member who created this reminder — also its notification recipient, since reminders are personal. Server-set; a member id, so resolve it with GET /members/{id}.
The related Task, present only when you pass ?expand=task.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
reminderCreate
dateWhen the reminder fires, as an ISO 8601 instant (not a calendar date). Must be at least five minutes in the future. This is the only updatable field.
taskIdThe task this reminder is attached to. Required on create; immutable afterwards.
typeReminder kind. custom is the only kind you can create — omit this field and you get it. overdue reminders also exist but Nifty creates them from task due dates; they are read-only and cannot be created, changed, or deleted through the API.
reminderUpdate
dateWhen the reminder fires, as an ISO 8601 instant (not a calendar date). Must be at least five minutes in the future. This is the only updatable field.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
reportChart
idUnique identifier for this resource.
createdAtCreation timestamp.
dataTypeAggregation mode for the chart: live, events, or historical.
chartTypeVisualization type: line, bar, area, areaStacked, pie, table, number, or funnel.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
Restricts the chart to a window of time. Omitted is stored (and read back) as {} rather than null.
Which tasks the chart counts. Every facet is optional; omit the whole object for no filter, and note that an omitted filter is stored (and read back) as {} rather than null.
The lines, bars or slices the chart draws, in order. Omit it and the chart is created with none (stored and read back as []); send it and it must have at least one entry.
nameOptional display name for the chart.
projectsThe projects whose tasks this chart aggregates. At least one is required when the chart is created. Read them back with ?expand=projects, or edit them one at a time via POST/DELETE /report-charts/{id}/projects.
reportChartExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
dataTypeAggregation mode for the chart: live, events, or historical.
chartTypeVisualization type: line, bar, area, areaStacked, pie, table, number, or funnel.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
Restricts the chart to a window of time. Omitted is stored (and read back) as {} rather than null.
Which tasks the chart counts. Every facet is optional; omit the whole object for no filter, and note that an omitted filter is stored (and read back) as {} rather than null.
The lines, bars or slices the chart draws, in order. Omit it and the chart is created with none (stored and read back as []); send it and it must have at least one entry.
nameOptional display name for the chart.
projectsThe projects whose tasks this chart aggregates. At least one is required when the chart is created. Read them back with ?expand=projects, or edit them one at a time via POST/DELETE /report-charts/{id}/projects.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
reportChartCreate
projectsThe projects whose tasks this chart aggregates. At least one is required. On update, use POST/DELETE /report-charts/{id}/projects.
dataTypeAggregation mode for the chart: live, events, or historical.
chartTypeVisualization type: line, bar, area, areaStacked, pie, table, number, or funnel.
Restricts the chart to a window of time. Omitted is stored (and read back) as {} rather than null.
Which tasks the chart counts. Every facet is optional; omit the whole object for no filter, and note that an omitted filter is stored (and read back) as {} rather than null.
The lines, bars or slices the chart draws, in order. Omit it and the chart is created with none (stored and read back as []); send it and it must have at least one entry.
nameOptional display name for the chart.
reportChartUpdate
projectsThe projects whose tasks this chart aggregates. At least one is required. On update, use POST/DELETE /report-charts/{id}/projects.
dataTypeAggregation mode for the chart: live, events, or historical.
chartTypeVisualization type: line, bar, area, areaStacked, pie, table, number, or funnel.
Restricts the chart to a window of time. Omitted is stored (and read back) as {} rather than null.
Which tasks the chart counts. Every facet is optional; omit the whole object for no filter, and note that an omitted filter is stored (and read back) as {} rather than null.
The lines, bars or slices the chart draws, in order. Omit it and the chart is created with none (stored and read back as []); send it and it must have at least one entry.
nameOptional display name for the chart.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
role
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
nameThe role's name, unique within the workspace. Cannot be owner, manager, regular or client — those four are built in.
editableFalse for the four built-in roles (owner, manager, regular, client). Those cannot be renamed, re-permissioned or deleted — only initialScreen may change.
permissionsThe permissions this role grants. Send names; an unknown name is rejected with 400, and omitting the field (or sending []) means the role grants nothing. You may only grant permissions you hold yourself; on update this is judged on the delta, so permissions the role already had can be carried forward untouched.
initialScreenThe screen members holding this role land on when they open the workspace.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
roleExpanded
idUnique identifier — an opaque string; never parse or generate one.
createdAtCreation timestamp.
nameThe role's name, unique within the workspace. Cannot be owner, manager, regular or client — those four are built in.
editableFalse for the four built-in roles (owner, manager, regular, client). Those cannot be renamed, re-permissioned or deleted — only initialScreen may change.
permissionsThe permissions this role grants. Send names; an unknown name is rejected with 400, and omitting the field (or sending []) means the role grants nothing. You may only grant permissions you hold yourself; on update this is judged on the delta, so permissions the role already had can be carried forward untouched.
initialScreenThe screen members holding this role land on when they open the workspace.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
The related Actor, present only when you pass ?expand=createdByActor.
roleCreate
nameThe role's name, unique within the workspace. Cannot be owner, manager, regular or client — those four are built in.
permissionsThe permissions this role grants. Send names; an unknown name is rejected with 400, and omitting the field (or sending []) means the role grants nothing. You may only grant permissions you hold yourself; on update this is judged on the delta, so permissions the role already had can be carried forward untouched.
initialScreenThe screen members holding this role land on when they open the workspace.
roleUpdate
nameThe role's name, unique within the workspace. Cannot be owner, manager, regular or client — those four are built in.
permissionsThe permissions this role grants. Send names; an unknown name is rejected with 400, and omitting the field (or sending []) means the role grants nothing. You may only grant permissions you hold yourself; on update this is judged on the delta, so permissions the role already had can be carried forward untouched.
initialScreenThe screen members holding this role land on when they open the workspace.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
status
idUnique identifier for this resource.
createdAtCreation timestamp.
nameStatus column name (e.g. "To Do", "In Progress"). 1–100 characters after trimming.
archivedWhether this status column is archived (hidden from active boards but not deleted). Regular field, NOT a soft-delete. Unlike an archived task, an archived status carries no archivedAt/archivedById stamp — use the audit log if you need to know who archived it and when.
projectIdProject this status column belongs to. Set once on create — a status cannot be moved to another project.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
colorHex color (#RGB or #RRGGBB, case-insensitive). Omit it on create and Nifty assigns one from its palette, so a status created through the API is never colorless.
orderFractional rank of the column within the project. Omit it on create and the server appends the column at the end. To reposition, send the midpoint of the two neighbours' ranks.
listIdWhen this status column is also rendered as a list, the id of that list. Null otherwise.
statusExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
nameStatus column name (e.g. "To Do", "In Progress"). 1–100 characters after trimming.
archivedWhether this status column is archived (hidden from active boards but not deleted). Regular field, NOT a soft-delete. Unlike an archived task, an archived status carries no archivedAt/archivedById stamp — use the audit log if you need to know who archived it and when.
projectIdProject this status column belongs to. Set once on create — a status cannot be moved to another project.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
colorHex color (#RGB or #RRGGBB, case-insensitive). Omit it on create and Nifty assigns one from its palette, so a status created through the API is never colorless.
orderFractional rank of the column within the project. Omit it on create and the server appends the column at the end. To reposition, send the midpoint of the two neighbours' ranks.
listIdWhen this status column is also rendered as a list, the id of that list. Null otherwise.
The related Actor, present only when you pass ?expand=createdByActor.
The related Project, present only when you pass ?expand=project.
The linked Team Member rows, present only when you pass ?expand=assignees.
The linked Role rows, present only when you pass ?expand=hiddenFor.
The related List, present only when you pass ?expand=list.
The linked Task rows, present only when you pass ?expand=tasks.
The linked Recurring Rule rows, present only when you pass ?expand=recurringRules.
statusCreate
nameStatus column name (e.g. "To Do", "In Progress"). 1–100 characters after trimming.
projectIdProject this status column belongs to. Set once on create — a status cannot be moved to another project.
color^#([0-9A-Fa-f]{3}|[0…Hex color (#RGB or #RRGGBB, case-insensitive). Omit it on create and Nifty assigns one from its palette, so a status created through the API is never colorless.
orderFractional rank of the column within the project. Omit it on create and the server appends the column at the end. To reposition, send the midpoint of the two neighbours' ranks.
archivedWhether this status column is archived (hidden from active boards but not deleted). Regular field, NOT a soft-delete. Unlike an archived task, an archived status carries no archivedAt/archivedById stamp — use the audit log if you need to know who archived it and when.
statusUpdate
nameStatus column name (e.g. "To Do", "In Progress"). 1–100 characters after trimming.
color^#([0-9A-Fa-f]{3}|[0…Hex color (#RGB or #RRGGBB, case-insensitive). Omit it on create and Nifty assigns one from its palette, so a status created through the API is never colorless.
orderFractional rank of the column within the project. Omit it on create and the server appends the column at the end. To reposition, send the midpoint of the two neighbours' ranks.
archivedWhether this status column is archived (hidden from active boards but not deleted). Regular field, NOT a soft-delete. Unlike an archived task, an archived status carries no archivedAt/archivedById stamp — use the audit log if you need to know who archived it and when.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
task
idUnique identifier for this resource.
createdAtCreation timestamp.
archivedWhether this resource is archived.
nameTask name. 1–1024 characters after trimming. Content that reads as promotional (link-farm text, bulk marketing copy) is rejected with a 400.
completedWhether this task is marked complete. Set true to mark a task done — Nifty renders completed tasks in a virtual "Completed" column, so prefer this over creating a separate "Done" status. Pairs with completedAt (timestamp) and completedById (who completed it).
projectIdProject this task belongs to. Required on create; PATCH-ing it moves the task — and its subtasks — into another project.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
archivedAtTimestamp when the task was archived. Server-stamped from the archived boolean — not directly writable.
archivedByIdMember who archived this resource (server-stamped). A member id — resolve it with GET /members/{id}.
niceIdPer-project sequential counter assigned on insert. Compose with project.niceId for human-readable references (e.g. "PROJ-42"). Server-managed — read-only on the wire.
descriptionTask description. Supports Markdown formatting.
listIdThe list this task belongs to. Null when the task is not on a list. Legal ids come from GET /lists.
statusIdThe status column this task sits in. Null when the task has no status (e.g. a backlog item). Legal ids come from GET /statuses.
parentTaskIdThe parent task, when this task is a subtask. Null on top-level tasks. Subtask siblings are ranked by order.
dependencyIdThe single task this one waits on. Nifty models one predecessor per task, so this is an id and not an array. Null when the task has no predecessor.
recurringRuleIdThe recurrence rule that regenerates this task, for recurring tasks. Null otherwise. Legal ids come from GET /recurring-rules.
startAtWhen work on this task is scheduled to start.
dueAtWhen this task is due.
completedAtTimestamp when the task was marked complete. Server-stamped from the completed boolean — not directly writable.
remindAtA single reminder time for this task. Recurring or multiple reminders are separate objects on the reminder resource (GET /reminders?taskId[eq]=…).
storyPointsStory points used for agile estimation; client-supplied.
orderFractional rank of the task in its default ordering. To reposition, send the midpoint of the two neighbours' ranks. Two subtasks under the same parent cannot share a rank.
orderListFractional rank of the task within its list. Same read/write shape and midpoint recipe as order.
bannerCover image URL rendered at the top of the task detail view.
embedUrlExternal URL embedded in the task body (e.g. Loom recording, Figma frame).
createdByIdThe team member who created this task. Server-set. Resolve it with ?expand=createdBy or GET /members/{id}; pairs with archivedById and completedById. This is a member id — createdByActorId is a different identifier space and GET /members/{id} will not accept it.
completedByIdThe team member who marked the task complete. Server-set when completed flips; pairs with completedAt. A member id — resolve it with GET /members/{id}.
taskExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
archivedWhether this resource is archived.
nameTask name. 1–1024 characters after trimming. Content that reads as promotional (link-farm text, bulk marketing copy) is rejected with a 400.
completedWhether this task is marked complete. Set true to mark a task done — Nifty renders completed tasks in a virtual "Completed" column, so prefer this over creating a separate "Done" status. Pairs with completedAt (timestamp) and completedById (who completed it).
projectIdProject this task belongs to. Required on create; PATCH-ing it moves the task — and its subtasks — into another project.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
archivedAtTimestamp when the task was archived. Server-stamped from the archived boolean — not directly writable.
archivedByIdMember who archived this resource (server-stamped). A member id — resolve it with GET /members/{id}.
niceIdPer-project sequential counter assigned on insert. Compose with project.niceId for human-readable references (e.g. "PROJ-42"). Server-managed — read-only on the wire.
descriptionTask description. Supports Markdown formatting.
listIdThe list this task belongs to. Null when the task is not on a list. Legal ids come from GET /lists.
statusIdThe status column this task sits in. Null when the task has no status (e.g. a backlog item). Legal ids come from GET /statuses.
parentTaskIdThe parent task, when this task is a subtask. Null on top-level tasks. Subtask siblings are ranked by order.
dependencyIdThe single task this one waits on. Nifty models one predecessor per task, so this is an id and not an array. Null when the task has no predecessor.
recurringRuleIdThe recurrence rule that regenerates this task, for recurring tasks. Null otherwise. Legal ids come from GET /recurring-rules.
startAtWhen work on this task is scheduled to start.
dueAtWhen this task is due.
completedAtTimestamp when the task was marked complete. Server-stamped from the completed boolean — not directly writable.
remindAtA single reminder time for this task. Recurring or multiple reminders are separate objects on the reminder resource (GET /reminders?taskId[eq]=…).
storyPointsStory points used for agile estimation; client-supplied.
orderFractional rank of the task in its default ordering. To reposition, send the midpoint of the two neighbours' ranks. Two subtasks under the same parent cannot share a rank.
orderListFractional rank of the task within its list. Same read/write shape and midpoint recipe as order.
bannerCover image URL rendered at the top of the task detail view.
embedUrlExternal URL embedded in the task body (e.g. Loom recording, Figma frame).
createdByIdThe team member who created this task. Server-set. Resolve it with ?expand=createdBy or GET /members/{id}; pairs with archivedById and completedById. This is a member id — createdByActorId is a different identifier space and GET /members/{id} will not accept it.
completedByIdThe team member who marked the task complete. Server-set when completed flips; pairs with completedAt. A member id — resolve it with GET /members/{id}.
The related Project, present only when you pass ?expand=project.
The related Status, present only when you pass ?expand=status.
The related List, present only when you pass ?expand=list.
The related Task, present only when you pass ?expand=parentTask.
The related Task, present only when you pass ?expand=dependency.
The related Recurring Rule, present only when you pass ?expand=recurringRule.
The related Team Member, present only when you pass ?expand=createdBy.
The related Team Member, present only when you pass ?expand=archivedBy.
The related Team Member, present only when you pass ?expand=completedBy.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
The linked Team Member rows, present only when you pass ?expand=assignees.
The linked Label rows, present only when you pass ?expand=labels.
The linked Team Member rows, present only when you pass ?expand=subscribers.
The linked Role rows, present only when you pass ?expand=hiddenFor.
The linked Task rows, present only when you pass ?expand=connectedTasks.
The linked Task rows, present only when you pass ?expand=subtasks.
The linked Message rows, present only when you pass ?expand=messages.
The linked Checklist rows, present only when you pass ?expand=checklists.
The linked File rows, present only when you pass ?expand=files.
The linked attachedCustomField rows, present only when you pass ?expand=customFields.
taskCreate
nameTask name. 1–1024 characters after trimming. Content that reads as promotional (link-farm text, bulk marketing copy) is rejected with a 400.
projectIdProject this task belongs to. Required on create; PATCH-ing it moves the task — and its subtasks — into another project.
descriptionTask description. Supports Markdown formatting.
archivedWhether this resource is archived.
completedWhether this task is marked complete. Set true to mark a task done — Nifty renders completed tasks in a virtual "Completed" column, so prefer this over creating a separate "Done" status. Pairs with completedAt (timestamp) and completedById (who completed it).
listIdThe list this task belongs to. Null when the task is not on a list. Legal ids come from GET /lists.
statusIdThe status column this task sits in. Null when the task has no status (e.g. a backlog item). Legal ids come from GET /statuses.
parentTaskIdThe parent task, when this task is a subtask. Null on top-level tasks. Subtask siblings are ranked by order.
dependencyIdThe single task this one waits on. Nifty models one predecessor per task, so this is an id and not an array. Null when the task has no predecessor.
recurringRuleIdThe recurrence rule that regenerates this task, for recurring tasks. Null otherwise. Legal ids come from GET /recurring-rules.
startAtWhen work on this task is scheduled to start.
dueAtWhen this task is due.
remindAtA single reminder time for this task. Recurring or multiple reminders are separate objects on the reminder resource (GET /reminders?taskId[eq]=…).
storyPointsStory points used for agile estimation; client-supplied.
orderFractional rank of the task in its default ordering. To reposition, send the midpoint of the two neighbours' ranks. Two subtasks under the same parent cannot share a rank.
orderListFractional rank of the task within its list. Same read/write shape and midpoint recipe as order.
bannerCover image URL rendered at the top of the task detail view.
embedUrlExternal URL embedded in the task body (e.g. Loom recording, Figma frame).
Custom-field values on this task. READ: ?expand=customFields returns the values attached to this task. WRITE: include customFields: [{ customFieldId, value }] in the create/update body to set values — each one is checked against its field definition before the write commits (value is always a string; max 50 entries per request; "" clears). Field definitions live on the read-only customField resource.
assigneesTeam-member ids assigned to this task. On create, seeds the set. On update, REPLACES the whole set — members you leave out are unassigned. For additive changes use POST/DELETE /tasks/{id}/assignees. Read the current set with ?expand=assignees.
labelsLabel ids attached to this task. On create, seeds the set. On update, REPLACES the whole set — labels you leave out are detached. For additive changes use POST/DELETE /tasks/{id}/labels. Read the current set with ?expand=labels.
subscribersTeam-member ids subscribed to this task (they receive notifications on changes). On create, seeds the set. On update, REPLACES the whole set — members you leave out are unsubscribed. For additive changes use POST/DELETE /tasks/{id}/subscribers. Read the current set with ?expand=subscribers.
taskUpdate
nameTask name. 1–1024 characters after trimming. Content that reads as promotional (link-farm text, bulk marketing copy) is rejected with a 400.
descriptionTask description. Supports Markdown formatting.
archivedWhether this resource is archived.
completedWhether this task is marked complete. Set true to mark a task done — Nifty renders completed tasks in a virtual "Completed" column, so prefer this over creating a separate "Done" status. Pairs with completedAt (timestamp) and completedById (who completed it).
projectIdProject this task belongs to. Required on create; PATCH-ing it moves the task — and its subtasks — into another project.
listIdThe list this task belongs to. Null when the task is not on a list. Legal ids come from GET /lists.
statusIdThe status column this task sits in. Null when the task has no status (e.g. a backlog item). Legal ids come from GET /statuses.
parentTaskIdThe parent task, when this task is a subtask. Null on top-level tasks. Subtask siblings are ranked by order.
dependencyIdThe single task this one waits on. Nifty models one predecessor per task, so this is an id and not an array. Null when the task has no predecessor.
recurringRuleIdThe recurrence rule that regenerates this task, for recurring tasks. Null otherwise. Legal ids come from GET /recurring-rules.
startAtWhen work on this task is scheduled to start.
dueAtWhen this task is due.
remindAtA single reminder time for this task. Recurring or multiple reminders are separate objects on the reminder resource (GET /reminders?taskId[eq]=…).
storyPointsStory points used for agile estimation; client-supplied.
orderFractional rank of the task in its default ordering. To reposition, send the midpoint of the two neighbours' ranks. Two subtasks under the same parent cannot share a rank.
orderListFractional rank of the task within its list. Same read/write shape and midpoint recipe as order.
bannerCover image URL rendered at the top of the task detail view.
embedUrlExternal URL embedded in the task body (e.g. Loom recording, Figma frame).
Custom-field values on this task. READ: ?expand=customFields returns the values attached to this task. WRITE: include customFields: [{ customFieldId, value }] in the create/update body to set values — each one is checked against its field definition before the write commits (value is always a string; max 50 entries per request; "" clears). Field definitions live on the read-only customField resource.
assigneesTeam-member ids assigned to this task. On create, seeds the set. On update, REPLACES the whole set — members you leave out are unassigned. For additive changes use POST/DELETE /tasks/{id}/assignees. Read the current set with ?expand=assignees.
labelsLabel ids attached to this task. On create, seeds the set. On update, REPLACES the whole set — labels you leave out are detached. For additive changes use POST/DELETE /tasks/{id}/labels. Read the current set with ?expand=labels.
subscribersTeam-member ids subscribed to this task (they receive notifications on changes). On create, seeds the set. On update, REPLACES the whole set — members you leave out are unsubscribed. For additive changes use POST/DELETE /tasks/{id}/subscribers. Read the current set with ?expand=subscribers.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
taskHandoff
idUnique identifier for this resource.
createdAtCreation timestamp.
taskIdTask this hand-off belongs to. Required on create; immutable afterwards.
schema^[a-z0-9][a-z0-9-]*\… · requiredThe kind of body, copied from body.schema when the hand-off is created — filter on it to find the newest hand-off of your kind. Read-only.
summaryOne line a person reads on the task: what changed and what is next. Plain text, at most 500 characters, no markdown.
Working context for whoever picks this task up next — a person or an agent. JSON at most 20,000 UTF-8 bytes, no string over 10,000 characters. body.schema names the kind: nifty.checkpoint/1 is validated, any other <vendor>.<kind>/<version> is stored as-is (the nifty. namespace is reserved). Newest of a kind wins; never edit an old one. Put decisions WITH their reasons, checks WITH their result, and one concrete next action.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
taskHandoffExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
taskIdTask this hand-off belongs to. Required on create; immutable afterwards.
schema^[a-z0-9][a-z0-9-]*\… · requiredThe kind of body, copied from body.schema when the hand-off is created — filter on it to find the newest hand-off of your kind. Read-only.
summaryOne line a person reads on the task: what changed and what is next. Plain text, at most 500 characters, no markdown.
Working context for whoever picks this task up next — a person or an agent. JSON at most 20,000 UTF-8 bytes, no string over 10,000 characters. body.schema names the kind: nifty.checkpoint/1 is validated, any other <vendor>.<kind>/<version> is stored as-is (the nifty. namespace is reserved). Newest of a kind wins; never edit an old one. Put decisions WITH their reasons, checks WITH their result, and one concrete next action.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
The related Task, present only when you pass ?expand=task.
The related Actor, present only when you pass ?expand=createdByActor.
The related Actor, present only when you pass ?expand=updatedByActor.
taskHandoffCreate
taskIdTask this hand-off belongs to. Required on create; immutable afterwards.
summaryOne line a person reads on the task: what changed and what is next. Plain text, at most 500 characters, no markdown.
Working context for whoever picks this task up next — a person or an agent. JSON at most 20,000 UTF-8 bytes, no string over 10,000 characters. body.schema names the kind: nifty.checkpoint/1 is validated, any other <vendor>.<kind>/<version> is stored as-is (the nifty. namespace is reserved). Newest of a kind wins; never edit an old one. Put decisions WITH their reasons, checks WITH their result, and one concrete next action.
timeEntry
idUnique identifier for this resource.
createdAtCreation timestamp.
startWhen the tracked interval began (ISO 8601).
manualTrue for entries created through this API; false for entries captured by the timer in the Nifty app. Server-set.
memberIdThe team member this time is tracked for. Set by the server from whoever is calling — you cannot log time on someone else's behalf.
taskIdThe task this time is tracked against. Set once when the entry is created: an entry cannot be moved to another task afterwards.
updatedAtLast update timestamp.
descriptionFree-text note about what the time was spent on. This is the field GET /time-entries/search matches against.
endWhen the tracked interval ended (ISO 8601). Omit it, or send null, to create a running entry; PATCH end to stop it.
projectIdThe project this time is booked against. Set once when the entry is created: an entry cannot be moved to another project afterwards.
timeEntryExpanded
idUnique identifier for this resource.
createdAtCreation timestamp.
startWhen the tracked interval began (ISO 8601).
manualTrue for entries created through this API; false for entries captured by the timer in the Nifty app. Server-set.
memberIdThe team member this time is tracked for. Set by the server from whoever is calling — you cannot log time on someone else's behalf.
taskIdThe task this time is tracked against. Set once when the entry is created: an entry cannot be moved to another task afterwards.
updatedAtLast update timestamp.
descriptionFree-text note about what the time was spent on. This is the field GET /time-entries/search matches against.
endWhen the tracked interval ended (ISO 8601). Omit it, or send null, to create a running entry; PATCH end to stop it.
projectIdThe project this time is booked against. Set once when the entry is created: an entry cannot be moved to another project afterwards.
The related Team Member, present only when you pass ?expand=member.
timeEntryCreate
startWhen the tracked interval began (ISO 8601).
taskIdThe task this time is tracked against. Set once when the entry is created: an entry cannot be moved to another task afterwards.
descriptionFree-text note about what the time was spent on. This is the field GET /time-entries/search matches against.
endWhen the tracked interval ended (ISO 8601). Omit it, or send null, to create a running entry; PATCH end to stop it.
projectIdThe project this time is booked against. Set once when the entry is created: an entry cannot be moved to another project afterwards.
timeEntryUpdate
descriptionFree-text note about what the time was spent on. This is the field GET /time-entries/search matches against.
startWhen the tracked interval began (ISO 8601).
endWhen the tracked interval ended (ISO 8601). Omit it, or send null, to create a running entry; PATCH end to stop it.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.
webhook
idUnique identifier. Server-minted, stable, opaque.
createdAtCreation timestamp.
nameHuman-readable label for this endpoint, shown in the integrations UI.
urlThe HTTPS endpoint each matching event is POSTed to.
Verifying a delivery. Every request carries an X-Webhook-Signature header of the form t=<unix_seconds>,v1=<hex>, where the hex is an HMAC-SHA256 of ${t}.${rawBody} keyed with this webhook's secret. Reject a request whose t is more than 300 seconds away from your own clock — that window is what stops a captured request being replayed at you.
Delivery semantics. Each event is attempted up to 4 times (the first try plus 3 retries) before it is given up on. Ten consecutive failed deliveries deactivate the webhook (active flips to false) and you will have to re-enable it; any success resets that counter and updates lastDeliveredAt. Send POST /webhooks/{id}/test to fire a synthetic delivery at your endpoint before going live.
eventsWhich events this webhook receives.
Grammar. An entry is either an exact event name such as task.created, or a pattern. In a pattern each * stands for exactly ONE dot-segment, and an entry may carry at most 4 of them — so task.* matches task.created and task.updated but NOT the three-segment task.assignees.added; reach those with task.*.*, or by exact name. The bare * is the one exception: it is a catch-all that matches every event, at any segment count. An entry matching nothing in the event catalog is rejected at registration, so subscribe using the values listed below.
Lifecycle events. Each resource below emits all five of created, updated, removed, restored and force_deleted, as {resource}.{action}:
annotation, chat, checkIn, checkInRequest, checklist, checklistItem, document, favorite, favoriteFolder, file, form, goal, goalGroup, label, list, member, message, portfolio, project, projectDashboard, projectFolder, recurringRule, reminder, reportChart, role, status, task, taskHandoff, presenceStatus, timeEntry, webhook.
Membership events. {resource}.{relation}.added and {resource}.{relation}.removed fire when a link is made or broken — one pair per relation listed here:
checkIn—assignees,subscriberscheckInRequest—assigneesfile—labels,subscriberslist—assignees,goals,hiddenForportfolio—membersreportChart—projectsstatus—assignees,hiddenFortask—assignees,connectedTasks,hiddenFor,labels,subscribers
Operation events. Each named operation emits an event of the same name — the verb, not a past tense: document.append, document.editText, file.createFromContent, file.createUploadUrl, file.uploadFromUrl, project.addMember, project.removeMember, project.transfer, task.attachDocument, task.createTree, task.detachDocument, webhook.rotateSecret, webhook.test.
apiVersionWhich payload format your endpoint receives, echoed back to you as the X-Api-Version request header. latest follows the newest format and can change without notice; pin a dated version if you need stability. Defaults to latest.
activeWhether deliveries are attempted. Set it false to pause the webhook without deleting it. The server also flips it false by itself after 10 consecutive failed deliveries; any success resets that counter.
failCountConsecutive delivery failures. Reset to 0 on any success; at 10 the webhook is automatically deactivated.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdTeam member who deleted this webhook. A member id — resolve it with GET /members/{id}.
createdByIdTeam member who registered this webhook. Server-set from the caller identity; a member id, so resolve it with GET /members/{id}.
lastDeliveredAtWhen a delivery to this endpoint last succeeded. null if it has never delivered.
webhookExpanded
idUnique identifier. Server-minted, stable, opaque.
createdAtCreation timestamp.
nameHuman-readable label for this endpoint, shown in the integrations UI.
urlThe HTTPS endpoint each matching event is POSTed to.
Verifying a delivery. Every request carries an X-Webhook-Signature header of the form t=<unix_seconds>,v1=<hex>, where the hex is an HMAC-SHA256 of ${t}.${rawBody} keyed with this webhook's secret. Reject a request whose t is more than 300 seconds away from your own clock — that window is what stops a captured request being replayed at you.
Delivery semantics. Each event is attempted up to 4 times (the first try plus 3 retries) before it is given up on. Ten consecutive failed deliveries deactivate the webhook (active flips to false) and you will have to re-enable it; any success resets that counter and updates lastDeliveredAt. Send POST /webhooks/{id}/test to fire a synthetic delivery at your endpoint before going live.
eventsWhich events this webhook receives.
Grammar. An entry is either an exact event name such as task.created, or a pattern. In a pattern each * stands for exactly ONE dot-segment, and an entry may carry at most 4 of them — so task.* matches task.created and task.updated but NOT the three-segment task.assignees.added; reach those with task.*.*, or by exact name. The bare * is the one exception: it is a catch-all that matches every event, at any segment count. An entry matching nothing in the event catalog is rejected at registration, so subscribe using the values listed below.
Lifecycle events. Each resource below emits all five of created, updated, removed, restored and force_deleted, as {resource}.{action}:
annotation, chat, checkIn, checkInRequest, checklist, checklistItem, document, favorite, favoriteFolder, file, form, goal, goalGroup, label, list, member, message, portfolio, project, projectDashboard, projectFolder, recurringRule, reminder, reportChart, role, status, task, taskHandoff, presenceStatus, timeEntry, webhook.
Membership events. {resource}.{relation}.added and {resource}.{relation}.removed fire when a link is made or broken — one pair per relation listed here:
checkIn—assignees,subscriberscheckInRequest—assigneesfile—labels,subscriberslist—assignees,goals,hiddenForportfolio—membersreportChart—projectsstatus—assignees,hiddenFortask—assignees,connectedTasks,hiddenFor,labels,subscribers
Operation events. Each named operation emits an event of the same name — the verb, not a past tense: document.append, document.editText, file.createFromContent, file.createUploadUrl, file.uploadFromUrl, project.addMember, project.removeMember, project.transfer, task.attachDocument, task.createTree, task.detachDocument, webhook.rotateSecret, webhook.test.
apiVersionWhich payload format your endpoint receives, echoed back to you as the X-Api-Version request header. latest follows the newest format and can change without notice; pin a dated version if you need stability. Defaults to latest.
activeWhether deliveries are attempted. Set it false to pause the webhook without deleting it. The server also flips it false by itself after 10 consecutive failed deliveries; any success resets that counter.
failCountConsecutive delivery failures. Reset to 0 on any success; at 10 the webhook is automatically deactivated.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdTeam member who deleted this webhook. A member id — resolve it with GET /members/{id}.
createdByIdTeam member who registered this webhook. Server-set from the caller identity; a member id, so resolve it with GET /members/{id}.
lastDeliveredAtWhen a delivery to this endpoint last succeeded. null if it has never delivered.
webhookCreated
idUnique identifier. Server-minted, stable, opaque.
createdAtCreation timestamp.
nameHuman-readable label for this endpoint, shown in the integrations UI.
urlThe HTTPS endpoint each matching event is POSTed to.
Verifying a delivery. Every request carries an X-Webhook-Signature header of the form t=<unix_seconds>,v1=<hex>, where the hex is an HMAC-SHA256 of ${t}.${rawBody} keyed with this webhook's secret. Reject a request whose t is more than 300 seconds away from your own clock — that window is what stops a captured request being replayed at you.
Delivery semantics. Each event is attempted up to 4 times (the first try plus 3 retries) before it is given up on. Ten consecutive failed deliveries deactivate the webhook (active flips to false) and you will have to re-enable it; any success resets that counter and updates lastDeliveredAt. Send POST /webhooks/{id}/test to fire a synthetic delivery at your endpoint before going live.
eventsWhich events this webhook receives.
Grammar. An entry is either an exact event name such as task.created, or a pattern. In a pattern each * stands for exactly ONE dot-segment, and an entry may carry at most 4 of them — so task.* matches task.created and task.updated but NOT the three-segment task.assignees.added; reach those with task.*.*, or by exact name. The bare * is the one exception: it is a catch-all that matches every event, at any segment count. An entry matching nothing in the event catalog is rejected at registration, so subscribe using the values listed below.
Lifecycle events. Each resource below emits all five of created, updated, removed, restored and force_deleted, as {resource}.{action}:
annotation, chat, checkIn, checkInRequest, checklist, checklistItem, document, favorite, favoriteFolder, file, form, goal, goalGroup, label, list, member, message, portfolio, project, projectDashboard, projectFolder, recurringRule, reminder, reportChart, role, status, task, taskHandoff, presenceStatus, timeEntry, webhook.
Membership events. {resource}.{relation}.added and {resource}.{relation}.removed fire when a link is made or broken — one pair per relation listed here:
checkIn—assignees,subscriberscheckInRequest—assigneesfile—labels,subscriberslist—assignees,goals,hiddenForportfolio—membersreportChart—projectsstatus—assignees,hiddenFortask—assignees,connectedTasks,hiddenFor,labels,subscribers
Operation events. Each named operation emits an event of the same name — the verb, not a past tense: document.append, document.editText, file.createFromContent, file.createUploadUrl, file.uploadFromUrl, project.addMember, project.removeMember, project.transfer, task.attachDocument, task.createTree, task.detachDocument, webhook.rotateSecret, webhook.test.
apiVersionWhich payload format your endpoint receives, echoed back to you as the X-Api-Version request header. latest follows the newest format and can change without notice; pin a dated version if you need stability. Defaults to latest.
activeWhether deliveries are attempted. Set it false to pause the webhook without deleting it. The server also flips it false by itself after 10 consecutive failed deliveries; any success resets that counter.
failCountConsecutive delivery failures. Reset to 0 on any success; at 10 the webhook is automatically deactivated.
secretThe signing secret for this webhook, in plaintext. Returned exactly once — here, and again from POST /webhooks/{id}/rotate-secret — and never readable afterwards, so store it before you do anything else. Use it to verify the X-Webhook-Signature header on every delivery. If you lose it, rotate: POST /webhooks/{id}/rotate-secret mints a new one and invalidates the old. NOTE: replaying this exact request with the same Idempotency-Key returns the body WITHOUT secret — once means once.
updatedAtLast update timestamp.
createdByActorIdWho created this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records created any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
updatedByActorIdWho last wrote to this record — a person, an agent, an automation or the system itself. Read-only, stamped by the server on writes made through this API, and null on records last written any other way, so treat it as present-or-null rather than always populated. This is an actor id (a UUID), not a member id: look it up with GET /actors/{id}, whose memberId gives you the person to use against /members.
createdByActorTypeThe creator actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type; read-only, not directly writable.
updatedByActorTypeThe last writer actor's type (human, agent, cron, recurringTask, automation, outboxRetry, systemDefault). Server-derived from actors.type via the row's updatedByActorId; read-only, not directly writable.
purgeAtWhen this resource will be permanently deleted — soft-delete time + 30-day retention; null while live.
deletedByIdTeam member who deleted this webhook. A member id — resolve it with GET /members/{id}.
createdByIdTeam member who registered this webhook. Server-set from the caller identity; a member id, so resolve it with GET /members/{id}.
lastDeliveredAtWhen a delivery to this endpoint last succeeded. null if it has never delivered.
webhookCreate
nameHuman-readable label for this endpoint, shown in the integrations UI.
url^https:\/\/ · requiredThe HTTPS endpoint each matching event is POSTed to.
Verifying a delivery. Every request carries an X-Webhook-Signature header of the form t=<unix_seconds>,v1=<hex>, where the hex is an HMAC-SHA256 of ${t}.${rawBody} keyed with this webhook's secret. Reject a request whose t is more than 300 seconds away from your own clock — that window is what stops a captured request being replayed at you.
Delivery semantics. Each event is attempted up to 4 times (the first try plus 3 retries) before it is given up on. Ten consecutive failed deliveries deactivate the webhook (active flips to false) and you will have to re-enable it; any success resets that counter and updates lastDeliveredAt. Send POST /webhooks/{id}/test to fire a synthetic delivery at your endpoint before going live.
eventsWhich events this webhook receives.
Grammar. An entry is either an exact event name such as task.created, or a pattern. In a pattern each * stands for exactly ONE dot-segment, and an entry may carry at most 4 of them — so task.* matches task.created and task.updated but NOT the three-segment task.assignees.added; reach those with task.*.*, or by exact name. The bare * is the one exception: it is a catch-all that matches every event, at any segment count. An entry matching nothing in the event catalog is rejected at registration, so subscribe using the values listed below.
Lifecycle events. Each resource below emits all five of created, updated, removed, restored and force_deleted, as {resource}.{action}:
annotation, chat, checkIn, checkInRequest, checklist, checklistItem, document, favorite, favoriteFolder, file, form, goal, goalGroup, label, list, member, message, portfolio, project, projectDashboard, projectFolder, recurringRule, reminder, reportChart, role, status, task, taskHandoff, presenceStatus, timeEntry, webhook.
Membership events. {resource}.{relation}.added and {resource}.{relation}.removed fire when a link is made or broken — one pair per relation listed here:
checkIn—assignees,subscriberscheckInRequest—assigneesfile—labels,subscriberslist—assignees,goals,hiddenForportfolio—membersreportChart—projectsstatus—assignees,hiddenFortask—assignees,connectedTasks,hiddenFor,labels,subscribers
Operation events. Each named operation emits an event of the same name — the verb, not a past tense: document.append, document.editText, file.createFromContent, file.createUploadUrl, file.uploadFromUrl, project.addMember, project.removeMember, project.transfer, task.attachDocument, task.createTree, task.detachDocument, webhook.rotateSecret, webhook.test.
apiVersionWhich payload format your endpoint receives, echoed back to you as the X-Api-Version request header. latest follows the newest format and can change without notice; pin a dated version if you need stability. Defaults to latest.
activeWhether deliveries are attempted. Set it false to pause the webhook without deleting it. The server also flips it false by itself after 10 consecutive failed deliveries; any success resets that counter.
webhookUpdate
nameHuman-readable label for this endpoint, shown in the integrations UI.
url^https:\/\/The HTTPS endpoint each matching event is POSTed to.
Verifying a delivery. Every request carries an X-Webhook-Signature header of the form t=<unix_seconds>,v1=<hex>, where the hex is an HMAC-SHA256 of ${t}.${rawBody} keyed with this webhook's secret. Reject a request whose t is more than 300 seconds away from your own clock — that window is what stops a captured request being replayed at you.
Delivery semantics. Each event is attempted up to 4 times (the first try plus 3 retries) before it is given up on. Ten consecutive failed deliveries deactivate the webhook (active flips to false) and you will have to re-enable it; any success resets that counter and updates lastDeliveredAt. Send POST /webhooks/{id}/test to fire a synthetic delivery at your endpoint before going live.
eventsWhich events this webhook receives.
Grammar. An entry is either an exact event name such as task.created, or a pattern. In a pattern each * stands for exactly ONE dot-segment, and an entry may carry at most 4 of them — so task.* matches task.created and task.updated but NOT the three-segment task.assignees.added; reach those with task.*.*, or by exact name. The bare * is the one exception: it is a catch-all that matches every event, at any segment count. An entry matching nothing in the event catalog is rejected at registration, so subscribe using the values listed below.
Lifecycle events. Each resource below emits all five of created, updated, removed, restored and force_deleted, as {resource}.{action}:
annotation, chat, checkIn, checkInRequest, checklist, checklistItem, document, favorite, favoriteFolder, file, form, goal, goalGroup, label, list, member, message, portfolio, project, projectDashboard, projectFolder, recurringRule, reminder, reportChart, role, status, task, taskHandoff, presenceStatus, timeEntry, webhook.
Membership events. {resource}.{relation}.added and {resource}.{relation}.removed fire when a link is made or broken — one pair per relation listed here:
checkIn—assignees,subscriberscheckInRequest—assigneesfile—labels,subscriberslist—assignees,goals,hiddenForportfolio—membersreportChart—projectsstatus—assignees,hiddenFortask—assignees,connectedTasks,hiddenFor,labels,subscribers
Operation events. Each named operation emits an event of the same name — the verb, not a past tense: document.append, document.editText, file.createFromContent, file.createUploadUrl, file.uploadFromUrl, project.addMember, project.removeMember, project.transfer, task.attachDocument, task.createTree, task.detachDocument, webhook.rotateSecret, webhook.test.
apiVersionWhich payload format your endpoint receives, echoed back to you as the X-Api-Version request header. latest follows the newest format and can change without notice; pin a dated version if you need stability. Defaults to latest.
activeWhether deliveries are attempted. Set it false to pause the webhook without deleting it. The server also flips it false by itself after 10 consecutive failed deliveries; any success resets that counter.
expectedUpdatedAtOptional concurrency guard: the updatedAt you last read. If the resource has changed since, the update is rejected with 409 instead of overwriting the other writer. Re-read, re-derive your change from the current values, and retry with the fresh updatedAt.