Skip to content

Depot projects

Registers the whole authenticated project surface.

This page is generated from the Depot route table. Every operation carries the permission it needs and the anchor an agent can link to.

GETproject:readmsp facemspIdempotent

Source: [object Object]

List projects

NameInTypeRequiredDescription
cidpathstringYes
billingModequerystringNo
healthquerystring, one of amber, green, redNoComma-separated set. An unrecognised value is refused.
managerquerystringNo
pagequeryintegerNoOne-based page number. Defaults to 1.
pageSizequeryintegerNoRows per page, 1 to 200. Defaults to 50.
qquerystringNo
sortquerystringNo
statusquerystring, one of active, cancelled, completed, draft, on_holdNoComma-separated set. An unrecognised value is refused.
StatusBodyDescription
200application/json, PagedResultProjectSummaryViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectSummaryView
items[].amountBurnBprequiredinteger
items[].atRiskTasksrequiredinteger
items[].billableSecondsrequiredinteger
items[].billingModerequiredstring
items[].budgetAmountCentsrequiredinteger

int64.

items[].budgetMinutesrequiredinteger
items[].clientNamerequiredstring
items[].clientPublicIdrequiredstring
items[].createdAtrequiredstring (date-time)
items[].fixedPriceCentsrequiredinteger

int64.

items[].healthrequiredstring
items[].healthComputedAtstring (date-time) or null
items[].healthReasonrequiredstring
items[].hoursBurnBprequiredinteger
items[].isSelfrequiredboolean
items[].loggedSecondsrequiredinteger
items[].managerNamestring or null
items[].managerUserPublicIdstring or null
items[].namerequiredstring
items[].nextMilestoneNextMilestoneView
items[].nextMilestone.dueOnrequiredstring
items[].nextMilestone.namerequiredstring
items[].nextMilestone.publicIdrequiredstring
items[].numberrequiredinteger

int64.

items[].openTasksrequiredinteger
items[].overdueMilestonesrequiredinteger
items[].percentCompleterequiredinteger
items[].plannedEndOnstring or null
items[].plannedStartOnrequiredstring
items[].publicIdrequiredstring
items[].referencerequiredstring
items[].statusrequiredstring
items[].updatedAtrequiredstring (date-time)
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects?billingMode=<billingMode>&health=amber&manager=<manager>&page=0&pageSize=0&q=<q>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POSTproject:writemsp facemspNot fully resolved

What this page does not know
  • response-status

These are parts of the route the extractor could not read from the source. Everything else on this page came straight from it.

Source: [object Object]

createProject opens a job, from a template or from nothing, and optionally from a ticket.

A TEMPLATE COPIES THE CURRENT VERSION of its family, not the version whose id was typed: a console holding last month’s id must not open a project from a plan the practice has since improved. project.Instantiate mints every id and the store writes the whole plan in one transaction that rolls back whole, so a plan with a bad dependency leaves no half-built project for somebody to find.

NameInTypeRequiredDescription
cidpathstringYes

Required, sent as application/json.

FieldTypeDescription
agreementPublicIdstring or null
billingModerequiredstring
budgetAmountCentsinteger or null

int64.

budgetMinutesinteger or null
clientContactEmailrequiredstring
clientContactNamerequiredstring
descriptionrequiredstring
fixedPriceCentsinteger or null

int64.

fromTicketIdstring or null
managerUserPublicIdstring or null
namerequiredstring
plannedStartOnrequiredstring
prepaidLinePublicIdstring or null
rolesrequiredobject
skipWeekendsboolean or null
statusEmailCadencestring or null
statusEmailWeekdayinteger or null
templateIdstring or null
StatusBodyDescription
200application/json, ProjectViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
actualStartOnstring or null
agreementPublicIdstring or null
amountBurnBprequiredinteger
atRiskTasksrequiredinteger
billableSecondsrequiredinteger
billingModerequiredstring
budgetAmountCentsrequiredinteger

int64.

budgetCriticalBpinteger or null
budgetMinutesrequiredinteger
budgetWarnBpinteger or null
cancelledAtstring (date-time) or null
clientContactEmailrequiredstring
clientContactNamerequiredstring
clientNamerequiredstring
clientPublicIdrequiredstring
completedAtstring (date-time) or null
convertedFromTicketPublicIdstring or null
costCentsinteger or null

int64.

createdAtrequiredstring (date-time)
descriptionrequiredstring
fixedPriceCentsrequiredinteger

int64.

healthrequiredstring
healthComputedAtstring (date-time) or null
healthReasonrequiredstring
hoursBurnBprequiredinteger
isSelfrequiredboolean
lastStatusEmailOnstring or null
loggedSecondsrequiredinteger
managerNamestring or null
managerUserPublicIdstring or null
milestonesrequiredarray of ProjectMilestoneView
milestones[].acceptanceMilestoneAcceptanceView
milestones[].acceptance.consentTextrequiredstring
milestones[].acceptance.consentVersionrequiredinteger
milestones[].acceptance.iprequiredstring
milestones[].acceptance.signedAtrequiredstring (date-time)
milestones[].acceptance.signerNamerequiredstring
milestones[].acceptance.signerTitlerequiredstring
milestones[].acceptance.userAgentrequiredstring
milestones[].acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

milestones[].acceptanceLink.activerequiredboolean
milestones[].acceptanceLink.expiresAtstring (date-time) or null
milestones[].acceptanceLink.viewCountrequiredinteger
milestones[].acceptanceSentAtstring (date-time) or null
milestones[].acceptedAtstring (date-time) or null
milestones[].amountCentsinteger or null

int64.

milestones[].certificateAvailablerequiredboolean
milestones[].clientVisiblerequiredboolean
milestones[].completedAtstring (date-time) or null
milestones[].declineReasonrequiredstring
milestones[].declinedAtstring (date-time) or null
milestones[].descriptionrequiredstring
milestones[].dueOnrequiredstring
milestones[].invoicePublicIdstring or null
milestones[].invoicedAtstring (date-time) or null
milestones[].namerequiredstring
milestones[].phaseNamestring or null
milestones[].phasePublicIdstring or null
milestones[].positionrequiredinteger
milestones[].publicIdrequiredstring
milestones[].requiresClientAcceptancerequiredboolean
milestones[].statusrequiredstring
namerequiredstring
nextMilestoneNextMilestoneView
nextMilestone.dueOnrequiredstring
nextMilestone.namerequiredstring
nextMilestone.publicIdrequiredstring
notesrequiredstring
numberrequiredinteger

int64.

openTasksrequiredinteger
overdueMilestonesrequiredinteger
percentCompleterequiredinteger
phasesrequiredarray of ProjectPhaseView
phases[].billableSecondsrequiredinteger
phases[].billingModeOverridestring or null
phases[].budgetAmountCentsinteger or null

int64.

phases[].budgetMinutesinteger or null
phases[].completedAtstring (date-time) or null
phases[].costCentsinteger or null

int64.

phases[].loggedSecondsrequiredinteger
phases[].namerequiredstring
phases[].percentCompleterequiredinteger
phases[].plannedEndOnstring or null
phases[].plannedStartOnstring or null
phases[].positionrequiredinteger
phases[].prepaidLinePublicIdstring or null
phases[].publicIdrequiredstring
phases[].statusrequiredstring
plannedEndOnstring or null
plannedStartOnrequiredstring
prepaidLinePublicIdstring or null
publicIdrequiredstring
quotePublicIdstring or null
referencerequiredstring
retrospectiverequiredany
skipWeekendsrequiredboolean
statusrequiredstring
statusEmailCadencerequiredstring
statusEmailWeekdayrequiredinteger
statusLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

statusLink.activerequiredboolean
statusLink.expiresAtstring (date-time) or null
statusLink.viewCountrequiredinteger
templatePublicIdstring or null
templateVersioninteger or null
ticketLinksrequiredarray of ProjectTicketLinkView
ticketLinks[].createdAtrequiredstring (date-time)
ticketLinks[].kindrequiredstring
ticketLinks[].publicIdrequiredstring
ticketLinks[].taskPublicIdstring or null
ticketLinks[].ticketPublicIdrequiredstring
ticketLinks[].ticketReferencerequiredstring
ticketLinks[].ticketSubjectrequiredstring
updatedAtrequiredstring (date-time)
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"agreementPublicId": "string",
"billingMode": "string",
"budgetAmountCents": 0,
"budgetMinutes": 0,
"clientContactEmail": "string",
"clientContactName": "string",
"description": "string",
"fixedPriceCents": 0,
"fromTicketId": "string",
"managerUserPublicId": "string",
"name": "string",
"plannedStartOn": "string",
"prepaidLinePublicId": "string",
"roles": {
"key": "string"
},
"skipWeekends": false,
"statusEmailCadence": "string",
"statusEmailWeekday": 0,
"templateId": "string"
}'

GETproject:readmsp facemspIdempotent

Source: [object Object]

Get project

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
actualStartOnstring or null
agreementPublicIdstring or null
amountBurnBprequiredinteger
atRiskTasksrequiredinteger
billableSecondsrequiredinteger
billingModerequiredstring
budgetAmountCentsrequiredinteger

int64.

budgetCriticalBpinteger or null
budgetMinutesrequiredinteger
budgetWarnBpinteger or null
cancelledAtstring (date-time) or null
clientContactEmailrequiredstring
clientContactNamerequiredstring
clientNamerequiredstring
clientPublicIdrequiredstring
completedAtstring (date-time) or null
convertedFromTicketPublicIdstring or null
costCentsinteger or null

int64.

createdAtrequiredstring (date-time)
descriptionrequiredstring
fixedPriceCentsrequiredinteger

int64.

healthrequiredstring
healthComputedAtstring (date-time) or null
healthReasonrequiredstring
hoursBurnBprequiredinteger
isSelfrequiredboolean
lastStatusEmailOnstring or null
loggedSecondsrequiredinteger
managerNamestring or null
managerUserPublicIdstring or null
milestonesrequiredarray of ProjectMilestoneView
milestones[].acceptanceMilestoneAcceptanceView
milestones[].acceptance.consentTextrequiredstring
milestones[].acceptance.consentVersionrequiredinteger
milestones[].acceptance.iprequiredstring
milestones[].acceptance.signedAtrequiredstring (date-time)
milestones[].acceptance.signerNamerequiredstring
milestones[].acceptance.signerTitlerequiredstring
milestones[].acceptance.userAgentrequiredstring
milestones[].acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

milestones[].acceptanceLink.activerequiredboolean
milestones[].acceptanceLink.expiresAtstring (date-time) or null
milestones[].acceptanceLink.viewCountrequiredinteger
milestones[].acceptanceSentAtstring (date-time) or null
milestones[].acceptedAtstring (date-time) or null
milestones[].amountCentsinteger or null

int64.

milestones[].certificateAvailablerequiredboolean
milestones[].clientVisiblerequiredboolean
milestones[].completedAtstring (date-time) or null
milestones[].declineReasonrequiredstring
milestones[].declinedAtstring (date-time) or null
milestones[].descriptionrequiredstring
milestones[].dueOnrequiredstring
milestones[].invoicePublicIdstring or null
milestones[].invoicedAtstring (date-time) or null
milestones[].namerequiredstring
milestones[].phaseNamestring or null
milestones[].phasePublicIdstring or null
milestones[].positionrequiredinteger
milestones[].publicIdrequiredstring
milestones[].requiresClientAcceptancerequiredboolean
milestones[].statusrequiredstring
namerequiredstring
nextMilestoneNextMilestoneView
nextMilestone.dueOnrequiredstring
nextMilestone.namerequiredstring
nextMilestone.publicIdrequiredstring
notesrequiredstring
numberrequiredinteger

int64.

openTasksrequiredinteger
overdueMilestonesrequiredinteger
percentCompleterequiredinteger
phasesrequiredarray of ProjectPhaseView
phases[].billableSecondsrequiredinteger
phases[].billingModeOverridestring or null
phases[].budgetAmountCentsinteger or null

int64.

phases[].budgetMinutesinteger or null
phases[].completedAtstring (date-time) or null
phases[].costCentsinteger or null

int64.

phases[].loggedSecondsrequiredinteger
phases[].namerequiredstring
phases[].percentCompleterequiredinteger
phases[].plannedEndOnstring or null
phases[].plannedStartOnstring or null
phases[].positionrequiredinteger
phases[].prepaidLinePublicIdstring or null
phases[].publicIdrequiredstring
phases[].statusrequiredstring
plannedEndOnstring or null
plannedStartOnrequiredstring
prepaidLinePublicIdstring or null
publicIdrequiredstring
quotePublicIdstring or null
referencerequiredstring
retrospectiverequiredany
skipWeekendsrequiredboolean
statusrequiredstring
statusEmailCadencerequiredstring
statusEmailWeekdayrequiredinteger
statusLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

statusLink.activerequiredboolean
statusLink.expiresAtstring (date-time) or null
statusLink.viewCountrequiredinteger
templatePublicIdstring or null
templateVersioninteger or null
ticketLinksrequiredarray of ProjectTicketLinkView
ticketLinks[].createdAtrequiredstring (date-time)
ticketLinks[].kindrequiredstring
ticketLinks[].publicIdrequiredstring
ticketLinks[].taskPublicIdstring or null
ticketLinks[].ticketPublicIdrequiredstring
ticketLinks[].ticketReferencerequiredstring
ticketLinks[].ticketSubjectrequiredstring
updatedAtrequiredstring (date-time)
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PATCHproject:writemsp facemspNot fully resolved

What this page does not know
  • response-status

These are parts of the route the extractor could not read from the source. Everything else on this page came straight from it.

Source: [object Object]

Patch project

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
agreementPublicIdstring or null
billingModestring or null
budgetAmountCentsinteger or null

int64.

budgetCriticalBpinteger or null
budgetMinutesinteger or null
budgetWarnBpinteger or null
clientContactEmailstring or null
clientContactNamestring or null
descriptionstring or null
fixedPriceCentsinteger or null

int64.

managerUserPublicIdstring or null
namestring or null
notesstring or null
plannedStartOnstring or null
prepaidLinePublicIdstring or null
skipWeekendsboolean or null
statusEmailCadencestring or null
statusEmailWeekdayinteger or null
StatusBodyDescription
200application/json, ProjectViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
actualStartOnstring or null
agreementPublicIdstring or null
amountBurnBprequiredinteger
atRiskTasksrequiredinteger
billableSecondsrequiredinteger
billingModerequiredstring
budgetAmountCentsrequiredinteger

int64.

budgetCriticalBpinteger or null
budgetMinutesrequiredinteger
budgetWarnBpinteger or null
cancelledAtstring (date-time) or null
clientContactEmailrequiredstring
clientContactNamerequiredstring
clientNamerequiredstring
clientPublicIdrequiredstring
completedAtstring (date-time) or null
convertedFromTicketPublicIdstring or null
costCentsinteger or null

int64.

createdAtrequiredstring (date-time)
descriptionrequiredstring
fixedPriceCentsrequiredinteger

int64.

healthrequiredstring
healthComputedAtstring (date-time) or null
healthReasonrequiredstring
hoursBurnBprequiredinteger
isSelfrequiredboolean
lastStatusEmailOnstring or null
loggedSecondsrequiredinteger
managerNamestring or null
managerUserPublicIdstring or null
milestonesrequiredarray of ProjectMilestoneView
milestones[].acceptanceMilestoneAcceptanceView
milestones[].acceptance.consentTextrequiredstring
milestones[].acceptance.consentVersionrequiredinteger
milestones[].acceptance.iprequiredstring
milestones[].acceptance.signedAtrequiredstring (date-time)
milestones[].acceptance.signerNamerequiredstring
milestones[].acceptance.signerTitlerequiredstring
milestones[].acceptance.userAgentrequiredstring
milestones[].acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

milestones[].acceptanceLink.activerequiredboolean
milestones[].acceptanceLink.expiresAtstring (date-time) or null
milestones[].acceptanceLink.viewCountrequiredinteger
milestones[].acceptanceSentAtstring (date-time) or null
milestones[].acceptedAtstring (date-time) or null
milestones[].amountCentsinteger or null

int64.

milestones[].certificateAvailablerequiredboolean
milestones[].clientVisiblerequiredboolean
milestones[].completedAtstring (date-time) or null
milestones[].declineReasonrequiredstring
milestones[].declinedAtstring (date-time) or null
milestones[].descriptionrequiredstring
milestones[].dueOnrequiredstring
milestones[].invoicePublicIdstring or null
milestones[].invoicedAtstring (date-time) or null
milestones[].namerequiredstring
milestones[].phaseNamestring or null
milestones[].phasePublicIdstring or null
milestones[].positionrequiredinteger
milestones[].publicIdrequiredstring
milestones[].requiresClientAcceptancerequiredboolean
milestones[].statusrequiredstring
namerequiredstring
nextMilestoneNextMilestoneView
nextMilestone.dueOnrequiredstring
nextMilestone.namerequiredstring
nextMilestone.publicIdrequiredstring
notesrequiredstring
numberrequiredinteger

int64.

openTasksrequiredinteger
overdueMilestonesrequiredinteger
percentCompleterequiredinteger
phasesrequiredarray of ProjectPhaseView
phases[].billableSecondsrequiredinteger
phases[].billingModeOverridestring or null
phases[].budgetAmountCentsinteger or null

int64.

phases[].budgetMinutesinteger or null
phases[].completedAtstring (date-time) or null
phases[].costCentsinteger or null

int64.

phases[].loggedSecondsrequiredinteger
phases[].namerequiredstring
phases[].percentCompleterequiredinteger
phases[].plannedEndOnstring or null
phases[].plannedStartOnstring or null
phases[].positionrequiredinteger
phases[].prepaidLinePublicIdstring or null
phases[].publicIdrequiredstring
phases[].statusrequiredstring
plannedEndOnstring or null
plannedStartOnrequiredstring
prepaidLinePublicIdstring or null
publicIdrequiredstring
quotePublicIdstring or null
referencerequiredstring
retrospectiverequiredany
skipWeekendsrequiredboolean
statusrequiredstring
statusEmailCadencerequiredstring
statusEmailWeekdayrequiredinteger
statusLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

statusLink.activerequiredboolean
statusLink.expiresAtstring (date-time) or null
statusLink.viewCountrequiredinteger
templatePublicIdstring or null
templateVersioninteger or null
ticketLinksrequiredarray of ProjectTicketLinkView
ticketLinks[].createdAtrequiredstring (date-time)
ticketLinks[].kindrequiredstring
ticketLinks[].publicIdrequiredstring
ticketLinks[].taskPublicIdstring or null
ticketLinks[].ticketPublicIdrequiredstring
ticketLinks[].ticketReferencerequiredstring
ticketLinks[].ticketSubjectrequiredstring
updatedAtrequiredstring (date-time)
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X PATCH 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"agreementPublicId": "string",
"billingMode": "string",
"budgetAmountCents": 0,
"budgetCriticalBp": 0,
"budgetMinutes": 0,
"budgetWarnBp": 0,
"clientContactEmail": "string",
"clientContactName": "string",
"description": "string",
"fixedPriceCents": 0,
"managerUserPublicId": "string",
"name": "string",
"notes": "string",
"plannedStartOn": "string",
"prepaidLinePublicId": "string",
"skipWeekends": false,
"statusEmailCadence": "string",
"statusEmailWeekday": 0
}'

DELETE /api/v1/clients/{cid}/projects/{id}

Section titled “DELETE /api/v1/clients/{cid}/projects/{id}”

DELETEproject:managemsp facemspIdempotent

Source: [object Object]

deleteProject removes a project that never got started.

project:manage and 409 hasTime, which the store decides under a lock: a project with any logged time or any invoiced milestone is a record, and the answer for one worked by mistake is to cancel it.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/clients/{cid}/projects/{id}/activity

Section titled “GET /api/v1/clients/{cid}/projects/{id}/activity”

GETproject:readmsp facemspIdempotent

Source: [object Object]

getProjectActivity merges what was DONE to the project with what was SENT about it.

Two sources because the two live in different databases and neither is complete on its own: the audit chain in the client database records the operator’s actions, and the outbox in control records the customer’s mail. A timeline showing one of them would leave the reader asking why an acceptance request appears with no request in it.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
pagequeryintegerNoOne-based page number. Defaults to 1.
pageSizequeryintegerNoRows per page, 1 to 200. Defaults to 50.
StatusBodyDescription
200application/json, PagedResultProjectActivityViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectActivityView
items[].actorrequiredstring
items[].atrequiredstring (date-time)
items[].detailrequiredstring
items[].kindrequiredstring
items[].verbrequiredstring
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/activity?page=0&pageSize=0' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/clients/{cid}/projects/{id}/budget

Section titled “GET /api/v1/clients/{cid}/projects/{id}/budget”

GETproject:readmsp facemspIdempotent

Source: [object Object]

getProjectBudget answers the budget tab in one aggregate read plus the change orders that moved it.

UnknownCostSeconds is REPORTED and never counted as zero. “This hour cost nothing” and “nobody told us what this hour costs” are different answers, and a margin that conflated them would be wrong in the practice’s own favour.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectBudgetViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
amountBurnBprequiredinteger
budgetAmountCentsrequiredinteger

int64.

budgetMinutesrequiredinteger
changeOrdersrequiredarray of BudgetChangeOrderView
changeOrders[].addedAmountCentsrequiredinteger

int64.

changeOrders[].addedMinutesrequiredinteger
changeOrders[].numberrequiredinteger
changeOrders[].publicIdrequiredstring
changeOrders[].statusrequiredstring
costCentsinteger or null

int64.

hoursBurnBprequiredinteger
invoicedCentsrequiredinteger

int64.

loggedSecondsrequiredinteger
marginCentsinteger or null

int64.

phasesrequiredarray of BudgetPhaseView
phases[].amountBurnBprequiredinteger
phases[].budgetAmountCentsinteger or null

int64.

phases[].budgetMinutesinteger or null
phases[].costCentsinteger or null

int64.

phases[].hoursBurnBprequiredinteger
phases[].loggedSecondsrequiredinteger
phases[].namerequiredstring
phases[].phasePublicIdrequiredstring
uninvoicedCentsrequiredinteger

int64.

unknownCostSecondsinteger or null
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/budget' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/clients/{cid}/projects/{id}/change-orders

Section titled “GET /api/v1/clients/{cid}/projects/{id}/change-orders”

GETproject:readmsp facemspIdempotent

Source: [object Object]

List change orders

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
200application/json, PagedResultProjectChangeOrderViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectChangeOrderView
items[].addedAmountCentsrequiredinteger

int64.

items[].addedMinutesrequiredinteger
items[].approvedAtstring (date-time) or null
items[].approvedByNamerequiredstring
items[].createdAtrequiredstring (date-time)
items[].descriptionrequiredstring
items[].invoicePublicIdstring or null
items[].invoicedAtstring (date-time) or null
items[].numberrequiredinteger
items[].phasePublicIdstring or null
items[].publicIdrequiredstring
items[].raiseInvoiceLinerequiredboolean
items[].statusrequiredstring
items[].titlerequiredstring
items[].updatedAtrequiredstring (date-time)
items[].voidReasonrequiredstring
items[].voidedAtstring (date-time) or null
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/clients/{cid}/projects/{id}/change-orders

Section titled “POST /api/v1/clients/{cid}/projects/{id}/change-orders”

POSTproject:managemsp facemsp

Source: [object Object]

Create change order

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
addedAmountCentsinteger or null

int64.

addedMinutesinteger or null
descriptionstring or null
phasePublicIdstring or null
raiseInvoiceLineboolean or null
titlestring or null
StatusBodyDescription
201application/json, ProjectChangeOrderViewCreated.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

201 response body

FieldTypeDescription
addedAmountCentsrequiredinteger

int64.

addedMinutesrequiredinteger
approvedAtstring (date-time) or null
approvedByNamerequiredstring
createdAtrequiredstring (date-time)
descriptionrequiredstring
invoicePublicIdstring or null
invoicedAtstring (date-time) or null
numberrequiredinteger
phasePublicIdstring or null
publicIdrequiredstring
raiseInvoiceLinerequiredboolean
statusrequiredstring
titlerequiredstring
updatedAtrequiredstring (date-time)
voidReasonrequiredstring
voidedAtstring (date-time) or null
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"addedAmountCents": 0,
"addedMinutes": 0,
"description": "string",
"phasePublicId": "string",
"raiseInvoiceLine": false,
"title": "string"
}'

PATCH /api/v1/clients/{cid}/projects/{id}/change-orders/{coId}

Section titled “PATCH /api/v1/clients/{cid}/projects/{id}/change-orders/{coId}”

PATCHproject:managemsp facemsp

Source: [object Object]

Patch change order

NameInTypeRequiredDescription
cidpathstringYes
coIdpathstringYesA uuid.
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
addedAmountCentsinteger or null

int64.

addedMinutesinteger or null
descriptionstring or null
phasePublicIdstring or null
raiseInvoiceLineboolean or null
titlestring or null
StatusBodyDescription
200application/json, ProjectChangeOrderViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
addedAmountCentsrequiredinteger

int64.

addedMinutesrequiredinteger
approvedAtstring (date-time) or null
approvedByNamerequiredstring
createdAtrequiredstring (date-time)
descriptionrequiredstring
invoicePublicIdstring or null
invoicedAtstring (date-time) or null
numberrequiredinteger
phasePublicIdstring or null
publicIdrequiredstring
raiseInvoiceLinerequiredboolean
statusrequiredstring
titlerequiredstring
updatedAtrequiredstring (date-time)
voidReasonrequiredstring
voidedAtstring (date-time) or null
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X PATCH 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"addedAmountCents": 0,
"addedMinutes": 0,
"description": "string",
"phasePublicId": "string",
"raiseInvoiceLine": false,
"title": "string"
}'

POST /api/v1/clients/{cid}/projects/{id}/change-orders/{coId}/approve

Section titled “POST /api/v1/clients/{cid}/projects/{id}/change-orders/{coId}/approve”

POSTproject:managemsp facemsp

Source: [object Object]

approveChangeOrder stamps the sign-off, moves the budget and raises the money.

The budget move is INSIDE the store’s transaction: a budget that moved without the approval, or the reverse, would be two facts that disagree. The two tails are the invoice line and the recompute, and the recompute is what clears a budget alert the extra scope has just made untrue.

NameInTypeRequiredDescription
cidpathstringYes
coIdpathstringYesA uuid.
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
approvedByNamerequiredstring
StatusBodyDescription
200application/json, ProjectChangeOrderViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
addedAmountCentsrequiredinteger

int64.

addedMinutesrequiredinteger
approvedAtstring (date-time) or null
approvedByNamerequiredstring
createdAtrequiredstring (date-time)
descriptionrequiredstring
invoicePublicIdstring or null
invoicedAtstring (date-time) or null
numberrequiredinteger
phasePublicIdstring or null
publicIdrequiredstring
raiseInvoiceLinerequiredboolean
statusrequiredstring
titlerequiredstring
updatedAtrequiredstring (date-time)
voidReasonrequiredstring
voidedAtstring (date-time) or null
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/approve' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"approvedByName": "string"
}'

POST /api/v1/clients/{cid}/projects/{id}/change-orders/{coId}/void

Section titled “POST /api/v1/clients/{cid}/projects/{id}/change-orders/{coId}/void”

POSTproject:managemsp facemsp

Source: [object Object]

voidChangeOrder reverses the budget the approval added.

409 ONCE INVOICED. A change order whose money is on a document a customer has been sent cannot be unwound by moving a budget number: that is a credit note, which slice 1 already ships and which somebody has to decide to raise.

NameInTypeRequiredDescription
cidpathstringYes
coIdpathstringYesA uuid.
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
reasonrequiredstring
StatusBodyDescription
200application/json, ProjectChangeOrderViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
addedAmountCentsrequiredinteger

int64.

addedMinutesrequiredinteger
approvedAtstring (date-time) or null
approvedByNamerequiredstring
createdAtrequiredstring (date-time)
descriptionrequiredstring
invoicePublicIdstring or null
invoicedAtstring (date-time) or null
numberrequiredinteger
phasePublicIdstring or null
publicIdrequiredstring
raiseInvoiceLinerequiredboolean
statusrequiredstring
titlerequiredstring
updatedAtrequiredstring (date-time)
voidReasonrequiredstring
voidedAtstring (date-time) or null
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/void' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"reason": "string"
}'

POST /api/v1/clients/{cid}/projects/{id}/close

Section titled “POST /api/v1/clients/{cid}/projects/{id}/close”

POSTproject:managemsp facemspNot fully resolved

What this page does not know
  • response-status

These are parts of the route the extractor could not read from the source. Everything else on this page came straight from it.

Source: [object Object]

closeProject completes a project and stores what was learned from it.

One transaction in the store for the completion and the retrospective, then the two tails: the public links are revoked and, when asked, the template gets the estimates this job actually took.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
notesrequiredstring
updateTemplateEstimatesrequiredboolean
StatusBodyDescription
200application/json, ProjectViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
actualStartOnstring or null
agreementPublicIdstring or null
amountBurnBprequiredinteger
atRiskTasksrequiredinteger
billableSecondsrequiredinteger
billingModerequiredstring
budgetAmountCentsrequiredinteger

int64.

budgetCriticalBpinteger or null
budgetMinutesrequiredinteger
budgetWarnBpinteger or null
cancelledAtstring (date-time) or null
clientContactEmailrequiredstring
clientContactNamerequiredstring
clientNamerequiredstring
clientPublicIdrequiredstring
completedAtstring (date-time) or null
convertedFromTicketPublicIdstring or null
costCentsinteger or null

int64.

createdAtrequiredstring (date-time)
descriptionrequiredstring
fixedPriceCentsrequiredinteger

int64.

healthrequiredstring
healthComputedAtstring (date-time) or null
healthReasonrequiredstring
hoursBurnBprequiredinteger
isSelfrequiredboolean
lastStatusEmailOnstring or null
loggedSecondsrequiredinteger
managerNamestring or null
managerUserPublicIdstring or null
milestonesrequiredarray of ProjectMilestoneView
milestones[].acceptanceMilestoneAcceptanceView
milestones[].acceptance.consentTextrequiredstring
milestones[].acceptance.consentVersionrequiredinteger
milestones[].acceptance.iprequiredstring
milestones[].acceptance.signedAtrequiredstring (date-time)
milestones[].acceptance.signerNamerequiredstring
milestones[].acceptance.signerTitlerequiredstring
milestones[].acceptance.userAgentrequiredstring
milestones[].acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

milestones[].acceptanceLink.activerequiredboolean
milestones[].acceptanceLink.expiresAtstring (date-time) or null
milestones[].acceptanceLink.viewCountrequiredinteger
milestones[].acceptanceSentAtstring (date-time) or null
milestones[].acceptedAtstring (date-time) or null
milestones[].amountCentsinteger or null

int64.

milestones[].certificateAvailablerequiredboolean
milestones[].clientVisiblerequiredboolean
milestones[].completedAtstring (date-time) or null
milestones[].declineReasonrequiredstring
milestones[].declinedAtstring (date-time) or null
milestones[].descriptionrequiredstring
milestones[].dueOnrequiredstring
milestones[].invoicePublicIdstring or null
milestones[].invoicedAtstring (date-time) or null
milestones[].namerequiredstring
milestones[].phaseNamestring or null
milestones[].phasePublicIdstring or null
milestones[].positionrequiredinteger
milestones[].publicIdrequiredstring
milestones[].requiresClientAcceptancerequiredboolean
milestones[].statusrequiredstring
namerequiredstring
nextMilestoneNextMilestoneView
nextMilestone.dueOnrequiredstring
nextMilestone.namerequiredstring
nextMilestone.publicIdrequiredstring
notesrequiredstring
numberrequiredinteger

int64.

openTasksrequiredinteger
overdueMilestonesrequiredinteger
percentCompleterequiredinteger
phasesrequiredarray of ProjectPhaseView
phases[].billableSecondsrequiredinteger
phases[].billingModeOverridestring or null
phases[].budgetAmountCentsinteger or null

int64.

phases[].budgetMinutesinteger or null
phases[].completedAtstring (date-time) or null
phases[].costCentsinteger or null

int64.

phases[].loggedSecondsrequiredinteger
phases[].namerequiredstring
phases[].percentCompleterequiredinteger
phases[].plannedEndOnstring or null
phases[].plannedStartOnstring or null
phases[].positionrequiredinteger
phases[].prepaidLinePublicIdstring or null
phases[].publicIdrequiredstring
phases[].statusrequiredstring
plannedEndOnstring or null
plannedStartOnrequiredstring
prepaidLinePublicIdstring or null
publicIdrequiredstring
quotePublicIdstring or null
referencerequiredstring
retrospectiverequiredany
skipWeekendsrequiredboolean
statusrequiredstring
statusEmailCadencerequiredstring
statusEmailWeekdayrequiredinteger
statusLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

statusLink.activerequiredboolean
statusLink.expiresAtstring (date-time) or null
statusLink.viewCountrequiredinteger
templatePublicIdstring or null
templateVersioninteger or null
ticketLinksrequiredarray of ProjectTicketLinkView
ticketLinks[].createdAtrequiredstring (date-time)
ticketLinks[].kindrequiredstring
ticketLinks[].publicIdrequiredstring
ticketLinks[].taskPublicIdstring or null
ticketLinks[].ticketPublicIdrequiredstring
ticketLinks[].ticketReferencerequiredstring
ticketLinks[].ticketSubjectrequiredstring
updatedAtrequiredstring (date-time)
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/close' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"notes": "string",
"updateTemplateEstimates": false
}'

GET /api/v1/clients/{cid}/projects/{id}/documents

Section titled “GET /api/v1/clients/{cid}/projects/{id}/documents”

GETproject:readmsp facemspIdempotent

Source: [object Object]

List project documents

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
pagequeryintegerNoOne-based page number. Defaults to 1.
pageSizequeryintegerNoRows per page, 1 to 200. Defaults to 50.
StatusBodyDescription
200application/json, PagedResultProjectDocumentViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectDocumentView
items[].changeOrderPublicIdstring or null
items[].contentTyperequiredstring
items[].createdAtrequiredstring (date-time)
items[].deletedAtstring (date-time) or null
items[].downloadUrlrequiredstring
items[].fileNamerequiredstring
items[].kindrequiredstring
items[].milestonePublicIdstring or null
items[].publicIdrequiredstring
items[].sizeBytesrequiredinteger

int64.

items[].uploadedByUserPublicIdstring or null
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents?page=0&pageSize=0' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/clients/{cid}/projects/{id}/documents

Section titled “POST /api/v1/clients/{cid}/projects/{id}/documents”

POSTproject:writemsp facemsp

Source: [object Object]

uploadProjectDocument takes one file as the raw request body.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
fileNamequerystringNo
StatusBodyDescription
201application/json, ProjectDocumentViewCreated.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
413application/problem+json, ProblemDetailsThe request was refused.
415application/problem+json, ProblemDetailsA fileName query parameter is required.
500application/problem+json, ProblemDetailsCould not build a storage key.
502application/problem+json, ProblemDetailsThe document could not be stored. Nothing was attached to the project.
503application/problem+json, ProblemDetailsProjects are not available on this server.
507application/problem+json, ProblemDetailsThis client’s storage is full. Raise the quota or remove old documents.

201 response body

FieldTypeDescription
changeOrderPublicIdstring or null
contentTyperequiredstring
createdAtrequiredstring (date-time)
deletedAtstring (date-time) or null
downloadUrlrequiredstring
fileNamerequiredstring
kindrequiredstring
milestonePublicIdstring or null
publicIdrequiredstring
sizeBytesrequiredinteger

int64.

uploadedByUserPublicIdstring or null
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents?fileName=<fileName>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/clients/{cid}/projects/{id}/documents/{docId}

Section titled “GET /api/v1/clients/{cid}/projects/{id}/documents/{docId}”

GETproject:readmsp facemspIdempotentdownloadNot fully resolved

What this page does not know
  • response

These are parts of the route the extractor could not read from the source. Everything else on this page came straight from it.

Source: [object Object]

downloadProjectDocument streams one file back.

Read attachments.go’s header before changing any header this writes. The combination of a forced generic content type, an attachment disposition and nosniff is what keeps an uploaded HTML file from executing on the console’s own origin, and each one alone is insufficient.

NameInTypeRequiredDescription
cidpathstringYes
docIdpathstringYesA uuid.
idpathstringYesA uuid.
StatusBodyDescription
200application/octet-stream, string (binary)Success. The body shape was not resolved; see x-outpost-unresolved.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
502application/problem+json, ProblemDetailsThe document could not be read from storage.
503application/problem+json, ProblemDetailsDocument storage is not configured on this Depot.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

DELETE /api/v1/clients/{cid}/projects/{id}/documents/{docId}

Section titled “DELETE /api/v1/clients/{cid}/projects/{id}/documents/{docId}”

DELETEproject:writemsp facemspIdempotent

Source: [object Object]

deleteProjectDocument removes an uploaded file.

A CERTIFICATE CANNOT BE DELETED, and that is a 409 rather than a permission check: PROJECT_CONTRACTS.md’s fourth rule is that evidence is never deleted, and an acceptance certificate is the document a customer’s signature produced. The change-order document is refused for the same reason.

NameInTypeRequiredDescription
cidpathstringYes
docIdpathstringYesA uuid.
idpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/clients/{cid}/projects/{id}/mail

Section titled “GET /api/v1/clients/{cid}/projects/{id}/mail”

GETproject:readmsp facemspIdempotent

Source: [object Object]

List project mail

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
pagequeryintegerNoOne-based page number. Defaults to 1.
pageSizequeryintegerNoRows per page, 1 to 200. Defaults to 50.
StatusBodyDescription
200application/json, PagedResultProjectMailViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectMailView
items[].attemptsrequiredinteger
items[].createdAtrequiredstring (date-time)
items[].kindrequiredstring
items[].lastErrorrequiredstring
items[].publicIdrequiredstring
items[].refPublicIdstring or null
items[].sentAtstring (date-time) or null
items[].staterequiredstring
items[].subjectrequiredstring
items[].torequiredstring
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/mail?page=0&pageSize=0' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/clients/{cid}/projects/{id}/milestones

Section titled “GET /api/v1/clients/{cid}/projects/{id}/milestones”

GETproject:readmsp facemspIdempotent

Source: [object Object]

List milestones

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
200application/json, PagedResultProjectMilestoneViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectMilestoneView
items[].acceptanceMilestoneAcceptanceView
items[].acceptance.consentTextrequiredstring
items[].acceptance.consentVersionrequiredinteger
items[].acceptance.iprequiredstring
items[].acceptance.signedAtrequiredstring (date-time)
items[].acceptance.signerNamerequiredstring
items[].acceptance.signerTitlerequiredstring
items[].acceptance.userAgentrequiredstring
items[].acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

items[].acceptanceLink.activerequiredboolean
items[].acceptanceLink.expiresAtstring (date-time) or null
items[].acceptanceLink.viewCountrequiredinteger
items[].acceptanceSentAtstring (date-time) or null
items[].acceptedAtstring (date-time) or null
items[].amountCentsinteger or null

int64.

items[].certificateAvailablerequiredboolean
items[].clientVisiblerequiredboolean
items[].completedAtstring (date-time) or null
items[].declineReasonrequiredstring
items[].declinedAtstring (date-time) or null
items[].descriptionrequiredstring
items[].dueOnrequiredstring
items[].invoicePublicIdstring or null
items[].invoicedAtstring (date-time) or null
items[].namerequiredstring
items[].phaseNamestring or null
items[].phasePublicIdstring or null
items[].positionrequiredinteger
items[].publicIdrequiredstring
items[].requiresClientAcceptancerequiredboolean
items[].statusrequiredstring
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/clients/{cid}/projects/{id}/milestones

Section titled “POST /api/v1/clients/{cid}/projects/{id}/milestones”

POSTproject:writemsp facemsp

Source: [object Object]

Create milestone

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
amountCentsinteger or null

int64.

clientVisibleboolean or null
descriptionstring or null
dueOnstring or null
namestring or null
phasePublicIdstring or null
positioninteger or null
requiresClientAcceptanceboolean or null
StatusBodyDescription
201application/json, ProjectMilestoneViewCreated.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

201 response body

FieldTypeDescription
acceptanceMilestoneAcceptanceView
acceptance.consentTextrequiredstring
acceptance.consentVersionrequiredinteger
acceptance.iprequiredstring
acceptance.signedAtrequiredstring (date-time)
acceptance.signerNamerequiredstring
acceptance.signerTitlerequiredstring
acceptance.userAgentrequiredstring
acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

acceptanceLink.activerequiredboolean
acceptanceLink.expiresAtstring (date-time) or null
acceptanceLink.viewCountrequiredinteger
acceptanceSentAtstring (date-time) or null
acceptedAtstring (date-time) or null
amountCentsinteger or null

int64.

certificateAvailablerequiredboolean
clientVisiblerequiredboolean
completedAtstring (date-time) or null
declineReasonrequiredstring
declinedAtstring (date-time) or null
descriptionrequiredstring
dueOnrequiredstring
invoicePublicIdstring or null
invoicedAtstring (date-time) or null
namerequiredstring
phaseNamestring or null
phasePublicIdstring or null
positionrequiredinteger
publicIdrequiredstring
requiresClientAcceptancerequiredboolean
statusrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"amountCents": 0,
"clientVisible": false,
"description": "string",
"dueOn": "string",
"name": "string",
"phasePublicId": "string",
"position": 0,
"requiresClientAcceptance": false
}'

GET /api/v1/clients/{cid}/projects/{id}/milestones/{msId}

Section titled “GET /api/v1/clients/{cid}/projects/{id}/milestones/{msId}”

GETproject:readmsp facemspIdempotent

Source: [object Object]

getMilestone answers one milestone with its signed acceptance.

It is the drawer the console opens from the milestones tab, and it is the only read in the product that has ever been able to answer “who signed this, when, from where, and against which sentence”. milestoneFor reads through GetProjectMilestone, which hydrates the evidence row; the list hydrates it in a batch beside it.

The link ref is enriched for the same reason the list enriches it: the state and the expiry of an acceptance link live in the CONTROL database, and the milestone row carries only its id.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
msIdpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectMilestoneViewSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
acceptanceMilestoneAcceptanceView
acceptance.consentTextrequiredstring
acceptance.consentVersionrequiredinteger
acceptance.iprequiredstring
acceptance.signedAtrequiredstring (date-time)
acceptance.signerNamerequiredstring
acceptance.signerTitlerequiredstring
acceptance.userAgentrequiredstring
acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

acceptanceLink.activerequiredboolean
acceptanceLink.expiresAtstring (date-time) or null
acceptanceLink.viewCountrequiredinteger
acceptanceSentAtstring (date-time) or null
acceptedAtstring (date-time) or null
amountCentsinteger or null

int64.

certificateAvailablerequiredboolean
clientVisiblerequiredboolean
completedAtstring (date-time) or null
declineReasonrequiredstring
declinedAtstring (date-time) or null
descriptionrequiredstring
dueOnrequiredstring
invoicePublicIdstring or null
invoicedAtstring (date-time) or null
namerequiredstring
phaseNamestring or null
phasePublicIdstring or null
positionrequiredinteger
publicIdrequiredstring
requiresClientAcceptancerequiredboolean
statusrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PATCH /api/v1/clients/{cid}/projects/{id}/milestones/{msId}

Section titled “PATCH /api/v1/clients/{cid}/projects/{id}/milestones/{msId}”

PATCHproject:writemsp facemsp

Source: [object Object]

patchMilestone edits a milestone.

The store refuses everything but DueOn, Description and ClientVisible once the milestone is past pending, and that is the rule rather than a convenience: what a client was ASKED TO ACCEPT must not change under them between the request and the signature.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
msIdpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
amountCentsinteger or null

int64.

clientVisibleboolean or null
descriptionstring or null
dueOnstring or null
namestring or null
phasePublicIdstring or null
positioninteger or null
requiresClientAcceptanceboolean or null
StatusBodyDescription
200application/json, ProjectMilestoneViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
acceptanceMilestoneAcceptanceView
acceptance.consentTextrequiredstring
acceptance.consentVersionrequiredinteger
acceptance.iprequiredstring
acceptance.signedAtrequiredstring (date-time)
acceptance.signerNamerequiredstring
acceptance.signerTitlerequiredstring
acceptance.userAgentrequiredstring
acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

acceptanceLink.activerequiredboolean
acceptanceLink.expiresAtstring (date-time) or null
acceptanceLink.viewCountrequiredinteger
acceptanceSentAtstring (date-time) or null
acceptedAtstring (date-time) or null
amountCentsinteger or null

int64.

certificateAvailablerequiredboolean
clientVisiblerequiredboolean
completedAtstring (date-time) or null
declineReasonrequiredstring
declinedAtstring (date-time) or null
descriptionrequiredstring
dueOnrequiredstring
invoicePublicIdstring or null
invoicedAtstring (date-time) or null
namerequiredstring
phaseNamestring or null
phasePublicIdstring or null
positionrequiredinteger
publicIdrequiredstring
requiresClientAcceptancerequiredboolean
statusrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X PATCH 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"amountCents": 0,
"clientVisible": false,
"description": "string",
"dueOn": "string",
"name": "string",
"phasePublicId": "string",
"position": 0,
"requiresClientAcceptance": false
}'

DELETE /api/v1/clients/{cid}/projects/{id}/milestones/{msId}

Section titled “DELETE /api/v1/clients/{cid}/projects/{id}/milestones/{msId}”

DELETEproject:writemsp facemspIdempotent

Source: [object Object]

Delete milestone

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
msIdpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'
Section titled “GET /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/acceptance-link”

GETproject:managemsp facemspIdempotent

Source: [object Object]

getAcceptanceLink opens the sealed token.

project:manage and not project:read: a link is a bearer credential for a document a customer is about to sign, so whoever may hand one out is whoever owns the commercial side of the job.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
msIdpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectLinkViewSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
activerequiredboolean
expiresAtstring (date-time) or null
kindrequiredstring
urlrequiredstring
viewCountrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/acceptance-link' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/cancel

Section titled “POST /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/cancel”

POSTproject:writemsp facemsp

Source: [object Object]

Cancel milestone

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
msIdpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectMilestoneViewSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
acceptanceMilestoneAcceptanceView
acceptance.consentTextrequiredstring
acceptance.consentVersionrequiredinteger
acceptance.iprequiredstring
acceptance.signedAtrequiredstring (date-time)
acceptance.signerNamerequiredstring
acceptance.signerTitlerequiredstring
acceptance.userAgentrequiredstring
acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

acceptanceLink.activerequiredboolean
acceptanceLink.expiresAtstring (date-time) or null
acceptanceLink.viewCountrequiredinteger
acceptanceSentAtstring (date-time) or null
acceptedAtstring (date-time) or null
amountCentsinteger or null

int64.

certificateAvailablerequiredboolean
clientVisiblerequiredboolean
completedAtstring (date-time) or null
declineReasonrequiredstring
declinedAtstring (date-time) or null
descriptionrequiredstring
dueOnrequiredstring
invoicePublicIdstring or null
invoicedAtstring (date-time) or null
namerequiredstring
phaseNamestring or null
phasePublicIdstring or null
positionrequiredinteger
publicIdrequiredstring
requiresClientAcceptancerequiredboolean
statusrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/cancel' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/certificate

Section titled “GET /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/certificate”

GETproject:readmsp facemspIdempotentdownloadNot fully resolved

What this page does not know
  • response

These are parts of the route the extractor could not read from the source. Everything else on this page came straight from it.

Source: [object Object]

getMilestoneCertificate serves the two-page acceptance certificate.

404 UNTIL THE FINISHER RAN. An acceptance exists the instant a client signs and the certificate is rendered after that commit, so a milestone can be accepted with no document for a second or a minute. Rendering one here on demand would hand somebody a document that is a different document tomorrow.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
msIdpathstringYesA uuid.
StatusBodyDescription
200application/octet-stream, string (binary)Success. The body shape was not resolved; see x-outpost-unresolved.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/certificate' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/complete

Section titled “POST /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/complete”

POSTproject:writemsp facemsp

Source: [object Object]

Complete milestone

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
msIdpathstringYesA uuid.

Required, sent as application/json.

The body is any.

StatusBodyDescription
200application/json, ProjectMilestoneViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not acceptable.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsCompleting a milestone without the client’s acceptance needs the project:manage permission.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
acceptanceMilestoneAcceptanceView
acceptance.consentTextrequiredstring
acceptance.consentVersionrequiredinteger
acceptance.iprequiredstring
acceptance.signedAtrequiredstring (date-time)
acceptance.signerNamerequiredstring
acceptance.signerTitlerequiredstring
acceptance.userAgentrequiredstring
acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

acceptanceLink.activerequiredboolean
acceptanceLink.expiresAtstring (date-time) or null
acceptanceLink.viewCountrequiredinteger
acceptanceSentAtstring (date-time) or null
acceptedAtstring (date-time) or null
amountCentsinteger or null

int64.

certificateAvailablerequiredboolean
clientVisiblerequiredboolean
completedAtstring (date-time) or null
declineReasonrequiredstring
declinedAtstring (date-time) or null
descriptionrequiredstring
dueOnrequiredstring
invoicePublicIdstring or null
invoicedAtstring (date-time) or null
namerequiredstring
phaseNamestring or null
phasePublicIdstring or null
positionrequiredinteger
publicIdrequiredstring
requiresClientAcceptancerequiredboolean
statusrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/complete' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '"string"'

POST /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/resend-acceptance

Section titled “POST /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/resend-acceptance”

POSTproject:writemsp facemsp

Source: [object Object]

resendAcceptance re-queues the request with the SAME link.

From declined it also returns the milestone to awaiting_acceptance, which is the whole reason declined is a status rather than a note: a client who says “this is not done” leaves the milestone somewhere the PM can act on, and the resend is the act. The customer does not get a second address for one decision.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
msIdpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectMilestoneViewSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
acceptanceMilestoneAcceptanceView
acceptance.consentTextrequiredstring
acceptance.consentVersionrequiredinteger
acceptance.iprequiredstring
acceptance.signedAtrequiredstring (date-time)
acceptance.signerNamerequiredstring
acceptance.signerTitlerequiredstring
acceptance.userAgentrequiredstring
acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

acceptanceLink.activerequiredboolean
acceptanceLink.expiresAtstring (date-time) or null
acceptanceLink.viewCountrequiredinteger
acceptanceSentAtstring (date-time) or null
acceptedAtstring (date-time) or null
amountCentsinteger or null

int64.

certificateAvailablerequiredboolean
clientVisiblerequiredboolean
completedAtstring (date-time) or null
declineReasonrequiredstring
declinedAtstring (date-time) or null
descriptionrequiredstring
dueOnrequiredstring
invoicePublicIdstring or null
invoicedAtstring (date-time) or null
namerequiredstring
phaseNamestring or null
phasePublicIdstring or null
positionrequiredinteger
publicIdrequiredstring
requiresClientAcceptancerequiredboolean
statusrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/resend-acceptance' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'
Section titled “POST /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/rotate-acceptance-link”

POSTproject:managemsp facemsp

Source: [object Object]

rotateAcceptanceLink revokes the live link and mints a new one.

One store call: MintProjectPublicLink revokes the previous live link of that kind for that subject in the same transaction, so the partial unique index never trips in normal operation and there is no window in which a milestone has two live addresses.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
msIdpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectLinkViewSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
activerequiredboolean
expiresAtstring (date-time) or null
kindrequiredstring
urlrequiredstring
viewCountrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/rotate-acceptance-link' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/clients/{cid}/projects/{id}/notes

Section titled “GET /api/v1/clients/{cid}/projects/{id}/notes”

GETproject:readmsp facemspIdempotent

Source: [object Object]

List project notes

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
pagequeryintegerNoOne-based page number. Defaults to 1.
pageSizequeryintegerNoRows per page, 1 to 200. Defaults to 50.
taskquerystringNo
StatusBodyDescription
200application/json, PagedResultProjectNoteViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectNoteView
items[].authorNamestring or null
items[].authorUserPublicIdstring or null
items[].bodyrequiredstring
items[].clientVisiblerequiredboolean
items[].createdAtrequiredstring (date-time)
items[].publicIdrequiredstring
items[].taskPublicIdstring or null
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes?page=0&pageSize=0&task=<task>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/clients/{cid}/projects/{id}/notes

Section titled “POST /api/v1/clients/{cid}/projects/{id}/notes”

POSTproject:writemsp facemsp

Source: [object Object]

Create project note

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
bodyrequiredstring
clientVisibleboolean or null
taskPublicIdrequiredstring
StatusBodyDescription
201application/json, ProjectNoteViewCreated.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

201 response body

FieldTypeDescription
authorNamestring or null
authorUserPublicIdstring or null
bodyrequiredstring
clientVisiblerequiredboolean
createdAtrequiredstring (date-time)
publicIdrequiredstring
taskPublicIdstring or null
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"body": "string",
"clientVisible": false,
"taskPublicId": "string"
}'

DELETE /api/v1/clients/{cid}/projects/{id}/notes/{noteId}

Section titled “DELETE /api/v1/clients/{cid}/projects/{id}/notes/{noteId}”

DELETEproject:writemsp facemspIdempotent

Source: [object Object]

Delete project note

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
noteIdpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes/<noteId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/clients/{cid}/projects/{id}/phases

Section titled “GET /api/v1/clients/{cid}/projects/{id}/phases”

GETproject:readmsp facemspIdempotent

Source: [object Object]

List phases

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
200application/json, PagedResultProjectPhaseViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectPhaseView
items[].billableSecondsrequiredinteger
items[].billingModeOverridestring or null
items[].budgetAmountCentsinteger or null

int64.

items[].budgetMinutesinteger or null
items[].completedAtstring (date-time) or null
items[].costCentsinteger or null

int64.

items[].loggedSecondsrequiredinteger
items[].namerequiredstring
items[].percentCompleterequiredinteger
items[].plannedEndOnstring or null
items[].plannedStartOnstring or null
items[].positionrequiredinteger
items[].prepaidLinePublicIdstring or null
items[].publicIdrequiredstring
items[].statusrequiredstring
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/clients/{cid}/projects/{id}/phases

Section titled “POST /api/v1/clients/{cid}/projects/{id}/phases”

POSTproject:writemsp facemsp

Source: [object Object]

Create phase

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
billingModeOverridestring or null
budgetAmountCentsinteger or null

int64.

budgetCriticalBpinteger or null
budgetMinutesinteger or null
budgetWarnBpinteger or null
namestring or null
positioninteger or null
prepaidLinePublicIdstring or null
StatusBodyDescription
201application/json, ProjectPhaseViewCreated.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsOverriding a phase’s billing mode needs the project:manage permission.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

201 response body

FieldTypeDescription
billableSecondsrequiredinteger
billingModeOverridestring or null
budgetAmountCentsinteger or null

int64.

budgetMinutesinteger or null
completedAtstring (date-time) or null
costCentsinteger or null

int64.

loggedSecondsrequiredinteger
namerequiredstring
percentCompleterequiredinteger
plannedEndOnstring or null
plannedStartOnstring or null
positionrequiredinteger
prepaidLinePublicIdstring or null
publicIdrequiredstring
statusrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"billingModeOverride": "string",
"budgetAmountCents": 0,
"budgetCriticalBp": 0,
"budgetMinutes": 0,
"budgetWarnBp": 0,
"name": "string",
"position": 0,
"prepaidLinePublicId": "string"
}'

PATCH /api/v1/clients/{cid}/projects/{id}/phases/{phaseId}

Section titled “PATCH /api/v1/clients/{cid}/projects/{id}/phases/{phaseId}”

PATCHproject:writemsp facemsp

Source: [object Object]

Patch phase

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
phaseIdpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
billingModeOverridestring or null
budgetAmountCentsinteger or null

int64.

budgetCriticalBpinteger or null
budgetMinutesinteger or null
budgetWarnBpinteger or null
namestring or null
positioninteger or null
prepaidLinePublicIdstring or null
StatusBodyDescription
200application/json, ProjectPhaseViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsOverriding a phase’s billing mode needs the project:manage permission.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
billableSecondsrequiredinteger
billingModeOverridestring or null
budgetAmountCentsinteger or null

int64.

budgetMinutesinteger or null
completedAtstring (date-time) or null
costCentsinteger or null

int64.

loggedSecondsrequiredinteger
namerequiredstring
percentCompleterequiredinteger
plannedEndOnstring or null
plannedStartOnstring or null
positionrequiredinteger
prepaidLinePublicIdstring or null
publicIdrequiredstring
statusrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X PATCH 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"billingModeOverride": "string",
"budgetAmountCents": 0,
"budgetCriticalBp": 0,
"budgetMinutes": 0,
"budgetWarnBp": 0,
"name": "string",
"position": 0,
"prepaidLinePublicId": "string"
}'

DELETE /api/v1/clients/{cid}/projects/{id}/phases/{phaseId}

Section titled “DELETE /api/v1/clients/{cid}/projects/{id}/phases/{phaseId}”

DELETEproject:writemsp facemspIdempotent

Source: [object Object]

Delete phase

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
phaseIdpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PUT /api/v1/clients/{cid}/projects/{id}/phases/order

Section titled “PUT /api/v1/clients/{cid}/projects/{id}/phases/order”

PUTproject:writemsp facemspIdempotent

Source: [object Object]

Reorder phases

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
publicIdsrequiredarray of string
StatusBodyDescription
200application/json, PagedResultProjectPhaseViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectPhaseView
items[].billableSecondsrequiredinteger
items[].billingModeOverridestring or null
items[].budgetAmountCentsinteger or null

int64.

items[].budgetMinutesinteger or null
items[].completedAtstring (date-time) or null
items[].costCentsinteger or null

int64.

items[].loggedSecondsrequiredinteger
items[].namerequiredstring
items[].percentCompleterequiredinteger
items[].plannedEndOnstring or null
items[].plannedStartOnstring or null
items[].positionrequiredinteger
items[].prepaidLinePublicIdstring or null
items[].publicIdrequiredstring
items[].statusrequiredstring
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X PUT 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/order' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"publicIds": [
"string"
]
}'

GET /api/v1/clients/{cid}/projects/{id}/retrospective

Section titled “GET /api/v1/clients/{cid}/projects/{id}/retrospective”

GETproject:readmsp facemspIdempotent

Source: [object Object]

Get retrospective

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
200application/json, RetrospectiveViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
canUpdateTemplaterequiredboolean
notesrequiredstring
rowsrequiredarray of RetrospectiveRowView
rows[].estimateMinutesrequiredinteger
rows[].loggedSecondsrequiredinteger
rows[].taskPublicIdrequiredstring
rows[].templateTaskPublicIdrequiredstring
rows[].titlerequiredstring
suggestionsrequiredarray of RetrospectiveSuggestionView
suggestions[].currentMinutesrequiredinteger
suggestions[].suggestedMinutesrequiredinteger
suggestions[].templateTaskPublicIdrequiredstring
suggestions[].titlerequiredstring
templateNamerequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/retrospective' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/clients/{cid}/projects/{id}/schedule

Section titled “GET /api/v1/clients/{cid}/projects/{id}/schedule”

GETproject:readmsp facemspIdempotent

Source: [object Object]

Get project schedule plan

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectScheduleViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
criticalPathrequiredarray of string
dependenciesrequiredarray of ScheduleDependencyView
dependencies[].lagDaysrequiredinteger
dependencies[].predecessorTaskPublicIdrequiredstring
dependencies[].taskPublicIdrequiredstring
generatedAtrequiredstring (date-time)
plannedEndOnstring or null
plannedStartOnstring or null
slackDaysrequiredobject
tasksrequiredarray of ProjectTaskView
tasks[].actualStartOnstring or null
tasks[].assigneeNamestring or null
tasks[].assigneeUserPublicIdstring or null
tasks[].atRiskrequiredboolean
tasks[].atRiskReasonrequiredstring
tasks[].billableSecondsrequiredinteger
tasks[].blockedReasonrequiredstring
tasks[].checklistrequiredarray of ChecklistItemView
tasks[].checklist[].donerequiredboolean
tasks[].checklist[].doneAtstring (date-time) or null
tasks[].checklist[].positionrequiredinteger
tasks[].checklist[].publicIdrequiredstring
tasks[].checklist[].textrequiredstring
tasks[].clientVisiblerequiredboolean
tasks[].completedAtstring (date-time) or null
tasks[].costCentsinteger or null

int64.

tasks[].descriptionrequiredstring
tasks[].durationDaysrequiredinteger
tasks[].estimateMinutesrequiredinteger
tasks[].loggedSecondsrequiredinteger
tasks[].onCriticalPathrequiredboolean
tasks[].parentTaskPublicIdstring or null
tasks[].phasePublicIdstring or null
tasks[].plannedDueOnstring or null
tasks[].plannedStartOnstring or null
tasks[].positionrequiredinteger
tasks[].predecessorsrequiredarray of TaskDependencyView
tasks[].predecessors[].lagDaysrequiredinteger
tasks[].predecessors[].taskPublicIdrequiredstring
tasks[].priorityrequiredstring
tasks[].projectPublicIdrequiredstring
tasks[].publicIdrequiredstring
tasks[].rolePlaceholderrequiredstring
tasks[].spawnedTicketPublicIdstring or null
tasks[].statusrequiredstring
tasks[].subtasksarray of ProjectTaskView
tasks[].subtasks[].actualStartOnstring or null
tasks[].subtasks[].assigneeNamestring or null
tasks[].subtasks[].assigneeUserPublicIdstring or null
tasks[].subtasks[].atRiskrequiredboolean
tasks[].subtasks[].atRiskReasonrequiredstring
tasks[].subtasks[].billableSecondsrequiredinteger
tasks[].subtasks[].blockedReasonrequiredstring
tasks[].subtasks[].checklistrequiredarray of ChecklistItemView
tasks[].subtasks[].checklist[].donerequiredboolean
tasks[].subtasks[].checklist[].doneAtstring (date-time) or null
tasks[].subtasks[].checklist[].positionrequiredinteger
tasks[].subtasks[].checklist[].publicIdrequiredstring
tasks[].subtasks[].checklist[].textrequiredstring
tasks[].subtasks[].clientVisiblerequiredboolean
tasks[].subtasks[].completedAtstring (date-time) or null
tasks[].subtasks[].costCentsinteger or null

int64.

tasks[].subtasks[].descriptionrequiredstring
tasks[].subtasks[].durationDaysrequiredinteger
tasks[].subtasks[].estimateMinutesrequiredinteger
tasks[].subtasks[].loggedSecondsrequiredinteger
tasks[].subtasks[].onCriticalPathrequiredboolean
tasks[].subtasks[].parentTaskPublicIdstring or null
tasks[].subtasks[].phasePublicIdstring or null
tasks[].subtasks[].plannedDueOnstring or null
tasks[].subtasks[].plannedStartOnstring or null
tasks[].subtasks[].positionrequiredinteger
tasks[].subtasks[].predecessorsrequiredarray of TaskDependencyView
tasks[].subtasks[].predecessors[].lagDaysrequiredinteger
tasks[].subtasks[].predecessors[].taskPublicIdrequiredstring
tasks[].subtasks[].priorityrequiredstring
tasks[].subtasks[].projectPublicIdrequiredstring
tasks[].subtasks[].publicIdrequiredstring
tasks[].subtasks[].rolePlaceholderrequiredstring
tasks[].subtasks[].spawnedTicketPublicIdstring or null
tasks[].subtasks[].statusrequiredstring
tasks[].subtasks[].subtasksarray of ProjectTaskView
tasks[].subtasks[].titlerequiredstring
tasks[].subtasks[].updatedAtrequiredstring (date-time)
tasks[].subtasks[].watchersrequiredarray of TaskWatcherView
tasks[].subtasks[].watchers[].displayNamerequiredstring
tasks[].subtasks[].watchers[].userPublicIdrequiredstring
tasks[].subtasks[].watchingrequiredboolean
tasks[].titlerequiredstring
tasks[].updatedAtrequiredstring (date-time)
tasks[].watchersrequiredarray of TaskWatcherView
tasks[].watchers[].displayNamerequiredstring
tasks[].watchers[].userPublicIdrequiredstring
tasks[].watchingrequiredboolean
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PUT /api/v1/clients/{cid}/projects/{id}/schedule/shift

Section titled “PUT /api/v1/clients/{cid}/projects/{id}/schedule/shift”

PUTproject:writemsp facemspIdempotent

Source: [object Object]

shiftProjectSchedule applies a drag and cascades it.

The moves are applied to the node set, ShiftForward pushes every successor that no longer fits, and ApplySchedulePlan writes every date, risk flag and phase window in ONE transaction. The response is the WHOLE new chart, so the console redraws from one round trip rather than guessing what cascaded.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
expectedGeneratedAtrequiredstring (date-time)
movesrequiredarray of ScheduleMove
moves[].plannedDueOnrequiredstring
moves[].plannedStartOnrequiredstring
moves[].taskPublicIdrequiredstring
StatusBodyDescription
200application/json, ProjectScheduleViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
criticalPathrequiredarray of string
dependenciesrequiredarray of ScheduleDependencyView
dependencies[].lagDaysrequiredinteger
dependencies[].predecessorTaskPublicIdrequiredstring
dependencies[].taskPublicIdrequiredstring
generatedAtrequiredstring (date-time)
plannedEndOnstring or null
plannedStartOnstring or null
slackDaysrequiredobject
tasksrequiredarray of ProjectTaskView
tasks[].actualStartOnstring or null
tasks[].assigneeNamestring or null
tasks[].assigneeUserPublicIdstring or null
tasks[].atRiskrequiredboolean
tasks[].atRiskReasonrequiredstring
tasks[].billableSecondsrequiredinteger
tasks[].blockedReasonrequiredstring
tasks[].checklistrequiredarray of ChecklistItemView
tasks[].checklist[].donerequiredboolean
tasks[].checklist[].doneAtstring (date-time) or null
tasks[].checklist[].positionrequiredinteger
tasks[].checklist[].publicIdrequiredstring
tasks[].checklist[].textrequiredstring
tasks[].clientVisiblerequiredboolean
tasks[].completedAtstring (date-time) or null
tasks[].costCentsinteger or null

int64.

tasks[].descriptionrequiredstring
tasks[].durationDaysrequiredinteger
tasks[].estimateMinutesrequiredinteger
tasks[].loggedSecondsrequiredinteger
tasks[].onCriticalPathrequiredboolean
tasks[].parentTaskPublicIdstring or null
tasks[].phasePublicIdstring or null
tasks[].plannedDueOnstring or null
tasks[].plannedStartOnstring or null
tasks[].positionrequiredinteger
tasks[].predecessorsrequiredarray of TaskDependencyView
tasks[].predecessors[].lagDaysrequiredinteger
tasks[].predecessors[].taskPublicIdrequiredstring
tasks[].priorityrequiredstring
tasks[].projectPublicIdrequiredstring
tasks[].publicIdrequiredstring
tasks[].rolePlaceholderrequiredstring
tasks[].spawnedTicketPublicIdstring or null
tasks[].statusrequiredstring
tasks[].subtasksarray of ProjectTaskView
tasks[].subtasks[].actualStartOnstring or null
tasks[].subtasks[].assigneeNamestring or null
tasks[].subtasks[].assigneeUserPublicIdstring or null
tasks[].subtasks[].atRiskrequiredboolean
tasks[].subtasks[].atRiskReasonrequiredstring
tasks[].subtasks[].billableSecondsrequiredinteger
tasks[].subtasks[].blockedReasonrequiredstring
tasks[].subtasks[].checklistrequiredarray of ChecklistItemView
tasks[].subtasks[].checklist[].donerequiredboolean
tasks[].subtasks[].checklist[].doneAtstring (date-time) or null
tasks[].subtasks[].checklist[].positionrequiredinteger
tasks[].subtasks[].checklist[].publicIdrequiredstring
tasks[].subtasks[].checklist[].textrequiredstring
tasks[].subtasks[].clientVisiblerequiredboolean
tasks[].subtasks[].completedAtstring (date-time) or null
tasks[].subtasks[].costCentsinteger or null

int64.

tasks[].subtasks[].descriptionrequiredstring
tasks[].subtasks[].durationDaysrequiredinteger
tasks[].subtasks[].estimateMinutesrequiredinteger
tasks[].subtasks[].loggedSecondsrequiredinteger
tasks[].subtasks[].onCriticalPathrequiredboolean
tasks[].subtasks[].parentTaskPublicIdstring or null
tasks[].subtasks[].phasePublicIdstring or null
tasks[].subtasks[].plannedDueOnstring or null
tasks[].subtasks[].plannedStartOnstring or null
tasks[].subtasks[].positionrequiredinteger
tasks[].subtasks[].predecessorsrequiredarray of TaskDependencyView
tasks[].subtasks[].predecessors[].lagDaysrequiredinteger
tasks[].subtasks[].predecessors[].taskPublicIdrequiredstring
tasks[].subtasks[].priorityrequiredstring
tasks[].subtasks[].projectPublicIdrequiredstring
tasks[].subtasks[].publicIdrequiredstring
tasks[].subtasks[].rolePlaceholderrequiredstring
tasks[].subtasks[].spawnedTicketPublicIdstring or null
tasks[].subtasks[].statusrequiredstring
tasks[].subtasks[].subtasksarray of ProjectTaskView
tasks[].subtasks[].titlerequiredstring
tasks[].subtasks[].updatedAtrequiredstring (date-time)
tasks[].subtasks[].watchersrequiredarray of TaskWatcherView
tasks[].subtasks[].watchers[].displayNamerequiredstring
tasks[].subtasks[].watchers[].userPublicIdrequiredstring
tasks[].subtasks[].watchingrequiredboolean
tasks[].titlerequiredstring
tasks[].updatedAtrequiredstring (date-time)
tasks[].watchersrequiredarray of TaskWatcherView
tasks[].watchers[].displayNamerequiredstring
tasks[].watchers[].userPublicIdrequiredstring
tasks[].watchingrequiredboolean
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X PUT 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule/shift' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"expectedGeneratedAt": "2026-01-01T00:00:00Z",
"moves": [
{
"plannedDueOn": "string",
"plannedStartOn": "string",
"taskPublicId": "string"
}
]
}'

POST /api/v1/clients/{cid}/projects/{id}/status

Section titled “POST /api/v1/clients/{cid}/projects/{id}/status”

POSTproject:writemsp facemspNot fully resolved

What this page does not know
  • response-status

These are parts of the route the extractor could not read from the source. Everything else on this page came straight from it.

Source: [object Object]

Set project status

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
forcerequiredboolean
statusrequiredstring
StatusBodyDescription
200application/json, ProjectViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsCompleting or canceling a project needs the project:manage permission.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
actualStartOnstring or null
agreementPublicIdstring or null
amountBurnBprequiredinteger
atRiskTasksrequiredinteger
billableSecondsrequiredinteger
billingModerequiredstring
budgetAmountCentsrequiredinteger

int64.

budgetCriticalBpinteger or null
budgetMinutesrequiredinteger
budgetWarnBpinteger or null
cancelledAtstring (date-time) or null
clientContactEmailrequiredstring
clientContactNamerequiredstring
clientNamerequiredstring
clientPublicIdrequiredstring
completedAtstring (date-time) or null
convertedFromTicketPublicIdstring or null
costCentsinteger or null

int64.

createdAtrequiredstring (date-time)
descriptionrequiredstring
fixedPriceCentsrequiredinteger

int64.

healthrequiredstring
healthComputedAtstring (date-time) or null
healthReasonrequiredstring
hoursBurnBprequiredinteger
isSelfrequiredboolean
lastStatusEmailOnstring or null
loggedSecondsrequiredinteger
managerNamestring or null
managerUserPublicIdstring or null
milestonesrequiredarray of ProjectMilestoneView
milestones[].acceptanceMilestoneAcceptanceView
milestones[].acceptance.consentTextrequiredstring
milestones[].acceptance.consentVersionrequiredinteger
milestones[].acceptance.iprequiredstring
milestones[].acceptance.signedAtrequiredstring (date-time)
milestones[].acceptance.signerNamerequiredstring
milestones[].acceptance.signerTitlerequiredstring
milestones[].acceptance.userAgentrequiredstring
milestones[].acceptanceLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

milestones[].acceptanceLink.activerequiredboolean
milestones[].acceptanceLink.expiresAtstring (date-time) or null
milestones[].acceptanceLink.viewCountrequiredinteger
milestones[].acceptanceSentAtstring (date-time) or null
milestones[].acceptedAtstring (date-time) or null
milestones[].amountCentsinteger or null

int64.

milestones[].certificateAvailablerequiredboolean
milestones[].clientVisiblerequiredboolean
milestones[].completedAtstring (date-time) or null
milestones[].declineReasonrequiredstring
milestones[].declinedAtstring (date-time) or null
milestones[].descriptionrequiredstring
milestones[].dueOnrequiredstring
milestones[].invoicePublicIdstring or null
milestones[].invoicedAtstring (date-time) or null
milestones[].namerequiredstring
milestones[].phaseNamestring or null
milestones[].phasePublicIdstring or null
milestones[].positionrequiredinteger
milestones[].publicIdrequiredstring
milestones[].requiresClientAcceptancerequiredboolean
milestones[].statusrequiredstring
namerequiredstring
nextMilestoneNextMilestoneView
nextMilestone.dueOnrequiredstring
nextMilestone.namerequiredstring
nextMilestone.publicIdrequiredstring
notesrequiredstring
numberrequiredinteger

int64.

openTasksrequiredinteger
overdueMilestonesrequiredinteger
percentCompleterequiredinteger
phasesrequiredarray of ProjectPhaseView
phases[].billableSecondsrequiredinteger
phases[].billingModeOverridestring or null
phases[].budgetAmountCentsinteger or null

int64.

phases[].budgetMinutesinteger or null
phases[].completedAtstring (date-time) or null
phases[].costCentsinteger or null

int64.

phases[].loggedSecondsrequiredinteger
phases[].namerequiredstring
phases[].percentCompleterequiredinteger
phases[].plannedEndOnstring or null
phases[].plannedStartOnstring or null
phases[].positionrequiredinteger
phases[].prepaidLinePublicIdstring or null
phases[].publicIdrequiredstring
phases[].statusrequiredstring
plannedEndOnstring or null
plannedStartOnrequiredstring
prepaidLinePublicIdstring or null
publicIdrequiredstring
quotePublicIdstring or null
referencerequiredstring
retrospectiverequiredany
skipWeekendsrequiredboolean
statusrequiredstring
statusEmailCadencerequiredstring
statusEmailWeekdayrequiredinteger
statusLinkPublicLinkRefView

publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working.

statusLink.activerequiredboolean
statusLink.expiresAtstring (date-time) or null
statusLink.viewCountrequiredinteger
templatePublicIdstring or null
templateVersioninteger or null
ticketLinksrequiredarray of ProjectTicketLinkView
ticketLinks[].createdAtrequiredstring (date-time)
ticketLinks[].kindrequiredstring
ticketLinks[].publicIdrequiredstring
ticketLinks[].taskPublicIdstring or null
ticketLinks[].ticketPublicIdrequiredstring
ticketLinks[].ticketReferencerequiredstring
ticketLinks[].ticketSubjectrequiredstring
updatedAtrequiredstring (date-time)
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"force": false,
"status": "string"
}'

POST /api/v1/clients/{cid}/projects/{id}/status-email/send-now

Section titled “POST /api/v1/clients/{cid}/projects/{id}/status-email/send-now”

POSTproject:writemsp facemsp

Source: [object Object]

sendStatusEmailNow queues this project’s status update immediately.

THE SAME COMPOSER THE WORKER USES, WITH NO DEDUPE. The cadence sweep dedupes per project per day so a restart cannot send twice; this button is somebody deciding to send one now, and a dedupe would make the second click do nothing with no way to tell that from a failure.

It does NOT move LastStatusEmailOn, deliberately: that column is the cadence sweep’s own bookkeeping, and letting a manual send push the next scheduled one out by a week would make the cadence mean something different from what the project’s settings say.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
202NoneAccepted.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-email/send-now' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'
Section titled “GET /api/v1/clients/{cid}/projects/{id}/status-link”

GETproject:managemsp facemspIdempotent

Source: [object Object]

getStatusLink opens the sealed token.

project:manage and not project:read, on the acceptance link’s reasoning: a link is a bearer credential for a page that shows a customer their own project, and whoever may hand one out is whoever owns the commercial side of the job.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectLinkViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
activerequiredboolean
expiresAtstring (date-time) or null
kindrequiredstring
urlrequiredstring
viewCountrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'
Section titled “POST /api/v1/clients/{cid}/projects/{id}/status-link”

POSTproject:managemsp facemsp

Source: [object Object]

mintStatusLink creates the client’s read-only page, or replaces the live one.

NO EXPIRY. A status link lives until it is rotated, revoked, or the project has been closed for ninety days, unlike an acceptance link’s thirty days: an acceptance link is a request to sign something and a status page is a standing window onto work in flight, and a customer whose window went dark halfway through a migration would ring the service desk about it.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
201application/json, ProjectLinkViewCreated.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

201 response body

FieldTypeDescription
activerequiredboolean
expiresAtstring (date-time) or null
kindrequiredstring
urlrequiredstring
viewCountrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'
Section titled “DELETE /api/v1/clients/{cid}/projects/{id}/status-link”

DELETEproject:managemsp facemspIdempotent

Source: [object Object]

Revoke status link

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'
Section titled “POST /api/v1/clients/{cid}/projects/{id}/status-link/rotate”

POSTproject:managemsp facemsp

Source: [object Object]

rotateStatusLink is the mint again: one call revokes and replaces.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
201application/json, ProjectLinkViewCreated.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

201 response body

FieldTypeDescription
activerequiredboolean
expiresAtstring (date-time) or null
kindrequiredstring
urlrequiredstring
viewCountrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link/rotate' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/clients/{cid}/projects/{id}/tasks

Section titled “GET /api/v1/clients/{cid}/projects/{id}/tasks”

GETproject:readmsp facemspIdempotent

Source: [object Object]

List tasks

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
assigneequerystringNo
pagequeryintegerNoOne-based page number. Defaults to 1.
pageSizequeryintegerNoRows per page, 1 to 200. Defaults to 50.
phasequerystringNo
statusquerystring, one of blocked, cancelled, done, in_progress, todoNoComma-separated set. An unrecognised value is refused.
StatusBodyDescription
200application/json, PagedResultProjectTaskViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectTaskView
items[].actualStartOnstring or null
items[].assigneeNamestring or null
items[].assigneeUserPublicIdstring or null
items[].atRiskrequiredboolean
items[].atRiskReasonrequiredstring
items[].billableSecondsrequiredinteger
items[].blockedReasonrequiredstring
items[].checklistrequiredarray of ChecklistItemView
items[].checklist[].donerequiredboolean
items[].checklist[].doneAtstring (date-time) or null
items[].checklist[].positionrequiredinteger
items[].checklist[].publicIdrequiredstring
items[].checklist[].textrequiredstring
items[].clientVisiblerequiredboolean
items[].completedAtstring (date-time) or null
items[].costCentsinteger or null

int64.

items[].descriptionrequiredstring
items[].durationDaysrequiredinteger
items[].estimateMinutesrequiredinteger
items[].loggedSecondsrequiredinteger
items[].onCriticalPathrequiredboolean
items[].parentTaskPublicIdstring or null
items[].phasePublicIdstring or null
items[].plannedDueOnstring or null
items[].plannedStartOnstring or null
items[].positionrequiredinteger
items[].predecessorsrequiredarray of TaskDependencyView
items[].predecessors[].lagDaysrequiredinteger
items[].predecessors[].taskPublicIdrequiredstring
items[].priorityrequiredstring
items[].projectPublicIdrequiredstring
items[].publicIdrequiredstring
items[].rolePlaceholderrequiredstring
items[].spawnedTicketPublicIdstring or null
items[].statusrequiredstring
items[].subtasksarray of ProjectTaskView
items[].subtasks[].actualStartOnstring or null
items[].subtasks[].assigneeNamestring or null
items[].subtasks[].assigneeUserPublicIdstring or null
items[].subtasks[].atRiskrequiredboolean
items[].subtasks[].atRiskReasonrequiredstring
items[].subtasks[].billableSecondsrequiredinteger
items[].subtasks[].blockedReasonrequiredstring
items[].subtasks[].checklistrequiredarray of ChecklistItemView
items[].subtasks[].checklist[].donerequiredboolean
items[].subtasks[].checklist[].doneAtstring (date-time) or null
items[].subtasks[].checklist[].positionrequiredinteger
items[].subtasks[].checklist[].publicIdrequiredstring
items[].subtasks[].checklist[].textrequiredstring
items[].subtasks[].clientVisiblerequiredboolean
items[].subtasks[].completedAtstring (date-time) or null
items[].subtasks[].costCentsinteger or null

int64.

items[].subtasks[].descriptionrequiredstring
items[].subtasks[].durationDaysrequiredinteger
items[].subtasks[].estimateMinutesrequiredinteger
items[].subtasks[].loggedSecondsrequiredinteger
items[].subtasks[].onCriticalPathrequiredboolean
items[].subtasks[].parentTaskPublicIdstring or null
items[].subtasks[].phasePublicIdstring or null
items[].subtasks[].plannedDueOnstring or null
items[].subtasks[].plannedStartOnstring or null
items[].subtasks[].positionrequiredinteger
items[].subtasks[].predecessorsrequiredarray of TaskDependencyView
items[].subtasks[].predecessors[].lagDaysrequiredinteger
items[].subtasks[].predecessors[].taskPublicIdrequiredstring
items[].subtasks[].priorityrequiredstring
items[].subtasks[].projectPublicIdrequiredstring
items[].subtasks[].publicIdrequiredstring
items[].subtasks[].rolePlaceholderrequiredstring
items[].subtasks[].spawnedTicketPublicIdstring or null
items[].subtasks[].statusrequiredstring
items[].subtasks[].subtasksarray of ProjectTaskView
items[].subtasks[].titlerequiredstring
items[].subtasks[].updatedAtrequiredstring (date-time)
items[].subtasks[].watchersrequiredarray of TaskWatcherView
items[].subtasks[].watchers[].displayNamerequiredstring
items[].subtasks[].watchers[].userPublicIdrequiredstring
items[].subtasks[].watchingrequiredboolean
items[].titlerequiredstring
items[].updatedAtrequiredstring (date-time)
items[].watchersrequiredarray of TaskWatcherView
items[].watchers[].displayNamerequiredstring
items[].watchers[].userPublicIdrequiredstring
items[].watchingrequiredboolean
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks?assignee=<assignee>&page=0&pageSize=0&phase=<phase>&status=blocked' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/clients/{cid}/projects/{id}/tasks

Section titled “POST /api/v1/clients/{cid}/projects/{id}/tasks”

POSTproject:writemsp facemsp

Source: [object Object]

Create task

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
assigneeUserPublicIdstring or null
blockedReasonstring or null
clientVisibleboolean or null
descriptionstring or null
durationDaysinteger or null
estimateMinutesinteger or null
parentTaskPublicIdstring or null
phasePublicIdstring or null
plannedDueOnstring or null
plannedStartOnstring or null
positioninteger or null
prioritystring or null
rolePlaceholderstring or null
statusstring or null
titlestring or null
StatusBodyDescription
201application/json, ProjectTaskViewCreated.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

201 response body

FieldTypeDescription
actualStartOnstring or null
assigneeNamestring or null
assigneeUserPublicIdstring or null
atRiskrequiredboolean
atRiskReasonrequiredstring
billableSecondsrequiredinteger
blockedReasonrequiredstring
checklistrequiredarray of ChecklistItemView
checklist[].donerequiredboolean
checklist[].doneAtstring (date-time) or null
checklist[].positionrequiredinteger
checklist[].publicIdrequiredstring
checklist[].textrequiredstring
clientVisiblerequiredboolean
completedAtstring (date-time) or null
costCentsinteger or null

int64.

descriptionrequiredstring
durationDaysrequiredinteger
estimateMinutesrequiredinteger
loggedSecondsrequiredinteger
onCriticalPathrequiredboolean
parentTaskPublicIdstring or null
phasePublicIdstring or null
plannedDueOnstring or null
plannedStartOnstring or null
positionrequiredinteger
predecessorsrequiredarray of TaskDependencyView
predecessors[].lagDaysrequiredinteger
predecessors[].taskPublicIdrequiredstring
priorityrequiredstring
projectPublicIdrequiredstring
publicIdrequiredstring
rolePlaceholderrequiredstring
spawnedTicketPublicIdstring or null
statusrequiredstring
subtasksarray of ProjectTaskView
subtasks[].actualStartOnstring or null
subtasks[].assigneeNamestring or null
subtasks[].assigneeUserPublicIdstring or null
subtasks[].atRiskrequiredboolean
subtasks[].atRiskReasonrequiredstring
subtasks[].billableSecondsrequiredinteger
subtasks[].blockedReasonrequiredstring
subtasks[].checklistrequiredarray of ChecklistItemView
subtasks[].checklist[].donerequiredboolean
subtasks[].checklist[].doneAtstring (date-time) or null
subtasks[].checklist[].positionrequiredinteger
subtasks[].checklist[].publicIdrequiredstring
subtasks[].checklist[].textrequiredstring
subtasks[].clientVisiblerequiredboolean
subtasks[].completedAtstring (date-time) or null
subtasks[].costCentsinteger or null

int64.

subtasks[].descriptionrequiredstring
subtasks[].durationDaysrequiredinteger
subtasks[].estimateMinutesrequiredinteger
subtasks[].loggedSecondsrequiredinteger
subtasks[].onCriticalPathrequiredboolean
subtasks[].parentTaskPublicIdstring or null
subtasks[].phasePublicIdstring or null
subtasks[].plannedDueOnstring or null
subtasks[].plannedStartOnstring or null
subtasks[].positionrequiredinteger
subtasks[].predecessorsrequiredarray of TaskDependencyView
subtasks[].predecessors[].lagDaysrequiredinteger
subtasks[].predecessors[].taskPublicIdrequiredstring
subtasks[].priorityrequiredstring
subtasks[].projectPublicIdrequiredstring
subtasks[].publicIdrequiredstring
subtasks[].rolePlaceholderrequiredstring
subtasks[].spawnedTicketPublicIdstring or null
subtasks[].statusrequiredstring
subtasks[].subtasksarray of ProjectTaskView
subtasks[].titlerequiredstring
subtasks[].updatedAtrequiredstring (date-time)
subtasks[].watchersrequiredarray of TaskWatcherView
subtasks[].watchers[].displayNamerequiredstring
subtasks[].watchers[].userPublicIdrequiredstring
subtasks[].watchingrequiredboolean
titlerequiredstring
updatedAtrequiredstring (date-time)
watchersrequiredarray of TaskWatcherView
watchers[].displayNamerequiredstring
watchers[].userPublicIdrequiredstring
watchingrequiredboolean
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"assigneeUserPublicId": "string",
"blockedReason": "string",
"clientVisible": false,
"description": "string",
"durationDays": 0,
"estimateMinutes": 0,
"parentTaskPublicId": "string",
"phasePublicId": "string",
"plannedDueOn": "string",
"plannedStartOn": "string",
"position": 0,
"priority": "string",
"rolePlaceholder": "string",
"status": "string",
"title": "string"
}'

GET /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}

Section titled “GET /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}”

GETproject:readmsp facemspIdempotent

Source: [object Object]

Get task

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
taskIdpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectTaskViewSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
actualStartOnstring or null
assigneeNamestring or null
assigneeUserPublicIdstring or null
atRiskrequiredboolean
atRiskReasonrequiredstring
billableSecondsrequiredinteger
blockedReasonrequiredstring
checklistrequiredarray of ChecklistItemView
checklist[].donerequiredboolean
checklist[].doneAtstring (date-time) or null
checklist[].positionrequiredinteger
checklist[].publicIdrequiredstring
checklist[].textrequiredstring
clientVisiblerequiredboolean
completedAtstring (date-time) or null
costCentsinteger or null

int64.

descriptionrequiredstring
durationDaysrequiredinteger
estimateMinutesrequiredinteger
loggedSecondsrequiredinteger
onCriticalPathrequiredboolean
parentTaskPublicIdstring or null
phasePublicIdstring or null
plannedDueOnstring or null
plannedStartOnstring or null
positionrequiredinteger
predecessorsrequiredarray of TaskDependencyView
predecessors[].lagDaysrequiredinteger
predecessors[].taskPublicIdrequiredstring
priorityrequiredstring
projectPublicIdrequiredstring
publicIdrequiredstring
rolePlaceholderrequiredstring
spawnedTicketPublicIdstring or null
statusrequiredstring
subtasksarray of ProjectTaskView
subtasks[].actualStartOnstring or null
subtasks[].assigneeNamestring or null
subtasks[].assigneeUserPublicIdstring or null
subtasks[].atRiskrequiredboolean
subtasks[].atRiskReasonrequiredstring
subtasks[].billableSecondsrequiredinteger
subtasks[].blockedReasonrequiredstring
subtasks[].checklistrequiredarray of ChecklistItemView
subtasks[].checklist[].donerequiredboolean
subtasks[].checklist[].doneAtstring (date-time) or null
subtasks[].checklist[].positionrequiredinteger
subtasks[].checklist[].publicIdrequiredstring
subtasks[].checklist[].textrequiredstring
subtasks[].clientVisiblerequiredboolean
subtasks[].completedAtstring (date-time) or null
subtasks[].costCentsinteger or null

int64.

subtasks[].descriptionrequiredstring
subtasks[].durationDaysrequiredinteger
subtasks[].estimateMinutesrequiredinteger
subtasks[].loggedSecondsrequiredinteger
subtasks[].onCriticalPathrequiredboolean
subtasks[].parentTaskPublicIdstring or null
subtasks[].phasePublicIdstring or null
subtasks[].plannedDueOnstring or null
subtasks[].plannedStartOnstring or null
subtasks[].positionrequiredinteger
subtasks[].predecessorsrequiredarray of TaskDependencyView
subtasks[].predecessors[].lagDaysrequiredinteger
subtasks[].predecessors[].taskPublicIdrequiredstring
subtasks[].priorityrequiredstring
subtasks[].projectPublicIdrequiredstring
subtasks[].publicIdrequiredstring
subtasks[].rolePlaceholderrequiredstring
subtasks[].spawnedTicketPublicIdstring or null
subtasks[].statusrequiredstring
subtasks[].subtasksarray of ProjectTaskView
subtasks[].titlerequiredstring
subtasks[].updatedAtrequiredstring (date-time)
subtasks[].watchersrequiredarray of TaskWatcherView
subtasks[].watchers[].displayNamerequiredstring
subtasks[].watchers[].userPublicIdrequiredstring
subtasks[].watchingrequiredboolean
titlerequiredstring
updatedAtrequiredstring (date-time)
watchersrequiredarray of TaskWatcherView
watchers[].displayNamerequiredstring
watchers[].userPublicIdrequiredstring
watchingrequiredboolean
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PATCH /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}

Section titled “PATCH /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}”

PATCHproject:writemsp facemsp

Source: [object Object]

Patch task

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
taskIdpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
assigneeUserPublicIdstring or null
blockedReasonstring or null
clientVisibleboolean or null
descriptionstring or null
durationDaysinteger or null
estimateMinutesinteger or null
parentTaskPublicIdstring or null
phasePublicIdstring or null
plannedDueOnstring or null
plannedStartOnstring or null
positioninteger or null
prioritystring or null
rolePlaceholderstring or null
statusstring or null
titlestring or null
StatusBodyDescription
200application/json, ProjectTaskViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
actualStartOnstring or null
assigneeNamestring or null
assigneeUserPublicIdstring or null
atRiskrequiredboolean
atRiskReasonrequiredstring
billableSecondsrequiredinteger
blockedReasonrequiredstring
checklistrequiredarray of ChecklistItemView
checklist[].donerequiredboolean
checklist[].doneAtstring (date-time) or null
checklist[].positionrequiredinteger
checklist[].publicIdrequiredstring
checklist[].textrequiredstring
clientVisiblerequiredboolean
completedAtstring (date-time) or null
costCentsinteger or null

int64.

descriptionrequiredstring
durationDaysrequiredinteger
estimateMinutesrequiredinteger
loggedSecondsrequiredinteger
onCriticalPathrequiredboolean
parentTaskPublicIdstring or null
phasePublicIdstring or null
plannedDueOnstring or null
plannedStartOnstring or null
positionrequiredinteger
predecessorsrequiredarray of TaskDependencyView
predecessors[].lagDaysrequiredinteger
predecessors[].taskPublicIdrequiredstring
priorityrequiredstring
projectPublicIdrequiredstring
publicIdrequiredstring
rolePlaceholderrequiredstring
spawnedTicketPublicIdstring or null
statusrequiredstring
subtasksarray of ProjectTaskView
subtasks[].actualStartOnstring or null
subtasks[].assigneeNamestring or null
subtasks[].assigneeUserPublicIdstring or null
subtasks[].atRiskrequiredboolean
subtasks[].atRiskReasonrequiredstring
subtasks[].billableSecondsrequiredinteger
subtasks[].blockedReasonrequiredstring
subtasks[].checklistrequiredarray of ChecklistItemView
subtasks[].checklist[].donerequiredboolean
subtasks[].checklist[].doneAtstring (date-time) or null
subtasks[].checklist[].positionrequiredinteger
subtasks[].checklist[].publicIdrequiredstring
subtasks[].checklist[].textrequiredstring
subtasks[].clientVisiblerequiredboolean
subtasks[].completedAtstring (date-time) or null
subtasks[].costCentsinteger or null

int64.

subtasks[].descriptionrequiredstring
subtasks[].durationDaysrequiredinteger
subtasks[].estimateMinutesrequiredinteger
subtasks[].loggedSecondsrequiredinteger
subtasks[].onCriticalPathrequiredboolean
subtasks[].parentTaskPublicIdstring or null
subtasks[].phasePublicIdstring or null
subtasks[].plannedDueOnstring or null
subtasks[].plannedStartOnstring or null
subtasks[].positionrequiredinteger
subtasks[].predecessorsrequiredarray of TaskDependencyView
subtasks[].predecessors[].lagDaysrequiredinteger
subtasks[].predecessors[].taskPublicIdrequiredstring
subtasks[].priorityrequiredstring
subtasks[].projectPublicIdrequiredstring
subtasks[].publicIdrequiredstring
subtasks[].rolePlaceholderrequiredstring
subtasks[].spawnedTicketPublicIdstring or null
subtasks[].statusrequiredstring
subtasks[].subtasksarray of ProjectTaskView
subtasks[].titlerequiredstring
subtasks[].updatedAtrequiredstring (date-time)
subtasks[].watchersrequiredarray of TaskWatcherView
subtasks[].watchers[].displayNamerequiredstring
subtasks[].watchers[].userPublicIdrequiredstring
subtasks[].watchingrequiredboolean
titlerequiredstring
updatedAtrequiredstring (date-time)
watchersrequiredarray of TaskWatcherView
watchers[].displayNamerequiredstring
watchers[].userPublicIdrequiredstring
watchingrequiredboolean
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X PATCH 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"assigneeUserPublicId": "string",
"blockedReason": "string",
"clientVisible": false,
"description": "string",
"durationDays": 0,
"estimateMinutes": 0,
"parentTaskPublicId": "string",
"phasePublicId": "string",
"plannedDueOn": "string",
"plannedStartOn": "string",
"position": 0,
"priority": "string",
"rolePlaceholder": "string",
"status": "string",
"title": "string"
}'

DELETE /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}

Section titled “DELETE /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}”

DELETEproject:writemsp facemspIdempotent

Source: [object Object]

Delete task

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
taskIdpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PUT /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/checklist

Section titled “PUT /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/checklist”

PUTproject:writemsp facemspIdempotent

Source: [object Object]

putTaskChecklist rewrites one task’s procedural steps whole.

A whole-list write and not a per-item API, because a checklist is edited as one form: six endpoints for one screen would be six chances for the list to end up in an order nobody typed.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
taskIdpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
itemsrequiredarray of ChecklistItemView
items[].donerequiredboolean
items[].doneAtstring (date-time) or null
items[].positionrequiredinteger
items[].publicIdrequiredstring
items[].textrequiredstring
StatusBodyDescription
200application/json, objectSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X PUT 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"items": [
{
"done": false,
"doneAt": "2026-01-01T00:00:00Z",
"position": 0,
"publicId": "string",
"text": "string"
}
]
}'

POST /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/checklist/{itemId}/toggle

Section titled “POST /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/checklist/{itemId}/toggle”

POSTproject:writemsp facemsp

Source: [object Object]

Toggle checklist item

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
itemIdpathstringYesA uuid.
taskIdpathstringYesA uuid.

Required, sent as application/json.

The body is any.

StatusBodyDescription
200application/json, ChecklistItemViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not acceptable.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
donerequiredboolean
doneAtstring (date-time) or null
positionrequiredinteger
publicIdrequiredstring
textrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist/<itemId>/toggle' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '"string"'

PUT /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/dependencies

Section titled “PUT /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/dependencies”

PUTproject:writemsp facemspIdempotent

Source: [object Object]

putTaskDependencies rewrites one task’s predecessors whole.

A CYCLE IS 422 AND NOT 409. The store runs project.Topo over the project’s whole graph inside the transaction that holds the rows and answers ErrConflict; this surface reports it as a validation failure on the field somebody edited, because the console renders it beside the dependency picker rather than as a conflict banner. PROJECT_CONTRACTS.md 4.2 freezes it that way.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
taskIdpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
predecessorsrequiredarray of TaskDependencyView
predecessors[].lagDaysrequiredinteger
predecessors[].taskPublicIdrequiredstring
StatusBodyDescription
200application/json, ProjectTaskViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
actualStartOnstring or null
assigneeNamestring or null
assigneeUserPublicIdstring or null
atRiskrequiredboolean
atRiskReasonrequiredstring
billableSecondsrequiredinteger
blockedReasonrequiredstring
checklistrequiredarray of ChecklistItemView
checklist[].donerequiredboolean
checklist[].doneAtstring (date-time) or null
checklist[].positionrequiredinteger
checklist[].publicIdrequiredstring
checklist[].textrequiredstring
clientVisiblerequiredboolean
completedAtstring (date-time) or null
costCentsinteger or null

int64.

descriptionrequiredstring
durationDaysrequiredinteger
estimateMinutesrequiredinteger
loggedSecondsrequiredinteger
onCriticalPathrequiredboolean
parentTaskPublicIdstring or null
phasePublicIdstring or null
plannedDueOnstring or null
plannedStartOnstring or null
positionrequiredinteger
predecessorsrequiredarray of TaskDependencyView
predecessors[].lagDaysrequiredinteger
predecessors[].taskPublicIdrequiredstring
priorityrequiredstring
projectPublicIdrequiredstring
publicIdrequiredstring
rolePlaceholderrequiredstring
spawnedTicketPublicIdstring or null
statusrequiredstring
subtasksarray of ProjectTaskView
subtasks[].actualStartOnstring or null
subtasks[].assigneeNamestring or null
subtasks[].assigneeUserPublicIdstring or null
subtasks[].atRiskrequiredboolean
subtasks[].atRiskReasonrequiredstring
subtasks[].billableSecondsrequiredinteger
subtasks[].blockedReasonrequiredstring
subtasks[].checklistrequiredarray of ChecklistItemView
subtasks[].checklist[].donerequiredboolean
subtasks[].checklist[].doneAtstring (date-time) or null
subtasks[].checklist[].positionrequiredinteger
subtasks[].checklist[].publicIdrequiredstring
subtasks[].checklist[].textrequiredstring
subtasks[].clientVisiblerequiredboolean
subtasks[].completedAtstring (date-time) or null
subtasks[].costCentsinteger or null

int64.

subtasks[].descriptionrequiredstring
subtasks[].durationDaysrequiredinteger
subtasks[].estimateMinutesrequiredinteger
subtasks[].loggedSecondsrequiredinteger
subtasks[].onCriticalPathrequiredboolean
subtasks[].parentTaskPublicIdstring or null
subtasks[].phasePublicIdstring or null
subtasks[].plannedDueOnstring or null
subtasks[].plannedStartOnstring or null
subtasks[].positionrequiredinteger
subtasks[].predecessorsrequiredarray of TaskDependencyView
subtasks[].predecessors[].lagDaysrequiredinteger
subtasks[].predecessors[].taskPublicIdrequiredstring
subtasks[].priorityrequiredstring
subtasks[].projectPublicIdrequiredstring
subtasks[].publicIdrequiredstring
subtasks[].rolePlaceholderrequiredstring
subtasks[].spawnedTicketPublicIdstring or null
subtasks[].statusrequiredstring
subtasks[].subtasksarray of ProjectTaskView
subtasks[].titlerequiredstring
subtasks[].updatedAtrequiredstring (date-time)
subtasks[].watchersrequiredarray of TaskWatcherView
subtasks[].watchers[].displayNamerequiredstring
subtasks[].watchers[].userPublicIdrequiredstring
subtasks[].watchingrequiredboolean
titlerequiredstring
updatedAtrequiredstring (date-time)
watchersrequiredarray of TaskWatcherView
watchers[].displayNamerequiredstring
watchers[].userPublicIdrequiredstring
watchingrequiredboolean
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X PUT 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/dependencies' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"predecessors": [
{
"lagDays": 0,
"taskPublicId": "string"
}
]
}'

POST /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/spawn-ticket

Section titled “POST /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/spawn-ticket”

POSTticket:writemsp facemsp

Source: [object Object]

spawnTicket raises a ticket from a task and links the two.

THE AND-GUARD IS ON THE ROUTE: project:write AND ticket:write. Raising a ticket creates a row on the service desk, so it answers to the desk’s own permission as well as to the project’s; a project manager who could not otherwise open a ticket must not gain that by opening one from a task.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
taskIdpathstringYesA uuid.

Required, sent as application/json.

The body is any.

StatusBodyDescription
201application/json, objectCreated.
400application/problem+json, ProblemDetailsThe request body is not acceptable.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold ticket:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/spawn-ticket' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '"string"'

GET /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/time

Section titled “GET /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/time”

GETproject:readmsp facemspIdempotent

Source: [object Object]

List task time

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
taskIdpathstringYesA uuid.
pagequeryintegerNoOne-based page number. Defaults to 1.
pageSizequeryintegerNoRows per page, 1 to 200. Defaults to 50.
StatusBodyDescription
200application/json, PagedResultProjectTimeEntryViewSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectTimeEntryView
items[].amountCentsrequiredinteger

int64.

items[].billablerequiredboolean
items[].chargeTypeCoderequiredstring
items[].classifiedAtstring (date-time) or null
items[].costRateCentsSnapshotinteger or null

int64.

items[].invoicePublicIdstring or null
items[].invoicedrequiredboolean
items[].lockedboolean
items[].minutesrequiredinteger
items[].noterequiredstring
items[].occurredAtrequiredstring (date-time)
items[].outcomestring
items[].projectPublicIdstring or null
items[].publicIdrequiredstring
items[].rateCentsSnapshotinteger or null

int64.

items[].taskPublicIdstring or null
items[].technicianNamerequiredstring
items[].userPublicIdrequiredstring
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time?page=0&pageSize=0' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/time

Section titled “POST /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/time”

POSTproject:timemsp facemsp

Source: [object Object]

createTaskTime logs one entry against a task.

The body is createTicketTimeEntryRequest’s shape UNCHANGED, which is deliberate: a technician logging forty minutes types the same three fields whether the work was a ticket or a task, and two shapes would be two forms to keep in step and one chance to log ninety seconds where ninety minutes were meant.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
taskIdpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
billablerequiredboolean
chargeTypeCoderequiredstring
messageTimeEntryMessageRequest
message.bodyrequiredstring
message.internalboolean or null
minutesrequiredinteger
noterequiredstring
occurredAtrequiredstring
StatusBodyDescription
201application/json, ProjectTimeEntryViewCreated.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsLogging time requires a signed-in technician.
403application/problem+json, ProblemDetailsThe identity does not hold project:time.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsCould not check whether this week’s timesheet is approved. Nothing was changed; try again in a moment.

201 response body

FieldTypeDescription
amountCentsrequiredinteger

int64.

billablerequiredboolean
chargeTypeCoderequiredstring
classifiedAtstring (date-time) or null
costRateCentsSnapshotinteger or null

int64.

invoicePublicIdstring or null
invoicedrequiredboolean
lockedboolean
minutesrequiredinteger
noterequiredstring
occurredAtrequiredstring (date-time)
outcomestring
projectPublicIdstring or null
publicIdrequiredstring
rateCentsSnapshotinteger or null

int64.

taskPublicIdstring or null
technicianNamerequiredstring
userPublicIdrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"billable": false,
"chargeTypeCode": "string",
"message": {
"body": "string",
"internal": false
},
"minutes": 0,
"note": "string",
"occurredAt": "string"
}'

PATCH /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/time/{entryId}

Section titled “PATCH /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/time/{entryId}”

PATCHproject:timemsp facemsp

Source: [object Object]

patchTaskTime corrects what a technician logged.

409 ONCE THE ENTRY IS INVOICED, and the check is the store’s under a row lock rather than a status read here: a check in the handler would race a concurrent finalize and let an edit land on work that had already been billed.

THE COST RATE IS RE-RESOLVED ONLY WHEN StartedAt MOVES. That is section 6.5’s rule: the snapshot is frozen with the row, and a rate change is not a repricing of past work, but work that happened on a different day happened under whatever the rate was that day.

NameInTypeRequiredDescription
cidpathstringYes
entryIdpathstringYesA uuid.
idpathstringYesA uuid.
taskIdpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
billableboolean or null
chargeTypeCodestring or null
minutesinteger or null
notestring or null
occurredAtstring or null
StatusBodyDescription
200application/json, ProjectTimeEntryViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:time.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsCould not check whether this week’s timesheet is approved. Nothing was changed; try again in a moment.

200 response body

FieldTypeDescription
amountCentsrequiredinteger

int64.

billablerequiredboolean
chargeTypeCoderequiredstring
classifiedAtstring (date-time) or null
costRateCentsSnapshotinteger or null

int64.

invoicePublicIdstring or null
invoicedrequiredboolean
lockedboolean
minutesrequiredinteger
noterequiredstring
occurredAtrequiredstring (date-time)
outcomestring
projectPublicIdstring or null
publicIdrequiredstring
rateCentsSnapshotinteger or null

int64.

taskPublicIdstring or null
technicianNamerequiredstring
userPublicIdrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X PATCH 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"billable": false,
"chargeTypeCode": "string",
"minutes": 0,
"note": "string",
"occurredAt": "string"
}'

DELETE /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/time/{entryId}

Section titled “DELETE /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/time/{entryId}”

DELETEproject:timemsp facemspIdempotent

Source: [object Object]

Delete task time

NameInTypeRequiredDescription
cidpathstringYes
entryIdpathstringYesA uuid.
idpathstringYesA uuid.
taskIdpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:time.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsCould not check whether this week’s timesheet is approved. Nothing was changed; try again in a moment.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/time/{entryId}/reprice

Section titled “POST /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/time/{entryId}/reprice”

POSTpsa:writemsp facemsp

Source: [object Object]

repriceTaskTime re-runs the project’s mode and the agreement’s rules over one logged entry and restamps what they decide.

The ticket reprice’s twin: psa:write and not project:time, because editing what you logged is part of doing the work and changing what a customer is charged for it is not. IT DOES NOT TOUCH THE COST SNAPSHOT, which is section 6.5’s rule stated once more where somebody might be tempted to.

NameInTypeRequiredDescription
cidpathstringYes
entryIdpathstringYesA uuid.
idpathstringYesA uuid.
taskIdpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectTimeEntryViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold psa:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.

200 response body

FieldTypeDescription
amountCentsrequiredinteger

int64.

billablerequiredboolean
chargeTypeCoderequiredstring
classifiedAtstring (date-time) or null
costRateCentsSnapshotinteger or null

int64.

invoicePublicIdstring or null
invoicedrequiredboolean
lockedboolean
minutesrequiredinteger
noterequiredstring
occurredAtrequiredstring (date-time)
outcomestring
projectPublicIdstring or null
publicIdrequiredstring
rateCentsSnapshotinteger or null

int64.

taskPublicIdstring or null
technicianNamerequiredstring
userPublicIdrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>/reprice' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PUT /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/watchers/{userId}

Section titled “PUT /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/watchers/{userId}”

PUTproject:writemsp facemspIdempotent

Source: [object Object]

putTaskWatcher subscribes one operator to a task.

IDEMPOTENT, which the store guarantees: watching a task twice is watching it, and a console that answered 409 to a double-click would be a star that sometimes refuses. me is accepted for the user id, because the commonest case by far is somebody subscribing themselves.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
taskIdpathstringYesA uuid.
userIdpathstringYes
StatusBodyDescription
204NoneSuccess, with no body.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X PUT 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

DELETE /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/watchers/{userId}

Section titled “DELETE /api/v1/clients/{cid}/projects/{id}/tasks/{taskId}/watchers/{userId}”

DELETEproject:writemsp facemspIdempotent

Source: [object Object]

deleteTaskWatcher unsubscribes.

Removing somebody who is not watching is a 204, for putTaskWatcher’s reason.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
taskIdpathstringYesA uuid.
userIdpathstringYes
StatusBodyDescription
204NoneSuccess, with no body.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PUT /api/v1/clients/{cid}/projects/{id}/tasks/order

Section titled “PUT /api/v1/clients/{cid}/projects/{id}/tasks/order”

PUTproject:writemsp facemspIdempotent

Source: [object Object]

reorderTasks renumbers one phase’s tasks, or the project’s unphased ones.

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
phasequerystringNo

Required, sent as application/json.

FieldTypeDescription
publicIdsrequiredarray of string
StatusBodyDescription
204NoneSuccess, with no body.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X PUT 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/order?phase=<phase>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"publicIds": [
"string"
]
}'
Section titled “GET /api/v1/clients/{cid}/projects/{id}/tickets”

GETproject:readmsp facemspIdempotent

Source: [object Object]

List project ticket links

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
StatusBodyDescription
200application/json, PagedResultProjectTicketLinkViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectTicketLinkView
items[].createdAtrequiredstring (date-time)
items[].kindrequiredstring
items[].publicIdrequiredstring
items[].taskPublicIdstring or null
items[].ticketPublicIdrequiredstring
items[].ticketReferencerequiredstring
items[].ticketSubjectrequiredstring
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/clients/{cid}/projects/{id}/tickets

Section titled “POST /api/v1/clients/{cid}/projects/{id}/tickets”

POSTproject:writemsp facemsp

Source: [object Object]

Link ticket

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
kindrequiredstring
taskIdrequiredstring
ticketIdrequiredstring
StatusBodyDescription
201application/json, ProjectTicketLinkViewCreated.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

201 response body

FieldTypeDescription
createdAtrequiredstring (date-time)
kindrequiredstring
publicIdrequiredstring
taskPublicIdstring or null
ticketPublicIdrequiredstring
ticketReferencerequiredstring
ticketSubjectrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"kind": "string",
"taskId": "string",
"ticketId": "string"
}'

DELETE /api/v1/clients/{cid}/projects/{id}/tickets/{linkId}

Section titled “DELETE /api/v1/clients/{cid}/projects/{id}/tickets/{linkId}”

DELETEproject:writemsp facemspIdempotent

Source: [object Object]

Unlink ticket

NameInTypeRequiredDescription
cidpathstringYes
idpathstringYesA uuid.
linkIdpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:write.
404application/problem+json, ProblemDetailsNo client matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets/<linkId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GETproject:readmsp facemspIdempotent

Source: [object Object]

List all projects

NameInTypeRequiredDescription
billingModequerystringNo
clientquerystringNo
clientIdquerystringNo
healthquerystring, one of amber, green, redNoComma-separated set. An unrecognised value is refused.
managerquerystringNo
pagequeryintegerNoOne-based page number. Defaults to 1.
pageSizequeryintegerNoRows per page, 1 to 200. Defaults to 50.
qquerystringNo
sortquerystringNo
statusquerystring, one of active, cancelled, completed, draft, on_holdNoComma-separated set. An unrecognised value is refused.
StatusBodyDescription
200application/json, PsaFanOutPageProjectSummaryViewSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
500application/problem+json, ProblemDetailsCould not list clients.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectSummaryView
items[].amountBurnBprequiredinteger
items[].atRiskTasksrequiredinteger
items[].billableSecondsrequiredinteger
items[].billingModerequiredstring
items[].budgetAmountCentsrequiredinteger

int64.

items[].budgetMinutesrequiredinteger
items[].clientNamerequiredstring
items[].clientPublicIdrequiredstring
items[].createdAtrequiredstring (date-time)
items[].fixedPriceCentsrequiredinteger

int64.

items[].healthrequiredstring
items[].healthComputedAtstring (date-time) or null
items[].healthReasonrequiredstring
items[].hoursBurnBprequiredinteger
items[].isSelfrequiredboolean
items[].loggedSecondsrequiredinteger
items[].managerNamestring or null
items[].managerUserPublicIdstring or null
items[].namerequiredstring
items[].nextMilestoneNextMilestoneView
items[].nextMilestone.dueOnrequiredstring
items[].nextMilestone.namerequiredstring
items[].nextMilestone.publicIdrequiredstring
items[].numberrequiredinteger

int64.

items[].openTasksrequiredinteger
items[].overdueMilestonesrequiredinteger
items[].percentCompleterequiredinteger
items[].plannedEndOnstring or null
items[].plannedStartOnrequiredstring
items[].publicIdrequiredstring
items[].referencerequiredstring
items[].statusrequiredstring
items[].updatedAtrequiredstring (date-time)
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
totalClientsrequiredinteger
unavailableClientsrequiredarray of string
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects?billingMode=<billingMode>&client=<client>&clientId=<clientId>&health=amber&manager=<manager>&page=0' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GETproject:readmsp facemspIdempotent

Source: [object Object]

List at risk

NameInTypeRequiredDescription
clientquerystringNo
clientIdquerystringNo
pagequeryintegerNoOne-based page number. Defaults to 1.
pageSizequeryintegerNoRows per page, 1 to 200. Defaults to 50.
StatusBodyDescription
200application/json, PsaFanOutPageProjectSummaryViewSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
500application/problem+json, ProblemDetailsCould not list clients.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectSummaryView
items[].amountBurnBprequiredinteger
items[].atRiskTasksrequiredinteger
items[].billableSecondsrequiredinteger
items[].billingModerequiredstring
items[].budgetAmountCentsrequiredinteger

int64.

items[].budgetMinutesrequiredinteger
items[].clientNamerequiredstring
items[].clientPublicIdrequiredstring
items[].createdAtrequiredstring (date-time)
items[].fixedPriceCentsrequiredinteger

int64.

items[].healthrequiredstring
items[].healthComputedAtstring (date-time) or null
items[].healthReasonrequiredstring
items[].hoursBurnBprequiredinteger
items[].isSelfrequiredboolean
items[].loggedSecondsrequiredinteger
items[].managerNamestring or null
items[].managerUserPublicIdstring or null
items[].namerequiredstring
items[].nextMilestoneNextMilestoneView
items[].nextMilestone.dueOnrequiredstring
items[].nextMilestone.namerequiredstring
items[].nextMilestone.publicIdrequiredstring
items[].numberrequiredinteger

int64.

items[].openTasksrequiredinteger
items[].overdueMilestonesrequiredinteger
items[].percentCompleterequiredinteger
items[].plannedEndOnstring or null
items[].plannedStartOnrequiredstring
items[].publicIdrequiredstring
items[].referencerequiredstring
items[].statusrequiredstring
items[].updatedAtrequiredstring (date-time)
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
totalClientsrequiredinteger
unavailableClientsrequiredarray of string
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/at-risk?client=<client>&clientId=<clientId>&page=0&pageSize=0' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GETproject:readmsp facemspIdempotent

Source: [object Object]

List budget alerts

NameInTypeRequiredDescription
clientquerystringNo
clientIdquerystringNo
pagequeryintegerNoOne-based page number. Defaults to 1.
pageSizequeryintegerNoRows per page, 1 to 200. Defaults to 50.
StatusBodyDescription
200application/json, PsaFanOutPageBudgetAlertViewSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
500application/problem+json, ProblemDetailsCould not list clients.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of BudgetAlertView
items[].clientNamerequiredstring
items[].clientPublicIdrequiredstring
items[].detailrequiredstring
items[].firstRaisedAtrequiredstring (date-time)
items[].occurrencesrequiredinteger
items[].projectNamerequiredstring
items[].projectPublicIdrequiredstring
items[].projectReferencerequiredstring
items[].publicIdrequiredstring
items[].raisedAtrequiredstring (date-time)
items[].severityrequiredstring
items[].sourceKeyrequiredstring
items[].staterequiredstring
items[].titlerequiredstring
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
totalClientsrequiredinteger
unavailableClientsrequiredarray of string
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/budget-alerts?client=<client>&clientId=<clientId>&page=0&pageSize=0' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/projects/calendar/appointments

Section titled “GET /api/v1/projects/calendar/appointments”

GETproject:calendarmsp facemspIdempotent

Source: [object Object]

List appointments

NameInTypeRequiredDescription
clientquerystringNo
projectquerystringNo
technicianquerystringNo
StatusBodyDescription
200application/json, PagedResultAppointmentViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:calendar.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of AppointmentView
items[].cancelledAtstring (date-time) or null
items[].clientNamestring or null
items[].clientPublicIdstring or null
items[].endsAtrequiredstring (date-time)
items[].locationrequiredstring
items[].noterequiredstring
items[].onSiterequiredboolean
items[].projectPublicIdstring or null
items[].publicIdrequiredstring
items[].reminderMinutesBeforerequiredinteger
items[].reminderSentAtstring (date-time) or null
items[].requesterEmailrequiredstring
items[].requesterNamerequiredstring
items[].startsAtrequiredstring (date-time)
items[].taskPublicIdstring or null
items[].technicianNamerequiredstring
items[].technicianUserPublicIdrequiredstring
items[].ticketPublicIdstring or null
items[].titlerequiredstring
items[].warningsrequiredAppointmentWarningsView
items[].warnings.bookedMinutesrequiredinteger
items[].warnings.capacityMinutesrequiredinteger
items[].warnings.duringTimeOffrequiredboolean
items[].warnings.outsideBusinessHoursrequiredboolean
items[].warnings.overCapacityrequiredboolean
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/calendar/appointments?client=<client>&project=<project>&technician=<technician>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/projects/calendar/appointments

Section titled “POST /api/v1/projects/calendar/appointments”

POSTproject:calendarmsp facemsp

Source: [object Object]

createAppointment books a slot and WARNS.

It never refuses for a capacity reason; see the file header.

Required, sent as application/json.

FieldTypeDescription
clientPublicIdstring or null
endsAtstring or null
locationstring or null
notestring or null
onSiteboolean or null
projectPublicIdstring or null
reminderMinutesBeforeinteger or null
requesterEmailstring or null
requesterNamestring or null
startsAtstring or null
taskPublicIdstring or null
technicianUserPublicIdstring or null
ticketPublicIdstring or null
titlestring or null
StatusBodyDescription
201application/json, AppointmentViewCreated.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:calendar.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

201 response body

FieldTypeDescription
cancelledAtstring (date-time) or null
clientNamestring or null
clientPublicIdstring or null
endsAtrequiredstring (date-time)
locationrequiredstring
noterequiredstring
onSiterequiredboolean
projectPublicIdstring or null
publicIdrequiredstring
reminderMinutesBeforerequiredinteger
reminderSentAtstring (date-time) or null
requesterEmailrequiredstring
requesterNamerequiredstring
startsAtrequiredstring (date-time)
taskPublicIdstring or null
technicianNamerequiredstring
technicianUserPublicIdrequiredstring
ticketPublicIdstring or null
titlerequiredstring
warningsrequiredAppointmentWarningsView
warnings.bookedMinutesrequiredinteger
warnings.capacityMinutesrequiredinteger
warnings.duringTimeOffrequiredboolean
warnings.outsideBusinessHoursrequiredboolean
warnings.overCapacityrequiredboolean
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/projects/calendar/appointments' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"clientPublicId": "string",
"endsAt": "string",
"location": "string",
"note": "string",
"onSite": false,
"projectPublicId": "string",
"reminderMinutesBefore": 0,
"requesterEmail": "string",
"requesterName": "string",
"startsAt": "string",
"taskPublicId": "string",
"technicianUserPublicId": "string",
"ticketPublicId": "string",
"title": "string"
}'

GET /api/v1/projects/calendar/appointments/{apptID}

Section titled “GET /api/v1/projects/calendar/appointments/{apptID}”

GETproject:calendarmsp facemspIdempotent

Source: [object Object]

Get appointment

NameInTypeRequiredDescription
apptIDpathstringYesA uuid.
StatusBodyDescription
200application/json, AppointmentViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:calendar.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
cancelledAtstring (date-time) or null
clientNamestring or null
clientPublicIdstring or null
endsAtrequiredstring (date-time)
locationrequiredstring
noterequiredstring
onSiterequiredboolean
projectPublicIdstring or null
publicIdrequiredstring
reminderMinutesBeforerequiredinteger
reminderSentAtstring (date-time) or null
requesterEmailrequiredstring
requesterNamerequiredstring
startsAtrequiredstring (date-time)
taskPublicIdstring or null
technicianNamerequiredstring
technicianUserPublicIdrequiredstring
ticketPublicIdstring or null
titlerequiredstring
warningsrequiredAppointmentWarningsView
warnings.bookedMinutesrequiredinteger
warnings.capacityMinutesrequiredinteger
warnings.duringTimeOffrequiredboolean
warnings.outsideBusinessHoursrequiredboolean
warnings.overCapacityrequiredboolean
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PATCH /api/v1/projects/calendar/appointments/{apptID}

Section titled “PATCH /api/v1/projects/calendar/appointments/{apptID}”

PATCHproject:calendarmsp facemsp

Source: [object Object]

Patch appointment

NameInTypeRequiredDescription
apptIDpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
clientPublicIdstring or null
endsAtstring or null
locationstring or null
notestring or null
onSiteboolean or null
projectPublicIdstring or null
reminderMinutesBeforeinteger or null
requesterEmailstring or null
requesterNamestring or null
startsAtstring or null
taskPublicIdstring or null
technicianUserPublicIdstring or null
ticketPublicIdstring or null
titlestring or null
StatusBodyDescription
200application/json, AppointmentViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:calendar.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
cancelledAtstring (date-time) or null
clientNamestring or null
clientPublicIdstring or null
endsAtrequiredstring (date-time)
locationrequiredstring
noterequiredstring
onSiterequiredboolean
projectPublicIdstring or null
publicIdrequiredstring
reminderMinutesBeforerequiredinteger
reminderSentAtstring (date-time) or null
requesterEmailrequiredstring
requesterNamerequiredstring
startsAtrequiredstring (date-time)
taskPublicIdstring or null
technicianNamerequiredstring
technicianUserPublicIdrequiredstring
ticketPublicIdstring or null
titlerequiredstring
warningsrequiredAppointmentWarningsView
warnings.bookedMinutesrequiredinteger
warnings.capacityMinutesrequiredinteger
warnings.duringTimeOffrequiredboolean
warnings.outsideBusinessHoursrequiredboolean
warnings.overCapacityrequiredboolean
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X PATCH 'https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"clientPublicId": "string",
"endsAt": "string",
"location": "string",
"note": "string",
"onSite": false,
"projectPublicId": "string",
"reminderMinutesBefore": 0,
"requesterEmail": "string",
"requesterName": "string",
"startsAt": "string",
"taskPublicId": "string",
"technicianUserPublicId": "string",
"ticketPublicId": "string",
"title": "string"
}'

DELETE /api/v1/projects/calendar/appointments/{apptID}

Section titled “DELETE /api/v1/projects/calendar/appointments/{apptID}”

DELETEproject:calendarmsp facemspIdempotent

Source: [object Object]

Cancel appointment

NameInTypeRequiredDescription
apptIDpathstringYesA uuid.

Required, sent as application/json.

The body is any.

StatusBodyDescription
204NoneSuccess, with no body.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:calendar.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '"string"'

GETproject:calendarmsp facemspIdempotent

Source: [object Object]

listHolidays answers the days the dispatch board shades.

FROM THE PRACTICE’S OWN BUSINESS SCHEDULE in the SELF client database, which is where the days a practice does not work are already declared. A second list on ProjectSettings was the alternative and is worse: two places to say the same thing, and the first Christmas somebody added to one and not the other is the day the board and the SLA clock disagree.

HOLIDAYS DO NOT MOVE TASK DATES, which PROJECT_CONTRACTS.md 12 states: they reduce capacity on this calendar and nothing else. A project’s own working-day rule is its SkipWeekends flag.

A RECURRING holiday carries no year, so it is expanded across every year the window touches. A one-off carries its own and is emitted only if it lands inside.

StatusBodyDescription
200application/json, array of CalendarHolidayViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:calendar.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
[].daterequiredstring
[].namerequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/calendar/holidays' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GETproject:calendarmsp facemspIdempotent

Source: [object Object]

listTechnicians answers the dispatch board’s left column: every active console user with their weekly capacity, and their cost rate ONLY when the caller may see one.

The rates are read in ONE query through CurrentStaffCostRates rather than one per person, and the permission is evaluated ONCE per request: a check per row would be a permission query per technician on a screen that lists all of them.

StatusBodyDescription
200application/json, PagedResultTechnicianProfileViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:calendar.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of TechnicianProfileView
items[].costRateCentsPerHourinteger or null

int64.

items[].displayNamerequiredstring
items[].emailrequiredstring
items[].userPublicIdrequiredstring
items[].weeklyCapacityMinutesrequiredinteger
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/calendar/technicians' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PUT /api/v1/projects/calendar/technicians/{userID}

Section titled “PUT /api/v1/projects/calendar/technicians/{userID}”

PUTproject:managemsp facemspIdempotent

Source: [object Object]

putTechnician writes the capacity and the cost rate, in TWO STORE CALLS.

They live in two databases on purpose: the capacity is a fact about a DepotUser in the self client database, and the rate is the practice’s own commercial figure in control, read by a handler that runs against a TENANT’s store with only a user id in hand. Neither can move to the other’s side without one of the two callers losing it.

NameInTypeRequiredDescription
userIDpathstringYes

Required, sent as application/json.

FieldTypeDescription
costRateCentsPerHourinteger or null

int64.

effectiveFromrequiredstring
weeklyCapacityMinutesinteger or null
StatusBodyDescription
200application/json, TechnicianProfileViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo operator matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
costRateCentsPerHourinteger or null

int64.

displayNamerequiredstring
emailrequiredstring
userPublicIdrequiredstring
weeklyCapacityMinutesrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X PUT 'https://depot.example.com/api/v1/projects/calendar/technicians/<userID>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"costRateCentsPerHour": 0,
"effectiveFrom": "string",
"weeklyCapacityMinutes": 0
}'

GET /api/v1/projects/calendar/technicians/{userID}/load

Section titled “GET /api/v1/projects/calendar/technicians/{userID}/load”

GETproject:calendarmsp facemspIdempotent

Source: [object Object]

getTechnicianLoad answers one technician’s week: booked, capacity, time off and logged.

NameInTypeRequiredDescription
userIDpathstringYes
StatusBodyDescription
200application/json, TechnicianLoadViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:calendar.
404application/problem+json, ProblemDetailsNo operator matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
bookedMinutesrequiredinteger
capacityMinutesrequiredinteger
loggedSecondsrequiredinteger
timeOffrequiredarray of TimeOffView
timeOff[].endsOnrequiredstring
timeOff[].kindrequiredstring
timeOff[].noterequiredstring
timeOff[].publicIdrequiredstring
timeOff[].startsOnrequiredstring
timeOff[].userPublicIdrequiredstring
userPublicIdrequiredstring
weekStartrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/calendar/technicians/<userID>/load' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GETproject:calendarmsp facemspIdempotent

Source: [object Object]

List time off

NameInTypeRequiredDescription
technicianquerystringNo
StatusBodyDescription
200application/json, PagedResultTimeOffViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:calendar.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of TimeOffView
items[].endsOnrequiredstring
items[].kindrequiredstring
items[].noterequiredstring
items[].publicIdrequiredstring
items[].startsOnrequiredstring
items[].userPublicIdrequiredstring
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/calendar/time-off?technician=<technician>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POSTproject:calendarmsp facemsp

Source: [object Object]

Create time off

Required, sent as application/json.

FieldTypeDescription
endsOnrequiredstring
kindrequiredstring
noterequiredstring
startsOnrequiredstring
userPublicIdrequiredstring
StatusBodyDescription
201application/json, TimeOffViewCreated.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:calendar.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

201 response body

FieldTypeDescription
endsOnrequiredstring
kindrequiredstring
noterequiredstring
publicIdrequiredstring
startsOnrequiredstring
userPublicIdrequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/projects/calendar/time-off' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"endsOn": "string",
"kind": "string",
"note": "string",
"startsOn": "string",
"userPublicId": "string"
}'

DELETE /api/v1/projects/calendar/time-off/{offID}

Section titled “DELETE /api/v1/projects/calendar/time-off/{offID}”

DELETEproject:calendarmsp facemspIdempotent

Source: [object Object]

Delete time off

NameInTypeRequiredDescription
offIDpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:calendar.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/projects/calendar/time-off/<offID>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GETproject:readmsp facemspIdempotent

Source: [object Object]

Get project dashboard

NameInTypeRequiredDescription
clientIdquerystringNo
siteIdquerystringNo
StatusBodyDescription
200application/json, ProjectDashboardViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo resource matches that scope.
500application/problem+json, ProblemDetailsCould not list clients.
503application/problem+json, ProblemDetailsThe client scope is unavailable.

200 response body

FieldTypeDescription
appointmentsThisWeekrequiredPagedResultAppointmentView

PagedResult is the generic envelope for paginated list responses.

appointmentsThisWeek.itemsrequiredarray of AppointmentView
appointmentsThisWeek.items[].cancelledAtstring (date-time) or null
appointmentsThisWeek.items[].clientNamestring or null
appointmentsThisWeek.items[].clientPublicIdstring or null
appointmentsThisWeek.items[].endsAtrequiredstring (date-time)
appointmentsThisWeek.items[].locationrequiredstring
appointmentsThisWeek.items[].noterequiredstring
appointmentsThisWeek.items[].onSiterequiredboolean
appointmentsThisWeek.items[].projectPublicIdstring or null
appointmentsThisWeek.items[].publicIdrequiredstring
appointmentsThisWeek.items[].reminderMinutesBeforerequiredinteger
appointmentsThisWeek.items[].reminderSentAtstring (date-time) or null
appointmentsThisWeek.items[].requesterEmailrequiredstring
appointmentsThisWeek.items[].requesterNamerequiredstring
appointmentsThisWeek.items[].startsAtrequiredstring (date-time)
appointmentsThisWeek.items[].taskPublicIdstring or null
appointmentsThisWeek.items[].technicianNamerequiredstring
appointmentsThisWeek.items[].technicianUserPublicIdrequiredstring
appointmentsThisWeek.items[].ticketPublicIdstring or null
appointmentsThisWeek.items[].titlerequiredstring
appointmentsThisWeek.items[].warningsrequiredAppointmentWarningsView
appointmentsThisWeek.items[].warnings.bookedMinutesrequiredinteger
appointmentsThisWeek.items[].warnings.capacityMinutesrequiredinteger
appointmentsThisWeek.items[].warnings.duringTimeOffrequiredboolean
appointmentsThisWeek.items[].warnings.outsideBusinessHoursrequiredboolean
appointmentsThisWeek.items[].warnings.overCapacityrequiredboolean
appointmentsThisWeek.pagerequiredinteger
appointmentsThisWeek.pageSizerequiredinteger
appointmentsThisWeek.totalrequiredinteger
atRiskrequiredPsaFanOutPageProjectSummaryView

psaFanOutPage is the partial-result envelope BILLING_CONTRACTS.md section 4 freezes: a PagedResult plus the two fields that make it honest.

atRisk.itemsrequiredarray of ProjectSummaryView
atRisk.items[].amountBurnBprequiredinteger
atRisk.items[].atRiskTasksrequiredinteger
atRisk.items[].billableSecondsrequiredinteger
atRisk.items[].billingModerequiredstring
atRisk.items[].budgetAmountCentsrequiredinteger

int64.

atRisk.items[].budgetMinutesrequiredinteger
atRisk.items[].clientNamerequiredstring
atRisk.items[].clientPublicIdrequiredstring
atRisk.items[].createdAtrequiredstring (date-time)
atRisk.items[].fixedPriceCentsrequiredinteger

int64.

atRisk.items[].healthrequiredstring
atRisk.items[].healthComputedAtstring (date-time) or null
atRisk.items[].healthReasonrequiredstring
atRisk.items[].hoursBurnBprequiredinteger
atRisk.items[].isSelfrequiredboolean
atRisk.items[].loggedSecondsrequiredinteger
atRisk.items[].managerNamestring or null
atRisk.items[].managerUserPublicIdstring or null
atRisk.items[].namerequiredstring
atRisk.items[].nextMilestoneNextMilestoneView
atRisk.items[].nextMilestone.dueOnrequiredstring
atRisk.items[].nextMilestone.namerequiredstring
atRisk.items[].nextMilestone.publicIdrequiredstring
atRisk.items[].numberrequiredinteger

int64.

atRisk.items[].openTasksrequiredinteger
atRisk.items[].overdueMilestonesrequiredinteger
atRisk.items[].percentCompleterequiredinteger
atRisk.items[].plannedEndOnstring or null
atRisk.items[].plannedStartOnrequiredstring
atRisk.items[].publicIdrequiredstring
atRisk.items[].referencerequiredstring
atRisk.items[].statusrequiredstring
atRisk.items[].updatedAtrequiredstring (date-time)
atRisk.pagerequiredinteger
atRisk.pageSizerequiredinteger
atRisk.totalrequiredinteger
atRisk.totalClientsrequiredinteger
atRisk.unavailableClientsrequiredarray of string
budgetAlertsrequiredPsaFanOutPageBudgetAlertView

psaFanOutPage is the partial-result envelope BILLING_CONTRACTS.md section 4 freezes: a PagedResult plus the two fields that make it honest.

budgetAlerts.itemsrequiredarray of BudgetAlertView
budgetAlerts.items[].clientNamerequiredstring
budgetAlerts.items[].clientPublicIdrequiredstring
budgetAlerts.items[].detailrequiredstring
budgetAlerts.items[].firstRaisedAtrequiredstring (date-time)
budgetAlerts.items[].occurrencesrequiredinteger
budgetAlerts.items[].projectNamerequiredstring
budgetAlerts.items[].projectPublicIdrequiredstring
budgetAlerts.items[].projectReferencerequiredstring
budgetAlerts.items[].publicIdrequiredstring
budgetAlerts.items[].raisedAtrequiredstring (date-time)
budgetAlerts.items[].severityrequiredstring
budgetAlerts.items[].sourceKeyrequiredstring
budgetAlerts.items[].staterequiredstring
budgetAlerts.items[].titlerequiredstring
budgetAlerts.pagerequiredinteger
budgetAlerts.pageSizerequiredinteger
budgetAlerts.totalrequiredinteger
budgetAlerts.totalClientsrequiredinteger
budgetAlerts.unavailableClientsrequiredarray of string
myTasksrequiredPsaFanOutPageDashboardTaskView

psaFanOutPage is the partial-result envelope BILLING_CONTRACTS.md section 4 freezes: a PagedResult plus the two fields that make it honest.

myTasks.itemsrequiredarray of DashboardTaskView
myTasks.items[].actualStartOnstring or null
myTasks.items[].assigneeNamestring or null
myTasks.items[].assigneeUserPublicIdstring or null
myTasks.items[].atRiskrequiredboolean
myTasks.items[].atRiskReasonrequiredstring
myTasks.items[].billableSecondsrequiredinteger
myTasks.items[].blockedReasonrequiredstring
myTasks.items[].checklistrequiredarray of ChecklistItemView
myTasks.items[].checklist[].donerequiredboolean
myTasks.items[].checklist[].doneAtstring (date-time) or null
myTasks.items[].checklist[].positionrequiredinteger
myTasks.items[].checklist[].publicIdrequiredstring
myTasks.items[].checklist[].textrequiredstring
myTasks.items[].clientNamerequiredstring
myTasks.items[].clientPublicIdrequiredstring
myTasks.items[].clientVisiblerequiredboolean
myTasks.items[].completedAtstring (date-time) or null
myTasks.items[].costCentsinteger or null

int64.

myTasks.items[].descriptionrequiredstring
myTasks.items[].durationDaysrequiredinteger
myTasks.items[].estimateMinutesrequiredinteger
myTasks.items[].loggedSecondsrequiredinteger
myTasks.items[].onCriticalPathrequiredboolean
myTasks.items[].parentTaskPublicIdstring or null
myTasks.items[].phasePublicIdstring or null
myTasks.items[].plannedDueOnstring or null
myTasks.items[].plannedStartOnstring or null
myTasks.items[].positionrequiredinteger
myTasks.items[].predecessorsrequiredarray of TaskDependencyView
myTasks.items[].predecessors[].lagDaysrequiredinteger
myTasks.items[].predecessors[].taskPublicIdrequiredstring
myTasks.items[].priorityrequiredstring
myTasks.items[].projectNamerequiredstring
myTasks.items[].projectPublicIdrequiredstring
myTasks.items[].projectReferencerequiredstring
myTasks.items[].publicIdrequiredstring
myTasks.items[].rolePlaceholderrequiredstring
myTasks.items[].spawnedTicketPublicIdstring or null
myTasks.items[].statusrequiredstring
myTasks.items[].subtasksarray of ProjectTaskView
myTasks.items[].subtasks[].actualStartOnstring or null
myTasks.items[].subtasks[].assigneeNamestring or null
myTasks.items[].subtasks[].assigneeUserPublicIdstring or null
myTasks.items[].subtasks[].atRiskrequiredboolean
myTasks.items[].subtasks[].atRiskReasonrequiredstring
myTasks.items[].subtasks[].billableSecondsrequiredinteger
myTasks.items[].subtasks[].blockedReasonrequiredstring
myTasks.items[].subtasks[].checklistrequiredarray of ChecklistItemView
myTasks.items[].subtasks[].clientVisiblerequiredboolean
myTasks.items[].subtasks[].completedAtstring (date-time) or null
myTasks.items[].subtasks[].costCentsinteger or null

int64.

myTasks.items[].subtasks[].descriptionrequiredstring
myTasks.items[].subtasks[].durationDaysrequiredinteger
myTasks.items[].subtasks[].estimateMinutesrequiredinteger
myTasks.items[].subtasks[].loggedSecondsrequiredinteger
myTasks.items[].subtasks[].onCriticalPathrequiredboolean
myTasks.items[].subtasks[].parentTaskPublicIdstring or null
myTasks.items[].subtasks[].phasePublicIdstring or null
myTasks.items[].subtasks[].plannedDueOnstring or null
myTasks.items[].subtasks[].plannedStartOnstring or null
myTasks.items[].subtasks[].positionrequiredinteger
myTasks.items[].subtasks[].predecessorsrequiredarray of TaskDependencyView
myTasks.items[].subtasks[].priorityrequiredstring
myTasks.items[].subtasks[].projectPublicIdrequiredstring
myTasks.items[].subtasks[].publicIdrequiredstring
myTasks.items[].subtasks[].rolePlaceholderrequiredstring
myTasks.items[].subtasks[].spawnedTicketPublicIdstring or null
myTasks.items[].subtasks[].statusrequiredstring
myTasks.items[].subtasks[].subtasksarray of ProjectTaskView
myTasks.items[].subtasks[].titlerequiredstring
myTasks.items[].subtasks[].updatedAtrequiredstring (date-time)
myTasks.items[].subtasks[].watchersrequiredarray of TaskWatcherView
myTasks.items[].subtasks[].watchingrequiredboolean
myTasks.items[].titlerequiredstring
myTasks.items[].updatedAtrequiredstring (date-time)
myTasks.items[].watchersrequiredarray of TaskWatcherView
myTasks.items[].watchers[].displayNamerequiredstring
myTasks.items[].watchers[].userPublicIdrequiredstring
myTasks.items[].watchingrequiredboolean
myTasks.pagerequiredinteger
myTasks.pageSizerequiredinteger
myTasks.totalrequiredinteger
myTasks.totalClientsrequiredinteger
myTasks.unavailableClientsrequiredarray of string
siteFilteredrequiredboolean
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/dashboard?clientId=<clientId>&siteId=<siteId>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GETproject:readmsp facemspIdempotent

Source: [object Object]

Get decision counts

StatusBodyDescription
200application/json, ProjectDecisionCountsResponseSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
500application/problem+json, ProblemDetailsCould not list clients.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
clientsrequiredarray of ProjectDecisionClientCount
clients[].changeOrdersDraftrequiredinteger
clients[].clientNamerequiredstring
clients[].clientPublicIdrequiredstring
clients[].milestonesDeclinedrequiredinteger
totalWaitingrequiredinteger
unavailableClientsrequiredarray of string
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/decision-counts' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GETproject:readmsp facemspIdempotent

Source: [object Object]

List my tasks

NameInTypeRequiredDescription
clientquerystringNo
clientIdquerystringNo
pagequeryintegerNoOne-based page number. Defaults to 1.
pageSizequeryintegerNoRows per page, 1 to 200. Defaults to 50.
StatusBodyDescription
200application/json, PsaFanOutPageDashboardTaskViewSuccess.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
500application/problem+json, ProblemDetailsCould not list clients.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of DashboardTaskView
items[].actualStartOnstring or null
items[].assigneeNamestring or null
items[].assigneeUserPublicIdstring or null
items[].atRiskrequiredboolean
items[].atRiskReasonrequiredstring
items[].billableSecondsrequiredinteger
items[].blockedReasonrequiredstring
items[].checklistrequiredarray of ChecklistItemView
items[].checklist[].donerequiredboolean
items[].checklist[].doneAtstring (date-time) or null
items[].checklist[].positionrequiredinteger
items[].checklist[].publicIdrequiredstring
items[].checklist[].textrequiredstring
items[].clientNamerequiredstring
items[].clientPublicIdrequiredstring
items[].clientVisiblerequiredboolean
items[].completedAtstring (date-time) or null
items[].costCentsinteger or null

int64.

items[].descriptionrequiredstring
items[].durationDaysrequiredinteger
items[].estimateMinutesrequiredinteger
items[].loggedSecondsrequiredinteger
items[].onCriticalPathrequiredboolean
items[].parentTaskPublicIdstring or null
items[].phasePublicIdstring or null
items[].plannedDueOnstring or null
items[].plannedStartOnstring or null
items[].positionrequiredinteger
items[].predecessorsrequiredarray of TaskDependencyView
items[].predecessors[].lagDaysrequiredinteger
items[].predecessors[].taskPublicIdrequiredstring
items[].priorityrequiredstring
items[].projectNamerequiredstring
items[].projectPublicIdrequiredstring
items[].projectReferencerequiredstring
items[].publicIdrequiredstring
items[].rolePlaceholderrequiredstring
items[].spawnedTicketPublicIdstring or null
items[].statusrequiredstring
items[].subtasksarray of ProjectTaskView
items[].subtasks[].actualStartOnstring or null
items[].subtasks[].assigneeNamestring or null
items[].subtasks[].assigneeUserPublicIdstring or null
items[].subtasks[].atRiskrequiredboolean
items[].subtasks[].atRiskReasonrequiredstring
items[].subtasks[].billableSecondsrequiredinteger
items[].subtasks[].blockedReasonrequiredstring
items[].subtasks[].checklistrequiredarray of ChecklistItemView
items[].subtasks[].checklist[].donerequiredboolean
items[].subtasks[].checklist[].doneAtstring (date-time) or null
items[].subtasks[].checklist[].positionrequiredinteger
items[].subtasks[].checklist[].publicIdrequiredstring
items[].subtasks[].checklist[].textrequiredstring
items[].subtasks[].clientVisiblerequiredboolean
items[].subtasks[].completedAtstring (date-time) or null
items[].subtasks[].costCentsinteger or null

int64.

items[].subtasks[].descriptionrequiredstring
items[].subtasks[].durationDaysrequiredinteger
items[].subtasks[].estimateMinutesrequiredinteger
items[].subtasks[].loggedSecondsrequiredinteger
items[].subtasks[].onCriticalPathrequiredboolean
items[].subtasks[].parentTaskPublicIdstring or null
items[].subtasks[].phasePublicIdstring or null
items[].subtasks[].plannedDueOnstring or null
items[].subtasks[].plannedStartOnstring or null
items[].subtasks[].positionrequiredinteger
items[].subtasks[].predecessorsrequiredarray of TaskDependencyView
items[].subtasks[].predecessors[].lagDaysrequiredinteger
items[].subtasks[].predecessors[].taskPublicIdrequiredstring
items[].subtasks[].priorityrequiredstring
items[].subtasks[].projectPublicIdrequiredstring
items[].subtasks[].publicIdrequiredstring
items[].subtasks[].rolePlaceholderrequiredstring
items[].subtasks[].spawnedTicketPublicIdstring or null
items[].subtasks[].statusrequiredstring
items[].subtasks[].subtasksarray of ProjectTaskView
items[].subtasks[].subtasks[].actualStartOnstring or null
items[].subtasks[].subtasks[].assigneeNamestring or null
items[].subtasks[].subtasks[].assigneeUserPublicIdstring or null
items[].subtasks[].subtasks[].atRiskrequiredboolean
items[].subtasks[].subtasks[].atRiskReasonrequiredstring
items[].subtasks[].subtasks[].billableSecondsrequiredinteger
items[].subtasks[].subtasks[].blockedReasonrequiredstring
items[].subtasks[].subtasks[].checklistrequiredarray of ChecklistItemView
items[].subtasks[].subtasks[].clientVisiblerequiredboolean
items[].subtasks[].subtasks[].completedAtstring (date-time) or null
items[].subtasks[].subtasks[].costCentsinteger or null

int64.

items[].subtasks[].subtasks[].descriptionrequiredstring
items[].subtasks[].subtasks[].durationDaysrequiredinteger
items[].subtasks[].subtasks[].estimateMinutesrequiredinteger
items[].subtasks[].subtasks[].loggedSecondsrequiredinteger
items[].subtasks[].subtasks[].onCriticalPathrequiredboolean
items[].subtasks[].subtasks[].parentTaskPublicIdstring or null
items[].subtasks[].subtasks[].phasePublicIdstring or null
items[].subtasks[].subtasks[].plannedDueOnstring or null
items[].subtasks[].subtasks[].plannedStartOnstring or null
items[].subtasks[].subtasks[].positionrequiredinteger
items[].subtasks[].subtasks[].predecessorsrequiredarray of TaskDependencyView
items[].subtasks[].subtasks[].priorityrequiredstring
items[].subtasks[].subtasks[].projectPublicIdrequiredstring
items[].subtasks[].subtasks[].publicIdrequiredstring
items[].subtasks[].subtasks[].rolePlaceholderrequiredstring
items[].subtasks[].subtasks[].spawnedTicketPublicIdstring or null
items[].subtasks[].subtasks[].statusrequiredstring
items[].subtasks[].subtasks[].subtasksarray of ProjectTaskView
items[].subtasks[].subtasks[].titlerequiredstring
items[].subtasks[].subtasks[].updatedAtrequiredstring (date-time)
items[].subtasks[].subtasks[].watchersrequiredarray of TaskWatcherView
items[].subtasks[].subtasks[].watchingrequiredboolean
items[].subtasks[].titlerequiredstring
items[].subtasks[].updatedAtrequiredstring (date-time)
items[].subtasks[].watchersrequiredarray of TaskWatcherView
items[].subtasks[].watchers[].displayNamerequiredstring
items[].subtasks[].watchers[].userPublicIdrequiredstring
items[].subtasks[].watchingrequiredboolean
items[].titlerequiredstring
items[].updatedAtrequiredstring (date-time)
items[].watchersrequiredarray of TaskWatcherView
items[].watchers[].displayNamerequiredstring
items[].watchers[].userPublicIdrequiredstring
items[].watchingrequiredboolean
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
totalClientsrequiredinteger
unavailableClientsrequiredarray of string
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/my-tasks?client=<client>&clientId=<clientId>&page=0&pageSize=0' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GETproject:readmsp facemspIdempotent

Source: [object Object]

List project schedules

StatusBodyDescription
200application/json, PagedResultRecurringScheduleViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of RecurringScheduleView
items[].billingModestring or null
items[].clientNamerequiredstring
items[].clientPublicIdrequiredstring
items[].cronExprrequiredstring
items[].enabledrequiredboolean
items[].lastProjectPublicIdstring or null
items[].lastRunAtstring (date-time) or null
items[].managerUserPublicIdstring or null
items[].namerequiredstring
items[].nextRunAtstring (date-time) or null
items[].projectNamePatternrequiredstring
items[].publicIdrequiredstring
items[].templateFamilyPublicIdrequiredstring
items[].templateNamerequiredstring
items[].timeZonerequiredstring
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/schedules' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POSTproject:managemsp facemsp

Source: [object Object]

Create project schedule

Required, sent as application/json.

FieldTypeDescription
billingModestring or null
clientPublicIdstring or null
cronExprstring or null
enabledboolean or null
managerUserPublicIdstring or null
namestring or null
projectNamePatternstring or null
templateFamilyPublicIdstring or null
timeZonestring or null
StatusBodyDescription
201application/json, RecurringScheduleViewCreated.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

201 response body

FieldTypeDescription
billingModestring or null
clientNamerequiredstring
clientPublicIdrequiredstring
cronExprrequiredstring
enabledrequiredboolean
lastProjectPublicIdstring or null
lastRunAtstring (date-time) or null
managerUserPublicIdstring or null
namerequiredstring
nextRunAtstring (date-time) or null
projectNamePatternrequiredstring
publicIdrequiredstring
templateFamilyPublicIdrequiredstring
templateNamerequiredstring
timeZonerequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/projects/schedules' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"billingMode": "string",
"clientPublicId": "string",
"cronExpr": "string",
"enabled": false,
"managerUserPublicId": "string",
"name": "string",
"projectNamePattern": "string",
"templateFamilyPublicId": "string",
"timeZone": "string"
}'

GETproject:readmsp facemspIdempotent

Source: [object Object]

Get project schedule

NameInTypeRequiredDescription
schedIDpathstringYesA uuid.
StatusBodyDescription
200application/json, RecurringScheduleViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
billingModestring or null
clientNamerequiredstring
clientPublicIdrequiredstring
cronExprrequiredstring
enabledrequiredboolean
lastProjectPublicIdstring or null
lastRunAtstring (date-time) or null
managerUserPublicIdstring or null
namerequiredstring
nextRunAtstring (date-time) or null
projectNamePatternrequiredstring
publicIdrequiredstring
templateFamilyPublicIdrequiredstring
templateNamerequiredstring
timeZonerequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/schedules/<schedID>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PUTproject:managemsp facemspIdempotent

Source: [object Object]

Put project schedule

NameInTypeRequiredDescription
schedIDpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
billingModestring or null
clientPublicIdstring or null
cronExprstring or null
enabledboolean or null
managerUserPublicIdstring or null
namestring or null
projectNamePatternstring or null
templateFamilyPublicIdstring or null
timeZonestring or null
StatusBodyDescription
200application/json, RecurringScheduleViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
billingModestring or null
clientNamerequiredstring
clientPublicIdrequiredstring
cronExprrequiredstring
enabledrequiredboolean
lastProjectPublicIdstring or null
lastRunAtstring (date-time) or null
managerUserPublicIdstring or null
namerequiredstring
nextRunAtstring (date-time) or null
projectNamePatternrequiredstring
publicIdrequiredstring
templateFamilyPublicIdrequiredstring
templateNamerequiredstring
timeZonerequiredstring
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X PUT 'https://depot.example.com/api/v1/projects/schedules/<schedID>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"billingMode": "string",
"clientPublicId": "string",
"cronExpr": "string",
"enabled": false,
"managerUserPublicId": "string",
"name": "string",
"projectNamePattern": "string",
"templateFamilyPublicId": "string",
"timeZone": "string"
}'

DELETE /api/v1/projects/schedules/{schedID}

Section titled “DELETE /api/v1/projects/schedules/{schedID}”

DELETEproject:managemsp facemspIdempotent

Source: [object Object]

Delete project schedule

NameInTypeRequiredDescription
schedIDpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/projects/schedules/<schedID>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/projects/schedules/{schedID}/run-now

Section titled “POST /api/v1/projects/schedules/{schedID}/run-now”

POSTproject:managemsp facemsp

Source: [object Object]

runScheduleNow opens this schedule’s project immediately, through the worker.

A NIL RunSchedule ANSWERS 503, matching PsaDeps.GenerateNow and honest for the same reason: nothing else in this package can open a scheduled project, and pretending otherwise would answer 200 having done nothing.

NameInTypeRequiredDescription
schedIDpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectScheduleRunViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
attemptsrequiredinteger
claimedAtrequiredstring (date-time)
claimedByrequiredstring
clientPublicIdrequiredstring
errorrequiredstring
finishedAtstring (date-time) or null
projectPublicIdrequiredstring
schedulePublicIdrequiredstring
scheduledForrequiredstring (date-time)
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/projects/schedules/<schedID>/run-now' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/projects/schedules/{schedID}/runs

Section titled “GET /api/v1/projects/schedules/{schedID}/runs”

GETproject:readmsp facemspIdempotent

Source: [object Object]

List schedule runs

NameInTypeRequiredDescription
schedIDpathstringYesA uuid.
StatusBodyDescription
200application/json, PagedResultProjectScheduleRunViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectScheduleRunView
items[].attemptsrequiredinteger
items[].claimedAtrequiredstring (date-time)
items[].claimedByrequiredstring
items[].clientPublicIdrequiredstring
items[].errorrequiredstring
items[].finishedAtstring (date-time) or null
items[].projectPublicIdrequiredstring
items[].schedulePublicIdrequiredstring
items[].scheduledForrequiredstring (date-time)
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/schedules/<schedID>/runs' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GETproject:readmsp facemspIdempotent

Source: [object Object]

Get project settings

StatusBodyDescription
200application/json, ProjectSettingsViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
atRiskLeadDaysrequiredinteger
budgetCriticalBprequiredinteger
budgetWarnBprequiredinteger
defaultAppointmentReminderMinutesrequiredinteger
defaultStatusEmailCadencerequiredstring
pmDigestEnabledrequiredboolean
pmDigestHourLocalrequiredinteger
scopeCreepBprequiredinteger
seededTemplatesAtstring (date-time) or null
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/settings' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PUTproject:managemsp facemspIdempotent

Source: [object Object]

Put project settings

Required, sent as application/json.

FieldTypeDescription
atRiskLeadDaysinteger or null
budgetCriticalBpinteger or null
budgetWarnBpinteger or null
defaultAppointmentReminderMinutesinteger or null
defaultStatusEmailCadencestring or null
pmDigestEnabledboolean or null
pmDigestHourLocalinteger or null
scopeCreepBpinteger or null
StatusBodyDescription
200application/json, ProjectSettingsViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
atRiskLeadDaysrequiredinteger
budgetCriticalBprequiredinteger
budgetWarnBprequiredinteger
defaultAppointmentReminderMinutesrequiredinteger
defaultStatusEmailCadencerequiredstring
pmDigestEnabledrequiredboolean
pmDigestHourLocalrequiredinteger
scopeCreepBprequiredinteger
seededTemplatesAtstring (date-time) or null
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X PUT 'https://depot.example.com/api/v1/projects/settings' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"atRiskLeadDays": 0,
"budgetCriticalBp": 0,
"budgetWarnBp": 0,
"defaultAppointmentReminderMinutes": 0,
"defaultStatusEmailCadence": "string",
"pmDigestEnabled": false,
"pmDigestHourLocal": 0,
"scopeCreepBp": 0
}'

GETproject:readmsp facemspIdempotent

Source: [object Object]

List project templates

StatusBodyDescription
200application/json, PagedResultProjectTemplateViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectTemplateView
items[].activerequiredboolean
items[].categoryrequiredstring
items[].defaultBillingModerequiredstring
items[].defaultBudgetMinutesrequiredinteger
items[].defaultStatusEmailCadencerequiredstring
items[].defaultStatusEmailWeekdayrequiredinteger
items[].descriptionrequiredstring
items[].durationDaysrequiredinteger
items[].familyPublicIdrequiredstring
items[].isCurrentrequiredboolean
items[].isSeedrequiredboolean
items[].milestonesrequiredarray of TemplateMilestoneView
items[].milestones[].amountBprequiredinteger
items[].milestones[].clientVisiblerequiredboolean
items[].milestones[].descriptionrequiredstring
items[].milestones[].namerequiredstring
items[].milestones[].offsetDaysrequiredinteger
items[].milestones[].phasePublicIdstring or null
items[].milestones[].positionrequiredinteger
items[].milestones[].publicIdrequiredstring
items[].milestones[].requiresClientAcceptancerequiredboolean
items[].namerequiredstring
items[].phasesrequiredarray of TemplatePhaseView
items[].phases[].billingModeOverridestring or null
items[].phases[].budgetAmountBpinteger or null
items[].phases[].budgetMinutesinteger or null
items[].phases[].namerequiredstring
items[].phases[].positionrequiredinteger
items[].phases[].publicIdrequiredstring
items[].publicIdrequiredstring
items[].tasksrequiredarray of TemplateTaskView
items[].tasks[].checklistrequiredarray of string
items[].tasks[].clientVisiblerequiredboolean
items[].tasks[].descriptionrequiredstring
items[].tasks[].durationDaysrequiredinteger
items[].tasks[].estimateMinutesrequiredinteger
items[].tasks[].parentTaskPublicIdstring or null
items[].tasks[].phasePublicIdstring or null
items[].tasks[].positionrequiredinteger
items[].tasks[].predecessorsrequiredarray of TaskDependencyView
items[].tasks[].predecessors[].lagDaysrequiredinteger
items[].tasks[].predecessors[].taskPublicIdrequiredstring
items[].tasks[].priorityrequiredstring
items[].tasks[].publicIdrequiredstring
items[].tasks[].rolePlaceholderrequiredstring
items[].tasks[].startOffsetDaysrequiredinteger
items[].tasks[].titlerequiredstring
items[].usedCountrequiredinteger
items[].versionrequiredinteger
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/templates' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POSTproject:managemsp facemsp

Source: [object Object]

Create project template

Required, sent as application/json.

FieldTypeDescription
activeboolean or null
categoryrequiredstring
defaultBillingModerequiredstring
defaultBudgetMinutesinteger or null
defaultStatusEmailCadencerequiredstring
defaultStatusEmailWeekdayinteger or null
descriptionrequiredstring
milestonesrequiredarray of TemplateMilestoneView
milestones[].amountBprequiredinteger
milestones[].clientVisiblerequiredboolean
milestones[].descriptionrequiredstring
milestones[].namerequiredstring
milestones[].offsetDaysrequiredinteger
milestones[].phasePublicIdstring or null
milestones[].positionrequiredinteger
milestones[].publicIdrequiredstring
milestones[].requiresClientAcceptancerequiredboolean
namerequiredstring
phasesrequiredarray of TemplatePhaseView
phases[].billingModeOverridestring or null
phases[].budgetAmountBpinteger or null
phases[].budgetMinutesinteger or null
phases[].namerequiredstring
phases[].positionrequiredinteger
phases[].publicIdrequiredstring
tasksrequiredarray of TemplateTaskView
tasks[].checklistrequiredarray of string
tasks[].clientVisiblerequiredboolean
tasks[].descriptionrequiredstring
tasks[].durationDaysrequiredinteger
tasks[].estimateMinutesrequiredinteger
tasks[].parentTaskPublicIdstring or null
tasks[].phasePublicIdstring or null
tasks[].positionrequiredinteger
tasks[].predecessorsrequiredarray of TaskDependencyView
tasks[].predecessors[].lagDaysrequiredinteger
tasks[].predecessors[].taskPublicIdrequiredstring
tasks[].priorityrequiredstring
tasks[].publicIdrequiredstring
tasks[].rolePlaceholderrequiredstring
tasks[].startOffsetDaysrequiredinteger
tasks[].titlerequiredstring
StatusBodyDescription
201application/json, ProjectTemplateViewCreated.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo resource matches.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

201 response body

FieldTypeDescription
activerequiredboolean
categoryrequiredstring
defaultBillingModerequiredstring
defaultBudgetMinutesrequiredinteger
defaultStatusEmailCadencerequiredstring
defaultStatusEmailWeekdayrequiredinteger
descriptionrequiredstring
durationDaysrequiredinteger
familyPublicIdrequiredstring
isCurrentrequiredboolean
isSeedrequiredboolean
milestonesrequiredarray of TemplateMilestoneView
milestones[].amountBprequiredinteger
milestones[].clientVisiblerequiredboolean
milestones[].descriptionrequiredstring
milestones[].namerequiredstring
milestones[].offsetDaysrequiredinteger
milestones[].phasePublicIdstring or null
milestones[].positionrequiredinteger
milestones[].publicIdrequiredstring
milestones[].requiresClientAcceptancerequiredboolean
namerequiredstring
phasesrequiredarray of TemplatePhaseView
phases[].billingModeOverridestring or null
phases[].budgetAmountBpinteger or null
phases[].budgetMinutesinteger or null
phases[].namerequiredstring
phases[].positionrequiredinteger
phases[].publicIdrequiredstring
publicIdrequiredstring
tasksrequiredarray of TemplateTaskView
tasks[].checklistrequiredarray of string
tasks[].clientVisiblerequiredboolean
tasks[].descriptionrequiredstring
tasks[].durationDaysrequiredinteger
tasks[].estimateMinutesrequiredinteger
tasks[].parentTaskPublicIdstring or null
tasks[].phasePublicIdstring or null
tasks[].positionrequiredinteger
tasks[].predecessorsrequiredarray of TaskDependencyView
tasks[].predecessors[].lagDaysrequiredinteger
tasks[].predecessors[].taskPublicIdrequiredstring
tasks[].priorityrequiredstring
tasks[].publicIdrequiredstring
tasks[].rolePlaceholderrequiredstring
tasks[].startOffsetDaysrequiredinteger
tasks[].titlerequiredstring
usedCountrequiredinteger
versionrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/projects/templates' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"active": false,
"category": "string",
"defaultBillingMode": "string",
"defaultBudgetMinutes": 0,
"defaultStatusEmailCadence": "string",
"defaultStatusEmailWeekday": 0,
"description": "string",
"milestones": [
{
"amountBp": 0,
"clientVisible": false,
"description": "string",
"name": "string",
"offsetDays": 0,
"phasePublicId": "string",
"position": 0,
"publicId": "string",
"requiresClientAcceptance": false
}
],
"name": "string",
"phases": [
{
"billingModeOverride": "string",
"budgetAmountBp": 0,
"budgetMinutes": 0,
"name": "string",
"position": 0,
"publicId": "string"
}
],
"tasks": [
{
"checklist": [
"string"
],
"clientVisible": false,
"description": "string",
"durationDays": 0,
"estimateMinutes": 0,
"parentTaskPublicId": "string",
"phasePublicId": "string",
"position": 0,
"predecessors": [
{
"lagDays": 0,
"taskPublicId": "string"
}
],
"priority": "string",
"publicId": "string",
"rolePlaceholder": "string",
"startOffsetDays": 0,
"title": "string"
}
]
}'

GETproject:readmsp facemspIdempotent

Source: [object Object]

Get project template

NameInTypeRequiredDescription
tplIDpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectTemplateViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
activerequiredboolean
categoryrequiredstring
defaultBillingModerequiredstring
defaultBudgetMinutesrequiredinteger
defaultStatusEmailCadencerequiredstring
defaultStatusEmailWeekdayrequiredinteger
descriptionrequiredstring
durationDaysrequiredinteger
familyPublicIdrequiredstring
isCurrentrequiredboolean
isSeedrequiredboolean
milestonesrequiredarray of TemplateMilestoneView
milestones[].amountBprequiredinteger
milestones[].clientVisiblerequiredboolean
milestones[].descriptionrequiredstring
milestones[].namerequiredstring
milestones[].offsetDaysrequiredinteger
milestones[].phasePublicIdstring or null
milestones[].positionrequiredinteger
milestones[].publicIdrequiredstring
milestones[].requiresClientAcceptancerequiredboolean
namerequiredstring
phasesrequiredarray of TemplatePhaseView
phases[].billingModeOverridestring or null
phases[].budgetAmountBpinteger or null
phases[].budgetMinutesinteger or null
phases[].namerequiredstring
phases[].positionrequiredinteger
phases[].publicIdrequiredstring
publicIdrequiredstring
tasksrequiredarray of TemplateTaskView
tasks[].checklistrequiredarray of string
tasks[].clientVisiblerequiredboolean
tasks[].descriptionrequiredstring
tasks[].durationDaysrequiredinteger
tasks[].estimateMinutesrequiredinteger
tasks[].parentTaskPublicIdstring or null
tasks[].phasePublicIdstring or null
tasks[].positionrequiredinteger
tasks[].predecessorsrequiredarray of TaskDependencyView
tasks[].predecessors[].lagDaysrequiredinteger
tasks[].predecessors[].taskPublicIdrequiredstring
tasks[].priorityrequiredstring
tasks[].publicIdrequiredstring
tasks[].rolePlaceholderrequiredstring
tasks[].startOffsetDaysrequiredinteger
tasks[].titlerequiredstring
usedCountrequiredinteger
versionrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/templates/<tplID>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

PUTproject:managemsp facemspIdempotent

Source: [object Object]

putProjectTemplate rewrites a template, in place or as a new version.

200 AND NOT 204, carrying a possibly HIGHER version: the store versions by copy once a template has been used, so the console has to be told which version it is now looking at. Answering 204 would leave an editor showing version 2 while the practice’s current plan is version 3.

NameInTypeRequiredDescription
tplIDpathstringYesA uuid.

Required, sent as application/json.

FieldTypeDescription
activeboolean or null
categoryrequiredstring
defaultBillingModerequiredstring
defaultBudgetMinutesinteger or null
defaultStatusEmailCadencerequiredstring
defaultStatusEmailWeekdayinteger or null
descriptionrequiredstring
milestonesrequiredarray of TemplateMilestoneView
milestones[].amountBprequiredinteger
milestones[].clientVisiblerequiredboolean
milestones[].descriptionrequiredstring
milestones[].namerequiredstring
milestones[].offsetDaysrequiredinteger
milestones[].phasePublicIdstring or null
milestones[].positionrequiredinteger
milestones[].publicIdrequiredstring
milestones[].requiresClientAcceptancerequiredboolean
namerequiredstring
phasesrequiredarray of TemplatePhaseView
phases[].billingModeOverridestring or null
phases[].budgetAmountBpinteger or null
phases[].budgetMinutesinteger or null
phases[].namerequiredstring
phases[].positionrequiredinteger
phases[].publicIdrequiredstring
tasksrequiredarray of TemplateTaskView
tasks[].checklistrequiredarray of string
tasks[].clientVisiblerequiredboolean
tasks[].descriptionrequiredstring
tasks[].durationDaysrequiredinteger
tasks[].estimateMinutesrequiredinteger
tasks[].parentTaskPublicIdstring or null
tasks[].phasePublicIdstring or null
tasks[].positionrequiredinteger
tasks[].predecessorsrequiredarray of TaskDependencyView
tasks[].predecessors[].lagDaysrequiredinteger
tasks[].predecessors[].taskPublicIdrequiredstring
tasks[].priorityrequiredstring
tasks[].publicIdrequiredstring
tasks[].rolePlaceholderrequiredstring
tasks[].startOffsetDaysrequiredinteger
tasks[].titlerequiredstring
StatusBodyDescription
200application/json, ProjectTemplateViewSuccess.
400application/problem+json, ProblemDetailsThe request body is not valid JSON.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
activerequiredboolean
categoryrequiredstring
defaultBillingModerequiredstring
defaultBudgetMinutesrequiredinteger
defaultStatusEmailCadencerequiredstring
defaultStatusEmailWeekdayrequiredinteger
descriptionrequiredstring
durationDaysrequiredinteger
familyPublicIdrequiredstring
isCurrentrequiredboolean
isSeedrequiredboolean
milestonesrequiredarray of TemplateMilestoneView
milestones[].amountBprequiredinteger
milestones[].clientVisiblerequiredboolean
milestones[].descriptionrequiredstring
milestones[].namerequiredstring
milestones[].offsetDaysrequiredinteger
milestones[].phasePublicIdstring or null
milestones[].positionrequiredinteger
milestones[].publicIdrequiredstring
milestones[].requiresClientAcceptancerequiredboolean
namerequiredstring
phasesrequiredarray of TemplatePhaseView
phases[].billingModeOverridestring or null
phases[].budgetAmountBpinteger or null
phases[].budgetMinutesinteger or null
phases[].namerequiredstring
phases[].positionrequiredinteger
phases[].publicIdrequiredstring
publicIdrequiredstring
tasksrequiredarray of TemplateTaskView
tasks[].checklistrequiredarray of string
tasks[].clientVisiblerequiredboolean
tasks[].descriptionrequiredstring
tasks[].durationDaysrequiredinteger
tasks[].estimateMinutesrequiredinteger
tasks[].parentTaskPublicIdstring or null
tasks[].phasePublicIdstring or null
tasks[].positionrequiredinteger
tasks[].predecessorsrequiredarray of TaskDependencyView
tasks[].predecessors[].lagDaysrequiredinteger
tasks[].predecessors[].taskPublicIdrequiredstring
tasks[].priorityrequiredstring
tasks[].publicIdrequiredstring
tasks[].rolePlaceholderrequiredstring
tasks[].startOffsetDaysrequiredinteger
tasks[].titlerequiredstring
usedCountrequiredinteger
versionrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X PUT 'https://depot.example.com/api/v1/projects/templates/<tplID>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-b 'outpost_console=<console-session>' \
--data '{
"active": false,
"category": "string",
"defaultBillingMode": "string",
"defaultBudgetMinutes": 0,
"defaultStatusEmailCadence": "string",
"defaultStatusEmailWeekday": 0,
"description": "string",
"milestones": [
{
"amountBp": 0,
"clientVisible": false,
"description": "string",
"name": "string",
"offsetDays": 0,
"phasePublicId": "string",
"position": 0,
"publicId": "string",
"requiresClientAcceptance": false
}
],
"name": "string",
"phases": [
{
"billingModeOverride": "string",
"budgetAmountBp": 0,
"budgetMinutes": 0,
"name": "string",
"position": 0,
"publicId": "string"
}
],
"tasks": [
{
"checklist": [
"string"
],
"clientVisible": false,
"description": "string",
"durationDays": 0,
"estimateMinutes": 0,
"parentTaskPublicId": "string",
"phasePublicId": "string",
"position": 0,
"predecessors": [
{
"lagDays": 0,
"taskPublicId": "string"
}
],
"priority": "string",
"publicId": "string",
"rolePlaceholder": "string",
"startOffsetDays": 0,
"title": "string"
}
]
}'

DELETEproject:managemsp facemspIdempotent

Source: [object Object]

deleteProjectTemplate removes a version nobody used.

409 templateInUse otherwise, and there is no force: a project created from version 2 reads version 2 for its retrospective and its estimates write-back, and deleting it would leave that project unable to explain itself. Retire it instead, which is what the console offers beside this.

NameInTypeRequiredDescription
tplIDpathstringYesA uuid.
StatusBodyDescription
204NoneSuccess, with no body.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X DELETE 'https://depot.example.com/api/v1/projects/templates/<tplID>' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

POST /api/v1/projects/templates/{tplID}/retire

Section titled “POST /api/v1/projects/templates/{tplID}/retire”

POSTproject:managemsp facemsp

Source: [object Object]

Retire project template

NameInTypeRequiredDescription
tplIDpathstringYesA uuid.
StatusBodyDescription
200application/json, ProjectTemplateViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:manage.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
activerequiredboolean
categoryrequiredstring
defaultBillingModerequiredstring
defaultBudgetMinutesrequiredinteger
defaultStatusEmailCadencerequiredstring
defaultStatusEmailWeekdayrequiredinteger
descriptionrequiredstring
durationDaysrequiredinteger
familyPublicIdrequiredstring
isCurrentrequiredboolean
isSeedrequiredboolean
milestonesrequiredarray of TemplateMilestoneView
milestones[].amountBprequiredinteger
milestones[].clientVisiblerequiredboolean
milestones[].descriptionrequiredstring
milestones[].namerequiredstring
milestones[].offsetDaysrequiredinteger
milestones[].phasePublicIdstring or null
milestones[].positionrequiredinteger
milestones[].publicIdrequiredstring
milestones[].requiresClientAcceptancerequiredboolean
namerequiredstring
phasesrequiredarray of TemplatePhaseView
phases[].billingModeOverridestring or null
phases[].budgetAmountBpinteger or null
phases[].budgetMinutesinteger or null
phases[].namerequiredstring
phases[].positionrequiredinteger
phases[].publicIdrequiredstring
publicIdrequiredstring
tasksrequiredarray of TemplateTaskView
tasks[].checklistrequiredarray of string
tasks[].clientVisiblerequiredboolean
tasks[].descriptionrequiredstring
tasks[].durationDaysrequiredinteger
tasks[].estimateMinutesrequiredinteger
tasks[].parentTaskPublicIdstring or null
tasks[].phasePublicIdstring or null
tasks[].positionrequiredinteger
tasks[].predecessorsrequiredarray of TaskDependencyView
tasks[].predecessors[].lagDaysrequiredinteger
tasks[].predecessors[].taskPublicIdrequiredstring
tasks[].priorityrequiredstring
tasks[].publicIdrequiredstring
tasks[].rolePlaceholderrequiredstring
tasks[].startOffsetDaysrequiredinteger
tasks[].titlerequiredstring
usedCountrequiredinteger
versionrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
curl -X POST 'https://depot.example.com/api/v1/projects/templates/<tplID>/retire' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

GET /api/v1/projects/templates/{tplID}/versions

Section titled “GET /api/v1/projects/templates/{tplID}/versions”

GETproject:readmsp facemspIdempotent

Source: [object Object]

List template versions

NameInTypeRequiredDescription
tplIDpathstringYesA uuid.
StatusBodyDescription
200application/json, PagedResultProjectTemplateViewSuccess.
400application/problem+json, ProblemDetailsOne or more validation errors occurred.
401application/problem+json, ProblemDetailsNo signed-in identity.
403application/problem+json, ProblemDetailsThe identity does not hold project:read.
404application/problem+json, ProblemDetailsNo resource matches that id.
500application/problem+json, ProblemDetailsThe request failed.
503application/problem+json, ProblemDetailsProjects are not available on this server.

200 response body

FieldTypeDescription
itemsrequiredarray of ProjectTemplateView
items[].activerequiredboolean
items[].categoryrequiredstring
items[].defaultBillingModerequiredstring
items[].defaultBudgetMinutesrequiredinteger
items[].defaultStatusEmailCadencerequiredstring
items[].defaultStatusEmailWeekdayrequiredinteger
items[].descriptionrequiredstring
items[].durationDaysrequiredinteger
items[].familyPublicIdrequiredstring
items[].isCurrentrequiredboolean
items[].isSeedrequiredboolean
items[].milestonesrequiredarray of TemplateMilestoneView
items[].milestones[].amountBprequiredinteger
items[].milestones[].clientVisiblerequiredboolean
items[].milestones[].descriptionrequiredstring
items[].milestones[].namerequiredstring
items[].milestones[].offsetDaysrequiredinteger
items[].milestones[].phasePublicIdstring or null
items[].milestones[].positionrequiredinteger
items[].milestones[].publicIdrequiredstring
items[].milestones[].requiresClientAcceptancerequiredboolean
items[].namerequiredstring
items[].phasesrequiredarray of TemplatePhaseView
items[].phases[].billingModeOverridestring or null
items[].phases[].budgetAmountBpinteger or null
items[].phases[].budgetMinutesinteger or null
items[].phases[].namerequiredstring
items[].phases[].positionrequiredinteger
items[].phases[].publicIdrequiredstring
items[].publicIdrequiredstring
items[].tasksrequiredarray of TemplateTaskView
items[].tasks[].checklistrequiredarray of string
items[].tasks[].clientVisiblerequiredboolean
items[].tasks[].descriptionrequiredstring
items[].tasks[].durationDaysrequiredinteger
items[].tasks[].estimateMinutesrequiredinteger
items[].tasks[].parentTaskPublicIdstring or null
items[].tasks[].phasePublicIdstring or null
items[].tasks[].positionrequiredinteger
items[].tasks[].predecessorsrequiredarray of TaskDependencyView
items[].tasks[].predecessors[].lagDaysrequiredinteger
items[].tasks[].predecessors[].taskPublicIdrequiredstring
items[].tasks[].priorityrequiredstring
items[].tasks[].publicIdrequiredstring
items[].tasks[].rolePlaceholderrequiredstring
items[].tasks[].startOffsetDaysrequiredinteger
items[].tasks[].titlerequiredstring
items[].usedCountrequiredinteger
items[].versionrequiredinteger
pagerequiredinteger
pageSizerequiredinteger
totalrequiredinteger
Terminal window
# Sign in first. outpost_console is a session cookie, so send it with every request.
# This operation is idempotent. Repeating it does not repeat its effect.
curl -X GET 'https://depot.example.com/api/v1/projects/templates/<tplID>/versions' \
-H 'X-CSRF-Token: <csrf-token>' \
-H 'Accept: application/json' \
-b 'outpost_console=<console-session>'

Content is licensed CC BY 4.0. Code samples are MIT. Outpost and the Outpost mark are trademarks of Outpost Business Solutions, PBC and are not covered by either license.