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.
GET /api/v1/clients/{cid}/projects
Section titled “GET /api/v1/clients/{cid}/projects”GETproject:readmsp facemspIdempotent
Source: [object Object]
List projects
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
billingMode | query | string | No | |
health | query | string, one of amber, green, red | No | Comma-separated set. An unrecognised value is refused. |
manager | query | string | No | |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
q | query | string | No | |
sort | query | string | No | |
status | query | string, one of active, cancelled, completed, draft, on_hold | No | Comma-separated set. An unrecognised value is refused. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectSummaryView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectSummaryView | |
items[].amountBurnBprequired | integer | |
items[].atRiskTasksrequired | integer | |
items[].billableSecondsrequired | integer | |
items[].billingModerequired | string | |
items[].budgetAmountCentsrequired | integer | int64. |
items[].budgetMinutesrequired | integer | |
items[].clientNamerequired | string | |
items[].clientPublicIdrequired | string | |
items[].createdAtrequired | string (date-time) | |
items[].fixedPriceCentsrequired | integer | int64. |
items[].healthrequired | string | |
items[].healthComputedAt | string (date-time) or null | |
items[].healthReasonrequired | string | |
items[].hoursBurnBprequired | integer | |
items[].isSelfrequired | boolean | |
items[].loggedSecondsrequired | integer | |
items[].managerName | string or null | |
items[].managerUserPublicId | string or null | |
items[].namerequired | string | |
items[].nextMilestone | NextMilestoneView | |
items[].nextMilestone.dueOnrequired | string | |
items[].nextMilestone.namerequired | string | |
items[].nextMilestone.publicIdrequired | string | |
items[].numberrequired | integer | int64. |
items[].openTasksrequired | integer | |
items[].overdueMilestonesrequired | integer | |
items[].percentCompleterequired | integer | |
items[].plannedEndOn | string or null | |
items[].plannedStartOnrequired | string | |
items[].publicIdrequired | string | |
items[].referencerequired | string | |
items[].statusrequired | string | |
items[].updatedAtrequired | string (date-time) | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects?billingMode=<billingMode>&health=amber&manager=<manager>&page=0&pageSize=0&q=<q>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects"params = { "billingMode": "<billingMode>", "health": "amber", "manager": "<manager>", "page": "0", "pageSize": "0", "q": "<q>",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects?billingMode=<billingMode>&health=amber&manager=<manager>&page=0&pageSize=0&q=<q>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/clients/<cid>/projects");url.searchParams.set("billingMode", "<billingMode>");url.searchParams.set("health", "amber");url.searchParams.set("manager", "<manager>");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");url.searchParams.set("q", "<q>");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects?billingMode=<billingMode>&health=amber&manager=<manager>&page=0&pageSize=0&q=<q>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/clients/{cid}/projects
Section titled “POST /api/v1/clients/{cid}/projects”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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
agreementPublicId | string or null | |
billingModerequired | string | |
budgetAmountCents | integer or null | int64. |
budgetMinutes | integer or null | |
clientContactEmailrequired | string | |
clientContactNamerequired | string | |
descriptionrequired | string | |
fixedPriceCents | integer or null | int64. |
fromTicketId | string or null | |
managerUserPublicId | string or null | |
namerequired | string | |
plannedStartOnrequired | string | |
prepaidLinePublicId | string or null | |
rolesrequired | object | |
skipWeekends | boolean or null | |
statusEmailCadence | string or null | |
statusEmailWeekday | integer or null | |
templateId | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
actualStartOn | string or null | |
agreementPublicId | string or null | |
amountBurnBprequired | integer | |
atRiskTasksrequired | integer | |
billableSecondsrequired | integer | |
billingModerequired | string | |
budgetAmountCentsrequired | integer | int64. |
budgetCriticalBp | integer or null | |
budgetMinutesrequired | integer | |
budgetWarnBp | integer or null | |
cancelledAt | string (date-time) or null | |
clientContactEmailrequired | string | |
clientContactNamerequired | string | |
clientNamerequired | string | |
clientPublicIdrequired | string | |
completedAt | string (date-time) or null | |
convertedFromTicketPublicId | string or null | |
costCents | integer or null | int64. |
createdAtrequired | string (date-time) | |
descriptionrequired | string | |
fixedPriceCentsrequired | integer | int64. |
healthrequired | string | |
healthComputedAt | string (date-time) or null | |
healthReasonrequired | string | |
hoursBurnBprequired | integer | |
isSelfrequired | boolean | |
lastStatusEmailOn | string or null | |
loggedSecondsrequired | integer | |
managerName | string or null | |
managerUserPublicId | string or null | |
milestonesrequired | array of ProjectMilestoneView | |
milestones[].acceptance | MilestoneAcceptanceView | |
milestones[].acceptance.consentTextrequired | string | |
milestones[].acceptance.consentVersionrequired | integer | |
milestones[].acceptance.iprequired | string | |
milestones[].acceptance.signedAtrequired | string (date-time) | |
milestones[].acceptance.signerNamerequired | string | |
milestones[].acceptance.signerTitlerequired | string | |
milestones[].acceptance.userAgentrequired | string | |
milestones[].acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
milestones[].acceptanceLink.activerequired | boolean | |
milestones[].acceptanceLink.expiresAt | string (date-time) or null | |
milestones[].acceptanceLink.viewCountrequired | integer | |
milestones[].acceptanceSentAt | string (date-time) or null | |
milestones[].acceptedAt | string (date-time) or null | |
milestones[].amountCents | integer or null | int64. |
milestones[].certificateAvailablerequired | boolean | |
milestones[].clientVisiblerequired | boolean | |
milestones[].completedAt | string (date-time) or null | |
milestones[].declineReasonrequired | string | |
milestones[].declinedAt | string (date-time) or null | |
milestones[].descriptionrequired | string | |
milestones[].dueOnrequired | string | |
milestones[].invoicePublicId | string or null | |
milestones[].invoicedAt | string (date-time) or null | |
milestones[].namerequired | string | |
milestones[].phaseName | string or null | |
milestones[].phasePublicId | string or null | |
milestones[].positionrequired | integer | |
milestones[].publicIdrequired | string | |
milestones[].requiresClientAcceptancerequired | boolean | |
milestones[].statusrequired | string | |
namerequired | string | |
nextMilestone | NextMilestoneView | |
nextMilestone.dueOnrequired | string | |
nextMilestone.namerequired | string | |
nextMilestone.publicIdrequired | string | |
notesrequired | string | |
numberrequired | integer | int64. |
openTasksrequired | integer | |
overdueMilestonesrequired | integer | |
percentCompleterequired | integer | |
phasesrequired | array of ProjectPhaseView | |
phases[].billableSecondsrequired | integer | |
phases[].billingModeOverride | string or null | |
phases[].budgetAmountCents | integer or null | int64. |
phases[].budgetMinutes | integer or null | |
phases[].completedAt | string (date-time) or null | |
phases[].costCents | integer or null | int64. |
phases[].loggedSecondsrequired | integer | |
phases[].namerequired | string | |
phases[].percentCompleterequired | integer | |
phases[].plannedEndOn | string or null | |
phases[].plannedStartOn | string or null | |
phases[].positionrequired | integer | |
phases[].prepaidLinePublicId | string or null | |
phases[].publicIdrequired | string | |
phases[].statusrequired | string | |
plannedEndOn | string or null | |
plannedStartOnrequired | string | |
prepaidLinePublicId | string or null | |
publicIdrequired | string | |
quotePublicId | string or null | |
referencerequired | string | |
retrospectiverequired | any | |
skipWeekendsrequired | boolean | |
statusrequired | string | |
statusEmailCadencerequired | string | |
statusEmailWeekdayrequired | integer | |
statusLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
statusLink.activerequired | boolean | |
statusLink.expiresAt | string (date-time) or null | |
statusLink.viewCountrequired | integer | |
templatePublicId | string or null | |
templateVersion | integer or null | |
ticketLinksrequired | array of ProjectTicketLinkView | |
ticketLinks[].createdAtrequired | string (date-time) | |
ticketLinks[].kindrequired | string | |
ticketLinks[].publicIdrequired | string | |
ticketLinks[].taskPublicId | string or null | |
ticketLinks[].ticketPublicIdrequired | string | |
ticketLinks[].ticketReferencerequired | string | |
ticketLinks[].ticketSubjectrequired | string | |
updatedAtrequired | string (date-time) |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "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"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "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",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "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"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "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" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "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"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/clients/{cid}/projects/{id}
Section titled “GET /api/v1/clients/{cid}/projects/{id}”GETproject:readmsp facemspIdempotent
Source: [object Object]
Get project
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
actualStartOn | string or null | |
agreementPublicId | string or null | |
amountBurnBprequired | integer | |
atRiskTasksrequired | integer | |
billableSecondsrequired | integer | |
billingModerequired | string | |
budgetAmountCentsrequired | integer | int64. |
budgetCriticalBp | integer or null | |
budgetMinutesrequired | integer | |
budgetWarnBp | integer or null | |
cancelledAt | string (date-time) or null | |
clientContactEmailrequired | string | |
clientContactNamerequired | string | |
clientNamerequired | string | |
clientPublicIdrequired | string | |
completedAt | string (date-time) or null | |
convertedFromTicketPublicId | string or null | |
costCents | integer or null | int64. |
createdAtrequired | string (date-time) | |
descriptionrequired | string | |
fixedPriceCentsrequired | integer | int64. |
healthrequired | string | |
healthComputedAt | string (date-time) or null | |
healthReasonrequired | string | |
hoursBurnBprequired | integer | |
isSelfrequired | boolean | |
lastStatusEmailOn | string or null | |
loggedSecondsrequired | integer | |
managerName | string or null | |
managerUserPublicId | string or null | |
milestonesrequired | array of ProjectMilestoneView | |
milestones[].acceptance | MilestoneAcceptanceView | |
milestones[].acceptance.consentTextrequired | string | |
milestones[].acceptance.consentVersionrequired | integer | |
milestones[].acceptance.iprequired | string | |
milestones[].acceptance.signedAtrequired | string (date-time) | |
milestones[].acceptance.signerNamerequired | string | |
milestones[].acceptance.signerTitlerequired | string | |
milestones[].acceptance.userAgentrequired | string | |
milestones[].acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
milestones[].acceptanceLink.activerequired | boolean | |
milestones[].acceptanceLink.expiresAt | string (date-time) or null | |
milestones[].acceptanceLink.viewCountrequired | integer | |
milestones[].acceptanceSentAt | string (date-time) or null | |
milestones[].acceptedAt | string (date-time) or null | |
milestones[].amountCents | integer or null | int64. |
milestones[].certificateAvailablerequired | boolean | |
milestones[].clientVisiblerequired | boolean | |
milestones[].completedAt | string (date-time) or null | |
milestones[].declineReasonrequired | string | |
milestones[].declinedAt | string (date-time) or null | |
milestones[].descriptionrequired | string | |
milestones[].dueOnrequired | string | |
milestones[].invoicePublicId | string or null | |
milestones[].invoicedAt | string (date-time) or null | |
milestones[].namerequired | string | |
milestones[].phaseName | string or null | |
milestones[].phasePublicId | string or null | |
milestones[].positionrequired | integer | |
milestones[].publicIdrequired | string | |
milestones[].requiresClientAcceptancerequired | boolean | |
milestones[].statusrequired | string | |
namerequired | string | |
nextMilestone | NextMilestoneView | |
nextMilestone.dueOnrequired | string | |
nextMilestone.namerequired | string | |
nextMilestone.publicIdrequired | string | |
notesrequired | string | |
numberrequired | integer | int64. |
openTasksrequired | integer | |
overdueMilestonesrequired | integer | |
percentCompleterequired | integer | |
phasesrequired | array of ProjectPhaseView | |
phases[].billableSecondsrequired | integer | |
phases[].billingModeOverride | string or null | |
phases[].budgetAmountCents | integer or null | int64. |
phases[].budgetMinutes | integer or null | |
phases[].completedAt | string (date-time) or null | |
phases[].costCents | integer or null | int64. |
phases[].loggedSecondsrequired | integer | |
phases[].namerequired | string | |
phases[].percentCompleterequired | integer | |
phases[].plannedEndOn | string or null | |
phases[].plannedStartOn | string or null | |
phases[].positionrequired | integer | |
phases[].prepaidLinePublicId | string or null | |
phases[].publicIdrequired | string | |
phases[].statusrequired | string | |
plannedEndOn | string or null | |
plannedStartOnrequired | string | |
prepaidLinePublicId | string or null | |
publicIdrequired | string | |
quotePublicId | string or null | |
referencerequired | string | |
retrospectiverequired | any | |
skipWeekendsrequired | boolean | |
statusrequired | string | |
statusEmailCadencerequired | string | |
statusEmailWeekdayrequired | integer | |
statusLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
statusLink.activerequired | boolean | |
statusLink.expiresAt | string (date-time) or null | |
statusLink.viewCountrequired | integer | |
templatePublicId | string or null | |
templateVersion | integer or null | |
ticketLinksrequired | array of ProjectTicketLinkView | |
ticketLinks[].createdAtrequired | string (date-time) | |
ticketLinks[].kindrequired | string | |
ticketLinks[].publicIdrequired | string | |
ticketLinks[].taskPublicId | string or null | |
ticketLinks[].ticketPublicIdrequired | string | |
ticketLinks[].ticketReferencerequired | string | |
ticketLinks[].ticketSubjectrequired | string | |
updatedAtrequired | string (date-time) |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());PATCH /api/v1/clients/{cid}/projects/{id}
Section titled “PATCH /api/v1/clients/{cid}/projects/{id}”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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
agreementPublicId | string or null | |
billingMode | string or null | |
budgetAmountCents | integer or null | int64. |
budgetCriticalBp | integer or null | |
budgetMinutes | integer or null | |
budgetWarnBp | integer or null | |
clientContactEmail | string or null | |
clientContactName | string or null | |
description | string or null | |
fixedPriceCents | integer or null | int64. |
managerUserPublicId | string or null | |
name | string or null | |
notes | string or null | |
plannedStartOn | string or null | |
prepaidLinePublicId | string or null | |
skipWeekends | boolean or null | |
statusEmailCadence | string or null | |
statusEmailWeekday | integer or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
actualStartOn | string or null | |
agreementPublicId | string or null | |
amountBurnBprequired | integer | |
atRiskTasksrequired | integer | |
billableSecondsrequired | integer | |
billingModerequired | string | |
budgetAmountCentsrequired | integer | int64. |
budgetCriticalBp | integer or null | |
budgetMinutesrequired | integer | |
budgetWarnBp | integer or null | |
cancelledAt | string (date-time) or null | |
clientContactEmailrequired | string | |
clientContactNamerequired | string | |
clientNamerequired | string | |
clientPublicIdrequired | string | |
completedAt | string (date-time) or null | |
convertedFromTicketPublicId | string or null | |
costCents | integer or null | int64. |
createdAtrequired | string (date-time) | |
descriptionrequired | string | |
fixedPriceCentsrequired | integer | int64. |
healthrequired | string | |
healthComputedAt | string (date-time) or null | |
healthReasonrequired | string | |
hoursBurnBprequired | integer | |
isSelfrequired | boolean | |
lastStatusEmailOn | string or null | |
loggedSecondsrequired | integer | |
managerName | string or null | |
managerUserPublicId | string or null | |
milestonesrequired | array of ProjectMilestoneView | |
milestones[].acceptance | MilestoneAcceptanceView | |
milestones[].acceptance.consentTextrequired | string | |
milestones[].acceptance.consentVersionrequired | integer | |
milestones[].acceptance.iprequired | string | |
milestones[].acceptance.signedAtrequired | string (date-time) | |
milestones[].acceptance.signerNamerequired | string | |
milestones[].acceptance.signerTitlerequired | string | |
milestones[].acceptance.userAgentrequired | string | |
milestones[].acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
milestones[].acceptanceLink.activerequired | boolean | |
milestones[].acceptanceLink.expiresAt | string (date-time) or null | |
milestones[].acceptanceLink.viewCountrequired | integer | |
milestones[].acceptanceSentAt | string (date-time) or null | |
milestones[].acceptedAt | string (date-time) or null | |
milestones[].amountCents | integer or null | int64. |
milestones[].certificateAvailablerequired | boolean | |
milestones[].clientVisiblerequired | boolean | |
milestones[].completedAt | string (date-time) or null | |
milestones[].declineReasonrequired | string | |
milestones[].declinedAt | string (date-time) or null | |
milestones[].descriptionrequired | string | |
milestones[].dueOnrequired | string | |
milestones[].invoicePublicId | string or null | |
milestones[].invoicedAt | string (date-time) or null | |
milestones[].namerequired | string | |
milestones[].phaseName | string or null | |
milestones[].phasePublicId | string or null | |
milestones[].positionrequired | integer | |
milestones[].publicIdrequired | string | |
milestones[].requiresClientAcceptancerequired | boolean | |
milestones[].statusrequired | string | |
namerequired | string | |
nextMilestone | NextMilestoneView | |
nextMilestone.dueOnrequired | string | |
nextMilestone.namerequired | string | |
nextMilestone.publicIdrequired | string | |
notesrequired | string | |
numberrequired | integer | int64. |
openTasksrequired | integer | |
overdueMilestonesrequired | integer | |
percentCompleterequired | integer | |
phasesrequired | array of ProjectPhaseView | |
phases[].billableSecondsrequired | integer | |
phases[].billingModeOverride | string or null | |
phases[].budgetAmountCents | integer or null | int64. |
phases[].budgetMinutes | integer or null | |
phases[].completedAt | string (date-time) or null | |
phases[].costCents | integer or null | int64. |
phases[].loggedSecondsrequired | integer | |
phases[].namerequired | string | |
phases[].percentCompleterequired | integer | |
phases[].plannedEndOn | string or null | |
phases[].plannedStartOn | string or null | |
phases[].positionrequired | integer | |
phases[].prepaidLinePublicId | string or null | |
phases[].publicIdrequired | string | |
phases[].statusrequired | string | |
plannedEndOn | string or null | |
plannedStartOnrequired | string | |
prepaidLinePublicId | string or null | |
publicIdrequired | string | |
quotePublicId | string or null | |
referencerequired | string | |
retrospectiverequired | any | |
skipWeekendsrequired | boolean | |
statusrequired | string | |
statusEmailCadencerequired | string | |
statusEmailWeekdayrequired | integer | |
statusLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
statusLink.activerequired | boolean | |
statusLink.expiresAt | string (date-time) or null | |
statusLink.viewCountrequired | integer | |
templatePublicId | string or null | |
templateVersion | integer or null | |
ticketLinksrequired | array of ProjectTicketLinkView | |
ticketLinks[].createdAtrequired | string (date-time) | |
ticketLinks[].kindrequired | string | |
ticketLinks[].publicIdrequired | string | |
ticketLinks[].taskPublicId | string or null | |
ticketLinks[].ticketPublicIdrequired | string | |
ticketLinks[].ticketReferencerequired | string | |
ticketLinks[].ticketSubjectrequired | string | |
updatedAtrequired | string (date-time) |
Request samples
Section titled “Request samples”# 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}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "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}'@
$response = Invoke-RestMethod ` -Method Patch ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "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,}
response = requests.patch(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "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}`)
req, err := http.NewRequest(http.MethodPatch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>";
const response = await fetch(url, { method: "PATCH", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "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 }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "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}""";
var request = new HttpRequestMessage(HttpMethod.Patch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectActivityView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectActivityView | |
items[].actorrequired | string | |
items[].atrequired | string (date-time) | |
items[].detailrequired | string | |
items[].kindrequired | string | |
items[].verbrequired | string | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/activity?page=0&pageSize=0' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/activity"params = { "page": "0", "pageSize": "0",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/activity?page=0&pageSize=0", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/clients/<cid>/projects/<id>/activity");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/activity?page=0&pageSize=0");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectBudgetView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
amountBurnBprequired | integer | |
budgetAmountCentsrequired | integer | int64. |
budgetMinutesrequired | integer | |
changeOrdersrequired | array of BudgetChangeOrderView | |
changeOrders[].addedAmountCentsrequired | integer | int64. |
changeOrders[].addedMinutesrequired | integer | |
changeOrders[].numberrequired | integer | |
changeOrders[].publicIdrequired | string | |
changeOrders[].statusrequired | string | |
costCents | integer or null | int64. |
hoursBurnBprequired | integer | |
invoicedCentsrequired | integer | int64. |
loggedSecondsrequired | integer | |
marginCents | integer or null | int64. |
phasesrequired | array of BudgetPhaseView | |
phases[].amountBurnBprequired | integer | |
phases[].budgetAmountCents | integer or null | int64. |
phases[].budgetMinutes | integer or null | |
phases[].costCents | integer or null | int64. |
phases[].hoursBurnBprequired | integer | |
phases[].loggedSecondsrequired | integer | |
phases[].namerequired | string | |
phases[].phasePublicIdrequired | string | |
uninvoicedCentsrequired | integer | int64. |
unknownCostSeconds | integer or null |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/budget' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/budget"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/budget", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/budget";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/budget");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectChangeOrderView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectChangeOrderView | |
items[].addedAmountCentsrequired | integer | int64. |
items[].addedMinutesrequired | integer | |
items[].approvedAt | string (date-time) or null | |
items[].approvedByNamerequired | string | |
items[].createdAtrequired | string (date-time) | |
items[].descriptionrequired | string | |
items[].invoicePublicId | string or null | |
items[].invoicedAt | string (date-time) or null | |
items[].numberrequired | integer | |
items[].phasePublicId | string or null | |
items[].publicIdrequired | string | |
items[].raiseInvoiceLinerequired | boolean | |
items[].statusrequired | string | |
items[].titlerequired | string | |
items[].updatedAtrequired | string (date-time) | |
items[].voidReasonrequired | string | |
items[].voidedAt | string (date-time) or null | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
addedAmountCents | integer or null | int64. |
addedMinutes | integer or null | |
description | string or null | |
phasePublicId | string or null | |
raiseInvoiceLine | boolean or null | |
title | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ProjectChangeOrderView | Created. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
addedAmountCentsrequired | integer | int64. |
addedMinutesrequired | integer | |
approvedAt | string (date-time) or null | |
approvedByNamerequired | string | |
createdAtrequired | string (date-time) | |
descriptionrequired | string | |
invoicePublicId | string or null | |
invoicedAt | string (date-time) or null | |
numberrequired | integer | |
phasePublicId | string or null | |
publicIdrequired | string | |
raiseInvoiceLinerequired | boolean | |
statusrequired | string | |
titlerequired | string | |
updatedAtrequired | string (date-time) | |
voidReasonrequired | string | |
voidedAt | string (date-time) or null |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "addedAmountCents": 0, "addedMinutes": 0, "description": "string", "phasePublicId": "string", "raiseInvoiceLine": false, "title": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "addedAmountCents": 0, "addedMinutes": 0, "description": "string", "phasePublicId": "string", "raiseInvoiceLine": False, "title": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "addedAmountCents": 0, "addedMinutes": 0, "description": "string", "phasePublicId": "string", "raiseInvoiceLine": false, "title": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "addedAmountCents": 0, "addedMinutes": 0, "description": "string", "phasePublicId": "string", "raiseInvoiceLine": false, "title": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "addedAmountCents": 0, "addedMinutes": 0, "description": "string", "phasePublicId": "string", "raiseInvoiceLine": false, "title": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
coId | path | string | Yes | A uuid. |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
addedAmountCents | integer or null | int64. |
addedMinutes | integer or null | |
description | string or null | |
phasePublicId | string or null | |
raiseInvoiceLine | boolean or null | |
title | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectChangeOrderView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
addedAmountCentsrequired | integer | int64. |
addedMinutesrequired | integer | |
approvedAt | string (date-time) or null | |
approvedByNamerequired | string | |
createdAtrequired | string (date-time) | |
descriptionrequired | string | |
invoicePublicId | string or null | |
invoicedAt | string (date-time) or null | |
numberrequired | integer | |
phasePublicId | string or null | |
publicIdrequired | string | |
raiseInvoiceLinerequired | boolean | |
statusrequired | string | |
titlerequired | string | |
updatedAtrequired | string (date-time) | |
voidReasonrequired | string | |
voidedAt | string (date-time) or null |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "addedAmountCents": 0, "addedMinutes": 0, "description": "string", "phasePublicId": "string", "raiseInvoiceLine": false, "title": "string"}'@
$response = Invoke-RestMethod ` -Method Patch ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "addedAmountCents": 0, "addedMinutes": 0, "description": "string", "phasePublicId": "string", "raiseInvoiceLine": False, "title": "string",}
response = requests.patch(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "addedAmountCents": 0, "addedMinutes": 0, "description": "string", "phasePublicId": "string", "raiseInvoiceLine": false, "title": "string"}`)
req, err := http.NewRequest(http.MethodPatch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>";
const response = await fetch(url, { method: "PATCH", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "addedAmountCents": 0, "addedMinutes": 0, "description": "string", "phasePublicId": "string", "raiseInvoiceLine": false, "title": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "addedAmountCents": 0, "addedMinutes": 0, "description": "string", "phasePublicId": "string", "raiseInvoiceLine": false, "title": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Patch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
coId | path | string | Yes | A uuid. |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
approvedByNamerequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectChangeOrderView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
addedAmountCentsrequired | integer | int64. |
addedMinutesrequired | integer | |
approvedAt | string (date-time) or null | |
approvedByNamerequired | string | |
createdAtrequired | string (date-time) | |
descriptionrequired | string | |
invoicePublicId | string or null | |
invoicedAt | string (date-time) or null | |
numberrequired | integer | |
phasePublicId | string or null | |
publicIdrequired | string | |
raiseInvoiceLinerequired | boolean | |
statusrequired | string | |
titlerequired | string | |
updatedAtrequired | string (date-time) | |
voidReasonrequired | string | |
voidedAt | string (date-time) or null |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "approvedByName": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/approve' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/approve"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "approvedByName": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "approvedByName": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/approve", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/approve";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "approvedByName": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "approvedByName": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/approve");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
coId | path | string | Yes | A uuid. |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
reasonrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectChangeOrderView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
addedAmountCentsrequired | integer | int64. |
addedMinutesrequired | integer | |
approvedAt | string (date-time) or null | |
approvedByNamerequired | string | |
createdAtrequired | string (date-time) | |
descriptionrequired | string | |
invoicePublicId | string or null | |
invoicedAt | string (date-time) or null | |
numberrequired | integer | |
phasePublicId | string or null | |
publicIdrequired | string | |
raiseInvoiceLinerequired | boolean | |
statusrequired | string | |
titlerequired | string | |
updatedAtrequired | string (date-time) | |
voidReasonrequired | string | |
voidedAt | string (date-time) or null |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "reason": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/void' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/void"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "reason": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "reason": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/void", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/void";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "reason": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "reason": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/change-orders/<coId>/void");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
notesrequired | string | |
updateTemplateEstimatesrequired | boolean |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
actualStartOn | string or null | |
agreementPublicId | string or null | |
amountBurnBprequired | integer | |
atRiskTasksrequired | integer | |
billableSecondsrequired | integer | |
billingModerequired | string | |
budgetAmountCentsrequired | integer | int64. |
budgetCriticalBp | integer or null | |
budgetMinutesrequired | integer | |
budgetWarnBp | integer or null | |
cancelledAt | string (date-time) or null | |
clientContactEmailrequired | string | |
clientContactNamerequired | string | |
clientNamerequired | string | |
clientPublicIdrequired | string | |
completedAt | string (date-time) or null | |
convertedFromTicketPublicId | string or null | |
costCents | integer or null | int64. |
createdAtrequired | string (date-time) | |
descriptionrequired | string | |
fixedPriceCentsrequired | integer | int64. |
healthrequired | string | |
healthComputedAt | string (date-time) or null | |
healthReasonrequired | string | |
hoursBurnBprequired | integer | |
isSelfrequired | boolean | |
lastStatusEmailOn | string or null | |
loggedSecondsrequired | integer | |
managerName | string or null | |
managerUserPublicId | string or null | |
milestonesrequired | array of ProjectMilestoneView | |
milestones[].acceptance | MilestoneAcceptanceView | |
milestones[].acceptance.consentTextrequired | string | |
milestones[].acceptance.consentVersionrequired | integer | |
milestones[].acceptance.iprequired | string | |
milestones[].acceptance.signedAtrequired | string (date-time) | |
milestones[].acceptance.signerNamerequired | string | |
milestones[].acceptance.signerTitlerequired | string | |
milestones[].acceptance.userAgentrequired | string | |
milestones[].acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
milestones[].acceptanceLink.activerequired | boolean | |
milestones[].acceptanceLink.expiresAt | string (date-time) or null | |
milestones[].acceptanceLink.viewCountrequired | integer | |
milestones[].acceptanceSentAt | string (date-time) or null | |
milestones[].acceptedAt | string (date-time) or null | |
milestones[].amountCents | integer or null | int64. |
milestones[].certificateAvailablerequired | boolean | |
milestones[].clientVisiblerequired | boolean | |
milestones[].completedAt | string (date-time) or null | |
milestones[].declineReasonrequired | string | |
milestones[].declinedAt | string (date-time) or null | |
milestones[].descriptionrequired | string | |
milestones[].dueOnrequired | string | |
milestones[].invoicePublicId | string or null | |
milestones[].invoicedAt | string (date-time) or null | |
milestones[].namerequired | string | |
milestones[].phaseName | string or null | |
milestones[].phasePublicId | string or null | |
milestones[].positionrequired | integer | |
milestones[].publicIdrequired | string | |
milestones[].requiresClientAcceptancerequired | boolean | |
milestones[].statusrequired | string | |
namerequired | string | |
nextMilestone | NextMilestoneView | |
nextMilestone.dueOnrequired | string | |
nextMilestone.namerequired | string | |
nextMilestone.publicIdrequired | string | |
notesrequired | string | |
numberrequired | integer | int64. |
openTasksrequired | integer | |
overdueMilestonesrequired | integer | |
percentCompleterequired | integer | |
phasesrequired | array of ProjectPhaseView | |
phases[].billableSecondsrequired | integer | |
phases[].billingModeOverride | string or null | |
phases[].budgetAmountCents | integer or null | int64. |
phases[].budgetMinutes | integer or null | |
phases[].completedAt | string (date-time) or null | |
phases[].costCents | integer or null | int64. |
phases[].loggedSecondsrequired | integer | |
phases[].namerequired | string | |
phases[].percentCompleterequired | integer | |
phases[].plannedEndOn | string or null | |
phases[].plannedStartOn | string or null | |
phases[].positionrequired | integer | |
phases[].prepaidLinePublicId | string or null | |
phases[].publicIdrequired | string | |
phases[].statusrequired | string | |
plannedEndOn | string or null | |
plannedStartOnrequired | string | |
prepaidLinePublicId | string or null | |
publicIdrequired | string | |
quotePublicId | string or null | |
referencerequired | string | |
retrospectiverequired | any | |
skipWeekendsrequired | boolean | |
statusrequired | string | |
statusEmailCadencerequired | string | |
statusEmailWeekdayrequired | integer | |
statusLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
statusLink.activerequired | boolean | |
statusLink.expiresAt | string (date-time) or null | |
statusLink.viewCountrequired | integer | |
templatePublicId | string or null | |
templateVersion | integer or null | |
ticketLinksrequired | array of ProjectTicketLinkView | |
ticketLinks[].createdAtrequired | string (date-time) | |
ticketLinks[].kindrequired | string | |
ticketLinks[].publicIdrequired | string | |
ticketLinks[].taskPublicId | string or null | |
ticketLinks[].ticketPublicIdrequired | string | |
ticketLinks[].ticketReferencerequired | string | |
ticketLinks[].ticketSubjectrequired | string | |
updatedAtrequired | string (date-time) |
Request samples
Section titled “Request samples”# 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}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "notes": "string", "updateTemplateEstimates": false}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/close' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/close"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "notes": "string", "updateTemplateEstimates": False,}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "notes": "string", "updateTemplateEstimates": false}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/close", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/close";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "notes": "string", "updateTemplateEstimates": false }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "notes": "string", "updateTemplateEstimates": false}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/close");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectDocumentView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectDocumentView | |
items[].changeOrderPublicId | string or null | |
items[].contentTyperequired | string | |
items[].createdAtrequired | string (date-time) | |
items[].deletedAt | string (date-time) or null | |
items[].downloadUrlrequired | string | |
items[].fileNamerequired | string | |
items[].kindrequired | string | |
items[].milestonePublicId | string or null | |
items[].publicIdrequired | string | |
items[].sizeBytesrequired | integer | int64. |
items[].uploadedByUserPublicId | string or null | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents?page=0&pageSize=0' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents"params = { "page": "0", "pageSize": "0",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents?page=0&pageSize=0", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents?page=0&pageSize=0");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
fileName | query | string | No |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ProjectDocumentView | Created. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
413 | application/problem+json, ProblemDetails | The request was refused. |
415 | application/problem+json, ProblemDetails | A fileName query parameter is required. |
500 | application/problem+json, ProblemDetails | Could not build a storage key. |
502 | application/problem+json, ProblemDetails | The document could not be stored. Nothing was attached to the project. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
507 | application/problem+json, ProblemDetails | This client’s storage is full. Raise the quota or remove old documents. |
201 response body
| Field | Type | Description |
|---|---|---|
changeOrderPublicId | string or null | |
contentTyperequired | string | |
createdAtrequired | string (date-time) | |
deletedAt | string (date-time) or null | |
downloadUrlrequired | string | |
fileNamerequired | string | |
kindrequired | string | |
milestonePublicId | string or null | |
publicIdrequired | string | |
sizeBytesrequired | integer | int64. |
uploadedByUserPublicId | string or null |
Request samples
Section titled “Request samples”# 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>'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents?fileName=<fileName>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents"params = { "fileName": "<fileName>",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents?fileName=<fileName>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents");url.searchParams.set("fileName", "<fileName>");
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents?fileName=<fileName>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
docId | path | string | Yes | A uuid. |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/octet-stream, string (binary) | Success. The body shape was not resolved; see x-outpost-unresolved. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
502 | application/problem+json, ProblemDetails | The document could not be read from storage. |
503 | application/problem+json, ProblemDetails | Document storage is not configured on this Depot. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
docId | path | string | Yes | A uuid. |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/documents/<docId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectMailView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectMailView | |
items[].attemptsrequired | integer | |
items[].createdAtrequired | string (date-time) | |
items[].kindrequired | string | |
items[].lastErrorrequired | string | |
items[].publicIdrequired | string | |
items[].refPublicId | string or null | |
items[].sentAt | string (date-time) or null | |
items[].staterequired | string | |
items[].subjectrequired | string | |
items[].torequired | string | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/mail?page=0&pageSize=0' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/mail"params = { "page": "0", "pageSize": "0",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/mail?page=0&pageSize=0", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/clients/<cid>/projects/<id>/mail");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/mail?page=0&pageSize=0");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectMilestoneView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectMilestoneView | |
items[].acceptance | MilestoneAcceptanceView | |
items[].acceptance.consentTextrequired | string | |
items[].acceptance.consentVersionrequired | integer | |
items[].acceptance.iprequired | string | |
items[].acceptance.signedAtrequired | string (date-time) | |
items[].acceptance.signerNamerequired | string | |
items[].acceptance.signerTitlerequired | string | |
items[].acceptance.userAgentrequired | string | |
items[].acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
items[].acceptanceLink.activerequired | boolean | |
items[].acceptanceLink.expiresAt | string (date-time) or null | |
items[].acceptanceLink.viewCountrequired | integer | |
items[].acceptanceSentAt | string (date-time) or null | |
items[].acceptedAt | string (date-time) or null | |
items[].amountCents | integer or null | int64. |
items[].certificateAvailablerequired | boolean | |
items[].clientVisiblerequired | boolean | |
items[].completedAt | string (date-time) or null | |
items[].declineReasonrequired | string | |
items[].declinedAt | string (date-time) or null | |
items[].descriptionrequired | string | |
items[].dueOnrequired | string | |
items[].invoicePublicId | string or null | |
items[].invoicedAt | string (date-time) or null | |
items[].namerequired | string | |
items[].phaseName | string or null | |
items[].phasePublicId | string or null | |
items[].positionrequired | integer | |
items[].publicIdrequired | string | |
items[].requiresClientAcceptancerequired | boolean | |
items[].statusrequired | string | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
amountCents | integer or null | int64. |
clientVisible | boolean or null | |
description | string or null | |
dueOn | string or null | |
name | string or null | |
phasePublicId | string or null | |
position | integer or null | |
requiresClientAcceptance | boolean or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ProjectMilestoneView | Created. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
acceptance | MilestoneAcceptanceView | |
acceptance.consentTextrequired | string | |
acceptance.consentVersionrequired | integer | |
acceptance.iprequired | string | |
acceptance.signedAtrequired | string (date-time) | |
acceptance.signerNamerequired | string | |
acceptance.signerTitlerequired | string | |
acceptance.userAgentrequired | string | |
acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
acceptanceLink.activerequired | boolean | |
acceptanceLink.expiresAt | string (date-time) or null | |
acceptanceLink.viewCountrequired | integer | |
acceptanceSentAt | string (date-time) or null | |
acceptedAt | string (date-time) or null | |
amountCents | integer or null | int64. |
certificateAvailablerequired | boolean | |
clientVisiblerequired | boolean | |
completedAt | string (date-time) or null | |
declineReasonrequired | string | |
declinedAt | string (date-time) or null | |
descriptionrequired | string | |
dueOnrequired | string | |
invoicePublicId | string or null | |
invoicedAt | string (date-time) or null | |
namerequired | string | |
phaseName | string or null | |
phasePublicId | string or null | |
positionrequired | integer | |
publicIdrequired | string | |
requiresClientAcceptancerequired | boolean | |
statusrequired | string |
Request samples
Section titled “Request samples”# 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}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "amountCents": 0, "clientVisible": false, "description": "string", "dueOn": "string", "name": "string", "phasePublicId": "string", "position": 0, "requiresClientAcceptance": false}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "amountCents": 0, "clientVisible": False, "description": "string", "dueOn": "string", "name": "string", "phasePublicId": "string", "position": 0, "requiresClientAcceptance": False,}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "amountCents": 0, "clientVisible": false, "description": "string", "dueOn": "string", "name": "string", "phasePublicId": "string", "position": 0, "requiresClientAcceptance": false}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "amountCents": 0, "clientVisible": false, "description": "string", "dueOn": "string", "name": "string", "phasePublicId": "string", "position": 0, "requiresClientAcceptance": false }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "amountCents": 0, "clientVisible": false, "description": "string", "dueOn": "string", "name": "string", "phasePublicId": "string", "position": 0, "requiresClientAcceptance": false}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
msId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectMilestoneView | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
acceptance | MilestoneAcceptanceView | |
acceptance.consentTextrequired | string | |
acceptance.consentVersionrequired | integer | |
acceptance.iprequired | string | |
acceptance.signedAtrequired | string (date-time) | |
acceptance.signerNamerequired | string | |
acceptance.signerTitlerequired | string | |
acceptance.userAgentrequired | string | |
acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
acceptanceLink.activerequired | boolean | |
acceptanceLink.expiresAt | string (date-time) or null | |
acceptanceLink.viewCountrequired | integer | |
acceptanceSentAt | string (date-time) or null | |
acceptedAt | string (date-time) or null | |
amountCents | integer or null | int64. |
certificateAvailablerequired | boolean | |
clientVisiblerequired | boolean | |
completedAt | string (date-time) or null | |
declineReasonrequired | string | |
declinedAt | string (date-time) or null | |
descriptionrequired | string | |
dueOnrequired | string | |
invoicePublicId | string or null | |
invoicedAt | string (date-time) or null | |
namerequired | string | |
phaseName | string or null | |
phasePublicId | string or null | |
positionrequired | integer | |
publicIdrequired | string | |
requiresClientAcceptancerequired | boolean | |
statusrequired | string |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
msId | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
amountCents | integer or null | int64. |
clientVisible | boolean or null | |
description | string or null | |
dueOn | string or null | |
name | string or null | |
phasePublicId | string or null | |
position | integer or null | |
requiresClientAcceptance | boolean or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectMilestoneView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
acceptance | MilestoneAcceptanceView | |
acceptance.consentTextrequired | string | |
acceptance.consentVersionrequired | integer | |
acceptance.iprequired | string | |
acceptance.signedAtrequired | string (date-time) | |
acceptance.signerNamerequired | string | |
acceptance.signerTitlerequired | string | |
acceptance.userAgentrequired | string | |
acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
acceptanceLink.activerequired | boolean | |
acceptanceLink.expiresAt | string (date-time) or null | |
acceptanceLink.viewCountrequired | integer | |
acceptanceSentAt | string (date-time) or null | |
acceptedAt | string (date-time) or null | |
amountCents | integer or null | int64. |
certificateAvailablerequired | boolean | |
clientVisiblerequired | boolean | |
completedAt | string (date-time) or null | |
declineReasonrequired | string | |
declinedAt | string (date-time) or null | |
descriptionrequired | string | |
dueOnrequired | string | |
invoicePublicId | string or null | |
invoicedAt | string (date-time) or null | |
namerequired | string | |
phaseName | string or null | |
phasePublicId | string or null | |
positionrequired | integer | |
publicIdrequired | string | |
requiresClientAcceptancerequired | boolean | |
statusrequired | string |
Request samples
Section titled “Request samples”# 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}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "amountCents": 0, "clientVisible": false, "description": "string", "dueOn": "string", "name": "string", "phasePublicId": "string", "position": 0, "requiresClientAcceptance": false}'@
$response = Invoke-RestMethod ` -Method Patch ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "amountCents": 0, "clientVisible": False, "description": "string", "dueOn": "string", "name": "string", "phasePublicId": "string", "position": 0, "requiresClientAcceptance": False,}
response = requests.patch(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "amountCents": 0, "clientVisible": false, "description": "string", "dueOn": "string", "name": "string", "phasePublicId": "string", "position": 0, "requiresClientAcceptance": false}`)
req, err := http.NewRequest(http.MethodPatch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>";
const response = await fetch(url, { method: "PATCH", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "amountCents": 0, "clientVisible": false, "description": "string", "dueOn": "string", "name": "string", "phasePublicId": "string", "position": 0, "requiresClientAcceptance": false }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "amountCents": 0, "clientVisible": false, "description": "string", "dueOn": "string", "name": "string", "phasePublicId": "string", "position": 0, "requiresClientAcceptance": false}""";
var request = new HttpRequestMessage(HttpMethod.Patch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
msId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/acceptance-link
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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
msId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectLinkView | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
activerequired | boolean | |
expiresAt | string (date-time) or null | |
kindrequired | string | |
urlrequired | string | |
viewCountrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/acceptance-link' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/acceptance-link"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/acceptance-link", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/acceptance-link";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/acceptance-link");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
msId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectMilestoneView | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
acceptance | MilestoneAcceptanceView | |
acceptance.consentTextrequired | string | |
acceptance.consentVersionrequired | integer | |
acceptance.iprequired | string | |
acceptance.signedAtrequired | string (date-time) | |
acceptance.signerNamerequired | string | |
acceptance.signerTitlerequired | string | |
acceptance.userAgentrequired | string | |
acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
acceptanceLink.activerequired | boolean | |
acceptanceLink.expiresAt | string (date-time) or null | |
acceptanceLink.viewCountrequired | integer | |
acceptanceSentAt | string (date-time) or null | |
acceptedAt | string (date-time) or null | |
amountCents | integer or null | int64. |
certificateAvailablerequired | boolean | |
clientVisiblerequired | boolean | |
completedAt | string (date-time) or null | |
declineReasonrequired | string | |
declinedAt | string (date-time) or null | |
descriptionrequired | string | |
dueOnrequired | string | |
invoicePublicId | string or null | |
invoicedAt | string (date-time) or null | |
namerequired | string | |
phaseName | string or null | |
phasePublicId | string or null | |
positionrequired | integer | |
publicIdrequired | string | |
requiresClientAcceptancerequired | boolean | |
statusrequired | string |
Request samples
Section titled “Request samples”# 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>'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/cancel' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/cancel"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/cancel", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/cancel";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/cancel");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
msId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/octet-stream, string (binary) | Success. The body shape was not resolved; see x-outpost-unresolved. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/certificate' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/certificate"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/certificate", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/certificate";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/certificate");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
msId | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
The body is any.
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectMilestoneView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not acceptable. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | Completing a milestone without the client’s acceptance needs the project:manage permission. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
acceptance | MilestoneAcceptanceView | |
acceptance.consentTextrequired | string | |
acceptance.consentVersionrequired | integer | |
acceptance.iprequired | string | |
acceptance.signedAtrequired | string (date-time) | |
acceptance.signerNamerequired | string | |
acceptance.signerTitlerequired | string | |
acceptance.userAgentrequired | string | |
acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
acceptanceLink.activerequired | boolean | |
acceptanceLink.expiresAt | string (date-time) or null | |
acceptanceLink.viewCountrequired | integer | |
acceptanceSentAt | string (date-time) or null | |
acceptedAt | string (date-time) or null | |
amountCents | integer or null | int64. |
certificateAvailablerequired | boolean | |
clientVisiblerequired | boolean | |
completedAt | string (date-time) or null | |
declineReasonrequired | string | |
declinedAt | string (date-time) or null | |
descriptionrequired | string | |
dueOnrequired | string | |
invoicePublicId | string or null | |
invoicedAt | string (date-time) or null | |
namerequired | string | |
phaseName | string or null | |
phasePublicId | string or null | |
positionrequired | integer | |
publicIdrequired | string | |
requiresClientAcceptancerequired | boolean | |
statusrequired | string |
Request samples
Section titled “Request samples”# 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"'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'"string"'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/complete' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/complete"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = "string"
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`"string"`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/complete", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/complete";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify("string"),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """"string"""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/complete");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
msId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectMilestoneView | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
acceptance | MilestoneAcceptanceView | |
acceptance.consentTextrequired | string | |
acceptance.consentVersionrequired | integer | |
acceptance.iprequired | string | |
acceptance.signedAtrequired | string (date-time) | |
acceptance.signerNamerequired | string | |
acceptance.signerTitlerequired | string | |
acceptance.userAgentrequired | string | |
acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
acceptanceLink.activerequired | boolean | |
acceptanceLink.expiresAt | string (date-time) or null | |
acceptanceLink.viewCountrequired | integer | |
acceptanceSentAt | string (date-time) or null | |
acceptedAt | string (date-time) or null | |
amountCents | integer or null | int64. |
certificateAvailablerequired | boolean | |
clientVisiblerequired | boolean | |
completedAt | string (date-time) or null | |
declineReasonrequired | string | |
declinedAt | string (date-time) or null | |
descriptionrequired | string | |
dueOnrequired | string | |
invoicePublicId | string or null | |
invoicedAt | string (date-time) or null | |
namerequired | string | |
phaseName | string or null | |
phasePublicId | string or null | |
positionrequired | integer | |
publicIdrequired | string | |
requiresClientAcceptancerequired | boolean | |
statusrequired | string |
Request samples
Section titled “Request samples”# 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>'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/resend-acceptance' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/resend-acceptance"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/resend-acceptance", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/resend-acceptance";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/resend-acceptance");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/clients/{cid}/projects/{id}/milestones/{msId}/rotate-acceptance-link
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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
msId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectLinkView | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
activerequired | boolean | |
expiresAt | string (date-time) or null | |
kindrequired | string | |
urlrequired | string | |
viewCountrequired | integer |
Request samples
Section titled “Request samples”# 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>'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/rotate-acceptance-link' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/rotate-acceptance-link"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/rotate-acceptance-link", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/rotate-acceptance-link";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/milestones/<msId>/rotate-acceptance-link");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
task | query | string | No |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectNoteView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectNoteView | |
items[].authorName | string or null | |
items[].authorUserPublicId | string or null | |
items[].bodyrequired | string | |
items[].clientVisiblerequired | boolean | |
items[].createdAtrequired | string (date-time) | |
items[].publicIdrequired | string | |
items[].taskPublicId | string or null | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes?page=0&pageSize=0&task=<task>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes"params = { "page": "0", "pageSize": "0", "task": "<task>",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes?page=0&pageSize=0&task=<task>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");url.searchParams.set("task", "<task>");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes?page=0&pageSize=0&task=<task>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
bodyrequired | string | |
clientVisible | boolean or null | |
taskPublicIdrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ProjectNoteView | Created. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
authorName | string or null | |
authorUserPublicId | string or null | |
bodyrequired | string | |
clientVisiblerequired | boolean | |
createdAtrequired | string (date-time) | |
publicIdrequired | string | |
taskPublicId | string or null |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "body": "string", "clientVisible": false, "taskPublicId": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "body": "string", "clientVisible": False, "taskPublicId": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "body": "string", "clientVisible": false, "taskPublicId": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "body": "string", "clientVisible": false, "taskPublicId": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "body": "string", "clientVisible": false, "taskPublicId": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
noteId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes/<noteId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes/<noteId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes/<noteId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes/<noteId>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/notes/<noteId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectPhaseView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectPhaseView | |
items[].billableSecondsrequired | integer | |
items[].billingModeOverride | string or null | |
items[].budgetAmountCents | integer or null | int64. |
items[].budgetMinutes | integer or null | |
items[].completedAt | string (date-time) or null | |
items[].costCents | integer or null | int64. |
items[].loggedSecondsrequired | integer | |
items[].namerequired | string | |
items[].percentCompleterequired | integer | |
items[].plannedEndOn | string or null | |
items[].plannedStartOn | string or null | |
items[].positionrequired | integer | |
items[].prepaidLinePublicId | string or null | |
items[].publicIdrequired | string | |
items[].statusrequired | string | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
billingModeOverride | string or null | |
budgetAmountCents | integer or null | int64. |
budgetCriticalBp | integer or null | |
budgetMinutes | integer or null | |
budgetWarnBp | integer or null | |
name | string or null | |
position | integer or null | |
prepaidLinePublicId | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ProjectPhaseView | Created. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | Overriding a phase’s billing mode needs the project:manage permission. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
billableSecondsrequired | integer | |
billingModeOverride | string or null | |
budgetAmountCents | integer or null | int64. |
budgetMinutes | integer or null | |
completedAt | string (date-time) or null | |
costCents | integer or null | int64. |
loggedSecondsrequired | integer | |
namerequired | string | |
percentCompleterequired | integer | |
plannedEndOn | string or null | |
plannedStartOn | string or null | |
positionrequired | integer | |
prepaidLinePublicId | string or null | |
publicIdrequired | string | |
statusrequired | string |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "billingModeOverride": "string", "budgetAmountCents": 0, "budgetCriticalBp": 0, "budgetMinutes": 0, "budgetWarnBp": 0, "name": "string", "position": 0, "prepaidLinePublicId": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "billingModeOverride": "string", "budgetAmountCents": 0, "budgetCriticalBp": 0, "budgetMinutes": 0, "budgetWarnBp": 0, "name": "string", "position": 0, "prepaidLinePublicId": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "billingModeOverride": "string", "budgetAmountCents": 0, "budgetCriticalBp": 0, "budgetMinutes": 0, "budgetWarnBp": 0, "name": "string", "position": 0, "prepaidLinePublicId": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "billingModeOverride": "string", "budgetAmountCents": 0, "budgetCriticalBp": 0, "budgetMinutes": 0, "budgetWarnBp": 0, "name": "string", "position": 0, "prepaidLinePublicId": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "billingModeOverride": "string", "budgetAmountCents": 0, "budgetCriticalBp": 0, "budgetMinutes": 0, "budgetWarnBp": 0, "name": "string", "position": 0, "prepaidLinePublicId": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
phaseId | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
billingModeOverride | string or null | |
budgetAmountCents | integer or null | int64. |
budgetCriticalBp | integer or null | |
budgetMinutes | integer or null | |
budgetWarnBp | integer or null | |
name | string or null | |
position | integer or null | |
prepaidLinePublicId | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectPhaseView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | Overriding a phase’s billing mode needs the project:manage permission. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
billableSecondsrequired | integer | |
billingModeOverride | string or null | |
budgetAmountCents | integer or null | int64. |
budgetMinutes | integer or null | |
completedAt | string (date-time) or null | |
costCents | integer or null | int64. |
loggedSecondsrequired | integer | |
namerequired | string | |
percentCompleterequired | integer | |
plannedEndOn | string or null | |
plannedStartOn | string or null | |
positionrequired | integer | |
prepaidLinePublicId | string or null | |
publicIdrequired | string | |
statusrequired | string |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "billingModeOverride": "string", "budgetAmountCents": 0, "budgetCriticalBp": 0, "budgetMinutes": 0, "budgetWarnBp": 0, "name": "string", "position": 0, "prepaidLinePublicId": "string"}'@
$response = Invoke-RestMethod ` -Method Patch ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "billingModeOverride": "string", "budgetAmountCents": 0, "budgetCriticalBp": 0, "budgetMinutes": 0, "budgetWarnBp": 0, "name": "string", "position": 0, "prepaidLinePublicId": "string",}
response = requests.patch(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "billingModeOverride": "string", "budgetAmountCents": 0, "budgetCriticalBp": 0, "budgetMinutes": 0, "budgetWarnBp": 0, "name": "string", "position": 0, "prepaidLinePublicId": "string"}`)
req, err := http.NewRequest(http.MethodPatch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>";
const response = await fetch(url, { method: "PATCH", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "billingModeOverride": "string", "budgetAmountCents": 0, "budgetCriticalBp": 0, "budgetMinutes": 0, "budgetWarnBp": 0, "name": "string", "position": 0, "prepaidLinePublicId": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "billingModeOverride": "string", "budgetAmountCents": 0, "budgetCriticalBp": 0, "budgetMinutes": 0, "budgetWarnBp": 0, "name": "string", "position": 0, "prepaidLinePublicId": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Patch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
phaseId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/<phaseId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
publicIdsrequired | array of string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectPhaseView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectPhaseView | |
items[].billableSecondsrequired | integer | |
items[].billingModeOverride | string or null | |
items[].budgetAmountCents | integer or null | int64. |
items[].budgetMinutes | integer or null | |
items[].completedAt | string (date-time) or null | |
items[].costCents | integer or null | int64. |
items[].loggedSecondsrequired | integer | |
items[].namerequired | string | |
items[].percentCompleterequired | integer | |
items[].plannedEndOn | string or null | |
items[].plannedStartOn | string or null | |
items[].positionrequired | integer | |
items[].prepaidLinePublicId | string or null | |
items[].publicIdrequired | string | |
items[].statusrequired | string | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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" ]}'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "publicIds": [ "string" ]}'@
$response = Invoke-RestMethod ` -Method Put ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/order' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/order"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "publicIds": [ "string", ],}
response = requests.put(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "publicIds": [ "string" ]}`)
req, err := http.NewRequest(http.MethodPut, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/order", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/order";
const response = await fetch(url, { method: "PUT", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "publicIds": [ "string" ] }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "publicIds": [ "string" ]}""";
var request = new HttpRequestMessage(HttpMethod.Put, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/phases/order");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, RetrospectiveView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
canUpdateTemplaterequired | boolean | |
notesrequired | string | |
rowsrequired | array of RetrospectiveRowView | |
rows[].estimateMinutesrequired | integer | |
rows[].loggedSecondsrequired | integer | |
rows[].taskPublicIdrequired | string | |
rows[].templateTaskPublicIdrequired | string | |
rows[].titlerequired | string | |
suggestionsrequired | array of RetrospectiveSuggestionView | |
suggestions[].currentMinutesrequired | integer | |
suggestions[].suggestedMinutesrequired | integer | |
suggestions[].templateTaskPublicIdrequired | string | |
suggestions[].titlerequired | string | |
templateNamerequired | string |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/retrospective' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/retrospective"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/retrospective", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/retrospective";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/retrospective");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectScheduleView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
criticalPathrequired | array of string | |
dependenciesrequired | array of ScheduleDependencyView | |
dependencies[].lagDaysrequired | integer | |
dependencies[].predecessorTaskPublicIdrequired | string | |
dependencies[].taskPublicIdrequired | string | |
generatedAtrequired | string (date-time) | |
plannedEndOn | string or null | |
plannedStartOn | string or null | |
slackDaysrequired | object | |
tasksrequired | array of ProjectTaskView | |
tasks[].actualStartOn | string or null | |
tasks[].assigneeName | string or null | |
tasks[].assigneeUserPublicId | string or null | |
tasks[].atRiskrequired | boolean | |
tasks[].atRiskReasonrequired | string | |
tasks[].billableSecondsrequired | integer | |
tasks[].blockedReasonrequired | string | |
tasks[].checklistrequired | array of ChecklistItemView | |
tasks[].checklist[].donerequired | boolean | |
tasks[].checklist[].doneAt | string (date-time) or null | |
tasks[].checklist[].positionrequired | integer | |
tasks[].checklist[].publicIdrequired | string | |
tasks[].checklist[].textrequired | string | |
tasks[].clientVisiblerequired | boolean | |
tasks[].completedAt | string (date-time) or null | |
tasks[].costCents | integer or null | int64. |
tasks[].descriptionrequired | string | |
tasks[].durationDaysrequired | integer | |
tasks[].estimateMinutesrequired | integer | |
tasks[].loggedSecondsrequired | integer | |
tasks[].onCriticalPathrequired | boolean | |
tasks[].parentTaskPublicId | string or null | |
tasks[].phasePublicId | string or null | |
tasks[].plannedDueOn | string or null | |
tasks[].plannedStartOn | string or null | |
tasks[].positionrequired | integer | |
tasks[].predecessorsrequired | array of TaskDependencyView | |
tasks[].predecessors[].lagDaysrequired | integer | |
tasks[].predecessors[].taskPublicIdrequired | string | |
tasks[].priorityrequired | string | |
tasks[].projectPublicIdrequired | string | |
tasks[].publicIdrequired | string | |
tasks[].rolePlaceholderrequired | string | |
tasks[].spawnedTicketPublicId | string or null | |
tasks[].statusrequired | string | |
tasks[].subtasks | array of ProjectTaskView | |
tasks[].subtasks[].actualStartOn | string or null | |
tasks[].subtasks[].assigneeName | string or null | |
tasks[].subtasks[].assigneeUserPublicId | string or null | |
tasks[].subtasks[].atRiskrequired | boolean | |
tasks[].subtasks[].atRiskReasonrequired | string | |
tasks[].subtasks[].billableSecondsrequired | integer | |
tasks[].subtasks[].blockedReasonrequired | string | |
tasks[].subtasks[].checklistrequired | array of ChecklistItemView | |
tasks[].subtasks[].checklist[].donerequired | boolean | |
tasks[].subtasks[].checklist[].doneAt | string (date-time) or null | |
tasks[].subtasks[].checklist[].positionrequired | integer | |
tasks[].subtasks[].checklist[].publicIdrequired | string | |
tasks[].subtasks[].checklist[].textrequired | string | |
tasks[].subtasks[].clientVisiblerequired | boolean | |
tasks[].subtasks[].completedAt | string (date-time) or null | |
tasks[].subtasks[].costCents | integer or null | int64. |
tasks[].subtasks[].descriptionrequired | string | |
tasks[].subtasks[].durationDaysrequired | integer | |
tasks[].subtasks[].estimateMinutesrequired | integer | |
tasks[].subtasks[].loggedSecondsrequired | integer | |
tasks[].subtasks[].onCriticalPathrequired | boolean | |
tasks[].subtasks[].parentTaskPublicId | string or null | |
tasks[].subtasks[].phasePublicId | string or null | |
tasks[].subtasks[].plannedDueOn | string or null | |
tasks[].subtasks[].plannedStartOn | string or null | |
tasks[].subtasks[].positionrequired | integer | |
tasks[].subtasks[].predecessorsrequired | array of TaskDependencyView | |
tasks[].subtasks[].predecessors[].lagDaysrequired | integer | |
tasks[].subtasks[].predecessors[].taskPublicIdrequired | string | |
tasks[].subtasks[].priorityrequired | string | |
tasks[].subtasks[].projectPublicIdrequired | string | |
tasks[].subtasks[].publicIdrequired | string | |
tasks[].subtasks[].rolePlaceholderrequired | string | |
tasks[].subtasks[].spawnedTicketPublicId | string or null | |
tasks[].subtasks[].statusrequired | string | |
tasks[].subtasks[].subtasks | array of ProjectTaskView | |
tasks[].subtasks[].titlerequired | string | |
tasks[].subtasks[].updatedAtrequired | string (date-time) | |
tasks[].subtasks[].watchersrequired | array of TaskWatcherView | |
tasks[].subtasks[].watchers[].displayNamerequired | string | |
tasks[].subtasks[].watchers[].userPublicIdrequired | string | |
tasks[].subtasks[].watchingrequired | boolean | |
tasks[].titlerequired | string | |
tasks[].updatedAtrequired | string (date-time) | |
tasks[].watchersrequired | array of TaskWatcherView | |
tasks[].watchers[].displayNamerequired | string | |
tasks[].watchers[].userPublicIdrequired | string | |
tasks[].watchingrequired | boolean |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
expectedGeneratedAtrequired | string (date-time) | |
movesrequired | array of ScheduleMove | |
moves[].plannedDueOnrequired | string | |
moves[].plannedStartOnrequired | string | |
moves[].taskPublicIdrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectScheduleView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
criticalPathrequired | array of string | |
dependenciesrequired | array of ScheduleDependencyView | |
dependencies[].lagDaysrequired | integer | |
dependencies[].predecessorTaskPublicIdrequired | string | |
dependencies[].taskPublicIdrequired | string | |
generatedAtrequired | string (date-time) | |
plannedEndOn | string or null | |
plannedStartOn | string or null | |
slackDaysrequired | object | |
tasksrequired | array of ProjectTaskView | |
tasks[].actualStartOn | string or null | |
tasks[].assigneeName | string or null | |
tasks[].assigneeUserPublicId | string or null | |
tasks[].atRiskrequired | boolean | |
tasks[].atRiskReasonrequired | string | |
tasks[].billableSecondsrequired | integer | |
tasks[].blockedReasonrequired | string | |
tasks[].checklistrequired | array of ChecklistItemView | |
tasks[].checklist[].donerequired | boolean | |
tasks[].checklist[].doneAt | string (date-time) or null | |
tasks[].checklist[].positionrequired | integer | |
tasks[].checklist[].publicIdrequired | string | |
tasks[].checklist[].textrequired | string | |
tasks[].clientVisiblerequired | boolean | |
tasks[].completedAt | string (date-time) or null | |
tasks[].costCents | integer or null | int64. |
tasks[].descriptionrequired | string | |
tasks[].durationDaysrequired | integer | |
tasks[].estimateMinutesrequired | integer | |
tasks[].loggedSecondsrequired | integer | |
tasks[].onCriticalPathrequired | boolean | |
tasks[].parentTaskPublicId | string or null | |
tasks[].phasePublicId | string or null | |
tasks[].plannedDueOn | string or null | |
tasks[].plannedStartOn | string or null | |
tasks[].positionrequired | integer | |
tasks[].predecessorsrequired | array of TaskDependencyView | |
tasks[].predecessors[].lagDaysrequired | integer | |
tasks[].predecessors[].taskPublicIdrequired | string | |
tasks[].priorityrequired | string | |
tasks[].projectPublicIdrequired | string | |
tasks[].publicIdrequired | string | |
tasks[].rolePlaceholderrequired | string | |
tasks[].spawnedTicketPublicId | string or null | |
tasks[].statusrequired | string | |
tasks[].subtasks | array of ProjectTaskView | |
tasks[].subtasks[].actualStartOn | string or null | |
tasks[].subtasks[].assigneeName | string or null | |
tasks[].subtasks[].assigneeUserPublicId | string or null | |
tasks[].subtasks[].atRiskrequired | boolean | |
tasks[].subtasks[].atRiskReasonrequired | string | |
tasks[].subtasks[].billableSecondsrequired | integer | |
tasks[].subtasks[].blockedReasonrequired | string | |
tasks[].subtasks[].checklistrequired | array of ChecklistItemView | |
tasks[].subtasks[].checklist[].donerequired | boolean | |
tasks[].subtasks[].checklist[].doneAt | string (date-time) or null | |
tasks[].subtasks[].checklist[].positionrequired | integer | |
tasks[].subtasks[].checklist[].publicIdrequired | string | |
tasks[].subtasks[].checklist[].textrequired | string | |
tasks[].subtasks[].clientVisiblerequired | boolean | |
tasks[].subtasks[].completedAt | string (date-time) or null | |
tasks[].subtasks[].costCents | integer or null | int64. |
tasks[].subtasks[].descriptionrequired | string | |
tasks[].subtasks[].durationDaysrequired | integer | |
tasks[].subtasks[].estimateMinutesrequired | integer | |
tasks[].subtasks[].loggedSecondsrequired | integer | |
tasks[].subtasks[].onCriticalPathrequired | boolean | |
tasks[].subtasks[].parentTaskPublicId | string or null | |
tasks[].subtasks[].phasePublicId | string or null | |
tasks[].subtasks[].plannedDueOn | string or null | |
tasks[].subtasks[].plannedStartOn | string or null | |
tasks[].subtasks[].positionrequired | integer | |
tasks[].subtasks[].predecessorsrequired | array of TaskDependencyView | |
tasks[].subtasks[].predecessors[].lagDaysrequired | integer | |
tasks[].subtasks[].predecessors[].taskPublicIdrequired | string | |
tasks[].subtasks[].priorityrequired | string | |
tasks[].subtasks[].projectPublicIdrequired | string | |
tasks[].subtasks[].publicIdrequired | string | |
tasks[].subtasks[].rolePlaceholderrequired | string | |
tasks[].subtasks[].spawnedTicketPublicId | string or null | |
tasks[].subtasks[].statusrequired | string | |
tasks[].subtasks[].subtasks | array of ProjectTaskView | |
tasks[].subtasks[].titlerequired | string | |
tasks[].subtasks[].updatedAtrequired | string (date-time) | |
tasks[].subtasks[].watchersrequired | array of TaskWatcherView | |
tasks[].subtasks[].watchers[].displayNamerequired | string | |
tasks[].subtasks[].watchers[].userPublicIdrequired | string | |
tasks[].subtasks[].watchingrequired | boolean | |
tasks[].titlerequired | string | |
tasks[].updatedAtrequired | string (date-time) | |
tasks[].watchersrequired | array of TaskWatcherView | |
tasks[].watchers[].displayNamerequired | string | |
tasks[].watchers[].userPublicIdrequired | string | |
tasks[].watchingrequired | boolean |
Request samples
Section titled “Request samples”# 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" } ]}'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "expectedGeneratedAt": "2026-01-01T00:00:00Z", "moves": [ { "plannedDueOn": "string", "plannedStartOn": "string", "taskPublicId": "string" } ]}'@
$response = Invoke-RestMethod ` -Method Put ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule/shift' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule/shift"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "expectedGeneratedAt": "2026-01-01T00:00:00Z", "moves": [ { "plannedDueOn": "string", "plannedStartOn": "string", "taskPublicId": "string", }, ],}
response = requests.put(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "expectedGeneratedAt": "2026-01-01T00:00:00Z", "moves": [ { "plannedDueOn": "string", "plannedStartOn": "string", "taskPublicId": "string" } ]}`)
req, err := http.NewRequest(http.MethodPut, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule/shift", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule/shift";
const response = await fetch(url, { method: "PUT", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "expectedGeneratedAt": "2026-01-01T00:00:00Z", "moves": [ { "plannedDueOn": "string", "plannedStartOn": "string", "taskPublicId": "string" } ] }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "expectedGeneratedAt": "2026-01-01T00:00:00Z", "moves": [ { "plannedDueOn": "string", "plannedStartOn": "string", "taskPublicId": "string" } ]}""";
var request = new HttpRequestMessage(HttpMethod.Put, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/schedule/shift");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
forcerequired | boolean | |
statusrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | Completing or canceling a project needs the project:manage permission. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
actualStartOn | string or null | |
agreementPublicId | string or null | |
amountBurnBprequired | integer | |
atRiskTasksrequired | integer | |
billableSecondsrequired | integer | |
billingModerequired | string | |
budgetAmountCentsrequired | integer | int64. |
budgetCriticalBp | integer or null | |
budgetMinutesrequired | integer | |
budgetWarnBp | integer or null | |
cancelledAt | string (date-time) or null | |
clientContactEmailrequired | string | |
clientContactNamerequired | string | |
clientNamerequired | string | |
clientPublicIdrequired | string | |
completedAt | string (date-time) or null | |
convertedFromTicketPublicId | string or null | |
costCents | integer or null | int64. |
createdAtrequired | string (date-time) | |
descriptionrequired | string | |
fixedPriceCentsrequired | integer | int64. |
healthrequired | string | |
healthComputedAt | string (date-time) or null | |
healthReasonrequired | string | |
hoursBurnBprequired | integer | |
isSelfrequired | boolean | |
lastStatusEmailOn | string or null | |
loggedSecondsrequired | integer | |
managerName | string or null | |
managerUserPublicId | string or null | |
milestonesrequired | array of ProjectMilestoneView | |
milestones[].acceptance | MilestoneAcceptanceView | |
milestones[].acceptance.consentTextrequired | string | |
milestones[].acceptance.consentVersionrequired | integer | |
milestones[].acceptance.iprequired | string | |
milestones[].acceptance.signedAtrequired | string (date-time) | |
milestones[].acceptance.signerNamerequired | string | |
milestones[].acceptance.signerTitlerequired | string | |
milestones[].acceptance.userAgentrequired | string | |
milestones[].acceptanceLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
milestones[].acceptanceLink.activerequired | boolean | |
milestones[].acceptanceLink.expiresAt | string (date-time) or null | |
milestones[].acceptanceLink.viewCountrequired | integer | |
milestones[].acceptanceSentAt | string (date-time) or null | |
milestones[].acceptedAt | string (date-time) or null | |
milestones[].amountCents | integer or null | int64. |
milestones[].certificateAvailablerequired | boolean | |
milestones[].clientVisiblerequired | boolean | |
milestones[].completedAt | string (date-time) or null | |
milestones[].declineReasonrequired | string | |
milestones[].declinedAt | string (date-time) or null | |
milestones[].descriptionrequired | string | |
milestones[].dueOnrequired | string | |
milestones[].invoicePublicId | string or null | |
milestones[].invoicedAt | string (date-time) or null | |
milestones[].namerequired | string | |
milestones[].phaseName | string or null | |
milestones[].phasePublicId | string or null | |
milestones[].positionrequired | integer | |
milestones[].publicIdrequired | string | |
milestones[].requiresClientAcceptancerequired | boolean | |
milestones[].statusrequired | string | |
namerequired | string | |
nextMilestone | NextMilestoneView | |
nextMilestone.dueOnrequired | string | |
nextMilestone.namerequired | string | |
nextMilestone.publicIdrequired | string | |
notesrequired | string | |
numberrequired | integer | int64. |
openTasksrequired | integer | |
overdueMilestonesrequired | integer | |
percentCompleterequired | integer | |
phasesrequired | array of ProjectPhaseView | |
phases[].billableSecondsrequired | integer | |
phases[].billingModeOverride | string or null | |
phases[].budgetAmountCents | integer or null | int64. |
phases[].budgetMinutes | integer or null | |
phases[].completedAt | string (date-time) or null | |
phases[].costCents | integer or null | int64. |
phases[].loggedSecondsrequired | integer | |
phases[].namerequired | string | |
phases[].percentCompleterequired | integer | |
phases[].plannedEndOn | string or null | |
phases[].plannedStartOn | string or null | |
phases[].positionrequired | integer | |
phases[].prepaidLinePublicId | string or null | |
phases[].publicIdrequired | string | |
phases[].statusrequired | string | |
plannedEndOn | string or null | |
plannedStartOnrequired | string | |
prepaidLinePublicId | string or null | |
publicIdrequired | string | |
quotePublicId | string or null | |
referencerequired | string | |
retrospectiverequired | any | |
skipWeekendsrequired | boolean | |
statusrequired | string | |
statusEmailCadencerequired | string | |
statusEmailWeekdayrequired | integer | |
statusLink | PublicLinkRefView | publicLinkRefView is what a project or milestone says about its link: that one exists, and when it stops working. |
statusLink.activerequired | boolean | |
statusLink.expiresAt | string (date-time) or null | |
statusLink.viewCountrequired | integer | |
templatePublicId | string or null | |
templateVersion | integer or null | |
ticketLinksrequired | array of ProjectTicketLinkView | |
ticketLinks[].createdAtrequired | string (date-time) | |
ticketLinks[].kindrequired | string | |
ticketLinks[].publicIdrequired | string | |
ticketLinks[].taskPublicId | string or null | |
ticketLinks[].ticketPublicIdrequired | string | |
ticketLinks[].ticketReferencerequired | string | |
ticketLinks[].ticketSubjectrequired | string | |
updatedAtrequired | string (date-time) |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "force": false, "status": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "force": False, "status": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "force": false, "status": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "force": false, "status": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "force": false, "status": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
202 | None | Accepted. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
Request samples
Section titled “Request samples”# 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>'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-email/send-now' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-email/send-now"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-email/send-now", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-email/send-now";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-email/send-now");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/clients/{cid}/projects/{id}/status-link
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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectLinkView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
activerequired | boolean | |
expiresAt | string (date-time) or null | |
kindrequired | string | |
urlrequired | string | |
viewCountrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/clients/{cid}/projects/{id}/status-link
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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ProjectLinkView | Created. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
activerequired | boolean | |
expiresAt | string (date-time) or null | |
kindrequired | string | |
urlrequired | string | |
viewCountrequired | integer |
Request samples
Section titled “Request samples”# 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>'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());DELETE /api/v1/clients/{cid}/projects/{id}/status-link
Section titled “DELETE /api/v1/clients/{cid}/projects/{id}/status-link”DELETEproject:managemsp facemspIdempotent
Source: [object Object]
Revoke status link
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/clients/{cid}/projects/{id}/status-link/rotate
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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ProjectLinkView | Created. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
201 response body
| Field | Type | Description |
|---|---|---|
activerequired | boolean | |
expiresAt | string (date-time) or null | |
kindrequired | string | |
urlrequired | string | |
viewCountrequired | integer |
Request samples
Section titled “Request samples”# 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>'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link/rotate' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link/rotate"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link/rotate", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link/rotate";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/status-link/rotate");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
assignee | query | string | No | |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
phase | query | string | No | |
status | query | string, one of blocked, cancelled, done, in_progress, todo | No | Comma-separated set. An unrecognised value is refused. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectTaskView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectTaskView | |
items[].actualStartOn | string or null | |
items[].assigneeName | string or null | |
items[].assigneeUserPublicId | string or null | |
items[].atRiskrequired | boolean | |
items[].atRiskReasonrequired | string | |
items[].billableSecondsrequired | integer | |
items[].blockedReasonrequired | string | |
items[].checklistrequired | array of ChecklistItemView | |
items[].checklist[].donerequired | boolean | |
items[].checklist[].doneAt | string (date-time) or null | |
items[].checklist[].positionrequired | integer | |
items[].checklist[].publicIdrequired | string | |
items[].checklist[].textrequired | string | |
items[].clientVisiblerequired | boolean | |
items[].completedAt | string (date-time) or null | |
items[].costCents | integer or null | int64. |
items[].descriptionrequired | string | |
items[].durationDaysrequired | integer | |
items[].estimateMinutesrequired | integer | |
items[].loggedSecondsrequired | integer | |
items[].onCriticalPathrequired | boolean | |
items[].parentTaskPublicId | string or null | |
items[].phasePublicId | string or null | |
items[].plannedDueOn | string or null | |
items[].plannedStartOn | string or null | |
items[].positionrequired | integer | |
items[].predecessorsrequired | array of TaskDependencyView | |
items[].predecessors[].lagDaysrequired | integer | |
items[].predecessors[].taskPublicIdrequired | string | |
items[].priorityrequired | string | |
items[].projectPublicIdrequired | string | |
items[].publicIdrequired | string | |
items[].rolePlaceholderrequired | string | |
items[].spawnedTicketPublicId | string or null | |
items[].statusrequired | string | |
items[].subtasks | array of ProjectTaskView | |
items[].subtasks[].actualStartOn | string or null | |
items[].subtasks[].assigneeName | string or null | |
items[].subtasks[].assigneeUserPublicId | string or null | |
items[].subtasks[].atRiskrequired | boolean | |
items[].subtasks[].atRiskReasonrequired | string | |
items[].subtasks[].billableSecondsrequired | integer | |
items[].subtasks[].blockedReasonrequired | string | |
items[].subtasks[].checklistrequired | array of ChecklistItemView | |
items[].subtasks[].checklist[].donerequired | boolean | |
items[].subtasks[].checklist[].doneAt | string (date-time) or null | |
items[].subtasks[].checklist[].positionrequired | integer | |
items[].subtasks[].checklist[].publicIdrequired | string | |
items[].subtasks[].checklist[].textrequired | string | |
items[].subtasks[].clientVisiblerequired | boolean | |
items[].subtasks[].completedAt | string (date-time) or null | |
items[].subtasks[].costCents | integer or null | int64. |
items[].subtasks[].descriptionrequired | string | |
items[].subtasks[].durationDaysrequired | integer | |
items[].subtasks[].estimateMinutesrequired | integer | |
items[].subtasks[].loggedSecondsrequired | integer | |
items[].subtasks[].onCriticalPathrequired | boolean | |
items[].subtasks[].parentTaskPublicId | string or null | |
items[].subtasks[].phasePublicId | string or null | |
items[].subtasks[].plannedDueOn | string or null | |
items[].subtasks[].plannedStartOn | string or null | |
items[].subtasks[].positionrequired | integer | |
items[].subtasks[].predecessorsrequired | array of TaskDependencyView | |
items[].subtasks[].predecessors[].lagDaysrequired | integer | |
items[].subtasks[].predecessors[].taskPublicIdrequired | string | |
items[].subtasks[].priorityrequired | string | |
items[].subtasks[].projectPublicIdrequired | string | |
items[].subtasks[].publicIdrequired | string | |
items[].subtasks[].rolePlaceholderrequired | string | |
items[].subtasks[].spawnedTicketPublicId | string or null | |
items[].subtasks[].statusrequired | string | |
items[].subtasks[].subtasks | array of ProjectTaskView | |
items[].subtasks[].titlerequired | string | |
items[].subtasks[].updatedAtrequired | string (date-time) | |
items[].subtasks[].watchersrequired | array of TaskWatcherView | |
items[].subtasks[].watchers[].displayNamerequired | string | |
items[].subtasks[].watchers[].userPublicIdrequired | string | |
items[].subtasks[].watchingrequired | boolean | |
items[].titlerequired | string | |
items[].updatedAtrequired | string (date-time) | |
items[].watchersrequired | array of TaskWatcherView | |
items[].watchers[].displayNamerequired | string | |
items[].watchers[].userPublicIdrequired | string | |
items[].watchingrequired | boolean | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks?assignee=<assignee>&page=0&pageSize=0&phase=<phase>&status=blocked' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks"params = { "assignee": "<assignee>", "page": "0", "pageSize": "0", "phase": "<phase>", "status": "blocked",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks?assignee=<assignee>&page=0&pageSize=0&phase=<phase>&status=blocked", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks");url.searchParams.set("assignee", "<assignee>");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");url.searchParams.set("phase", "<phase>");url.searchParams.set("status", "blocked");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks?assignee=<assignee>&page=0&pageSize=0&phase=<phase>&status=blocked");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
assigneeUserPublicId | string or null | |
blockedReason | string or null | |
clientVisible | boolean or null | |
description | string or null | |
durationDays | integer or null | |
estimateMinutes | integer or null | |
parentTaskPublicId | string or null | |
phasePublicId | string or null | |
plannedDueOn | string or null | |
plannedStartOn | string or null | |
position | integer or null | |
priority | string or null | |
rolePlaceholder | string or null | |
status | string or null | |
title | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ProjectTaskView | Created. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
actualStartOn | string or null | |
assigneeName | string or null | |
assigneeUserPublicId | string or null | |
atRiskrequired | boolean | |
atRiskReasonrequired | string | |
billableSecondsrequired | integer | |
blockedReasonrequired | string | |
checklistrequired | array of ChecklistItemView | |
checklist[].donerequired | boolean | |
checklist[].doneAt | string (date-time) or null | |
checklist[].positionrequired | integer | |
checklist[].publicIdrequired | string | |
checklist[].textrequired | string | |
clientVisiblerequired | boolean | |
completedAt | string (date-time) or null | |
costCents | integer or null | int64. |
descriptionrequired | string | |
durationDaysrequired | integer | |
estimateMinutesrequired | integer | |
loggedSecondsrequired | integer | |
onCriticalPathrequired | boolean | |
parentTaskPublicId | string or null | |
phasePublicId | string or null | |
plannedDueOn | string or null | |
plannedStartOn | string or null | |
positionrequired | integer | |
predecessorsrequired | array of TaskDependencyView | |
predecessors[].lagDaysrequired | integer | |
predecessors[].taskPublicIdrequired | string | |
priorityrequired | string | |
projectPublicIdrequired | string | |
publicIdrequired | string | |
rolePlaceholderrequired | string | |
spawnedTicketPublicId | string or null | |
statusrequired | string | |
subtasks | array of ProjectTaskView | |
subtasks[].actualStartOn | string or null | |
subtasks[].assigneeName | string or null | |
subtasks[].assigneeUserPublicId | string or null | |
subtasks[].atRiskrequired | boolean | |
subtasks[].atRiskReasonrequired | string | |
subtasks[].billableSecondsrequired | integer | |
subtasks[].blockedReasonrequired | string | |
subtasks[].checklistrequired | array of ChecklistItemView | |
subtasks[].checklist[].donerequired | boolean | |
subtasks[].checklist[].doneAt | string (date-time) or null | |
subtasks[].checklist[].positionrequired | integer | |
subtasks[].checklist[].publicIdrequired | string | |
subtasks[].checklist[].textrequired | string | |
subtasks[].clientVisiblerequired | boolean | |
subtasks[].completedAt | string (date-time) or null | |
subtasks[].costCents | integer or null | int64. |
subtasks[].descriptionrequired | string | |
subtasks[].durationDaysrequired | integer | |
subtasks[].estimateMinutesrequired | integer | |
subtasks[].loggedSecondsrequired | integer | |
subtasks[].onCriticalPathrequired | boolean | |
subtasks[].parentTaskPublicId | string or null | |
subtasks[].phasePublicId | string or null | |
subtasks[].plannedDueOn | string or null | |
subtasks[].plannedStartOn | string or null | |
subtasks[].positionrequired | integer | |
subtasks[].predecessorsrequired | array of TaskDependencyView | |
subtasks[].predecessors[].lagDaysrequired | integer | |
subtasks[].predecessors[].taskPublicIdrequired | string | |
subtasks[].priorityrequired | string | |
subtasks[].projectPublicIdrequired | string | |
subtasks[].publicIdrequired | string | |
subtasks[].rolePlaceholderrequired | string | |
subtasks[].spawnedTicketPublicId | string or null | |
subtasks[].statusrequired | string | |
subtasks[].subtasks | array of ProjectTaskView | |
subtasks[].titlerequired | string | |
subtasks[].updatedAtrequired | string (date-time) | |
subtasks[].watchersrequired | array of TaskWatcherView | |
subtasks[].watchers[].displayNamerequired | string | |
subtasks[].watchers[].userPublicIdrequired | string | |
subtasks[].watchingrequired | boolean | |
titlerequired | string | |
updatedAtrequired | string (date-time) | |
watchersrequired | array of TaskWatcherView | |
watchers[].displayNamerequired | string | |
watchers[].userPublicIdrequired | string | |
watchingrequired | boolean |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "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"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "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",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "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"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "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" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "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"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectTaskView | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
actualStartOn | string or null | |
assigneeName | string or null | |
assigneeUserPublicId | string or null | |
atRiskrequired | boolean | |
atRiskReasonrequired | string | |
billableSecondsrequired | integer | |
blockedReasonrequired | string | |
checklistrequired | array of ChecklistItemView | |
checklist[].donerequired | boolean | |
checklist[].doneAt | string (date-time) or null | |
checklist[].positionrequired | integer | |
checklist[].publicIdrequired | string | |
checklist[].textrequired | string | |
clientVisiblerequired | boolean | |
completedAt | string (date-time) or null | |
costCents | integer or null | int64. |
descriptionrequired | string | |
durationDaysrequired | integer | |
estimateMinutesrequired | integer | |
loggedSecondsrequired | integer | |
onCriticalPathrequired | boolean | |
parentTaskPublicId | string or null | |
phasePublicId | string or null | |
plannedDueOn | string or null | |
plannedStartOn | string or null | |
positionrequired | integer | |
predecessorsrequired | array of TaskDependencyView | |
predecessors[].lagDaysrequired | integer | |
predecessors[].taskPublicIdrequired | string | |
priorityrequired | string | |
projectPublicIdrequired | string | |
publicIdrequired | string | |
rolePlaceholderrequired | string | |
spawnedTicketPublicId | string or null | |
statusrequired | string | |
subtasks | array of ProjectTaskView | |
subtasks[].actualStartOn | string or null | |
subtasks[].assigneeName | string or null | |
subtasks[].assigneeUserPublicId | string or null | |
subtasks[].atRiskrequired | boolean | |
subtasks[].atRiskReasonrequired | string | |
subtasks[].billableSecondsrequired | integer | |
subtasks[].blockedReasonrequired | string | |
subtasks[].checklistrequired | array of ChecklistItemView | |
subtasks[].checklist[].donerequired | boolean | |
subtasks[].checklist[].doneAt | string (date-time) or null | |
subtasks[].checklist[].positionrequired | integer | |
subtasks[].checklist[].publicIdrequired | string | |
subtasks[].checklist[].textrequired | string | |
subtasks[].clientVisiblerequired | boolean | |
subtasks[].completedAt | string (date-time) or null | |
subtasks[].costCents | integer or null | int64. |
subtasks[].descriptionrequired | string | |
subtasks[].durationDaysrequired | integer | |
subtasks[].estimateMinutesrequired | integer | |
subtasks[].loggedSecondsrequired | integer | |
subtasks[].onCriticalPathrequired | boolean | |
subtasks[].parentTaskPublicId | string or null | |
subtasks[].phasePublicId | string or null | |
subtasks[].plannedDueOn | string or null | |
subtasks[].plannedStartOn | string or null | |
subtasks[].positionrequired | integer | |
subtasks[].predecessorsrequired | array of TaskDependencyView | |
subtasks[].predecessors[].lagDaysrequired | integer | |
subtasks[].predecessors[].taskPublicIdrequired | string | |
subtasks[].priorityrequired | string | |
subtasks[].projectPublicIdrequired | string | |
subtasks[].publicIdrequired | string | |
subtasks[].rolePlaceholderrequired | string | |
subtasks[].spawnedTicketPublicId | string or null | |
subtasks[].statusrequired | string | |
subtasks[].subtasks | array of ProjectTaskView | |
subtasks[].titlerequired | string | |
subtasks[].updatedAtrequired | string (date-time) | |
subtasks[].watchersrequired | array of TaskWatcherView | |
subtasks[].watchers[].displayNamerequired | string | |
subtasks[].watchers[].userPublicIdrequired | string | |
subtasks[].watchingrequired | boolean | |
titlerequired | string | |
updatedAtrequired | string (date-time) | |
watchersrequired | array of TaskWatcherView | |
watchers[].displayNamerequired | string | |
watchers[].userPublicIdrequired | string | |
watchingrequired | boolean |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
assigneeUserPublicId | string or null | |
blockedReason | string or null | |
clientVisible | boolean or null | |
description | string or null | |
durationDays | integer or null | |
estimateMinutes | integer or null | |
parentTaskPublicId | string or null | |
phasePublicId | string or null | |
plannedDueOn | string or null | |
plannedStartOn | string or null | |
position | integer or null | |
priority | string or null | |
rolePlaceholder | string or null | |
status | string or null | |
title | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectTaskView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
actualStartOn | string or null | |
assigneeName | string or null | |
assigneeUserPublicId | string or null | |
atRiskrequired | boolean | |
atRiskReasonrequired | string | |
billableSecondsrequired | integer | |
blockedReasonrequired | string | |
checklistrequired | array of ChecklistItemView | |
checklist[].donerequired | boolean | |
checklist[].doneAt | string (date-time) or null | |
checklist[].positionrequired | integer | |
checklist[].publicIdrequired | string | |
checklist[].textrequired | string | |
clientVisiblerequired | boolean | |
completedAt | string (date-time) or null | |
costCents | integer or null | int64. |
descriptionrequired | string | |
durationDaysrequired | integer | |
estimateMinutesrequired | integer | |
loggedSecondsrequired | integer | |
onCriticalPathrequired | boolean | |
parentTaskPublicId | string or null | |
phasePublicId | string or null | |
plannedDueOn | string or null | |
plannedStartOn | string or null | |
positionrequired | integer | |
predecessorsrequired | array of TaskDependencyView | |
predecessors[].lagDaysrequired | integer | |
predecessors[].taskPublicIdrequired | string | |
priorityrequired | string | |
projectPublicIdrequired | string | |
publicIdrequired | string | |
rolePlaceholderrequired | string | |
spawnedTicketPublicId | string or null | |
statusrequired | string | |
subtasks | array of ProjectTaskView | |
subtasks[].actualStartOn | string or null | |
subtasks[].assigneeName | string or null | |
subtasks[].assigneeUserPublicId | string or null | |
subtasks[].atRiskrequired | boolean | |
subtasks[].atRiskReasonrequired | string | |
subtasks[].billableSecondsrequired | integer | |
subtasks[].blockedReasonrequired | string | |
subtasks[].checklistrequired | array of ChecklistItemView | |
subtasks[].checklist[].donerequired | boolean | |
subtasks[].checklist[].doneAt | string (date-time) or null | |
subtasks[].checklist[].positionrequired | integer | |
subtasks[].checklist[].publicIdrequired | string | |
subtasks[].checklist[].textrequired | string | |
subtasks[].clientVisiblerequired | boolean | |
subtasks[].completedAt | string (date-time) or null | |
subtasks[].costCents | integer or null | int64. |
subtasks[].descriptionrequired | string | |
subtasks[].durationDaysrequired | integer | |
subtasks[].estimateMinutesrequired | integer | |
subtasks[].loggedSecondsrequired | integer | |
subtasks[].onCriticalPathrequired | boolean | |
subtasks[].parentTaskPublicId | string or null | |
subtasks[].phasePublicId | string or null | |
subtasks[].plannedDueOn | string or null | |
subtasks[].plannedStartOn | string or null | |
subtasks[].positionrequired | integer | |
subtasks[].predecessorsrequired | array of TaskDependencyView | |
subtasks[].predecessors[].lagDaysrequired | integer | |
subtasks[].predecessors[].taskPublicIdrequired | string | |
subtasks[].priorityrequired | string | |
subtasks[].projectPublicIdrequired | string | |
subtasks[].publicIdrequired | string | |
subtasks[].rolePlaceholderrequired | string | |
subtasks[].spawnedTicketPublicId | string or null | |
subtasks[].statusrequired | string | |
subtasks[].subtasks | array of ProjectTaskView | |
subtasks[].titlerequired | string | |
subtasks[].updatedAtrequired | string (date-time) | |
subtasks[].watchersrequired | array of TaskWatcherView | |
subtasks[].watchers[].displayNamerequired | string | |
subtasks[].watchers[].userPublicIdrequired | string | |
subtasks[].watchingrequired | boolean | |
titlerequired | string | |
updatedAtrequired | string (date-time) | |
watchersrequired | array of TaskWatcherView | |
watchers[].displayNamerequired | string | |
watchers[].userPublicIdrequired | string | |
watchingrequired | boolean |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "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"}'@
$response = Invoke-RestMethod ` -Method Patch ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "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",}
response = requests.patch(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "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"}`)
req, err := http.NewRequest(http.MethodPatch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>";
const response = await fetch(url, { method: "PATCH", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "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" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "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"}""";
var request = new HttpRequestMessage(HttpMethod.Patch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ChecklistItemView | |
items[].donerequired | boolean | |
items[].doneAt | string (date-time) or null | |
items[].positionrequired | integer | |
items[].publicIdrequired | string | |
items[].textrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, object | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
Request samples
Section titled “Request samples”# 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" } ]}'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "items": [ { "done": false, "doneAt": "2026-01-01T00:00:00Z", "position": 0, "publicId": "string", "text": "string" } ]}'@
$response = Invoke-RestMethod ` -Method Put ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "items": [ { "done": False, "doneAt": "2026-01-01T00:00:00Z", "position": 0, "publicId": "string", "text": "string", }, ],}
response = requests.put(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "items": [ { "done": false, "doneAt": "2026-01-01T00:00:00Z", "position": 0, "publicId": "string", "text": "string" } ]}`)
req, err := http.NewRequest(http.MethodPut, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist";
const response = await fetch(url, { method: "PUT", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "items": [ { "done": false, "doneAt": "2026-01-01T00:00:00Z", "position": 0, "publicId": "string", "text": "string" } ] }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "items": [ { "done": false, "doneAt": "2026-01-01T00:00:00Z", "position": 0, "publicId": "string", "text": "string" } ]}""";
var request = new HttpRequestMessage(HttpMethod.Put, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
itemId | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
The body is any.
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ChecklistItemView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not acceptable. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
donerequired | boolean | |
doneAt | string (date-time) or null | |
positionrequired | integer | |
publicIdrequired | string | |
textrequired | string |
Request samples
Section titled “Request samples”# 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"'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'"string"'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist/<itemId>/toggle' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist/<itemId>/toggle"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = "string"
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`"string"`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist/<itemId>/toggle", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist/<itemId>/toggle";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify("string"),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """"string"""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/checklist/<itemId>/toggle");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
predecessorsrequired | array of TaskDependencyView | |
predecessors[].lagDaysrequired | integer | |
predecessors[].taskPublicIdrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectTaskView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
actualStartOn | string or null | |
assigneeName | string or null | |
assigneeUserPublicId | string or null | |
atRiskrequired | boolean | |
atRiskReasonrequired | string | |
billableSecondsrequired | integer | |
blockedReasonrequired | string | |
checklistrequired | array of ChecklistItemView | |
checklist[].donerequired | boolean | |
checklist[].doneAt | string (date-time) or null | |
checklist[].positionrequired | integer | |
checklist[].publicIdrequired | string | |
checklist[].textrequired | string | |
clientVisiblerequired | boolean | |
completedAt | string (date-time) or null | |
costCents | integer or null | int64. |
descriptionrequired | string | |
durationDaysrequired | integer | |
estimateMinutesrequired | integer | |
loggedSecondsrequired | integer | |
onCriticalPathrequired | boolean | |
parentTaskPublicId | string or null | |
phasePublicId | string or null | |
plannedDueOn | string or null | |
plannedStartOn | string or null | |
positionrequired | integer | |
predecessorsrequired | array of TaskDependencyView | |
predecessors[].lagDaysrequired | integer | |
predecessors[].taskPublicIdrequired | string | |
priorityrequired | string | |
projectPublicIdrequired | string | |
publicIdrequired | string | |
rolePlaceholderrequired | string | |
spawnedTicketPublicId | string or null | |
statusrequired | string | |
subtasks | array of ProjectTaskView | |
subtasks[].actualStartOn | string or null | |
subtasks[].assigneeName | string or null | |
subtasks[].assigneeUserPublicId | string or null | |
subtasks[].atRiskrequired | boolean | |
subtasks[].atRiskReasonrequired | string | |
subtasks[].billableSecondsrequired | integer | |
subtasks[].blockedReasonrequired | string | |
subtasks[].checklistrequired | array of ChecklistItemView | |
subtasks[].checklist[].donerequired | boolean | |
subtasks[].checklist[].doneAt | string (date-time) or null | |
subtasks[].checklist[].positionrequired | integer | |
subtasks[].checklist[].publicIdrequired | string | |
subtasks[].checklist[].textrequired | string | |
subtasks[].clientVisiblerequired | boolean | |
subtasks[].completedAt | string (date-time) or null | |
subtasks[].costCents | integer or null | int64. |
subtasks[].descriptionrequired | string | |
subtasks[].durationDaysrequired | integer | |
subtasks[].estimateMinutesrequired | integer | |
subtasks[].loggedSecondsrequired | integer | |
subtasks[].onCriticalPathrequired | boolean | |
subtasks[].parentTaskPublicId | string or null | |
subtasks[].phasePublicId | string or null | |
subtasks[].plannedDueOn | string or null | |
subtasks[].plannedStartOn | string or null | |
subtasks[].positionrequired | integer | |
subtasks[].predecessorsrequired | array of TaskDependencyView | |
subtasks[].predecessors[].lagDaysrequired | integer | |
subtasks[].predecessors[].taskPublicIdrequired | string | |
subtasks[].priorityrequired | string | |
subtasks[].projectPublicIdrequired | string | |
subtasks[].publicIdrequired | string | |
subtasks[].rolePlaceholderrequired | string | |
subtasks[].spawnedTicketPublicId | string or null | |
subtasks[].statusrequired | string | |
subtasks[].subtasks | array of ProjectTaskView | |
subtasks[].titlerequired | string | |
subtasks[].updatedAtrequired | string (date-time) | |
subtasks[].watchersrequired | array of TaskWatcherView | |
subtasks[].watchers[].displayNamerequired | string | |
subtasks[].watchers[].userPublicIdrequired | string | |
subtasks[].watchingrequired | boolean | |
titlerequired | string | |
updatedAtrequired | string (date-time) | |
watchersrequired | array of TaskWatcherView | |
watchers[].displayNamerequired | string | |
watchers[].userPublicIdrequired | string | |
watchingrequired | boolean |
Request samples
Section titled “Request samples”# 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" } ]}'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "predecessors": [ { "lagDays": 0, "taskPublicId": "string" } ]}'@
$response = Invoke-RestMethod ` -Method Put ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/dependencies' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/dependencies"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "predecessors": [ { "lagDays": 0, "taskPublicId": "string", }, ],}
response = requests.put(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "predecessors": [ { "lagDays": 0, "taskPublicId": "string" } ]}`)
req, err := http.NewRequest(http.MethodPut, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/dependencies", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/dependencies";
const response = await fetch(url, { method: "PUT", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "predecessors": [ { "lagDays": 0, "taskPublicId": "string" } ] }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "predecessors": [ { "lagDays": 0, "taskPublicId": "string" } ]}""";
var request = new HttpRequestMessage(HttpMethod.Put, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/dependencies");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
The body is any.
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, object | Created. |
400 | application/problem+json, ProblemDetails | The request body is not acceptable. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold ticket:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
Request samples
Section titled “Request samples”# 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"'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'"string"'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/spawn-ticket' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/spawn-ticket"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = "string"
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`"string"`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/spawn-ticket", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/spawn-ticket";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify("string"),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """"string"""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/spawn-ticket");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectTimeEntryView | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectTimeEntryView | |
items[].amountCentsrequired | integer | int64. |
items[].billablerequired | boolean | |
items[].chargeTypeCoderequired | string | |
items[].classifiedAt | string (date-time) or null | |
items[].costRateCentsSnapshot | integer or null | int64. |
items[].invoicePublicId | string or null | |
items[].invoicedrequired | boolean | |
items[].locked | boolean | |
items[].minutesrequired | integer | |
items[].noterequired | string | |
items[].occurredAtrequired | string (date-time) | |
items[].outcome | string | |
items[].projectPublicId | string or null | |
items[].publicIdrequired | string | |
items[].rateCentsSnapshot | integer or null | int64. |
items[].taskPublicId | string or null | |
items[].technicianNamerequired | string | |
items[].userPublicIdrequired | string | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time?page=0&pageSize=0' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time"params = { "page": "0", "pageSize": "0",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time?page=0&pageSize=0", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time?page=0&pageSize=0");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
billablerequired | boolean | |
chargeTypeCoderequired | string | |
message | TimeEntryMessageRequest | |
message.bodyrequired | string | |
message.internal | boolean or null | |
minutesrequired | integer | |
noterequired | string | |
occurredAtrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ProjectTimeEntryView | Created. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | Logging time requires a signed-in technician. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:time. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Could not check whether this week’s timesheet is approved. Nothing was changed; try again in a moment. |
201 response body
| Field | Type | Description |
|---|---|---|
amountCentsrequired | integer | int64. |
billablerequired | boolean | |
chargeTypeCoderequired | string | |
classifiedAt | string (date-time) or null | |
costRateCentsSnapshot | integer or null | int64. |
invoicePublicId | string or null | |
invoicedrequired | boolean | |
locked | boolean | |
minutesrequired | integer | |
noterequired | string | |
occurredAtrequired | string (date-time) | |
outcome | string | |
projectPublicId | string or null | |
publicIdrequired | string | |
rateCentsSnapshot | integer or null | int64. |
taskPublicId | string or null | |
technicianNamerequired | string | |
userPublicIdrequired | string |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "billable": false, "chargeTypeCode": "string", "message": { "body": "string", "internal": false }, "minutes": 0, "note": "string", "occurredAt": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "billable": False, "chargeTypeCode": "string", "message": { "body": "string", "internal": False, }, "minutes": 0, "note": "string", "occurredAt": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "billable": false, "chargeTypeCode": "string", "message": { "body": "string", "internal": false }, "minutes": 0, "note": "string", "occurredAt": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "billable": false, "chargeTypeCode": "string", "message": { "body": "string", "internal": false }, "minutes": 0, "note": "string", "occurredAt": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "billable": false, "chargeTypeCode": "string", "message": { "body": "string", "internal": false }, "minutes": 0, "note": "string", "occurredAt": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
entryId | path | string | Yes | A uuid. |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
billable | boolean or null | |
chargeTypeCode | string or null | |
minutes | integer or null | |
note | string or null | |
occurredAt | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectTimeEntryView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:time. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Could not check whether this week’s timesheet is approved. Nothing was changed; try again in a moment. |
200 response body
| Field | Type | Description |
|---|---|---|
amountCentsrequired | integer | int64. |
billablerequired | boolean | |
chargeTypeCoderequired | string | |
classifiedAt | string (date-time) or null | |
costRateCentsSnapshot | integer or null | int64. |
invoicePublicId | string or null | |
invoicedrequired | boolean | |
locked | boolean | |
minutesrequired | integer | |
noterequired | string | |
occurredAtrequired | string (date-time) | |
outcome | string | |
projectPublicId | string or null | |
publicIdrequired | string | |
rateCentsSnapshot | integer or null | int64. |
taskPublicId | string or null | |
technicianNamerequired | string | |
userPublicIdrequired | string |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "billable": false, "chargeTypeCode": "string", "minutes": 0, "note": "string", "occurredAt": "string"}'@
$response = Invoke-RestMethod ` -Method Patch ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "billable": False, "chargeTypeCode": "string", "minutes": 0, "note": "string", "occurredAt": "string",}
response = requests.patch(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "billable": false, "chargeTypeCode": "string", "minutes": 0, "note": "string", "occurredAt": "string"}`)
req, err := http.NewRequest(http.MethodPatch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>";
const response = await fetch(url, { method: "PATCH", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "billable": false, "chargeTypeCode": "string", "minutes": 0, "note": "string", "occurredAt": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "billable": false, "chargeTypeCode": "string", "minutes": 0, "note": "string", "occurredAt": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Patch, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
entryId | path | string | Yes | A uuid. |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:time. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Could not check whether this week’s timesheet is approved. Nothing was changed; try again in a moment. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
entryId | path | string | Yes | A uuid. |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectTimeEntryView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold psa:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
200 response body
| Field | Type | Description |
|---|---|---|
amountCentsrequired | integer | int64. |
billablerequired | boolean | |
chargeTypeCoderequired | string | |
classifiedAt | string (date-time) or null | |
costRateCentsSnapshot | integer or null | int64. |
invoicePublicId | string or null | |
invoicedrequired | boolean | |
locked | boolean | |
minutesrequired | integer | |
noterequired | string | |
occurredAtrequired | string (date-time) | |
outcome | string | |
projectPublicId | string or null | |
publicIdrequired | string | |
rateCentsSnapshot | integer or null | int64. |
taskPublicId | string or null | |
technicianNamerequired | string | |
userPublicIdrequired | string |
Request samples
Section titled “Request samples”# 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>'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>/reprice' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>/reprice"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>/reprice", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>/reprice";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/time/<entryId>/reprice");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
userId | path | string | Yes |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Put ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.put(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPut, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>";
const response = await fetch(url, { method: "PUT", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Put, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
taskId | path | string | Yes | A uuid. |
userId | path | string | Yes |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/<taskId>/watchers/<userId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
phase | query | string | No |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
publicIdsrequired | array of string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
Request samples
Section titled “Request samples”# 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" ]}'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "publicIds": [ "string" ]}'@
$response = Invoke-RestMethod ` -Method Put ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/order?phase=<phase>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/order"params = { "phase": "<phase>",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "publicIds": [ "string", ],}
response = requests.put(url, params=params, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "publicIds": [ "string" ]}`)
req, err := http.NewRequest(http.MethodPut, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/order?phase=<phase>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/order");url.searchParams.set("phase", "<phase>");
const response = await fetch(url, { method: "PUT", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "publicIds": [ "string" ] }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "publicIds": [ "string" ]}""";
var request = new HttpRequestMessage(HttpMethod.Put, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tasks/order?phase=<phase>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/clients/{cid}/projects/{id}/tickets
Section titled “GET /api/v1/clients/{cid}/projects/{id}/tickets”GETproject:readmsp facemspIdempotent
Source: [object Object]
List project ticket links
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectTicketLinkView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectTicketLinkView | |
items[].createdAtrequired | string (date-time) | |
items[].kindrequired | string | |
items[].publicIdrequired | string | |
items[].taskPublicId | string or null | |
items[].ticketPublicIdrequired | string | |
items[].ticketReferencerequired | string | |
items[].ticketSubjectrequired | string | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
kindrequired | string | |
taskIdrequired | string | |
ticketIdrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ProjectTicketLinkView | Created. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
createdAtrequired | string (date-time) | |
kindrequired | string | |
publicIdrequired | string | |
taskPublicId | string or null | |
ticketPublicIdrequired | string | |
ticketReferencerequired | string | |
ticketSubjectrequired | string |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "kind": "string", "taskId": "string", "ticketId": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "kind": "string", "taskId": "string", "ticketId": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "kind": "string", "taskId": "string", "ticketId": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "kind": "string", "taskId": "string", "ticketId": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "kind": "string", "taskId": "string", "ticketId": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
cid | path | string | Yes | |
id | path | string | Yes | A uuid. |
linkId | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:write. |
404 | application/problem+json, ProblemDetails | No client matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets/<linkId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets/<linkId>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets/<linkId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets/<linkId>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/clients/<cid>/projects/<id>/tickets/<linkId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects
Section titled “GET /api/v1/projects”GETproject:readmsp facemspIdempotent
Source: [object Object]
List all projects
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
billingMode | query | string | No | |
client | query | string | No | |
clientId | query | string | No | |
health | query | string, one of amber, green, red | No | Comma-separated set. An unrecognised value is refused. |
manager | query | string | No | |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
q | query | string | No | |
sort | query | string | No | |
status | query | string, one of active, cancelled, completed, draft, on_hold | No | Comma-separated set. An unrecognised value is refused. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PsaFanOutPageProjectSummaryView | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
500 | application/problem+json, ProblemDetails | Could not list clients. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectSummaryView | |
items[].amountBurnBprequired | integer | |
items[].atRiskTasksrequired | integer | |
items[].billableSecondsrequired | integer | |
items[].billingModerequired | string | |
items[].budgetAmountCentsrequired | integer | int64. |
items[].budgetMinutesrequired | integer | |
items[].clientNamerequired | string | |
items[].clientPublicIdrequired | string | |
items[].createdAtrequired | string (date-time) | |
items[].fixedPriceCentsrequired | integer | int64. |
items[].healthrequired | string | |
items[].healthComputedAt | string (date-time) or null | |
items[].healthReasonrequired | string | |
items[].hoursBurnBprequired | integer | |
items[].isSelfrequired | boolean | |
items[].loggedSecondsrequired | integer | |
items[].managerName | string or null | |
items[].managerUserPublicId | string or null | |
items[].namerequired | string | |
items[].nextMilestone | NextMilestoneView | |
items[].nextMilestone.dueOnrequired | string | |
items[].nextMilestone.namerequired | string | |
items[].nextMilestone.publicIdrequired | string | |
items[].numberrequired | integer | int64. |
items[].openTasksrequired | integer | |
items[].overdueMilestonesrequired | integer | |
items[].percentCompleterequired | integer | |
items[].plannedEndOn | string or null | |
items[].plannedStartOnrequired | string | |
items[].publicIdrequired | string | |
items[].referencerequired | string | |
items[].statusrequired | string | |
items[].updatedAtrequired | string (date-time) | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer | |
totalClientsrequired | integer | |
unavailableClientsrequired | array of string |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects?billingMode=<billingMode>&client=<client>&clientId=<clientId>&health=amber&manager=<manager>&page=0' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects"params = { "billingMode": "<billingMode>", "client": "<client>", "clientId": "<clientId>", "health": "amber", "manager": "<manager>", "page": "0",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects?billingMode=<billingMode>&client=<client>&clientId=<clientId>&health=amber&manager=<manager>&page=0", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/projects");url.searchParams.set("billingMode", "<billingMode>");url.searchParams.set("client", "<client>");url.searchParams.set("clientId", "<clientId>");url.searchParams.set("health", "amber");url.searchParams.set("manager", "<manager>");url.searchParams.set("page", "0");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects?billingMode=<billingMode>&client=<client>&clientId=<clientId>&health=amber&manager=<manager>&page=0");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/at-risk
Section titled “GET /api/v1/projects/at-risk”GETproject:readmsp facemspIdempotent
Source: [object Object]
List at risk
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
client | query | string | No | |
clientId | query | string | No | |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PsaFanOutPageProjectSummaryView | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
500 | application/problem+json, ProblemDetails | Could not list clients. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectSummaryView | |
items[].amountBurnBprequired | integer | |
items[].atRiskTasksrequired | integer | |
items[].billableSecondsrequired | integer | |
items[].billingModerequired | string | |
items[].budgetAmountCentsrequired | integer | int64. |
items[].budgetMinutesrequired | integer | |
items[].clientNamerequired | string | |
items[].clientPublicIdrequired | string | |
items[].createdAtrequired | string (date-time) | |
items[].fixedPriceCentsrequired | integer | int64. |
items[].healthrequired | string | |
items[].healthComputedAt | string (date-time) or null | |
items[].healthReasonrequired | string | |
items[].hoursBurnBprequired | integer | |
items[].isSelfrequired | boolean | |
items[].loggedSecondsrequired | integer | |
items[].managerName | string or null | |
items[].managerUserPublicId | string or null | |
items[].namerequired | string | |
items[].nextMilestone | NextMilestoneView | |
items[].nextMilestone.dueOnrequired | string | |
items[].nextMilestone.namerequired | string | |
items[].nextMilestone.publicIdrequired | string | |
items[].numberrequired | integer | int64. |
items[].openTasksrequired | integer | |
items[].overdueMilestonesrequired | integer | |
items[].percentCompleterequired | integer | |
items[].plannedEndOn | string or null | |
items[].plannedStartOnrequired | string | |
items[].publicIdrequired | string | |
items[].referencerequired | string | |
items[].statusrequired | string | |
items[].updatedAtrequired | string (date-time) | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer | |
totalClientsrequired | integer | |
unavailableClientsrequired | array of string |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/at-risk?client=<client>&clientId=<clientId>&page=0&pageSize=0' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/at-risk"params = { "client": "<client>", "clientId": "<clientId>", "page": "0", "pageSize": "0",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/at-risk?client=<client>&clientId=<clientId>&page=0&pageSize=0", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/projects/at-risk");url.searchParams.set("client", "<client>");url.searchParams.set("clientId", "<clientId>");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/at-risk?client=<client>&clientId=<clientId>&page=0&pageSize=0");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/budget-alerts
Section titled “GET /api/v1/projects/budget-alerts”GETproject:readmsp facemspIdempotent
Source: [object Object]
List budget alerts
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
client | query | string | No | |
clientId | query | string | No | |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PsaFanOutPageBudgetAlertView | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
500 | application/problem+json, ProblemDetails | Could not list clients. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of BudgetAlertView | |
items[].clientNamerequired | string | |
items[].clientPublicIdrequired | string | |
items[].detailrequired | string | |
items[].firstRaisedAtrequired | string (date-time) | |
items[].occurrencesrequired | integer | |
items[].projectNamerequired | string | |
items[].projectPublicIdrequired | string | |
items[].projectReferencerequired | string | |
items[].publicIdrequired | string | |
items[].raisedAtrequired | string (date-time) | |
items[].severityrequired | string | |
items[].sourceKeyrequired | string | |
items[].staterequired | string | |
items[].titlerequired | string | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer | |
totalClientsrequired | integer | |
unavailableClientsrequired | array of string |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/budget-alerts?client=<client>&clientId=<clientId>&page=0&pageSize=0' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/budget-alerts"params = { "client": "<client>", "clientId": "<clientId>", "page": "0", "pageSize": "0",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/budget-alerts?client=<client>&clientId=<clientId>&page=0&pageSize=0", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/projects/budget-alerts");url.searchParams.set("client", "<client>");url.searchParams.set("clientId", "<clientId>");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/budget-alerts?client=<client>&clientId=<clientId>&page=0&pageSize=0");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/calendar/appointments
Section titled “GET /api/v1/projects/calendar/appointments”GETproject:calendarmsp facemspIdempotent
Source: [object Object]
List appointments
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
client | query | string | No | |
project | query | string | No | |
technician | query | string | No |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultAppointmentView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:calendar. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of AppointmentView | |
items[].cancelledAt | string (date-time) or null | |
items[].clientName | string or null | |
items[].clientPublicId | string or null | |
items[].endsAtrequired | string (date-time) | |
items[].locationrequired | string | |
items[].noterequired | string | |
items[].onSiterequired | boolean | |
items[].projectPublicId | string or null | |
items[].publicIdrequired | string | |
items[].reminderMinutesBeforerequired | integer | |
items[].reminderSentAt | string (date-time) or null | |
items[].requesterEmailrequired | string | |
items[].requesterNamerequired | string | |
items[].startsAtrequired | string (date-time) | |
items[].taskPublicId | string or null | |
items[].technicianNamerequired | string | |
items[].technicianUserPublicIdrequired | string | |
items[].ticketPublicId | string or null | |
items[].titlerequired | string | |
items[].warningsrequired | AppointmentWarningsView | |
items[].warnings.bookedMinutesrequired | integer | |
items[].warnings.capacityMinutesrequired | integer | |
items[].warnings.duringTimeOffrequired | boolean | |
items[].warnings.outsideBusinessHoursrequired | boolean | |
items[].warnings.overCapacityrequired | boolean | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/calendar/appointments?client=<client>&project=<project>&technician=<technician>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/appointments"params = { "client": "<client>", "project": "<project>", "technician": "<technician>",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/calendar/appointments?client=<client>&project=<project>&technician=<technician>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/projects/calendar/appointments");url.searchParams.set("client", "<client>");url.searchParams.set("project", "<project>");url.searchParams.set("technician", "<technician>");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/calendar/appointments?client=<client>&project=<project>&technician=<technician>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
clientPublicId | string or null | |
endsAt | string or null | |
location | string or null | |
note | string or null | |
onSite | boolean or null | |
projectPublicId | string or null | |
reminderMinutesBefore | integer or null | |
requesterEmail | string or null | |
requesterName | string or null | |
startsAt | string or null | |
taskPublicId | string or null | |
technicianUserPublicId | string or null | |
ticketPublicId | string or null | |
title | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, AppointmentView | Created. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:calendar. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
cancelledAt | string (date-time) or null | |
clientName | string or null | |
clientPublicId | string or null | |
endsAtrequired | string (date-time) | |
locationrequired | string | |
noterequired | string | |
onSiterequired | boolean | |
projectPublicId | string or null | |
publicIdrequired | string | |
reminderMinutesBeforerequired | integer | |
reminderSentAt | string (date-time) or null | |
requesterEmailrequired | string | |
requesterNamerequired | string | |
startsAtrequired | string (date-time) | |
taskPublicId | string or null | |
technicianNamerequired | string | |
technicianUserPublicIdrequired | string | |
ticketPublicId | string or null | |
titlerequired | string | |
warningsrequired | AppointmentWarningsView | |
warnings.bookedMinutesrequired | integer | |
warnings.capacityMinutesrequired | integer | |
warnings.duringTimeOffrequired | boolean | |
warnings.outsideBusinessHoursrequired | boolean | |
warnings.overCapacityrequired | boolean |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "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"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/projects/calendar/appointments' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/appointments"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "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",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "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"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/projects/calendar/appointments", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/calendar/appointments";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "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" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "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"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/projects/calendar/appointments");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/calendar/appointments/{apptID}
Section titled “GET /api/v1/projects/calendar/appointments/{apptID}”GETproject:calendarmsp facemspIdempotent
Source: [object Object]
Get appointment
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
apptID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, AppointmentView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:calendar. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
cancelledAt | string (date-time) or null | |
clientName | string or null | |
clientPublicId | string or null | |
endsAtrequired | string (date-time) | |
locationrequired | string | |
noterequired | string | |
onSiterequired | boolean | |
projectPublicId | string or null | |
publicIdrequired | string | |
reminderMinutesBeforerequired | integer | |
reminderSentAt | string (date-time) or null | |
requesterEmailrequired | string | |
requesterNamerequired | string | |
startsAtrequired | string (date-time) | |
taskPublicId | string or null | |
technicianNamerequired | string | |
technicianUserPublicIdrequired | string | |
ticketPublicId | string or null | |
titlerequired | string | |
warningsrequired | AppointmentWarningsView | |
warnings.bookedMinutesrequired | integer | |
warnings.capacityMinutesrequired | integer | |
warnings.duringTimeOffrequired | boolean | |
warnings.outsideBusinessHoursrequired | boolean | |
warnings.overCapacityrequired | boolean |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());PATCH /api/v1/projects/calendar/appointments/{apptID}
Section titled “PATCH /api/v1/projects/calendar/appointments/{apptID}”PATCHproject:calendarmsp facemsp
Source: [object Object]
Patch appointment
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
apptID | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
clientPublicId | string or null | |
endsAt | string or null | |
location | string or null | |
note | string or null | |
onSite | boolean or null | |
projectPublicId | string or null | |
reminderMinutesBefore | integer or null | |
requesterEmail | string or null | |
requesterName | string or null | |
startsAt | string or null | |
taskPublicId | string or null | |
technicianUserPublicId | string or null | |
ticketPublicId | string or null | |
title | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, AppointmentView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:calendar. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
cancelledAt | string (date-time) or null | |
clientName | string or null | |
clientPublicId | string or null | |
endsAtrequired | string (date-time) | |
locationrequired | string | |
noterequired | string | |
onSiterequired | boolean | |
projectPublicId | string or null | |
publicIdrequired | string | |
reminderMinutesBeforerequired | integer | |
reminderSentAt | string (date-time) or null | |
requesterEmailrequired | string | |
requesterNamerequired | string | |
startsAtrequired | string (date-time) | |
taskPublicId | string or null | |
technicianNamerequired | string | |
technicianUserPublicIdrequired | string | |
ticketPublicId | string or null | |
titlerequired | string | |
warningsrequired | AppointmentWarningsView | |
warnings.bookedMinutesrequired | integer | |
warnings.capacityMinutesrequired | integer | |
warnings.duringTimeOffrequired | boolean | |
warnings.outsideBusinessHoursrequired | boolean | |
warnings.overCapacityrequired | boolean |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "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"}'@
$response = Invoke-RestMethod ` -Method Patch ` -Uri 'https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "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",}
response = requests.patch(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "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"}`)
req, err := http.NewRequest(http.MethodPatch, "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>";
const response = await fetch(url, { method: "PATCH", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "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" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "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"}""";
var request = new HttpRequestMessage(HttpMethod.Patch, "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());DELETE /api/v1/projects/calendar/appointments/{apptID}
Section titled “DELETE /api/v1/projects/calendar/appointments/{apptID}”DELETEproject:calendarmsp facemspIdempotent
Source: [object Object]
Cancel appointment
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
apptID | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
The body is any.
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:calendar. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
Request samples
Section titled “Request samples”# 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"'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'"string"'@
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = "string"
response = requests.delete(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`"string"`)
req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify("string"),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """"string"""";
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/projects/calendar/appointments/<apptID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/calendar/holidays
Section titled “GET /api/v1/projects/calendar/holidays”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.
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, array of CalendarHolidayView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:calendar. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
[].daterequired | string | |
[].namerequired | string |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/calendar/holidays' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/holidays"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/calendar/holidays", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/calendar/holidays";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/calendar/holidays");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/calendar/technicians
Section titled “GET /api/v1/projects/calendar/technicians”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.
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultTechnicianProfileView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:calendar. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of TechnicianProfileView | |
items[].costRateCentsPerHour | integer or null | int64. |
items[].displayNamerequired | string | |
items[].emailrequired | string | |
items[].userPublicIdrequired | string | |
items[].weeklyCapacityMinutesrequired | integer | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/calendar/technicians' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/technicians"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/calendar/technicians", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/calendar/technicians";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/calendar/technicians");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
userID | path | string | Yes |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
costRateCentsPerHour | integer or null | int64. |
effectiveFromrequired | string | |
weeklyCapacityMinutes | integer or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, TechnicianProfileView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No operator matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
costRateCentsPerHour | integer or null | int64. |
displayNamerequired | string | |
emailrequired | string | |
userPublicIdrequired | string | |
weeklyCapacityMinutesrequired | integer |
Request samples
Section titled “Request samples”# 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}'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "costRateCentsPerHour": 0, "effectiveFrom": "string", "weeklyCapacityMinutes": 0}'@
$response = Invoke-RestMethod ` -Method Put ` -Uri 'https://depot.example.com/api/v1/projects/calendar/technicians/<userID>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/technicians/<userID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "costRateCentsPerHour": 0, "effectiveFrom": "string", "weeklyCapacityMinutes": 0,}
response = requests.put(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "costRateCentsPerHour": 0, "effectiveFrom": "string", "weeklyCapacityMinutes": 0}`)
req, err := http.NewRequest(http.MethodPut, "https://depot.example.com/api/v1/projects/calendar/technicians/<userID>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/calendar/technicians/<userID>";
const response = await fetch(url, { method: "PUT", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "costRateCentsPerHour": 0, "effectiveFrom": "string", "weeklyCapacityMinutes": 0 }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "costRateCentsPerHour": 0, "effectiveFrom": "string", "weeklyCapacityMinutes": 0}""";
var request = new HttpRequestMessage(HttpMethod.Put, "https://depot.example.com/api/v1/projects/calendar/technicians/<userID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
userID | path | string | Yes |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, TechnicianLoadView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:calendar. |
404 | application/problem+json, ProblemDetails | No operator matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
bookedMinutesrequired | integer | |
capacityMinutesrequired | integer | |
loggedSecondsrequired | integer | |
timeOffrequired | array of TimeOffView | |
timeOff[].endsOnrequired | string | |
timeOff[].kindrequired | string | |
timeOff[].noterequired | string | |
timeOff[].publicIdrequired | string | |
timeOff[].startsOnrequired | string | |
timeOff[].userPublicIdrequired | string | |
userPublicIdrequired | string | |
weekStartrequired | string |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/calendar/technicians/<userID>/load' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/technicians/<userID>/load"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/calendar/technicians/<userID>/load", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/calendar/technicians/<userID>/load";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/calendar/technicians/<userID>/load");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/calendar/time-off
Section titled “GET /api/v1/projects/calendar/time-off”GETproject:calendarmsp facemspIdempotent
Source: [object Object]
List time off
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
technician | query | string | No |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultTimeOffView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:calendar. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of TimeOffView | |
items[].endsOnrequired | string | |
items[].kindrequired | string | |
items[].noterequired | string | |
items[].publicIdrequired | string | |
items[].startsOnrequired | string | |
items[].userPublicIdrequired | string | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/calendar/time-off?technician=<technician>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/time-off"params = { "technician": "<technician>",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/calendar/time-off?technician=<technician>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/projects/calendar/time-off");url.searchParams.set("technician", "<technician>");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/calendar/time-off?technician=<technician>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/projects/calendar/time-off
Section titled “POST /api/v1/projects/calendar/time-off”POSTproject:calendarmsp facemsp
Source: [object Object]
Create time off
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
endsOnrequired | string | |
kindrequired | string | |
noterequired | string | |
startsOnrequired | string | |
userPublicIdrequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, TimeOffView | Created. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:calendar. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
endsOnrequired | string | |
kindrequired | string | |
noterequired | string | |
publicIdrequired | string | |
startsOnrequired | string | |
userPublicIdrequired | string |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "endsOn": "string", "kind": "string", "note": "string", "startsOn": "string", "userPublicId": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/projects/calendar/time-off' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/time-off"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "endsOn": "string", "kind": "string", "note": "string", "startsOn": "string", "userPublicId": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "endsOn": "string", "kind": "string", "note": "string", "startsOn": "string", "userPublicId": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/projects/calendar/time-off", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/calendar/time-off";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "endsOn": "string", "kind": "string", "note": "string", "startsOn": "string", "userPublicId": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "endsOn": "string", "kind": "string", "note": "string", "startsOn": "string", "userPublicId": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/projects/calendar/time-off");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
offID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:calendar. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/projects/calendar/time-off/<offID>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/calendar/time-off/<offID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/projects/calendar/time-off/<offID>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/calendar/time-off/<offID>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/projects/calendar/time-off/<offID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/dashboard
Section titled “GET /api/v1/projects/dashboard”GETproject:readmsp facemspIdempotent
Source: [object Object]
Get project dashboard
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
clientId | query | string | No | |
siteId | query | string | No |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectDashboardView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No resource matches that scope. |
500 | application/problem+json, ProblemDetails | Could not list clients. |
503 | application/problem+json, ProblemDetails | The client scope is unavailable. |
200 response body
| Field | Type | Description |
|---|---|---|
appointmentsThisWeekrequired | PagedResultAppointmentView | PagedResult is the generic envelope for paginated list responses. |
appointmentsThisWeek.itemsrequired | array of AppointmentView | |
appointmentsThisWeek.items[].cancelledAt | string (date-time) or null | |
appointmentsThisWeek.items[].clientName | string or null | |
appointmentsThisWeek.items[].clientPublicId | string or null | |
appointmentsThisWeek.items[].endsAtrequired | string (date-time) | |
appointmentsThisWeek.items[].locationrequired | string | |
appointmentsThisWeek.items[].noterequired | string | |
appointmentsThisWeek.items[].onSiterequired | boolean | |
appointmentsThisWeek.items[].projectPublicId | string or null | |
appointmentsThisWeek.items[].publicIdrequired | string | |
appointmentsThisWeek.items[].reminderMinutesBeforerequired | integer | |
appointmentsThisWeek.items[].reminderSentAt | string (date-time) or null | |
appointmentsThisWeek.items[].requesterEmailrequired | string | |
appointmentsThisWeek.items[].requesterNamerequired | string | |
appointmentsThisWeek.items[].startsAtrequired | string (date-time) | |
appointmentsThisWeek.items[].taskPublicId | string or null | |
appointmentsThisWeek.items[].technicianNamerequired | string | |
appointmentsThisWeek.items[].technicianUserPublicIdrequired | string | |
appointmentsThisWeek.items[].ticketPublicId | string or null | |
appointmentsThisWeek.items[].titlerequired | string | |
appointmentsThisWeek.items[].warningsrequired | AppointmentWarningsView | |
appointmentsThisWeek.items[].warnings.bookedMinutesrequired | integer | |
appointmentsThisWeek.items[].warnings.capacityMinutesrequired | integer | |
appointmentsThisWeek.items[].warnings.duringTimeOffrequired | boolean | |
appointmentsThisWeek.items[].warnings.outsideBusinessHoursrequired | boolean | |
appointmentsThisWeek.items[].warnings.overCapacityrequired | boolean | |
appointmentsThisWeek.pagerequired | integer | |
appointmentsThisWeek.pageSizerequired | integer | |
appointmentsThisWeek.totalrequired | integer | |
atRiskrequired | PsaFanOutPageProjectSummaryView | psaFanOutPage is the partial-result envelope BILLING_CONTRACTS.md section 4 freezes: a PagedResult plus the two fields that make it honest. |
atRisk.itemsrequired | array of ProjectSummaryView | |
atRisk.items[].amountBurnBprequired | integer | |
atRisk.items[].atRiskTasksrequired | integer | |
atRisk.items[].billableSecondsrequired | integer | |
atRisk.items[].billingModerequired | string | |
atRisk.items[].budgetAmountCentsrequired | integer | int64. |
atRisk.items[].budgetMinutesrequired | integer | |
atRisk.items[].clientNamerequired | string | |
atRisk.items[].clientPublicIdrequired | string | |
atRisk.items[].createdAtrequired | string (date-time) | |
atRisk.items[].fixedPriceCentsrequired | integer | int64. |
atRisk.items[].healthrequired | string | |
atRisk.items[].healthComputedAt | string (date-time) or null | |
atRisk.items[].healthReasonrequired | string | |
atRisk.items[].hoursBurnBprequired | integer | |
atRisk.items[].isSelfrequired | boolean | |
atRisk.items[].loggedSecondsrequired | integer | |
atRisk.items[].managerName | string or null | |
atRisk.items[].managerUserPublicId | string or null | |
atRisk.items[].namerequired | string | |
atRisk.items[].nextMilestone | NextMilestoneView | |
atRisk.items[].nextMilestone.dueOnrequired | string | |
atRisk.items[].nextMilestone.namerequired | string | |
atRisk.items[].nextMilestone.publicIdrequired | string | |
atRisk.items[].numberrequired | integer | int64. |
atRisk.items[].openTasksrequired | integer | |
atRisk.items[].overdueMilestonesrequired | integer | |
atRisk.items[].percentCompleterequired | integer | |
atRisk.items[].plannedEndOn | string or null | |
atRisk.items[].plannedStartOnrequired | string | |
atRisk.items[].publicIdrequired | string | |
atRisk.items[].referencerequired | string | |
atRisk.items[].statusrequired | string | |
atRisk.items[].updatedAtrequired | string (date-time) | |
atRisk.pagerequired | integer | |
atRisk.pageSizerequired | integer | |
atRisk.totalrequired | integer | |
atRisk.totalClientsrequired | integer | |
atRisk.unavailableClientsrequired | array of string | |
budgetAlertsrequired | PsaFanOutPageBudgetAlertView | psaFanOutPage is the partial-result envelope BILLING_CONTRACTS.md section 4 freezes: a PagedResult plus the two fields that make it honest. |
budgetAlerts.itemsrequired | array of BudgetAlertView | |
budgetAlerts.items[].clientNamerequired | string | |
budgetAlerts.items[].clientPublicIdrequired | string | |
budgetAlerts.items[].detailrequired | string | |
budgetAlerts.items[].firstRaisedAtrequired | string (date-time) | |
budgetAlerts.items[].occurrencesrequired | integer | |
budgetAlerts.items[].projectNamerequired | string | |
budgetAlerts.items[].projectPublicIdrequired | string | |
budgetAlerts.items[].projectReferencerequired | string | |
budgetAlerts.items[].publicIdrequired | string | |
budgetAlerts.items[].raisedAtrequired | string (date-time) | |
budgetAlerts.items[].severityrequired | string | |
budgetAlerts.items[].sourceKeyrequired | string | |
budgetAlerts.items[].staterequired | string | |
budgetAlerts.items[].titlerequired | string | |
budgetAlerts.pagerequired | integer | |
budgetAlerts.pageSizerequired | integer | |
budgetAlerts.totalrequired | integer | |
budgetAlerts.totalClientsrequired | integer | |
budgetAlerts.unavailableClientsrequired | array of string | |
myTasksrequired | PsaFanOutPageDashboardTaskView | psaFanOutPage is the partial-result envelope BILLING_CONTRACTS.md section 4 freezes: a PagedResult plus the two fields that make it honest. |
myTasks.itemsrequired | array of DashboardTaskView | |
myTasks.items[].actualStartOn | string or null | |
myTasks.items[].assigneeName | string or null | |
myTasks.items[].assigneeUserPublicId | string or null | |
myTasks.items[].atRiskrequired | boolean | |
myTasks.items[].atRiskReasonrequired | string | |
myTasks.items[].billableSecondsrequired | integer | |
myTasks.items[].blockedReasonrequired | string | |
myTasks.items[].checklistrequired | array of ChecklistItemView | |
myTasks.items[].checklist[].donerequired | boolean | |
myTasks.items[].checklist[].doneAt | string (date-time) or null | |
myTasks.items[].checklist[].positionrequired | integer | |
myTasks.items[].checklist[].publicIdrequired | string | |
myTasks.items[].checklist[].textrequired | string | |
myTasks.items[].clientNamerequired | string | |
myTasks.items[].clientPublicIdrequired | string | |
myTasks.items[].clientVisiblerequired | boolean | |
myTasks.items[].completedAt | string (date-time) or null | |
myTasks.items[].costCents | integer or null | int64. |
myTasks.items[].descriptionrequired | string | |
myTasks.items[].durationDaysrequired | integer | |
myTasks.items[].estimateMinutesrequired | integer | |
myTasks.items[].loggedSecondsrequired | integer | |
myTasks.items[].onCriticalPathrequired | boolean | |
myTasks.items[].parentTaskPublicId | string or null | |
myTasks.items[].phasePublicId | string or null | |
myTasks.items[].plannedDueOn | string or null | |
myTasks.items[].plannedStartOn | string or null | |
myTasks.items[].positionrequired | integer | |
myTasks.items[].predecessorsrequired | array of TaskDependencyView | |
myTasks.items[].predecessors[].lagDaysrequired | integer | |
myTasks.items[].predecessors[].taskPublicIdrequired | string | |
myTasks.items[].priorityrequired | string | |
myTasks.items[].projectNamerequired | string | |
myTasks.items[].projectPublicIdrequired | string | |
myTasks.items[].projectReferencerequired | string | |
myTasks.items[].publicIdrequired | string | |
myTasks.items[].rolePlaceholderrequired | string | |
myTasks.items[].spawnedTicketPublicId | string or null | |
myTasks.items[].statusrequired | string | |
myTasks.items[].subtasks | array of ProjectTaskView | |
myTasks.items[].subtasks[].actualStartOn | string or null | |
myTasks.items[].subtasks[].assigneeName | string or null | |
myTasks.items[].subtasks[].assigneeUserPublicId | string or null | |
myTasks.items[].subtasks[].atRiskrequired | boolean | |
myTasks.items[].subtasks[].atRiskReasonrequired | string | |
myTasks.items[].subtasks[].billableSecondsrequired | integer | |
myTasks.items[].subtasks[].blockedReasonrequired | string | |
myTasks.items[].subtasks[].checklistrequired | array of ChecklistItemView | |
myTasks.items[].subtasks[].clientVisiblerequired | boolean | |
myTasks.items[].subtasks[].completedAt | string (date-time) or null | |
myTasks.items[].subtasks[].costCents | integer or null | int64. |
myTasks.items[].subtasks[].descriptionrequired | string | |
myTasks.items[].subtasks[].durationDaysrequired | integer | |
myTasks.items[].subtasks[].estimateMinutesrequired | integer | |
myTasks.items[].subtasks[].loggedSecondsrequired | integer | |
myTasks.items[].subtasks[].onCriticalPathrequired | boolean | |
myTasks.items[].subtasks[].parentTaskPublicId | string or null | |
myTasks.items[].subtasks[].phasePublicId | string or null | |
myTasks.items[].subtasks[].plannedDueOn | string or null | |
myTasks.items[].subtasks[].plannedStartOn | string or null | |
myTasks.items[].subtasks[].positionrequired | integer | |
myTasks.items[].subtasks[].predecessorsrequired | array of TaskDependencyView | |
myTasks.items[].subtasks[].priorityrequired | string | |
myTasks.items[].subtasks[].projectPublicIdrequired | string | |
myTasks.items[].subtasks[].publicIdrequired | string | |
myTasks.items[].subtasks[].rolePlaceholderrequired | string | |
myTasks.items[].subtasks[].spawnedTicketPublicId | string or null | |
myTasks.items[].subtasks[].statusrequired | string | |
myTasks.items[].subtasks[].subtasks | array of ProjectTaskView | |
myTasks.items[].subtasks[].titlerequired | string | |
myTasks.items[].subtasks[].updatedAtrequired | string (date-time) | |
myTasks.items[].subtasks[].watchersrequired | array of TaskWatcherView | |
myTasks.items[].subtasks[].watchingrequired | boolean | |
myTasks.items[].titlerequired | string | |
myTasks.items[].updatedAtrequired | string (date-time) | |
myTasks.items[].watchersrequired | array of TaskWatcherView | |
myTasks.items[].watchers[].displayNamerequired | string | |
myTasks.items[].watchers[].userPublicIdrequired | string | |
myTasks.items[].watchingrequired | boolean | |
myTasks.pagerequired | integer | |
myTasks.pageSizerequired | integer | |
myTasks.totalrequired | integer | |
myTasks.totalClientsrequired | integer | |
myTasks.unavailableClientsrequired | array of string | |
siteFilteredrequired | boolean |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/dashboard?clientId=<clientId>&siteId=<siteId>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/dashboard"params = { "clientId": "<clientId>", "siteId": "<siteId>",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/dashboard?clientId=<clientId>&siteId=<siteId>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/projects/dashboard");url.searchParams.set("clientId", "<clientId>");url.searchParams.set("siteId", "<siteId>");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/dashboard?clientId=<clientId>&siteId=<siteId>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/decision-counts
Section titled “GET /api/v1/projects/decision-counts”GETproject:readmsp facemspIdempotent
Source: [object Object]
Get decision counts
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectDecisionCountsResponse | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
500 | application/problem+json, ProblemDetails | Could not list clients. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
clientsrequired | array of ProjectDecisionClientCount | |
clients[].changeOrdersDraftrequired | integer | |
clients[].clientNamerequired | string | |
clients[].clientPublicIdrequired | string | |
clients[].milestonesDeclinedrequired | integer | |
totalWaitingrequired | integer | |
unavailableClientsrequired | array of string |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/decision-counts' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/decision-counts"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/decision-counts", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/decision-counts";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/decision-counts");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/my-tasks
Section titled “GET /api/v1/projects/my-tasks”GETproject:readmsp facemspIdempotent
Source: [object Object]
List my tasks
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
client | query | string | No | |
clientId | query | string | No | |
page | query | integer | No | One-based page number. Defaults to 1. |
pageSize | query | integer | No | Rows per page, 1 to 200. Defaults to 50. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PsaFanOutPageDashboardTaskView | Success. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
500 | application/problem+json, ProblemDetails | Could not list clients. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of DashboardTaskView | |
items[].actualStartOn | string or null | |
items[].assigneeName | string or null | |
items[].assigneeUserPublicId | string or null | |
items[].atRiskrequired | boolean | |
items[].atRiskReasonrequired | string | |
items[].billableSecondsrequired | integer | |
items[].blockedReasonrequired | string | |
items[].checklistrequired | array of ChecklistItemView | |
items[].checklist[].donerequired | boolean | |
items[].checklist[].doneAt | string (date-time) or null | |
items[].checklist[].positionrequired | integer | |
items[].checklist[].publicIdrequired | string | |
items[].checklist[].textrequired | string | |
items[].clientNamerequired | string | |
items[].clientPublicIdrequired | string | |
items[].clientVisiblerequired | boolean | |
items[].completedAt | string (date-time) or null | |
items[].costCents | integer or null | int64. |
items[].descriptionrequired | string | |
items[].durationDaysrequired | integer | |
items[].estimateMinutesrequired | integer | |
items[].loggedSecondsrequired | integer | |
items[].onCriticalPathrequired | boolean | |
items[].parentTaskPublicId | string or null | |
items[].phasePublicId | string or null | |
items[].plannedDueOn | string or null | |
items[].plannedStartOn | string or null | |
items[].positionrequired | integer | |
items[].predecessorsrequired | array of TaskDependencyView | |
items[].predecessors[].lagDaysrequired | integer | |
items[].predecessors[].taskPublicIdrequired | string | |
items[].priorityrequired | string | |
items[].projectNamerequired | string | |
items[].projectPublicIdrequired | string | |
items[].projectReferencerequired | string | |
items[].publicIdrequired | string | |
items[].rolePlaceholderrequired | string | |
items[].spawnedTicketPublicId | string or null | |
items[].statusrequired | string | |
items[].subtasks | array of ProjectTaskView | |
items[].subtasks[].actualStartOn | string or null | |
items[].subtasks[].assigneeName | string or null | |
items[].subtasks[].assigneeUserPublicId | string or null | |
items[].subtasks[].atRiskrequired | boolean | |
items[].subtasks[].atRiskReasonrequired | string | |
items[].subtasks[].billableSecondsrequired | integer | |
items[].subtasks[].blockedReasonrequired | string | |
items[].subtasks[].checklistrequired | array of ChecklistItemView | |
items[].subtasks[].checklist[].donerequired | boolean | |
items[].subtasks[].checklist[].doneAt | string (date-time) or null | |
items[].subtasks[].checklist[].positionrequired | integer | |
items[].subtasks[].checklist[].publicIdrequired | string | |
items[].subtasks[].checklist[].textrequired | string | |
items[].subtasks[].clientVisiblerequired | boolean | |
items[].subtasks[].completedAt | string (date-time) or null | |
items[].subtasks[].costCents | integer or null | int64. |
items[].subtasks[].descriptionrequired | string | |
items[].subtasks[].durationDaysrequired | integer | |
items[].subtasks[].estimateMinutesrequired | integer | |
items[].subtasks[].loggedSecondsrequired | integer | |
items[].subtasks[].onCriticalPathrequired | boolean | |
items[].subtasks[].parentTaskPublicId | string or null | |
items[].subtasks[].phasePublicId | string or null | |
items[].subtasks[].plannedDueOn | string or null | |
items[].subtasks[].plannedStartOn | string or null | |
items[].subtasks[].positionrequired | integer | |
items[].subtasks[].predecessorsrequired | array of TaskDependencyView | |
items[].subtasks[].predecessors[].lagDaysrequired | integer | |
items[].subtasks[].predecessors[].taskPublicIdrequired | string | |
items[].subtasks[].priorityrequired | string | |
items[].subtasks[].projectPublicIdrequired | string | |
items[].subtasks[].publicIdrequired | string | |
items[].subtasks[].rolePlaceholderrequired | string | |
items[].subtasks[].spawnedTicketPublicId | string or null | |
items[].subtasks[].statusrequired | string | |
items[].subtasks[].subtasks | array of ProjectTaskView | |
items[].subtasks[].subtasks[].actualStartOn | string or null | |
items[].subtasks[].subtasks[].assigneeName | string or null | |
items[].subtasks[].subtasks[].assigneeUserPublicId | string or null | |
items[].subtasks[].subtasks[].atRiskrequired | boolean | |
items[].subtasks[].subtasks[].atRiskReasonrequired | string | |
items[].subtasks[].subtasks[].billableSecondsrequired | integer | |
items[].subtasks[].subtasks[].blockedReasonrequired | string | |
items[].subtasks[].subtasks[].checklistrequired | array of ChecklistItemView | |
items[].subtasks[].subtasks[].clientVisiblerequired | boolean | |
items[].subtasks[].subtasks[].completedAt | string (date-time) or null | |
items[].subtasks[].subtasks[].costCents | integer or null | int64. |
items[].subtasks[].subtasks[].descriptionrequired | string | |
items[].subtasks[].subtasks[].durationDaysrequired | integer | |
items[].subtasks[].subtasks[].estimateMinutesrequired | integer | |
items[].subtasks[].subtasks[].loggedSecondsrequired | integer | |
items[].subtasks[].subtasks[].onCriticalPathrequired | boolean | |
items[].subtasks[].subtasks[].parentTaskPublicId | string or null | |
items[].subtasks[].subtasks[].phasePublicId | string or null | |
items[].subtasks[].subtasks[].plannedDueOn | string or null | |
items[].subtasks[].subtasks[].plannedStartOn | string or null | |
items[].subtasks[].subtasks[].positionrequired | integer | |
items[].subtasks[].subtasks[].predecessorsrequired | array of TaskDependencyView | |
items[].subtasks[].subtasks[].priorityrequired | string | |
items[].subtasks[].subtasks[].projectPublicIdrequired | string | |
items[].subtasks[].subtasks[].publicIdrequired | string | |
items[].subtasks[].subtasks[].rolePlaceholderrequired | string | |
items[].subtasks[].subtasks[].spawnedTicketPublicId | string or null | |
items[].subtasks[].subtasks[].statusrequired | string | |
items[].subtasks[].subtasks[].subtasks | array of ProjectTaskView | |
items[].subtasks[].subtasks[].titlerequired | string | |
items[].subtasks[].subtasks[].updatedAtrequired | string (date-time) | |
items[].subtasks[].subtasks[].watchersrequired | array of TaskWatcherView | |
items[].subtasks[].subtasks[].watchingrequired | boolean | |
items[].subtasks[].titlerequired | string | |
items[].subtasks[].updatedAtrequired | string (date-time) | |
items[].subtasks[].watchersrequired | array of TaskWatcherView | |
items[].subtasks[].watchers[].displayNamerequired | string | |
items[].subtasks[].watchers[].userPublicIdrequired | string | |
items[].subtasks[].watchingrequired | boolean | |
items[].titlerequired | string | |
items[].updatedAtrequired | string (date-time) | |
items[].watchersrequired | array of TaskWatcherView | |
items[].watchers[].displayNamerequired | string | |
items[].watchers[].userPublicIdrequired | string | |
items[].watchingrequired | boolean | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer | |
totalClientsrequired | integer | |
unavailableClientsrequired | array of string |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/my-tasks?client=<client>&clientId=<clientId>&page=0&pageSize=0' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/my-tasks"params = { "client": "<client>", "clientId": "<clientId>", "page": "0", "pageSize": "0",}headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/my-tasks?client=<client>&clientId=<clientId>&page=0&pageSize=0", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = new URL("https://depot.example.com/api/v1/projects/my-tasks");url.searchParams.set("client", "<client>");url.searchParams.set("clientId", "<clientId>");url.searchParams.set("page", "0");url.searchParams.set("pageSize", "0");
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/my-tasks?client=<client>&clientId=<clientId>&page=0&pageSize=0");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/schedules
Section titled “GET /api/v1/projects/schedules”GETproject:readmsp facemspIdempotent
Source: [object Object]
List project schedules
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultRecurringScheduleView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of RecurringScheduleView | |
items[].billingMode | string or null | |
items[].clientNamerequired | string | |
items[].clientPublicIdrequired | string | |
items[].cronExprrequired | string | |
items[].enabledrequired | boolean | |
items[].lastProjectPublicId | string or null | |
items[].lastRunAt | string (date-time) or null | |
items[].managerUserPublicId | string or null | |
items[].namerequired | string | |
items[].nextRunAt | string (date-time) or null | |
items[].projectNamePatternrequired | string | |
items[].publicIdrequired | string | |
items[].templateFamilyPublicIdrequired | string | |
items[].templateNamerequired | string | |
items[].timeZonerequired | string | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/schedules' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/schedules"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/schedules", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/schedules";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/schedules");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/projects/schedules
Section titled “POST /api/v1/projects/schedules”POSTproject:managemsp facemsp
Source: [object Object]
Create project schedule
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
billingMode | string or null | |
clientPublicId | string or null | |
cronExpr | string or null | |
enabled | boolean or null | |
managerUserPublicId | string or null | |
name | string or null | |
projectNamePattern | string or null | |
templateFamilyPublicId | string or null | |
timeZone | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, RecurringScheduleView | Created. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
billingMode | string or null | |
clientNamerequired | string | |
clientPublicIdrequired | string | |
cronExprrequired | string | |
enabledrequired | boolean | |
lastProjectPublicId | string or null | |
lastRunAt | string (date-time) or null | |
managerUserPublicId | string or null | |
namerequired | string | |
nextRunAt | string (date-time) or null | |
projectNamePatternrequired | string | |
publicIdrequired | string | |
templateFamilyPublicIdrequired | string | |
templateNamerequired | string | |
timeZonerequired | string |
Request samples
Section titled “Request samples”# 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"}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "billingMode": "string", "clientPublicId": "string", "cronExpr": "string", "enabled": false, "managerUserPublicId": "string", "name": "string", "projectNamePattern": "string", "templateFamilyPublicId": "string", "timeZone": "string"}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/projects/schedules' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/projects/schedules"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "billingMode": "string", "clientPublicId": "string", "cronExpr": "string", "enabled": False, "managerUserPublicId": "string", "name": "string", "projectNamePattern": "string", "templateFamilyPublicId": "string", "timeZone": "string",}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "billingMode": "string", "clientPublicId": "string", "cronExpr": "string", "enabled": false, "managerUserPublicId": "string", "name": "string", "projectNamePattern": "string", "templateFamilyPublicId": "string", "timeZone": "string"}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/projects/schedules", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/schedules";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "billingMode": "string", "clientPublicId": "string", "cronExpr": "string", "enabled": false, "managerUserPublicId": "string", "name": "string", "projectNamePattern": "string", "templateFamilyPublicId": "string", "timeZone": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "billingMode": "string", "clientPublicId": "string", "cronExpr": "string", "enabled": false, "managerUserPublicId": "string", "name": "string", "projectNamePattern": "string", "templateFamilyPublicId": "string", "timeZone": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/projects/schedules");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/schedules/{schedID}
Section titled “GET /api/v1/projects/schedules/{schedID}”GETproject:readmsp facemspIdempotent
Source: [object Object]
Get project schedule
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
schedID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, RecurringScheduleView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
billingMode | string or null | |
clientNamerequired | string | |
clientPublicIdrequired | string | |
cronExprrequired | string | |
enabledrequired | boolean | |
lastProjectPublicId | string or null | |
lastRunAt | string (date-time) or null | |
managerUserPublicId | string or null | |
namerequired | string | |
nextRunAt | string (date-time) or null | |
projectNamePatternrequired | string | |
publicIdrequired | string | |
templateFamilyPublicIdrequired | string | |
templateNamerequired | string | |
timeZonerequired | string |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/schedules/<schedID>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/schedules/<schedID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/schedules/<schedID>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/schedules/<schedID>";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/schedules/<schedID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());PUT /api/v1/projects/schedules/{schedID}
Section titled “PUT /api/v1/projects/schedules/{schedID}”PUTproject:managemsp facemspIdempotent
Source: [object Object]
Put project schedule
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
schedID | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
billingMode | string or null | |
clientPublicId | string or null | |
cronExpr | string or null | |
enabled | boolean or null | |
managerUserPublicId | string or null | |
name | string or null | |
projectNamePattern | string or null | |
templateFamilyPublicId | string or null | |
timeZone | string or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, RecurringScheduleView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
billingMode | string or null | |
clientNamerequired | string | |
clientPublicIdrequired | string | |
cronExprrequired | string | |
enabledrequired | boolean | |
lastProjectPublicId | string or null | |
lastRunAt | string (date-time) or null | |
managerUserPublicId | string or null | |
namerequired | string | |
nextRunAt | string (date-time) or null | |
projectNamePatternrequired | string | |
publicIdrequired | string | |
templateFamilyPublicIdrequired | string | |
templateNamerequired | string | |
timeZonerequired | string |
Request samples
Section titled “Request samples”# 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"}'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "billingMode": "string", "clientPublicId": "string", "cronExpr": "string", "enabled": false, "managerUserPublicId": "string", "name": "string", "projectNamePattern": "string", "templateFamilyPublicId": "string", "timeZone": "string"}'@
$response = Invoke-RestMethod ` -Method Put ` -Uri 'https://depot.example.com/api/v1/projects/schedules/<schedID>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/schedules/<schedID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "billingMode": "string", "clientPublicId": "string", "cronExpr": "string", "enabled": False, "managerUserPublicId": "string", "name": "string", "projectNamePattern": "string", "templateFamilyPublicId": "string", "timeZone": "string",}
response = requests.put(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "billingMode": "string", "clientPublicId": "string", "cronExpr": "string", "enabled": false, "managerUserPublicId": "string", "name": "string", "projectNamePattern": "string", "templateFamilyPublicId": "string", "timeZone": "string"}`)
req, err := http.NewRequest(http.MethodPut, "https://depot.example.com/api/v1/projects/schedules/<schedID>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/schedules/<schedID>";
const response = await fetch(url, { method: "PUT", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "billingMode": "string", "clientPublicId": "string", "cronExpr": "string", "enabled": false, "managerUserPublicId": "string", "name": "string", "projectNamePattern": "string", "templateFamilyPublicId": "string", "timeZone": "string" }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "billingMode": "string", "clientPublicId": "string", "cronExpr": "string", "enabled": false, "managerUserPublicId": "string", "name": "string", "projectNamePattern": "string", "templateFamilyPublicId": "string", "timeZone": "string"}""";
var request = new HttpRequestMessage(HttpMethod.Put, "https://depot.example.com/api/v1/projects/schedules/<schedID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());DELETE /api/v1/projects/schedules/{schedID}
Section titled “DELETE /api/v1/projects/schedules/{schedID}”DELETEproject:managemsp facemspIdempotent
Source: [object Object]
Delete project schedule
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
schedID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/projects/schedules/<schedID>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/schedules/<schedID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/projects/schedules/<schedID>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/schedules/<schedID>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/projects/schedules/<schedID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
schedID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectScheduleRunView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
attemptsrequired | integer | |
claimedAtrequired | string (date-time) | |
claimedByrequired | string | |
clientPublicIdrequired | string | |
errorrequired | string | |
finishedAt | string (date-time) or null | |
projectPublicIdrequired | string | |
schedulePublicIdrequired | string | |
scheduledForrequired | string (date-time) |
Request samples
Section titled “Request samples”# 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>'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/projects/schedules/<schedID>/run-now' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/projects/schedules/<schedID>/run-now"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/projects/schedules/<schedID>/run-now", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/schedules/<schedID>/run-now";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/projects/schedules/<schedID>/run-now");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
schedID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectScheduleRunView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectScheduleRunView | |
items[].attemptsrequired | integer | |
items[].claimedAtrequired | string (date-time) | |
items[].claimedByrequired | string | |
items[].clientPublicIdrequired | string | |
items[].errorrequired | string | |
items[].finishedAt | string (date-time) or null | |
items[].projectPublicIdrequired | string | |
items[].schedulePublicIdrequired | string | |
items[].scheduledForrequired | string (date-time) | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/schedules/<schedID>/runs' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/schedules/<schedID>/runs"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/schedules/<schedID>/runs", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/schedules/<schedID>/runs";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/schedules/<schedID>/runs");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/settings
Section titled “GET /api/v1/projects/settings”GETproject:readmsp facemspIdempotent
Source: [object Object]
Get project settings
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectSettingsView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
atRiskLeadDaysrequired | integer | |
budgetCriticalBprequired | integer | |
budgetWarnBprequired | integer | |
defaultAppointmentReminderMinutesrequired | integer | |
defaultStatusEmailCadencerequired | string | |
pmDigestEnabledrequired | boolean | |
pmDigestHourLocalrequired | integer | |
scopeCreepBprequired | integer | |
seededTemplatesAt | string (date-time) or null |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/settings' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/settings"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/settings", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/settings";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/settings");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());PUT /api/v1/projects/settings
Section titled “PUT /api/v1/projects/settings”PUTproject:managemsp facemspIdempotent
Source: [object Object]
Put project settings
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
atRiskLeadDays | integer or null | |
budgetCriticalBp | integer or null | |
budgetWarnBp | integer or null | |
defaultAppointmentReminderMinutes | integer or null | |
defaultStatusEmailCadence | string or null | |
pmDigestEnabled | boolean or null | |
pmDigestHourLocal | integer or null | |
scopeCreepBp | integer or null |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectSettingsView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
atRiskLeadDaysrequired | integer | |
budgetCriticalBprequired | integer | |
budgetWarnBprequired | integer | |
defaultAppointmentReminderMinutesrequired | integer | |
defaultStatusEmailCadencerequired | string | |
pmDigestEnabledrequired | boolean | |
pmDigestHourLocalrequired | integer | |
scopeCreepBprequired | integer | |
seededTemplatesAt | string (date-time) or null |
Request samples
Section titled “Request samples”# 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}'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "atRiskLeadDays": 0, "budgetCriticalBp": 0, "budgetWarnBp": 0, "defaultAppointmentReminderMinutes": 0, "defaultStatusEmailCadence": "string", "pmDigestEnabled": false, "pmDigestHourLocal": 0, "scopeCreepBp": 0}'@
$response = Invoke-RestMethod ` -Method Put ` -Uri 'https://depot.example.com/api/v1/projects/settings' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/settings"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "atRiskLeadDays": 0, "budgetCriticalBp": 0, "budgetWarnBp": 0, "defaultAppointmentReminderMinutes": 0, "defaultStatusEmailCadence": "string", "pmDigestEnabled": False, "pmDigestHourLocal": 0, "scopeCreepBp": 0,}
response = requests.put(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "atRiskLeadDays": 0, "budgetCriticalBp": 0, "budgetWarnBp": 0, "defaultAppointmentReminderMinutes": 0, "defaultStatusEmailCadence": "string", "pmDigestEnabled": false, "pmDigestHourLocal": 0, "scopeCreepBp": 0}`)
req, err := http.NewRequest(http.MethodPut, "https://depot.example.com/api/v1/projects/settings", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/settings";
const response = await fetch(url, { method: "PUT", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "atRiskLeadDays": 0, "budgetCriticalBp": 0, "budgetWarnBp": 0, "defaultAppointmentReminderMinutes": 0, "defaultStatusEmailCadence": "string", "pmDigestEnabled": false, "pmDigestHourLocal": 0, "scopeCreepBp": 0 }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "atRiskLeadDays": 0, "budgetCriticalBp": 0, "budgetWarnBp": 0, "defaultAppointmentReminderMinutes": 0, "defaultStatusEmailCadence": "string", "pmDigestEnabled": false, "pmDigestHourLocal": 0, "scopeCreepBp": 0}""";
var request = new HttpRequestMessage(HttpMethod.Put, "https://depot.example.com/api/v1/projects/settings");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/templates
Section titled “GET /api/v1/projects/templates”GETproject:readmsp facemspIdempotent
Source: [object Object]
List project templates
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectTemplateView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectTemplateView | |
items[].activerequired | boolean | |
items[].categoryrequired | string | |
items[].defaultBillingModerequired | string | |
items[].defaultBudgetMinutesrequired | integer | |
items[].defaultStatusEmailCadencerequired | string | |
items[].defaultStatusEmailWeekdayrequired | integer | |
items[].descriptionrequired | string | |
items[].durationDaysrequired | integer | |
items[].familyPublicIdrequired | string | |
items[].isCurrentrequired | boolean | |
items[].isSeedrequired | boolean | |
items[].milestonesrequired | array of TemplateMilestoneView | |
items[].milestones[].amountBprequired | integer | |
items[].milestones[].clientVisiblerequired | boolean | |
items[].milestones[].descriptionrequired | string | |
items[].milestones[].namerequired | string | |
items[].milestones[].offsetDaysrequired | integer | |
items[].milestones[].phasePublicId | string or null | |
items[].milestones[].positionrequired | integer | |
items[].milestones[].publicIdrequired | string | |
items[].milestones[].requiresClientAcceptancerequired | boolean | |
items[].namerequired | string | |
items[].phasesrequired | array of TemplatePhaseView | |
items[].phases[].billingModeOverride | string or null | |
items[].phases[].budgetAmountBp | integer or null | |
items[].phases[].budgetMinutes | integer or null | |
items[].phases[].namerequired | string | |
items[].phases[].positionrequired | integer | |
items[].phases[].publicIdrequired | string | |
items[].publicIdrequired | string | |
items[].tasksrequired | array of TemplateTaskView | |
items[].tasks[].checklistrequired | array of string | |
items[].tasks[].clientVisiblerequired | boolean | |
items[].tasks[].descriptionrequired | string | |
items[].tasks[].durationDaysrequired | integer | |
items[].tasks[].estimateMinutesrequired | integer | |
items[].tasks[].parentTaskPublicId | string or null | |
items[].tasks[].phasePublicId | string or null | |
items[].tasks[].positionrequired | integer | |
items[].tasks[].predecessorsrequired | array of TaskDependencyView | |
items[].tasks[].predecessors[].lagDaysrequired | integer | |
items[].tasks[].predecessors[].taskPublicIdrequired | string | |
items[].tasks[].priorityrequired | string | |
items[].tasks[].publicIdrequired | string | |
items[].tasks[].rolePlaceholderrequired | string | |
items[].tasks[].startOffsetDaysrequired | integer | |
items[].tasks[].titlerequired | string | |
items[].usedCountrequired | integer | |
items[].versionrequired | integer | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/templates' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/templates"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/templates", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/templates";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/templates");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());POST /api/v1/projects/templates
Section titled “POST /api/v1/projects/templates”POSTproject:managemsp facemsp
Source: [object Object]
Create project template
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
active | boolean or null | |
categoryrequired | string | |
defaultBillingModerequired | string | |
defaultBudgetMinutes | integer or null | |
defaultStatusEmailCadencerequired | string | |
defaultStatusEmailWeekday | integer or null | |
descriptionrequired | string | |
milestonesrequired | array of TemplateMilestoneView | |
milestones[].amountBprequired | integer | |
milestones[].clientVisiblerequired | boolean | |
milestones[].descriptionrequired | string | |
milestones[].namerequired | string | |
milestones[].offsetDaysrequired | integer | |
milestones[].phasePublicId | string or null | |
milestones[].positionrequired | integer | |
milestones[].publicIdrequired | string | |
milestones[].requiresClientAcceptancerequired | boolean | |
namerequired | string | |
phasesrequired | array of TemplatePhaseView | |
phases[].billingModeOverride | string or null | |
phases[].budgetAmountBp | integer or null | |
phases[].budgetMinutes | integer or null | |
phases[].namerequired | string | |
phases[].positionrequired | integer | |
phases[].publicIdrequired | string | |
tasksrequired | array of TemplateTaskView | |
tasks[].checklistrequired | array of string | |
tasks[].clientVisiblerequired | boolean | |
tasks[].descriptionrequired | string | |
tasks[].durationDaysrequired | integer | |
tasks[].estimateMinutesrequired | integer | |
tasks[].parentTaskPublicId | string or null | |
tasks[].phasePublicId | string or null | |
tasks[].positionrequired | integer | |
tasks[].predecessorsrequired | array of TaskDependencyView | |
tasks[].predecessors[].lagDaysrequired | integer | |
tasks[].predecessors[].taskPublicIdrequired | string | |
tasks[].priorityrequired | string | |
tasks[].publicIdrequired | string | |
tasks[].rolePlaceholderrequired | string | |
tasks[].startOffsetDaysrequired | integer | |
tasks[].titlerequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
201 | application/json, ProjectTemplateView | Created. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No resource matches. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
201 response body
| Field | Type | Description |
|---|---|---|
activerequired | boolean | |
categoryrequired | string | |
defaultBillingModerequired | string | |
defaultBudgetMinutesrequired | integer | |
defaultStatusEmailCadencerequired | string | |
defaultStatusEmailWeekdayrequired | integer | |
descriptionrequired | string | |
durationDaysrequired | integer | |
familyPublicIdrequired | string | |
isCurrentrequired | boolean | |
isSeedrequired | boolean | |
milestonesrequired | array of TemplateMilestoneView | |
milestones[].amountBprequired | integer | |
milestones[].clientVisiblerequired | boolean | |
milestones[].descriptionrequired | string | |
milestones[].namerequired | string | |
milestones[].offsetDaysrequired | integer | |
milestones[].phasePublicId | string or null | |
milestones[].positionrequired | integer | |
milestones[].publicIdrequired | string | |
milestones[].requiresClientAcceptancerequired | boolean | |
namerequired | string | |
phasesrequired | array of TemplatePhaseView | |
phases[].billingModeOverride | string or null | |
phases[].budgetAmountBp | integer or null | |
phases[].budgetMinutes | integer or null | |
phases[].namerequired | string | |
phases[].positionrequired | integer | |
phases[].publicIdrequired | string | |
publicIdrequired | string | |
tasksrequired | array of TemplateTaskView | |
tasks[].checklistrequired | array of string | |
tasks[].clientVisiblerequired | boolean | |
tasks[].descriptionrequired | string | |
tasks[].durationDaysrequired | integer | |
tasks[].estimateMinutesrequired | integer | |
tasks[].parentTaskPublicId | string or null | |
tasks[].phasePublicId | string or null | |
tasks[].positionrequired | integer | |
tasks[].predecessorsrequired | array of TaskDependencyView | |
tasks[].predecessors[].lagDaysrequired | integer | |
tasks[].predecessors[].taskPublicIdrequired | string | |
tasks[].priorityrequired | string | |
tasks[].publicIdrequired | string | |
tasks[].rolePlaceholderrequired | string | |
tasks[].startOffsetDaysrequired | integer | |
tasks[].titlerequired | string | |
usedCountrequired | integer | |
versionrequired | integer |
Request samples
Section titled “Request samples”# 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" } ]}'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "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" } ]}'@
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/projects/templates' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/projects/templates"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "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", }, ],}
response = requests.post(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "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" } ]}`)
req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/projects/templates", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/templates";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "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" } ] }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "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" } ]}""";
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/projects/templates");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());GET /api/v1/projects/templates/{tplID}
Section titled “GET /api/v1/projects/templates/{tplID}”GETproject:readmsp facemspIdempotent
Source: [object Object]
Get project template
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
tplID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectTemplateView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
activerequired | boolean | |
categoryrequired | string | |
defaultBillingModerequired | string | |
defaultBudgetMinutesrequired | integer | |
defaultStatusEmailCadencerequired | string | |
defaultStatusEmailWeekdayrequired | integer | |
descriptionrequired | string | |
durationDaysrequired | integer | |
familyPublicIdrequired | string | |
isCurrentrequired | boolean | |
isSeedrequired | boolean | |
milestonesrequired | array of TemplateMilestoneView | |
milestones[].amountBprequired | integer | |
milestones[].clientVisiblerequired | boolean | |
milestones[].descriptionrequired | string | |
milestones[].namerequired | string | |
milestones[].offsetDaysrequired | integer | |
milestones[].phasePublicId | string or null | |
milestones[].positionrequired | integer | |
milestones[].publicIdrequired | string | |
milestones[].requiresClientAcceptancerequired | boolean | |
namerequired | string | |
phasesrequired | array of TemplatePhaseView | |
phases[].billingModeOverride | string or null | |
phases[].budgetAmountBp | integer or null | |
phases[].budgetMinutes | integer or null | |
phases[].namerequired | string | |
phases[].positionrequired | integer | |
phases[].publicIdrequired | string | |
publicIdrequired | string | |
tasksrequired | array of TemplateTaskView | |
tasks[].checklistrequired | array of string | |
tasks[].clientVisiblerequired | boolean | |
tasks[].descriptionrequired | string | |
tasks[].durationDaysrequired | integer | |
tasks[].estimateMinutesrequired | integer | |
tasks[].parentTaskPublicId | string or null | |
tasks[].phasePublicId | string or null | |
tasks[].positionrequired | integer | |
tasks[].predecessorsrequired | array of TaskDependencyView | |
tasks[].predecessors[].lagDaysrequired | integer | |
tasks[].predecessors[].taskPublicIdrequired | string | |
tasks[].priorityrequired | string | |
tasks[].publicIdrequired | string | |
tasks[].rolePlaceholderrequired | string | |
tasks[].startOffsetDaysrequired | integer | |
tasks[].titlerequired | string | |
usedCountrequired | integer | |
versionrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/templates/<tplID>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/templates/<tplID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/templates/<tplID>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/templates/<tplID>";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/templates/<tplID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());PUT /api/v1/projects/templates/{tplID}
Section titled “PUT /api/v1/projects/templates/{tplID}”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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
tplID | path | string | Yes | A uuid. |
Request body
Section titled “Request body”Required, sent as application/json.
| Field | Type | Description |
|---|---|---|
active | boolean or null | |
categoryrequired | string | |
defaultBillingModerequired | string | |
defaultBudgetMinutes | integer or null | |
defaultStatusEmailCadencerequired | string | |
defaultStatusEmailWeekday | integer or null | |
descriptionrequired | string | |
milestonesrequired | array of TemplateMilestoneView | |
milestones[].amountBprequired | integer | |
milestones[].clientVisiblerequired | boolean | |
milestones[].descriptionrequired | string | |
milestones[].namerequired | string | |
milestones[].offsetDaysrequired | integer | |
milestones[].phasePublicId | string or null | |
milestones[].positionrequired | integer | |
milestones[].publicIdrequired | string | |
milestones[].requiresClientAcceptancerequired | boolean | |
namerequired | string | |
phasesrequired | array of TemplatePhaseView | |
phases[].billingModeOverride | string or null | |
phases[].budgetAmountBp | integer or null | |
phases[].budgetMinutes | integer or null | |
phases[].namerequired | string | |
phases[].positionrequired | integer | |
phases[].publicIdrequired | string | |
tasksrequired | array of TemplateTaskView | |
tasks[].checklistrequired | array of string | |
tasks[].clientVisiblerequired | boolean | |
tasks[].descriptionrequired | string | |
tasks[].durationDaysrequired | integer | |
tasks[].estimateMinutesrequired | integer | |
tasks[].parentTaskPublicId | string or null | |
tasks[].phasePublicId | string or null | |
tasks[].positionrequired | integer | |
tasks[].predecessorsrequired | array of TaskDependencyView | |
tasks[].predecessors[].lagDaysrequired | integer | |
tasks[].predecessors[].taskPublicIdrequired | string | |
tasks[].priorityrequired | string | |
tasks[].publicIdrequired | string | |
tasks[].rolePlaceholderrequired | string | |
tasks[].startOffsetDaysrequired | integer | |
tasks[].titlerequired | string |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectTemplateView | Success. |
400 | application/problem+json, ProblemDetails | The request body is not valid JSON. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
activerequired | boolean | |
categoryrequired | string | |
defaultBillingModerequired | string | |
defaultBudgetMinutesrequired | integer | |
defaultStatusEmailCadencerequired | string | |
defaultStatusEmailWeekdayrequired | integer | |
descriptionrequired | string | |
durationDaysrequired | integer | |
familyPublicIdrequired | string | |
isCurrentrequired | boolean | |
isSeedrequired | boolean | |
milestonesrequired | array of TemplateMilestoneView | |
milestones[].amountBprequired | integer | |
milestones[].clientVisiblerequired | boolean | |
milestones[].descriptionrequired | string | |
milestones[].namerequired | string | |
milestones[].offsetDaysrequired | integer | |
milestones[].phasePublicId | string or null | |
milestones[].positionrequired | integer | |
milestones[].publicIdrequired | string | |
milestones[].requiresClientAcceptancerequired | boolean | |
namerequired | string | |
phasesrequired | array of TemplatePhaseView | |
phases[].billingModeOverride | string or null | |
phases[].budgetAmountBp | integer or null | |
phases[].budgetMinutes | integer or null | |
phases[].namerequired | string | |
phases[].positionrequired | integer | |
phases[].publicIdrequired | string | |
publicIdrequired | string | |
tasksrequired | array of TemplateTaskView | |
tasks[].checklistrequired | array of string | |
tasks[].clientVisiblerequired | boolean | |
tasks[].descriptionrequired | string | |
tasks[].durationDaysrequired | integer | |
tasks[].estimateMinutesrequired | integer | |
tasks[].parentTaskPublicId | string or null | |
tasks[].phasePublicId | string or null | |
tasks[].positionrequired | integer | |
tasks[].predecessorsrequired | array of TaskDependencyView | |
tasks[].predecessors[].lagDaysrequired | integer | |
tasks[].predecessors[].taskPublicIdrequired | string | |
tasks[].priorityrequired | string | |
tasks[].publicIdrequired | string | |
tasks[].rolePlaceholderrequired | string | |
tasks[].startOffsetDaysrequired | integer | |
tasks[].titlerequired | string | |
usedCountrequired | integer | |
versionrequired | integer |
Request samples
Section titled “Request samples”# 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" } ]}'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Content-Type' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$body = @'{ "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" } ]}'@
$response = Invoke-RestMethod ` -Method Put ` -Uri 'https://depot.example.com/api/v1/projects/templates/<tplID>' ` -Headers $headers ` -ContentType 'application/json' ` -Body $body
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/templates/<tplID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json",}cookies = { "outpost_console": "<console-session>",}payload = { "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", }, ],}
response = requests.put(url, headers=headers, cookies=cookies, json=payload, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "bytes" "fmt" "io" "log" "net/http")
func main() { body := []byte(`{ "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" } ]}`)
req, err := http.NewRequest(http.MethodPut, "https://depot.example.com/api/v1/projects/templates/<tplID>", bytes.NewReader(body)) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.Header.Set("Content-Type", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/templates/<tplID>";
const response = await fetch(url, { method: "PUT", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify({ "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" } ] }),});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;using System.Text;
using var client = new HttpClient();
const string body = """{ "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" } ]}""";
var request = new HttpRequestMessage(HttpMethod.Put, "https://depot.example.com/api/v1/projects/templates/<tplID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");request.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());DELETE /api/v1/projects/templates/{tplID}
Section titled “DELETE /api/v1/projects/templates/{tplID}”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.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
tplID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
204 | None | Success, with no body. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Delete ` -Uri 'https://depot.example.com/api/v1/projects/templates/<tplID>' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/templates/<tplID>"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.delete(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodDelete, "https://depot.example.com/api/v1/projects/templates/<tplID>", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/templates/<tplID>";
const response = await fetch(url, { method: "DELETE", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Delete, "https://depot.example.com/api/v1/projects/templates/<tplID>");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
tplID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, ProjectTemplateView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:manage. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
activerequired | boolean | |
categoryrequired | string | |
defaultBillingModerequired | string | |
defaultBudgetMinutesrequired | integer | |
defaultStatusEmailCadencerequired | string | |
defaultStatusEmailWeekdayrequired | integer | |
descriptionrequired | string | |
durationDaysrequired | integer | |
familyPublicIdrequired | string | |
isCurrentrequired | boolean | |
isSeedrequired | boolean | |
milestonesrequired | array of TemplateMilestoneView | |
milestones[].amountBprequired | integer | |
milestones[].clientVisiblerequired | boolean | |
milestones[].descriptionrequired | string | |
milestones[].namerequired | string | |
milestones[].offsetDaysrequired | integer | |
milestones[].phasePublicId | string or null | |
milestones[].positionrequired | integer | |
milestones[].publicIdrequired | string | |
milestones[].requiresClientAcceptancerequired | boolean | |
namerequired | string | |
phasesrequired | array of TemplatePhaseView | |
phases[].billingModeOverride | string or null | |
phases[].budgetAmountBp | integer or null | |
phases[].budgetMinutes | integer or null | |
phases[].namerequired | string | |
phases[].positionrequired | integer | |
phases[].publicIdrequired | string | |
publicIdrequired | string | |
tasksrequired | array of TemplateTaskView | |
tasks[].checklistrequired | array of string | |
tasks[].clientVisiblerequired | boolean | |
tasks[].descriptionrequired | string | |
tasks[].durationDaysrequired | integer | |
tasks[].estimateMinutesrequired | integer | |
tasks[].parentTaskPublicId | string or null | |
tasks[].phasePublicId | string or null | |
tasks[].positionrequired | integer | |
tasks[].predecessorsrequired | array of TaskDependencyView | |
tasks[].predecessors[].lagDaysrequired | integer | |
tasks[].predecessors[].taskPublicIdrequired | string | |
tasks[].priorityrequired | string | |
tasks[].publicIdrequired | string | |
tasks[].rolePlaceholderrequired | string | |
tasks[].startOffsetDaysrequired | integer | |
tasks[].titlerequired | string | |
usedCountrequired | integer | |
versionrequired | integer |
Request samples
Section titled “Request samples”# 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>'# Sign in first. outpost_console is a session cookie, so send it with every request.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Post ` -Uri 'https://depot.example.com/api/v1/projects/templates/<tplID>/retire' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# Sign in first. outpost_console is a session cookie, so send it with every request.
import requests
url = "https://depot.example.com/api/v1/projects/templates/<tplID>/retire"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.post(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// Sign in first. outpost_console is a session cookie, so send it with every request.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodPost, "https://depot.example.com/api/v1/projects/templates/<tplID>/retire", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// Sign in first. outpost_console is a session cookie, so send it with every request.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/templates/<tplID>/retire";
const response = await fetch(url, { method: "POST", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// Sign in first. outpost_console is a session cookie, so send it with every request.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://depot.example.com/api/v1/projects/templates/<tplID>/retire");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
tplID | path | string | Yes | A uuid. |
Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
200 | application/json, PagedResultProjectTemplateView | Success. |
400 | application/problem+json, ProblemDetails | One or more validation errors occurred. |
401 | application/problem+json, ProblemDetails | No signed-in identity. |
403 | application/problem+json, ProblemDetails | The identity does not hold project:read. |
404 | application/problem+json, ProblemDetails | No resource matches that id. |
500 | application/problem+json, ProblemDetails | The request failed. |
503 | application/problem+json, ProblemDetails | Projects are not available on this server. |
200 response body
| Field | Type | Description |
|---|---|---|
itemsrequired | array of ProjectTemplateView | |
items[].activerequired | boolean | |
items[].categoryrequired | string | |
items[].defaultBillingModerequired | string | |
items[].defaultBudgetMinutesrequired | integer | |
items[].defaultStatusEmailCadencerequired | string | |
items[].defaultStatusEmailWeekdayrequired | integer | |
items[].descriptionrequired | string | |
items[].durationDaysrequired | integer | |
items[].familyPublicIdrequired | string | |
items[].isCurrentrequired | boolean | |
items[].isSeedrequired | boolean | |
items[].milestonesrequired | array of TemplateMilestoneView | |
items[].milestones[].amountBprequired | integer | |
items[].milestones[].clientVisiblerequired | boolean | |
items[].milestones[].descriptionrequired | string | |
items[].milestones[].namerequired | string | |
items[].milestones[].offsetDaysrequired | integer | |
items[].milestones[].phasePublicId | string or null | |
items[].milestones[].positionrequired | integer | |
items[].milestones[].publicIdrequired | string | |
items[].milestones[].requiresClientAcceptancerequired | boolean | |
items[].namerequired | string | |
items[].phasesrequired | array of TemplatePhaseView | |
items[].phases[].billingModeOverride | string or null | |
items[].phases[].budgetAmountBp | integer or null | |
items[].phases[].budgetMinutes | integer or null | |
items[].phases[].namerequired | string | |
items[].phases[].positionrequired | integer | |
items[].phases[].publicIdrequired | string | |
items[].publicIdrequired | string | |
items[].tasksrequired | array of TemplateTaskView | |
items[].tasks[].checklistrequired | array of string | |
items[].tasks[].clientVisiblerequired | boolean | |
items[].tasks[].descriptionrequired | string | |
items[].tasks[].durationDaysrequired | integer | |
items[].tasks[].estimateMinutesrequired | integer | |
items[].tasks[].parentTaskPublicId | string or null | |
items[].tasks[].phasePublicId | string or null | |
items[].tasks[].positionrequired | integer | |
items[].tasks[].predecessorsrequired | array of TaskDependencyView | |
items[].tasks[].predecessors[].lagDaysrequired | integer | |
items[].tasks[].predecessors[].taskPublicIdrequired | string | |
items[].tasks[].priorityrequired | string | |
items[].tasks[].publicIdrequired | string | |
items[].tasks[].rolePlaceholderrequired | string | |
items[].tasks[].startOffsetDaysrequired | integer | |
items[].tasks[].titlerequired | string | |
items[].usedCountrequired | integer | |
items[].versionrequired | integer | |
pagerequired | integer | |
pageSizerequired | integer | |
totalrequired | integer |
Request samples
Section titled “Request samples”# 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>'# 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.
$headers = @{ 'X-CSRF-Token' = '<csrf-token>' 'Accept' = 'application/json' 'Cookie' = 'outpost_console=<console-session>'}
$response = Invoke-RestMethod ` -Method Get ` -Uri 'https://depot.example.com/api/v1/projects/templates/<tplID>/versions' ` -Headers $headers
$response | ConvertTo-Json -Depth 10# 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.
import requests
url = "https://depot.example.com/api/v1/projects/templates/<tplID>/versions"headers = { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json",}cookies = { "outpost_console": "<console-session>",}
response = requests.get(url, headers=headers, cookies=cookies, timeout=30)response.raise_for_status()print(response.json())// 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.package main
import ( "fmt" "io" "log" "net/http")
func main() { req, err := http.NewRequest(http.MethodGet, "https://depot.example.com/api/v1/projects/templates/<tplID>/versions", nil) if err != nil { log.Fatal(err) }
req.Header.Set("X-CSRF-Token", "<csrf-token>") req.Header.Set("Accept", "application/json") req.AddCookie(&http.Cookie{Name: "outpost_console", Value: "<console-session>"})
resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close()
out, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(resp.Status, string(out))}// 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.// The session cookie is set by signing in. A script cannot set it itself.
const url = "https://depot.example.com/api/v1/projects/templates/<tplID>/versions";
const response = await fetch(url, { method: "GET", headers: { "X-CSRF-Token": "<csrf-token>", "Accept": "application/json", }, credentials: "include",});
if (!response.ok) { throw new Error(`Request failed with status ${response.status}`);}
const data = await response.json();console.log(data);// 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.
using System;using System.Net.Http;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://depot.example.com/api/v1/projects/templates/<tplID>/versions");request.Headers.TryAddWithoutValidation("X-CSRF-Token", "<csrf-token>");request.Headers.TryAddWithoutValidation("Accept", "application/json");request.Headers.TryAddWithoutValidation("Cookie", "outpost_console=<console-session>");
var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());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.