Portfolio
A team-scoped grouping of projects. Carries name, icon, colors, ownership, and order metadata.
List Portfolios
List portfolios. Returns a paginated envelope (data, total, limit, hasMore, nextCursor). Filterable by 5 fields. Ordered by order unless you pass sort.
Required scope: portfolios:read
query Parameters
sortField to sort by. Prefix with - for descending (-createdAt); a createdAt:desc / createdAt:asc suffix works too, but never both markers at once. Default: order.
cursorOpaque cursor for the next page (the envelope nextCursor).
limitItems per page (1–200, default 50). A larger value is clamped to the cap rather than rejected, so always follow nextCursor instead of assuming one page held everything.
includeTotalWhen true, the response envelope includes the total number of matching rows. Omit it for cheaper pagination.
expandComma-separated relations to inline (see Expanding objects above). Valid values are listed in the enum.
purgeAt[null]Filter where purgeAt is null (pass true).
purgeAt[notNull]Filter where purgeAt is not null (pass true).
purgeAt[gt]Filter where purgeAt is greater than.
purgeAt[gte]Filter where purgeAt is greater than or equal to.
purgeAt[lt]Filter where purgeAt is less than.
purgeAt[lte]Filter where purgeAt is less than or equal to.
name[eq]Filter where name equals.
name[contains]Filter where name contains.
name[startsWith]Filter where name starts with.
isGeneral[eq]Filter where isGeneral equals.
order[eq]Filter where order equals.
order[gt]Filter where order is greater than.
order[gte]Filter where order is greater than or equal to.
order[lt]Filter where order is less than.
order[lte]Filter where order is less than or equal to.
createdAt[gt]Filter where createdAt is greater than.
createdAt[gte]Filter where createdAt is greater than or equal to.
createdAt[lt]Filter where createdAt is less than.
createdAt[lte]Filter where createdAt is less than or equal to.
List Portfolios › Responses
OK
The page of results.
totalTotal rows matching the query (across pages).
limithasMorenextCursorOpaque cursor for the next page; null on the last page.
Create Portfolio
Create a Portfolio. Server-assigned fields are ignored if sent.
Required scope: portfolios:write
query Parameters
expandComma-separated relations to inline (see Expanding objects above). Valid values are listed in the enum.
Headers
Idempotency-KeyOptional replay key (see Idempotent requests above).
Create Portfolio › Request Body
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.
Create Portfolio › Responses
Created
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.
Get Portfolio
Retrieve a single Portfolio by id.
Required scope: portfolios:read
path Parameters
id^[0-9A-Za-z_!]+$ · requiredId of the Portfolio.
query Parameters
expandComma-separated relations to inline (see Expanding objects above). Valid values are listed in the enum.
Get Portfolio › Responses
OK
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.
Delete Portfolio
Move this Portfolio to trash. It disappears from list results immediately and is permanently purged after a 30-day retention window; until then it can be restored.
Required scope: portfolios:delete
path Parameters
id^[0-9A-Za-z_!]+$ · requiredId of the Portfolio.
Headers
Idempotency-KeyOptional replay key (see Idempotent requests above).
Delete Portfolio › Responses
No Content
Update Portfolio
Partially update a Portfolio. Only the fields you send are changed.
Required scope: portfolios:write
path Parameters
id^[0-9A-Za-z_!]+$ · requiredId of the Portfolio.
query Parameters
expandComma-separated relations to inline (see Expanding objects above). Valid values are listed in the enum.
Headers
Idempotency-KeyOptional replay key (see Idempotent requests above).
Update Portfolio › Request Body
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.
Update Portfolio › Responses
OK
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.
Search Portfolios
Full-text ranked search across portfolios. Ranked by relevance; pages are capped at 200 results. Filterable by 5 fields.
Required scope: portfolios:read
query Parameters
qFull-text search query. Trimmed before matching; URLs, e-mail addresses and HTML markup are rejected.
cursorOpaque cursor for the next page (the envelope nextCursor).
limitItems per page (1–200, default 50). A larger value is clamped to the cap rather than rejected, so always follow nextCursor instead of assuming one page held everything.
includeTotalWhen true, the response envelope includes the total number of matching rows. Omit it for cheaper pagination.
expandComma-separated relations to inline (see Expanding objects above). Valid values are listed in the enum.
purgeAt[null]Filter where purgeAt is null (pass true).
purgeAt[notNull]Filter where purgeAt is not null (pass true).
purgeAt[gt]Filter where purgeAt is greater than.
purgeAt[gte]Filter where purgeAt is greater than or equal to.
purgeAt[lt]Filter where purgeAt is less than.
purgeAt[lte]Filter where purgeAt is less than or equal to.
name[eq]Filter where name equals.
name[contains]Filter where name contains.
name[startsWith]Filter where name starts with.
isGeneral[eq]Filter where isGeneral equals.
order[eq]Filter where order equals.
order[gt]Filter where order is greater than.
order[gte]Filter where order is greater than or equal to.
order[lt]Filter where order is less than.
order[lte]Filter where order is less than or equal to.
createdAt[gt]Filter where createdAt is greater than.
createdAt[gte]Filter where createdAt is greater than or equal to.
createdAt[lt]Filter where createdAt is less than.
createdAt[lte]Filter where createdAt is less than or equal to.
Search Portfolios › Responses
OK
The page of results.
totalTotal rows matching the query (across pages).
limithasMorenextCursorOpaque cursor for the next page; null on the last page.
Add members to a Portfolio
Link the given ids to this Portfolio as members. Adds to the existing set rather than replacing it, and adding one that is already linked changes nothing. Returns the complete members set afterwards.
Required scopes: portfolios:write portfolios:link
path Parameters
id^[0-9A-Za-z_!]+$ · requiredId of the Portfolio.
Headers
Idempotency-KeyOptional replay key (see Idempotent requests above).
Add members to a Portfolio › Request Body
idsTeam Members to add or remove, by id.
Add members to a Portfolio › Responses
OK
The complete members set after the change.
affectedIdsThe ids that were actually linked (ones already linked are omitted).
missingIdsIds you sent that do not exist or are not visible to this token.
Remove members from a Portfolio
Unlink the given ids from this Portfolio's members. Removing one that is not linked changes nothing. Returns the complete members set afterwards.
Required scopes: portfolios:write portfolios:link
path Parameters
id^[0-9A-Za-z_!]+$ · requiredId of the Portfolio.
Headers
Idempotency-KeyOptional replay key (see Idempotent requests above).
Remove members from a Portfolio › Request Body
idsTeam Members to add or remove, by id.
Remove members from a Portfolio › Responses
OK
The complete members set after the change.
affectedIdsThe ids that were actually unlinked (ones not linked are omitted).
Restore Portfolio
Restore a Portfolio that was deleted, returning it to list results. Restoring one that is already active succeeds and changes nothing.
Required scope: portfolios:delete
path Parameters
id^[0-9A-Za-z_!]+$ · requiredId of the Portfolio.
Headers
Idempotency-KeyOptional replay key (see Idempotent requests above).
Restore Portfolio › Responses
OK
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.