Projects
/api/v1/projectsNewest first. Filter by status and customer.
Permission: projects:read
Query parameters
status"active" | "done" | "archived"only projects with this statuscontactIdstringonly projects of this customermax. 128 characterslimitintegerNumber of entries (1–100)1–100 · Default: 25cursorstring`nextCursor` of the previous pagemax. 500 characters
Response 200
object"list"requireddataArray<Project>requiredidstringrequirednumberstring | nullrequiredProject number from the "project" number rangenamestringrequireddescriptionstring | nullrequiredcontactIdstring | nullrequiredCustomer (contact ID)contactNamestring | nullrequiredDisplay name of the customerstatus"active" | "done" | "archived"requiredbudgetProjectBudget | nullrequiredhourlyRateCentsinteger | nullrequiredHourly rate in cents (net or gross depending on the invoice)0–10000000billablebooleanrequiredDefault for new time entriesstartDatestring (date) | nullrequiredDate (YYYY-MM-DD)endDatestring (date) | nullrequiredDate (YYYY-MM-DD)tasksArray<ProjectTask>requiredidstringrequirednamestringrequiredhourlyRateCentsinteger | nullrequireddifferent hourly rate; null = project rate0–10000000billableboolean | nullrequirednull = as projectdonebooleanrequired
archivedAtstring (date-time) | nullrequiredTimestamp (ISO 8601)createdAtstring (date-time)requiredTimestamp (ISO 8601)updatedAtstring (date-time)requiredTimestamp (ISO 8601)
hasMorebooleanrequirednextCursorstring | nullrequired
curl 'https://www.debt-flow.io/api/v1/projects' \
-H "Authorization: Bearer $DEBTFLOW_API_KEY"{
"object": "list",
"data": [
{
"id": "string",
"number": "string",
"name": "string",
"description": "string",
"contactId": "string",
"contactName": "string",
"status": "active",
"budget": null,
"hourlyRateCents": 0,
"billable": false,
"startDate": "2026-11-01",
"endDate": "2026-11-01",
"tasks": [
{
"id": null,
"name": null,
"hourlyRateCents": null,
"billable": null,
"done": null
}
],
"archivedAt": "2026-11-01T09:30:00.000Z",
"createdAt": "2026-11-01T09:30:00.000Z",
"updatedAt": "2026-11-01T09:30:00.000Z"
}
],
"hasMore": false,
"nextCursor": "string"
}/api/v1/projectsCustomer (contactId), budget in hours or euros, hourly rate and optional tasks. The project number comes from the project number range (can be turned off with assignNumber: false). Triggers project.created.
Permission: projects:write
Headers
Idempotency-KeystringUnique key (8–255 characters). Repeated requests with the same key return the same response for 24 h.max. 255 characters
Body (JSON) · ProjectCreate
namestringrequiredmax. 160 charactersdescriptionstring | nullmax. 2000 characterscontactIdstring | nullmax. 128 charactersstatus"active" | "done" | "archived"Default: "active"budgetProjectBudget | nullhourlyRateCentsinteger | nullHourly rate in cents (net or gross depending on the invoice)0–10000000billablebooleanDefault: truestartDatestring (date) | nullDate (YYYY-MM-DD)endDatestring (date) | nullDate (YYYY-MM-DD)tasksArray<object>namestringrequiredmax. 120 charactershourlyRateCentsinteger | nullHourly rate in cents (net or gross depending on the invoice)0–10000000billableboolean | null
assignNumberbooleanAssign project number from the number rangeDefault: true
Response 201 · Project
idstringrequirednumberstring | nullrequiredProject number from the "project" number rangenamestringrequireddescriptionstring | nullrequiredcontactIdstring | nullrequiredCustomer (contact ID)contactNamestring | nullrequiredDisplay name of the customerstatus"active" | "done" | "archived"requiredbudgetProjectBudget | nullrequiredhourlyRateCentsinteger | nullrequiredHourly rate in cents (net or gross depending on the invoice)0–10000000billablebooleanrequiredDefault for new time entriesstartDatestring (date) | nullrequiredDate (YYYY-MM-DD)endDatestring (date) | nullrequiredDate (YYYY-MM-DD)tasksArray<ProjectTask>requiredidstringrequirednamestringrequiredhourlyRateCentsinteger | nullrequireddifferent hourly rate; null = project rate0–10000000billableboolean | nullrequirednull = as projectdonebooleanrequired
archivedAtstring (date-time) | nullrequiredTimestamp (ISO 8601)createdAtstring (date-time)requiredTimestamp (ISO 8601)updatedAtstring (date-time)requiredTimestamp (ISO 8601)
curl -X POST 'https://www.debt-flow.io/api/v1/projects' \
-H "Authorization: Bearer $DEBTFLOW_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"description": "string",
"contactId": "string",
"status": "active",
"budget": {
"type": "hours",
"hours": 0
},
"hourlyRateCents": 0,
"billable": true,
"startDate": "2026-11-01",
"endDate": "2026-11-01",
"tasks": [
{
"name": "string",
"hourlyRateCents": 0,
"billable": false
}
],
"assignNumber": true
}'{
"id": "string",
"number": "string",
"name": "string",
"description": "string",
"contactId": "string",
"contactName": "string",
"status": "active",
"budget": {
"type": "hours",
"hours": 0
},
"hourlyRateCents": 0,
"billable": false,
"startDate": "2026-11-01",
"endDate": "2026-11-01",
"tasks": [
{
"id": "string",
"name": "string",
"hourlyRateCents": 0,
"billable": false,
"done": false
}
],
"archivedAt": "2026-11-01T09:30:00.000Z",
"createdAt": "2026-11-01T09:30:00.000Z",
"updatedAt": "2026-11-01T09:30:00.000Z"
}/api/v1/projects/{id}Permission: projects:read
Path parameters
idstringrequiredResource IDmax. 128 characters
Response 200 · Project
idstringrequirednumberstring | nullrequiredProject number from the "project" number rangenamestringrequireddescriptionstring | nullrequiredcontactIdstring | nullrequiredCustomer (contact ID)contactNamestring | nullrequiredDisplay name of the customerstatus"active" | "done" | "archived"requiredbudgetProjectBudget | nullrequiredhourlyRateCentsinteger | nullrequiredHourly rate in cents (net or gross depending on the invoice)0–10000000billablebooleanrequiredDefault for new time entriesstartDatestring (date) | nullrequiredDate (YYYY-MM-DD)endDatestring (date) | nullrequiredDate (YYYY-MM-DD)tasksArray<ProjectTask>requiredidstringrequirednamestringrequiredhourlyRateCentsinteger | nullrequireddifferent hourly rate; null = project rate0–10000000billableboolean | nullrequirednull = as projectdonebooleanrequired
archivedAtstring (date-time) | nullrequiredTimestamp (ISO 8601)createdAtstring (date-time)requiredTimestamp (ISO 8601)updatedAtstring (date-time)requiredTimestamp (ISO 8601)
curl 'https://www.debt-flow.io/api/v1/projects/ID' \
-H "Authorization: Bearer $DEBTFLOW_API_KEY"{
"id": "string",
"number": "string",
"name": "string",
"description": "string",
"contactId": "string",
"contactName": "string",
"status": "active",
"budget": {
"type": "hours",
"hours": 0
},
"hourlyRateCents": 0,
"billable": false,
"startDate": "2026-11-01",
"endDate": "2026-11-01",
"tasks": [
{
"id": "string",
"name": "string",
"hourlyRateCents": 0,
"billable": false,
"done": false
}
],
"archivedAt": "2026-11-01T09:30:00.000Z",
"createdAt": "2026-11-01T09:30:00.000Z",
"updatedAt": "2026-11-01T09:30:00.000Z"
}/api/v1/projects/{id}Only the fields you pass are changed. status: "archived" archives the project (event project.archived). A new customer is carried over to time entries that have not yet been invoiced.
Permission: projects:write
Path parameters
idstringrequiredResource IDmax. 128 characters
Body (JSON) · ProjectUpdate
namestringmax. 160 charactersdescriptionstring | nullmax. 2000 characterscontactIdstring | nullmax. 128 charactersstatus"active" | "done" | "archived"budgetProjectBudget | nullhourlyRateCentsinteger | nullHourly rate in cents (net or gross depending on the invoice)0–10000000billablebooleanstartDatestring (date) | nullDate (YYYY-MM-DD)endDatestring (date) | nullDate (YYYY-MM-DD)
Response 200 · Project
idstringrequirednumberstring | nullrequiredProject number from the "project" number rangenamestringrequireddescriptionstring | nullrequiredcontactIdstring | nullrequiredCustomer (contact ID)contactNamestring | nullrequiredDisplay name of the customerstatus"active" | "done" | "archived"requiredbudgetProjectBudget | nullrequiredhourlyRateCentsinteger | nullrequiredHourly rate in cents (net or gross depending on the invoice)0–10000000billablebooleanrequiredDefault for new time entriesstartDatestring (date) | nullrequiredDate (YYYY-MM-DD)endDatestring (date) | nullrequiredDate (YYYY-MM-DD)tasksArray<ProjectTask>requiredidstringrequirednamestringrequiredhourlyRateCentsinteger | nullrequireddifferent hourly rate; null = project rate0–10000000billableboolean | nullrequirednull = as projectdonebooleanrequired
archivedAtstring (date-time) | nullrequiredTimestamp (ISO 8601)createdAtstring (date-time)requiredTimestamp (ISO 8601)updatedAtstring (date-time)requiredTimestamp (ISO 8601)
curl -X PATCH 'https://www.debt-flow.io/api/v1/projects/ID' \
-H "Authorization: Bearer $DEBTFLOW_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"description": "string",
"contactId": "string",
"status": "active",
"budget": {
"type": "hours",
"hours": 0
},
"hourlyRateCents": 0,
"billable": false,
"startDate": "2026-11-01",
"endDate": "2026-11-01"
}'{
"id": "string",
"number": "string",
"name": "string",
"description": "string",
"contactId": "string",
"contactName": "string",
"status": "active",
"budget": {
"type": "hours",
"hours": 0
},
"hourlyRateCents": 0,
"billable": false,
"startDate": "2026-11-01",
"endDate": "2026-11-01",
"tasks": [
{
"id": "string",
"name": "string",
"hourlyRateCents": 0,
"billable": false,
"done": false
}
],
"archivedAt": "2026-11-01T09:30:00.000Z",
"createdAt": "2026-11-01T09:30:00.000Z",
"updatedAt": "2026-11-01T09:30:00.000Z"
}/api/v1/projects/{id}Only projects without time entries (otherwise 409 project_has_entries – archive instead).
Permission: projects:write
Path parameters
idstringrequiredResource IDmax. 128 characters
Response 204
Success, no content
curl -X DELETE 'https://www.debt-flow.io/api/v1/projects/ID' \
-H "Authorization: Bearer $DEBTFLOW_API_KEY"/api/v1/projects/{id}/summaryRecorded, billable, open and invoiced time and amounts over the entire duration, budget usage and breakdown by task. Amounts = exact minutes × hourly rate (without billing increment).
Permission: projects:read, time:read
Path parameters
idstringrequiredResource IDmax. 128 characters
Response 200 · ProjectSummary
projectIdstringrequiredentriesintegerrequired-9007199254740991–9007199254740991minutesintegerrequired-9007199254740991–9007199254740991billableMinutesintegerrequired-9007199254740991–9007199254740991nonBillableMinutesintegerrequired-9007199254740991–9007199254740991unbilledMinutesintegerrequired-9007199254740991–9007199254740991invoicedMinutesintegerrequired-9007199254740991–9007199254740991billableAmountCentsintegerrequiredbillable time × hourly rate-9007199254740991–9007199254740991unbilledAmountCentsintegerrequirednot yet invoiced-9007199254740991–9007199254740991invoicedAmountCentsintegerrequired-9007199254740991–9007199254740991missingRateMinutesintegerrequiredbillable minutes without an hourly rate (not included in the amount)-9007199254740991–9007199254740991firstDatestring (date) | nullrequiredDate (YYYY-MM-DD)lastDatestring (date) | nullrequiredDate (YYYY-MM-DD)budgetProjectBudget | nullrequiredbudgetUsedPercentnumber | nullrequiredbudget used in per cent (hours: all recorded; amount: billable amount)budgetRemainingnumber | nullrequiredRemaining in hours or centsbyTaskArray<TimeSummaryRow>requiredkeystringrequiredlabelstringrequiredentriesintegerrequired-9007199254740991–9007199254740991minutesintegerrequired-9007199254740991–9007199254740991billableMinutesintegerrequired-9007199254740991–9007199254740991nonBillableMinutesintegerrequired-9007199254740991–9007199254740991unbilledMinutesintegerrequired-9007199254740991–9007199254740991invoicedMinutesintegerrequired-9007199254740991–9007199254740991billableAmountCentsintegerrequiredbillable time × hourly rate-9007199254740991–9007199254740991unbilledAmountCentsintegerrequirednot yet invoiced-9007199254740991–9007199254740991invoicedAmountCentsintegerrequired-9007199254740991–9007199254740991missingRateMinutesintegerrequiredbillable minutes without an hourly rate (not included in the amount)-9007199254740991–9007199254740991
curl 'https://www.debt-flow.io/api/v1/projects/ID/summary' \
-H "Authorization: Bearer $DEBTFLOW_API_KEY"{
"projectId": "string",
"entries": 0,
"minutes": 0,
"billableMinutes": 0,
"nonBillableMinutes": 0,
"unbilledMinutes": 0,
"invoicedMinutes": 0,
"billableAmountCents": 0,
"unbilledAmountCents": 0,
"invoicedAmountCents": 0,
"missingRateMinutes": 0,
"firstDate": "2026-11-01",
"lastDate": "2026-11-01",
"budget": {
"type": "hours",
"hours": 0
},
"budgetUsedPercent": 0,
"budgetRemaining": 0,
"byTask": [
{
"key": "string",
"label": "string",
"entries": 0,
"minutes": 0,
"billableMinutes": 0,
"nonBillableMinutes": 0,
"unbilledMinutes": 0,
"invoicedMinutes": 0,
"billableAmountCents": 0,
"unbilledAmountCents": 0,
"invoicedAmountCents": 0,
"missingRateMinutes": 0
}
]
}/api/v1/projects/{id}/tasksTasks are optional. A task's own hourly rate/billable setting overrides the project values. Response: the updated project.
Permission: projects:write
Path parameters
idstringrequiredResource IDmax. 128 characters
Headers
Idempotency-KeystringUnique key (8–255 characters). Repeated requests with the same key return the same response for 24 h.max. 255 characters
Body (JSON) · ProjectTaskCreate
namestringrequiredmax. 120 charactershourlyRateCentsinteger | nullHourly rate in cents (net or gross depending on the invoice)0–10000000billableboolean | null
Response 201 · Project
idstringrequirednumberstring | nullrequiredProject number from the "project" number rangenamestringrequireddescriptionstring | nullrequiredcontactIdstring | nullrequiredCustomer (contact ID)contactNamestring | nullrequiredDisplay name of the customerstatus"active" | "done" | "archived"requiredbudgetProjectBudget | nullrequiredhourlyRateCentsinteger | nullrequiredHourly rate in cents (net or gross depending on the invoice)0–10000000billablebooleanrequiredDefault for new time entriesstartDatestring (date) | nullrequiredDate (YYYY-MM-DD)endDatestring (date) | nullrequiredDate (YYYY-MM-DD)tasksArray<ProjectTask>requiredidstringrequirednamestringrequiredhourlyRateCentsinteger | nullrequireddifferent hourly rate; null = project rate0–10000000billableboolean | nullrequirednull = as projectdonebooleanrequired
archivedAtstring (date-time) | nullrequiredTimestamp (ISO 8601)createdAtstring (date-time)requiredTimestamp (ISO 8601)updatedAtstring (date-time)requiredTimestamp (ISO 8601)
curl -X POST 'https://www.debt-flow.io/api/v1/projects/ID/tasks' \
-H "Authorization: Bearer $DEBTFLOW_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"hourlyRateCents": 0,
"billable": false
}'{
"id": "string",
"number": "string",
"name": "string",
"description": "string",
"contactId": "string",
"contactName": "string",
"status": "active",
"budget": {
"type": "hours",
"hours": 0
},
"hourlyRateCents": 0,
"billable": false,
"startDate": "2026-11-01",
"endDate": "2026-11-01",
"tasks": [
{
"id": "string",
"name": "string",
"hourlyRateCents": 0,
"billable": false,
"done": false
}
],
"archivedAt": "2026-11-01T09:30:00.000Z",
"createdAt": "2026-11-01T09:30:00.000Z",
"updatedAt": "2026-11-01T09:30:00.000Z"
}/api/v1/projects/{id}/tasks/{taskId}Name, hourly rate, billable or done. Response: the updated project.
Permission: projects:write
Path parameters
idstringrequiredmax. 128 characterstaskIdstringrequiredTask IDmax. 128 characters
Body (JSON) · ProjectTaskUpdate
namestringmax. 120 charactershourlyRateCentsinteger | nullHourly rate in cents (net or gross depending on the invoice)0–10000000billableboolean | nulldoneboolean
Response 200 · Project
idstringrequirednumberstring | nullrequiredProject number from the "project" number rangenamestringrequireddescriptionstring | nullrequiredcontactIdstring | nullrequiredCustomer (contact ID)contactNamestring | nullrequiredDisplay name of the customerstatus"active" | "done" | "archived"requiredbudgetProjectBudget | nullrequiredhourlyRateCentsinteger | nullrequiredHourly rate in cents (net or gross depending on the invoice)0–10000000billablebooleanrequiredDefault for new time entriesstartDatestring (date) | nullrequiredDate (YYYY-MM-DD)endDatestring (date) | nullrequiredDate (YYYY-MM-DD)tasksArray<ProjectTask>requiredidstringrequirednamestringrequiredhourlyRateCentsinteger | nullrequireddifferent hourly rate; null = project rate0–10000000billableboolean | nullrequirednull = as projectdonebooleanrequired
archivedAtstring (date-time) | nullrequiredTimestamp (ISO 8601)createdAtstring (date-time)requiredTimestamp (ISO 8601)updatedAtstring (date-time)requiredTimestamp (ISO 8601)
curl -X PATCH 'https://www.debt-flow.io/api/v1/projects/ID/tasks/TASKID' \
-H "Authorization: Bearer $DEBTFLOW_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"hourlyRateCents": 0,
"billable": false,
"done": false
}'{
"id": "string",
"number": "string",
"name": "string",
"description": "string",
"contactId": "string",
"contactName": "string",
"status": "active",
"budget": {
"type": "hours",
"hours": 0
},
"hourlyRateCents": 0,
"billable": false,
"startDate": "2026-11-01",
"endDate": "2026-11-01",
"tasks": [
{
"id": "string",
"name": "string",
"hourlyRateCents": 0,
"billable": false,
"done": false
}
],
"archivedAt": "2026-11-01T09:30:00.000Z",
"createdAt": "2026-11-01T09:30:00.000Z",
"updatedAt": "2026-11-01T09:30:00.000Z"
}/api/v1/projects/{id}/tasks/{taskId}Only tasks without time entries (otherwise 409 task_has_entries – mark as done instead). Response: the updated project.
Permission: projects:write
Path parameters
idstringrequiredmax. 128 characterstaskIdstringrequiredTask IDmax. 128 characters
Response 200 · Project
idstringrequirednumberstring | nullrequiredProject number from the "project" number rangenamestringrequireddescriptionstring | nullrequiredcontactIdstring | nullrequiredCustomer (contact ID)contactNamestring | nullrequiredDisplay name of the customerstatus"active" | "done" | "archived"requiredbudgetProjectBudget | nullrequiredhourlyRateCentsinteger | nullrequiredHourly rate in cents (net or gross depending on the invoice)0–10000000billablebooleanrequiredDefault for new time entriesstartDatestring (date) | nullrequiredDate (YYYY-MM-DD)endDatestring (date) | nullrequiredDate (YYYY-MM-DD)tasksArray<ProjectTask>requiredidstringrequirednamestringrequiredhourlyRateCentsinteger | nullrequireddifferent hourly rate; null = project rate0–10000000billableboolean | nullrequirednull = as projectdonebooleanrequired
archivedAtstring (date-time) | nullrequiredTimestamp (ISO 8601)createdAtstring (date-time)requiredTimestamp (ISO 8601)updatedAtstring (date-time)requiredTimestamp (ISO 8601)
curl -X DELETE 'https://www.debt-flow.io/api/v1/projects/ID/tasks/TASKID' \
-H "Authorization: Bearer $DEBTFLOW_API_KEY"{
"id": "string",
"number": "string",
"name": "string",
"description": "string",
"contactId": "string",
"contactName": "string",
"status": "active",
"budget": {
"type": "hours",
"hours": 0
},
"hourlyRateCents": 0,
"billable": false,
"startDate": "2026-11-01",
"endDate": "2026-11-01",
"tasks": [
{
"id": "string",
"name": "string",
"hourlyRateCents": 0,
"billable": false,
"done": false
}
],
"archivedAt": "2026-11-01T09:30:00.000Z",
"createdAt": "2026-11-01T09:30:00.000Z",
"updatedAt": "2026-11-01T09:30:00.000Z"
}