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.
When to use this
Section titled “When to use this”- 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
Prerequisites
Section titled “Prerequisites”- API credentials with the
reportingapiv1scope — see Authentication
Examples use the environment variables from Environments and default to the test environment.
Available endpoints
Section titled “Available endpoints”| Endpoint | What it returns |
|---|---|
GET /v1/project | Project list with details |
GET /v1/project/work-breakdown-structure | Work breakdown structure (all work orders) |
GET /v1/resource | Machine catalogue |
GET /v1/user | User roster |
All are paginated with ContinuationToken (see
Pagination) and support incremental sync with
ModifiedSince — see Full vs incremental
sync.
Fetch projects
Section titled “Fetch projects”curl -H "Authorization: Bearer $TOKEN" \ "$DITIO_REPORTING_BASE/v1/project"Fetch the work breakdown structure
Section titled “Fetch the work breakdown structure”curl -H "Authorization: Bearer $TOKEN" \ "$DITIO_REPORTING_BASE/v1/project/work-breakdown-structure"Combining data (Python)
Section titled “Combining data (Python)”To build a complete picture, fetch projects, then WBS entries, then correlate by project ID:
import osfrom 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")Combining data (C#)
Section titled “Combining data (C#)”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-expiryhttp.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await DitioAuth.GetTokenAsync(http, "reportingapiv1"));
// DitioPaging.FetchAllAsync: see /getting-started/pagination/#fetching-all-pages-in-codevar 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");}Related
Section titled “Related”- Projects (Integration API) — creating and updating projects
- Work Orders (Integration API) — creating and updating work orders
- Export Time Data — time registrations reference project IDs
- Machine Data — the machine catalogue and machine usage