Skip to content

Project Data

This guide covers how to retrieve project metadata from Ditio, including project hierarchies, work breakdown structures (WBS / work orders), and the supporting catalogues you need to resolve IDs in other exports.

  • You need to map Ditio projects to your ERP or accounting system
  • You want to display project structures in your BI tool
  • You need WBS codes for cost allocation
  • You’re building a dashboard that shows project-level KPIs
  • API credentials with the reportingapiv1 scope — see Authentication

Examples use the environment variables from Environments and default to the test environment.

EndpointWhat it returns
GET /v1/projectProject list with details
GET /v1/project/work-breakdown-structureWork breakdown structure (all work orders)
GET /v1/resourceMachine catalogue
GET /v1/userUser roster

All are paginated with ContinuationToken (see Pagination) and support incremental sync with ModifiedSince — see Full vs incremental sync.

Terminal window
curl -H "Authorization: Bearer $TOKEN" \
"$DITIO_REPORTING_BASE/v1/project"
Terminal window
curl -H "Authorization: Bearer $TOKEN" \
"$DITIO_REPORTING_BASE/v1/project/work-breakdown-structure"

To build a complete picture, fetch projects, then WBS entries, then correlate by project ID:

import os
from collections import defaultdict
# Paste get_token (/getting-started/authentication/#getting-a-token-in-your-scripts) and fetch_all (/getting-started/pagination/#fetching-all-pages-in-code) above this.
REPORTING_BASE = os.environ.get(
"DITIO_REPORTING_BASE", "https://core-api.ditio.dev/reporting"
)
headers = {"Authorization": f"Bearer {get_token('reportingapiv1')}"}
projects = list(fetch_all(f"{REPORTING_BASE}/v1/project", headers))
wbs_entries = list(fetch_all(f"{REPORTING_BASE}/v1/project/work-breakdown-structure", headers))
wbs_by_project = defaultdict(list)
for wbs_entry in wbs_entries:
wbs_by_project[wbs_entry["projectId"]].append(wbs_entry)
for project in projects:
codes = wbs_by_project.get(project["id"], [])
print(f"{project['name']}: {len(codes)} WBS entries")
using System.Net.Http.Headers;
using System.Text.Json;
var reportingBase = Environment.GetEnvironmentVariable("DITIO_REPORTING_BASE")
?? "https://core-api.ditio.dev/reporting";
using var http = new HttpClient();
// DitioAuth.GetTokenAsync: see /getting-started/authentication/#token-expiry
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", await DitioAuth.GetTokenAsync(http, "reportingapiv1"));
// DitioPaging.FetchAllAsync: see /getting-started/pagination/#fetching-all-pages-in-code
var wbsCountByProject = new Dictionary<string, int>();
await foreach (var wbsEntry in DitioPaging.FetchAllAsync<JsonElement>(
http, $"{reportingBase}/v1/project/work-breakdown-structure"))
{
var projectId = wbsEntry.GetProperty("projectId").GetString() ?? "";
wbsCountByProject[projectId] = wbsCountByProject.GetValueOrDefault(projectId) + 1;
}
await foreach (var project in DitioPaging.FetchAllAsync<JsonElement>(http, $"{reportingBase}/v1/project"))
{
var projectId = project.GetProperty("id").GetString() ?? "";
Console.WriteLine($"{project.GetProperty("name").GetString()}: " +
$"{wbsCountByProject.GetValueOrDefault(projectId)} WBS entries");
}