Task Schema Reference Guide
Complete developer reference for the normalized schedule schema
Schema Version: v1.3.0 — Last Updated: March 2026 — Covers Health & Analysis, Forensics, and Import APIs
Overview
The Normalized Schedule Schema is the canonical, platform-agnostic intermediate representation used by all Bellator Schedule Intelligence APIs. Whether you send data directly as JSON or import a native file through the Import APIs, every analysis endpoint consumes the same schema.
Architecture: Import → Normalize → Analyze
┌──────────────────────────────────────────────────────┐
│ SOURCE TOOLS │
│ (MS Project .mpp, Primavera P6 .xer, JSON) │
└──────────────────┬───────────────────────────────────┘
│ Native formats
▼
┌──────────────────────────────────────────────────────┐
│ IMPORT APIs │
│ POST /api/v1/import/mpp → Normalized JSON │
│ POST /api/v1/import/xer → Normalized JSON │
└──────────────────┬───────────────────────────────────┘
│ Normalized Schedule JSON
▼
┌──────────────────────────────────────────────────────┐
│ NORMALIZED SCHEDULE SCHEMA (this document) │
│ • Single canonical format for all tools │
│ • Platform-agnostic field definitions │
│ • Flexible field requirements per API │
└──────────────────┬───────────────────────────────────┘
│ All Analysis APIs consume this format
▼
┌──────────────────────────────────────────────────────┐
│ ANALYSIS APIs (all categories) │
│ Health Score • CPM • DCMA 14-Point │
│ Logic Audit • Progress Audit • Resource Analysis │
│ Delay Analysis • Baseline Compare • and more │
└──────────────────────────────────────────────────────┘
Key Characteristics
- Tool Independence — Same schema regardless of source (MS Project, P6, etc.)
- Flexible Requirements — Each API declares exactly what fields it needs; missing optional fields cause partial analysis, not failure
- Forward Compatible — New optional fields can be added without breaking existing callers
- Extra Fields Ignored — Unknown fields in your payload do not cause errors
Quick Start
Minimal Task (Required Fields Only)
{
"tasks": [
{ "id": "T1", "duration_days": 10 },
{ "id": "T2", "duration_days": 5, "predecessors": ["T1"] }
]
}
Typical Task (Recommended Fields)
{
"id": "T1",
"name": "Design Database Schema",
"duration_days": 8,
"predecessors": ["T0"],
"resources": ["Backend Team"],
"percent_complete": 0,
"planned_start": "2026-03-01",
"planned_finish": "2026-03-08"
}
Full Schedule Example (All Common Fields)
{
"tasks": [
{
"id": "M1",
"name": "Project Kickoff",
"duration_days": 0,
"predecessors": [],
"task_type": "milestone",
"percent_complete": 100,
"actual_start": "2026-01-02",
"actual_finish": "2026-01-02"
},
{
"id": "T1",
"name": "Requirements Gathering",
"duration_days": 10,
"predecessors": ["M1"],
"resources": ["BA Team", "Product Owner"],
"wbs_code": "1.1",
"percent_complete": 100,
"planned_start": "2026-01-03",
"planned_finish": "2026-01-16",
"actual_start": "2026-01-03",
"actual_finish": "2026-01-15",
"baseline_start": "2026-01-03",
"baseline_finish": "2026-01-16"
},
{
"id": "T2",
"name": "Architecture Design",
"duration_days": 15,
"predecessors": ["T1FS+2 d"],
"resources": ["Architecture Team"],
"wbs_code": "1.2",
"percent_complete": 60,
"planned_start": "2026-01-19",
"planned_finish": "2026-02-06",
"actual_start": "2026-01-22",
"forecast_finish": "2026-02-10",
"baseline_start": "2026-01-17",
"baseline_finish": "2026-02-06"
}
],
"start_task_ids": ["M1"],
"finish_task_ids": ["M99"],
"status_date": "2026-02-01",
"target_finish_date": "2026-12-31",
"milestone_task_ids": ["M1", "M99"],
"loe_task_ids": ["PROJECT_MGT"]
}
Task-Level Field Reference
Required Fields
| Field | Type | Validation | Description |
|---|---|---|---|
id |
string |
Non-empty, max 255 chars | Unique task identifier within the schedule. Alphanumeric, hyphens, underscores. |
Scheduling Fields
| Field | Type | Default | Description |
|---|---|---|---|
duration_days |
number |
0 |
Task duration in working days. Use 0 for milestones. Min: 0, Max: 10000. Fractional days supported (0.5 = 4 hours). |
predecessors |
array |
[] |
Predecessor task IDs or rich dependency links. See Predecessor Format below. |
Descriptive Fields
| Field | Type | Default | Description | Used By |
|---|---|---|---|---|
name |
string |
null |
Human-readable task name. Max 1000 chars. Recommended for readable results. | Optional |
wbs_code |
string |
null |
WBS code string (e.g., 1.2.3). Auto-populated by Import APIs. Max 100 chars. |
Progress Audit, Import APIs |
task_type |
string |
"task" |
Task classification enum. See Task Types below. When set, takes precedence over schedule-level exclusion arrays. | All APIs (exclusion logic) |
Resource Fields
| Field | Type | Default | Description | Used By |
|---|---|---|---|---|
resources |
array |
[] |
Multi-resource assignment. Preferred over resource. E.g., ["Backend Team", "DBA"] |
DCMA Check #10, Resource Analysis |
resource |
string |
null |
Single resource assignment. Legacy format — use resources[] for new integrations. |
DCMA Check #10 |
organization_code |
string |
null |
Org/department identifier for anomaly categorization by responsibility. Populated by Import APIs if source uses cost accounts. | Progress Audit |
Progress Tracking Fields
| Field | Type | Default | Description | Used By |
|---|---|---|---|---|
percent_complete |
number |
0 |
Completion percentage, 0–100. | DCMA Check #11, Progress Audit |
planned_start |
string |
null |
Planned start date (ISO 8601: YYYY-MM-DD). |
DCMA Check #11, Planning APIs |
planned_finish |
string |
null |
Planned finish date. Must be ≥ planned_start. |
DCMA Check #11, Planning APIs |
actual_start |
string |
null |
Actual start date if task has begun. | DCMA Check #11, Progress Audit |
actual_finish |
string |
null |
Actual finish date if task is complete. Must be ≥ actual_start. |
DCMA Check #11, Progress Audit |
forecast_start |
string |
null |
Current forecast start (ISO 8601). Distinct from planned_start — the current best estimate for remaining work. Auto-populated by P6 Import from reend_date. |
Change Tracking, Planning Horizon, DCMA DECM |
forecast_finish |
string |
null |
Current forecast finish (ISO 8601). Falls back to planned_finish if not set. |
Change Tracking, Planning Horizon, DCMA DECM |
total_float_days |
number |
null |
Pre-computed total float in working days. If absent, Planning Horizon auto-computes via CPM. Negative = behind schedule. | Planning Horizon |
delay_category |
string |
null |
Delay attribution category. Values: owner, contractor, design, procurement, weather, force_majeure. |
Delay Analysis |
Baseline Fields
| Field | Type | Default | Description | Used By |
|---|---|---|---|---|
baseline_start |
string |
null |
Approved baseline start date (ISO 8601). | DCMA Check #14, Baseline Compare |
baseline_finish |
string |
null |
Approved baseline finish date (ISO 8601). | DCMA Check #14, Baseline Compare |
baseline_duration_days |
number |
null |
Baseline duration in working days. Auto-computed from baseline_finish - baseline_start if absent. |
Baseline Compare, DCMA DECM BEI |
Constraint Fields
| Field | Type | Default | Description | Used By |
|---|---|---|---|---|
constraint_type |
string |
null |
Constraint code. Values: ASAP, ALAP, SNET, FNET, SNLT, FNLT, MSO, MFO. |
DCMA Check #5 |
constraint_date |
string |
null |
Constraint date (ISO 8601). Required when constraint_type is a hard constraint. |
DCMA Check #5 |
EVMS Fields
| Field | Type | Default | Description | Used By |
|---|---|---|---|---|
earned_value |
number |
null |
Earned Value / BCWP in cost units. Required for EVMS consistency checks. | Progress Audit (include_ev_validation: true) |
budgeted_cost |
number |
null |
BCWS (Budgeted Cost of Work Scheduled) in cost units. | Progress Audit EVMS module |
Readiness Fields
| Field | Type | Default | Description | Used By |
|---|---|---|---|---|
approval_required |
boolean |
false |
Whether this task requires explicit approval before work can start. | Planning Horizon |
approval_status |
string |
null |
Approval state: not_required, pending, approved, rejected. |
Planning Horizon |
Task Types
The task_type field classifies tasks for analysis exclusion logic per DCMA PAM 200.1 § 3.2 and NDIA PASEG § 4. When set, it takes precedence over the schedule-level exclusion arrays.
Auto-Classification via Import APIs
When using Import APIs (/import/mpp, /import/xer), task types are automatically detected from native file metadata (MS Project Milestone/Summary flags, P6 task_type codes). Additionally, the Import APIs support prefix-based classification using naming conventions like SM-, LOE-, PP- to identify special task types without requiring custom fields.
Example: A task named SM-Integration Buffer is automatically classified as schedule_margin, and a task named LOE-Project Management becomes loe.
👉 See the Import Guide for complete prefix classification details.
Valid Task Types
| Value | Description | Excluded From |
|---|---|---|
task |
Default — discrete work activity | Nothing |
milestone |
Zero-duration event marker. Auto-detected when duration_days = 0. |
ALL DCMA checks |
loe |
Level of Effort — ongoing support or management activity | ALL DCMA checks |
summary |
WBS parent / rollup task. Auto-detected by Import APIs. | ALL DCMA checks |
schedule_margin |
Schedule margin buffer task | ALL DCMA checks |
planning_package |
Future work not yet decomposed to discrete activities | DCMA Check #8 (High Duration) |
slpp |
Summary Level Planning Package | DCMA Check #8 |
schedule_visibility |
External coordination task | DCMA Checks #8, #10, #11, #14 |
{
"id": "PROJECT_MGT",
"name": "Program Management",
"duration_days": 180,
"task_type": "loe",
"resources": ["PM Office"]
}
Import APIs (/import/mpp, /import/xer) automatically populate both the task_type field on each task and the schedule-level exclusion arrays from native file metadata. When sending JSON directly, you can use either mechanism — task_type on the task, or the exclusion arrays at the schedule level.
Schedule-Level Fields
In addition to the tasks array, you can provide project-level metadata that enables more checks and more accurate analysis.
Project Metadata
| Field | Type | Default | Description | Used By |
|---|---|---|---|---|
tasks |
array |
required | Array of Task objects. | All APIs |
start_task_ids |
array |
[] |
Task IDs representing project start points. Multiple IDs for multi-workstream projects. | DCMA Check #1 |
finish_task_ids |
array |
[] |
Task IDs representing project finish points. | DCMA Check #1 |
status_date |
string |
null |
Data date for progress validation (ISO 8601). The "as of" date for all progress checks. | DCMA Checks #9, #11, #14; Progress APIs |
target_finish_date |
string |
null |
Target project completion date (ISO 8601). | DCMA Check #13 (CPLI) |
baseline_approved_date |
string |
null |
Date when baseline was formally approved. Governance metadata. | Baseline APIs |
Task Type Exclusion Arrays
These arrays list task IDs to exclude from specific checks. Alternative to setting task_type on individual tasks — use whichever is more convenient for your integration.
| Field | Description | Excluded From |
|---|---|---|
milestone_task_ids |
Milestones. Auto-detected when duration_days = 0. |
ALL DCMA checks |
loe_task_ids |
Level of Effort tasks. | ALL DCMA checks |
schedule_margin_task_ids |
Schedule margin buffers. | ALL DCMA checks |
summary_task_ids |
Summary/rollup tasks. Auto-detected by Import APIs. | ALL DCMA checks |
planning_package_task_ids |
Planning Packages (future work). | DCMA Check #8 |
summary_level_pp_task_ids |
Summary Level Planning Packages. | DCMA Check #8 |
schedule_visibility_task_ids |
External coordination tasks. | DCMA Checks #8, #10, #11, #14 |
Resource Availability
Required for over-allocation detection in the Resource Analysis API.
{
"resource_availability": [
{
"resource_name": "Backend Team",
"available_from": "2026-01-01",
"available_to": "2026-12-31",
"units_per_day": 2.0
},
{
"resource_name": "DBA",
"units_per_day": 1.0
}
]
}
| Field | Type | Description |
|---|---|---|
resource_name |
string |
Must match a value in tasks[*].resources. |
available_from |
string |
Start of availability window (ISO 8601). null = project start. |
available_to |
string |
End of availability window (ISO 8601). null = project finish. |
units_per_day |
number |
Available resource-units per working day. Default: 1.0 (100%). |
Predecessor Format
The predecessors field supports three formats:
1. Simple Format (Task ID Only)
Default relationship: Finish-to-Start (FS) with zero lag.
{
"id": "T2",
"predecessors": ["T1"]
}
2. Rich String Format (With Relationship & Lag)
Syntax: TaskID[FS|SS|FF|SF][+/-]lag [unit]
This is the runtime contract accepted by the API parser (MS Project / P6 style). There is no colon between the task ID and the relationship type.
Relationship Types:
FS— Finish-to-Start (default, ~90% of dependencies)SS— Start-to-Start (parallel work, ~5%)FF— Finish-to-Finish (synchronized completion, ~4%)SF— Start-to-Finish (rare, ~1%)
Lag Notation:
- Positive lag:
+N(delay/wait time, e.g.,+5= 5-day delay) - Negative lag:
-N(lead time/overlap, e.g.,-2= 2-day lead) - Optional unit after lag:
d/day/days,h/hour/hours,w/week/weeks,m/month/months,y/year/years
{
"id": "T3",
"predecessors": [
"T1FS",
"T2FS+5 d",
"T10SS-2 d",
"T5FF",
"T8SF+3 d"
]
}
Accepted examples:
{
"predecessors": ["10", "10FS", "10FS+5 d", "15SS-2 d", "20FF"]
}
Not accepted (colon form): "3:FS", "T1:FS+2", "T2:FS+5" — these raise a parse error. Use MSP form or object form instead.
The unit suffix is optional; when omitted, lag is treated as days.
3. Object Format (Explicit DependencyLink)
For advanced use cases with external project links:
{
"id": "T4",
"predecessors": [
{
"task_id": "T1",
"relationship_type": "FS",
"lag_days": 5.0,
"is_external": false
},
{
"task_id": "EXT_TASK_10",
"relationship_type": "FS",
"lag_days": 0,
"is_external": true,
"external_project": "/projects/phase1.mpp"
}
]
}
External project links are parsed but not currently evaluated. The API accepts the field for forward compatibility, but cross-project dependency resolution is not yet supported.
Field Requirements by API
Each API declares exactly which fields it needs. APIs with partial analysis mode run available checks and skip others with clear warning messages.
Health and Analysis
| API | Required | Key Optional Fields | Mode |
|---|---|---|---|
| Health Scoring | tasks, predecessors |
All others | Strict |
| CPM Calculation | tasks, predecessors, duration_days |
All others | Strict |
| Schedule Validation | tasks |
All others | Strict |
Health checks, Forensics, and Import
| API | Base Required | Key Additional Fields | Mode |
|---|---|---|---|
| DCMA 14-Point | tasks, predecessors, start_task_ids, finish_task_ids |
status_date (checks #9,#11,#14), constraint_type/date (#5), target_finish_date (#13), baseline_* (#14) |
Partial |
| Logic Audit | tasks, predecessors, duration_days |
constraint_type, constraint_date |
Strict |
| Progress Audit | tasks, status_date, percent_complete |
planned_*, actual_*, wbs_code, organization_code, earned_value + budgeted_cost |
Partial |
| DCMA DECM | tasks, predecessors, start_task_ids, finish_task_ids, status_date |
baseline_*, actual_*, forecast_* per check |
Partial |
| Resource Analysis | tasks, duration_days, predecessors |
resources, resource_availability, planned_*, task_type |
Partial |
| Baseline Compare | tasks, predecessors, status_date, baseline_start, baseline_finish |
baseline_approved_date |
Strict |
| Delay Analysis | tasks, predecessors, duration_days, status_date, baseline_*, actual_start |
actual_finish, percent_complete, delay_category |
Strict |
| Change Tracking | current_schedule.tasks, status_date, schedule_history |
baseline_*, actual_*, forecast_*, resources, predecessors |
Strict |
| Planning Horizon | tasks, duration_days, status_date |
forecast_start or planned_start, resources, total_float_days, approval_required, approval_status |
Partial |
| As-Planned vs. As-Built | tasks, predecessors, duration_days, status_date, baseline_*, actual_* (completed tasks) |
percent_complete, task_type |
Strict |
| Schedule Risk Index | tasks, predecessors, duration_days, status_date |
baseline_*, actual_*, constraint_type, task_type |
Partial |
| MPP Import | MS Project XML file content | — | Best Effort |
| XER Import | Primavera P6 XER file content | — | Best Effort |
Partial Analysis Mode: The API runs every check for which sufficient data is present and skips others. Each skipped check is listed in the response
warningsarray with the specific missing fields.
Validation Rules
Field-Level Validation
| Rule | Error Message |
|---|---|
id is required |
Field required |
id is empty/whitespace |
Task ID cannot be empty |
duration_days < 0 |
Input should be greater than or equal to 0 |
percent_complete out of 0–100 |
Input should be less than or equal to 100 |
| Invalid date format | Invalid date format. Expected ISO 8601 (YYYY-MM-DD) |
planned_finish < planned_start |
planned_finish must be after planned_start |
actual_finish < actual_start |
actual_finish must be after actual_start |
Cross-Task Validation
| Rule | Type | Description |
|---|---|---|
| Duplicate task IDs | Error | Each task must have a unique id |
| Predecessor references non-existent task | Warning | Predecessor ID not found in schedule |
| Circular dependencies | Error | Tasks form a dependency cycle (A→B→C→A) |
| Disconnected components | Warning | Schedule has isolated task groups |
Predecessor Parsing
| Input | Result |
|---|---|
"T1" |
{task_id: "T1", relationship_type: "FS", lag_days: 0} |
"T1FS+5 d" |
{task_id: "T1", relationship_type: "FS", lag_days: 5} |
"10SS-2 d" |
{task_id: "10", relationship_type: "SS", lag_days: -2} |
"3:FS" |
Error: Cannot parse dependency string (colon form is not accepted) |
"" |
Error: Empty predecessor string |
Best Practices
Use resources Instead of resource
// Legacy — single resource only
{ "resource": "Backend Team" }
// Preferred — supports multiple assignments
{ "resources": ["Backend Team", "DBA"] }
Set task_type on Non-Discrete Tasks
Setting task_type prevents false positives in DCMA checks. LOE and summary tasks are intentionally excluded from logic and progress checks.
{ "id": "PM", "name": "Project Management", "duration_days": 180, "task_type": "loe" }
{ "id": "WBS_1", "name": "Phase 1 (Summary)", "duration_days": 45, "task_type": "summary" }
Provide status_date for Progress Analysis
Without status_date, DCMA Checks #9, #11, and #14 cannot run. Always include it for in-progress schedules.
{
"tasks": [...],
"status_date": "2026-03-15"
}
Include Both Planned and Forecast Dates
planned_start/planned_finish represents the original approved plan. forecast_start/forecast_finish represents the current best estimate. Both are needed for trend analysis in Change Tracking and DECM checks.
Use Baseline Fields for Earned Value Analysis
Baseline Compare, BEI (DCMA Check #14), and Delay Analysis all require baseline_start and baseline_finish on each task.
Common Use Cases
Use Case 1: Government Program Schedule (DCMA 14-Point)
Full data required for all 14 checks:
{
"tasks": [
{
"id": "T1",
"name": "System Design",
"duration_days": 20,
"predecessors": [],
"resources": ["Systems Engineering"],
"percent_complete": 100,
"planned_start": "2026-01-05",
"planned_finish": "2026-01-30",
"actual_start": "2026-01-05",
"actual_finish": "2026-01-28",
"baseline_start": "2026-01-05",
"baseline_finish": "2026-01-30"
},
{
"id": "T2",
"name": "Preliminary Design Review",
"duration_days": 0,
"predecessors": ["T1FS"],
"task_type": "milestone",
"percent_complete": 100,
"actual_start": "2026-01-29",
"actual_finish": "2026-01-29",
"baseline_start": "2026-01-31",
"baseline_finish": "2026-01-31"
}
],
"start_task_ids": ["T1"],
"finish_task_ids": ["T99"],
"status_date": "2026-02-15",
"target_finish_date": "2026-12-31",
"milestone_task_ids": ["T2"]
}
Use Case 2: Resource-Loaded Schedule (Resource Analysis)
Include resources[] and resource_availability at the schedule level:
{
"tasks": [
{
"id": "T1",
"name": "Backend Development",
"duration_days": 20,
"predecessors": [],
"resources": ["Backend Team"],
"planned_start": "2026-03-01",
"planned_finish": "2026-03-28"
},
{
"id": "T2",
"name": "Database Migration",
"duration_days": 10,
"predecessors": ["T1SS+5 d"],
"resources": ["Backend Team", "DBA"],
"planned_start": "2026-03-06",
"planned_finish": "2026-03-19"
}
],
"resource_availability": [
{ "resource_name": "Backend Team", "units_per_day": 2.0 },
{ "resource_name": "DBA", "units_per_day": 1.0 }
]
}
Use Case 3: In-Progress Schedule with Forecast Dates
{
"tasks": [
{
"id": "T1",
"name": "Backend API",
"duration_days": 20,
"predecessors": [],
"percent_complete": 100,
"planned_start": "2026-01-01",
"planned_finish": "2026-01-20",
"actual_start": "2026-01-01",
"actual_finish": "2026-01-18",
"baseline_start": "2026-01-01",
"baseline_finish": "2026-01-20"
},
{
"id": "T2",
"name": "Frontend Development",
"duration_days": 15,
"predecessors": ["T1SS+5 d"],
"percent_complete": 60,
"planned_start": "2026-01-06",
"planned_finish": "2026-01-20",
"actual_start": "2026-01-06",
"forecast_finish": "2026-01-23",
"baseline_start": "2026-01-06",
"baseline_finish": "2026-01-20"
}
],
"status_date": "2026-01-15",
"target_finish_date": "2026-01-30"
}
Use Case 4: Schedule with LOE and Summary Tasks
{
"tasks": [
{
"id": "WBS_1",
"name": "Phase 1 — Design",
"duration_days": 30,
"task_type": "summary",
"predecessors": []
},
{
"id": "PM",
"name": "Program Management",
"duration_days": 180,
"task_type": "loe",
"resources": ["PM Office"],
"predecessors": []
},
{
"id": "T1",
"name": "Conceptual Design",
"duration_days": 15,
"predecessors": [],
"resources": ["Systems Engineering"]
}
],
"loe_task_ids": ["PM"],
"summary_task_ids": ["WBS_1"]
}
Use Case 5: Parallel Work with Start-to-Start Dependencies
{
"tasks": [
{
"id": "T1",
"name": "Foundation Excavation",
"duration_days": 10,
"predecessors": []
},
{
"id": "T2",
"name": "Concrete Pouring",
"duration_days": 3,
"predecessors": ["T1FS"]
},
{
"id": "T3",
"name": "Rebar Installation",
"duration_days": 8,
"predecessors": ["T1SS+2 d"]
}
]
}
T3 starts 2 days after T1 starts (SS+2), allowing rebar to proceed in parallel with excavation.
Standards Compliance
PMBOK 8
| Field | PMBOK Reference | Description |
|---|---|---|
predecessors |
Section 6.3.2.2 | Dependency types (FS/SS/FF/SF) |
duration_days |
Section 6.4.2.1 | Duration estimating |
planned_start, planned_finish |
Section 6.5.2.1 | Schedule baseline |
actual_start, actual_finish |
Section 6.6.2.3 | Performance measurement |
percent_complete |
Section 7.4.2.1 | Earned value (% complete method) |
forecast_start, forecast_finish |
Section 6.6.2.2 | Schedule forecasting |
DCMA 14-Point Assessment (PAM 200.1)
| Check | Task Fields Required | Notes |
|---|---|---|
| #1: Logic | predecessors, start_task_ids, finish_task_ids |
No danglers or circular deps |
| #2: Leads | predecessors (lag_days < 0) |
Minimize negative lag |
| #3: Lags | predecessors (lag_days > 0) |
Document lag reasons |
| #5: Hard Constraints | constraint_type, constraint_date |
SNLT, FNLT, MSO, MFO |
| #9: Invalid Dates | status_date |
Future actuals, logic errors |
| #10: Resources | resources or resource |
Coverage check |
| #11: Missed Tasks | status_date, actual_start, actual_finish, percent_complete |
Should-have-started check |
| #13: CPLI | target_finish_date |
Critical Path Length Index |
| #14: BEI | status_date, baseline_start, baseline_finish |
Baseline Execution Index |
GAO Schedule Assessment Guide (GAO-16-89G)
| Best Practice | Schema Support |
|---|---|
| BP-2: Sequence Activities | predecessors with all relationship types |
| BP-3: Assign Resources | resources[] (preferred), resource (legacy) |
| BP-6: Maintain Critical Path | CPM uses predecessors + duration_days |
| BP-8: Baseline Integrity | baseline_* vs planned_* / actual_* comparison |
| BP-9: Update Progress | percent_complete, actual_*, forecast_* |
Working with Import APIs
If you have MS Project or Primavera P6 files, use the Import APIs to convert them to normalized JSON — no manual conversion needed.
Workflow
POST /api/v1/import/mpp (multipart/form-data: file=schedule.mpp)
POST /api/v1/import/xer (multipart/form-data: file=schedule.xer)
→ Returns normalized_schedule JSON + parse_summary
→ Pass normalized_schedule directly to any analysis API
Import Response
{
"normalized_schedule": {
"tasks": [...],
"start_task_ids": ["T1"],
"finish_task_ids": ["T100"],
"milestone_task_ids": ["T1", "T50", "T100"],
"loe_task_ids": ["PM_LOE"],
"summary_task_ids": ["WBS_1", "WBS_2"]
},
"parse_summary": {
"tasks_imported": 147,
"dependencies_imported": 203,
"fields_populated": ["id", "duration_days", "predecessors", "name", "resources",
"baseline_start", "baseline_finish", "task_type", "wbs_code"],
"fields_missing": ["earned_value", "budgeted_cost"],
"warnings": []
}
}
Manual Conversion Reference
If you need to build the normalized schema from your own source data:
MS Project → Normalized:
| MS Project | Normalized Field | Conversion |
|---|---|---|
UniqueID |
id |
Direct (as string) |
Duration (minutes) |
duration_days |
÷ 480 (8-hour days) |
PredecessorLink |
predecessors |
Parse Type (1=FS, 2=SS, 3=FF, 4=SF) |
| Constraint type codes | constraint_type |
Map to ASAP/SNET/SNLT/MSO/etc. |
BaselineStart / BaselineFinish |
baseline_start / baseline_finish |
ISO 8601 format |
Primavera P6 → Normalized:
| P6 Field | Normalized Field | Conversion |
|---|---|---|
task_id |
id |
Direct (as string) |
target_drtn_hr_cnt |
duration_days |
÷ 8 (8-hour days) |
TASKPRED.pred_type |
predecessors |
Strip PR_ prefix (PR_FS → FS) |
reend_date |
forecast_start |
ISO 8601 format |
rem_late_end_date |
forecast_finish |
ISO 8601 format |
BL_target_drtn_hr_cnt |
baseline_duration_days |
÷ 8 |
task_type |
task_type |
Map TT_Task→task, TT_LOE→loe, TT_Mile→milestone, TT_WBS→summary |
API Integration Examples
Python — DCMA 14-Point Analysis
import requests
url = "https://api.bellatorsi.com/api/v1/health/dcma-14-point"
headers = {
"x-api-key": "your-api-key",
"Content-Type": "application/json"
}
payload = {
"tasks": [
{
"id": "T1",
"name": "Requirements",
"duration_days": 10,
"predecessors": [],
"resources": ["BA Team"],
"percent_complete": 100,
"actual_start": "2026-01-05",
"actual_finish": "2026-01-14",
"baseline_start": "2026-01-05",
"baseline_finish": "2026-01-16"
},
{
"id": "T2",
"name": "Design",
"duration_days": 15,
"predecessors": ["T1FS"],
"resources": ["Architecture Team"],
"percent_complete": 40,
"actual_start": "2026-01-15",
"baseline_start": "2026-01-19",
"baseline_finish": "2026-02-06"
}
],
"start_task_ids": ["T1"],
"finish_task_ids": ["T99"],
"status_date": "2026-02-01",
"target_finish_date": "2026-12-31"
}
response = requests.post(url, json=payload, headers=headers)
result = response.json()
print(f"DCMA Score: {result['summary']['overall_score']}")
print(f"Checks Passed: {result['summary']['checks_passed']} / {result['summary']['checks_run']}")
Python — Health Score
import requests
url = "https://api.bellatorsi.com/api/v1/health/score"
headers = {"x-api-key": "your-api-key", "Content-Type": "application/json"}
payload = {
"tasks": [
{"id": "T1", "name": "Requirements", "duration_days": 10, "predecessors": []},
{"id": "T2", "name": "Design", "duration_days": 15, "predecessors": ["T1FS"]},
{"id": "T3", "name": "Development", "duration_days": 30, "predecessors": ["T2FS"]}
],
"include_details": True
}
response = requests.post(url, json=payload, headers=headers)
result = response.json()
print(f"Health Score: {result['score']} ({result['grade']})")
JavaScript (Node.js) — Resource Analysis
const axios = require('axios')
const payload = {
tasks: [
{
id: 'T1', name: 'Backend Development', duration_days: 20,
predecessors: [], resources: ['Backend Team'],
planned_start: '2026-03-01', planned_finish: '2026-03-28'
},
{
id: 'T2', name: 'Database Migration', duration_days: 10,
predecessors: ['T1SS+5 d'], resources: ['Backend Team', 'DBA'],
planned_start: '2026-03-06', planned_finish: '2026-03-19'
}
],
resource_availability: [
{ resource_name: 'Backend Team', units_per_day: 2.0 },
{ resource_name: 'DBA', units_per_day: 1.0 }
]
}
axios.post('https://api.bellatorsi.com/api/v1/analysis/resources', payload, {
headers: { 'x-api-key': 'your-api-key', 'Content-Type': 'application/json' }
}).then(response => {
const r = response.data
console.log(`Resource Risk Score: ${r.resource_risk_score} (${r.resource_risk_grade})`)
console.log(`Coverage: ${(r.resource_coverage_pct * 100).toFixed(1)}%`)
})
cURL — Sparse Response (fields parameter)
# Request only summary fields — faster for dashboards
curl -X POST "https://api.bellatorsi.com/api/v1/health/dcma-14-point?fields=summary,check_results.check_id,check_results.passed" \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"tasks": [
{"id": "T1", "duration_days": 10, "predecessors": []},
{"id": "T2", "duration_days": 5, "predecessors": ["T1"]}
],
"start_task_ids": ["T1"],
"finish_task_ids": ["T2"]
}'
Troubleshooting
Field required: id
// Wrong
{"duration_days": 10}
// Correct
{"id": "T1", "duration_days": 10}
Circular dependency detected
// Wrong — T1 and T2 depend on each other
{"tasks": [{"id": "T1", "predecessors": ["T2"]}, {"id": "T2", "predecessors": ["T1"]}]}
Break the cycle by removing one dependency or introducing an intermediate task.
Cannot parse dependency string / colon form rejected
Rich predecessor strings use MS Project / P6 form — no colon between ID and type.
Supported relationship values: FS, SS, FF, SF
// Wrong — colon form is not accepted
{"predecessors": ["3:FS", "T1FS+5 d"]}
// Correct — MSP / runtime form
{"predecessors": ["3FS", "T1FS+5 d"]}
// Also correct — object form
{"predecessors": [{"task_id": "T1", "relationship_type": "FS", "lag_days": 5.0}]}
planned_finish must be after planned_start
// Wrong
{"planned_start": "2026-02-10", "planned_finish": "2026-02-01"}
// Correct
{"planned_start": "2026-02-01", "planned_finish": "2026-02-10"}
Check #9/#11/#14 not running
These checks require status_date at the schedule level. Add it to your payload:
{
"tasks": [...],
"status_date": "2026-03-15"
}
FAQ
Should I use resource or resources?
Use resources[] (array) for all new integrations — it supports multiple resource assignments per task and is used by Resource Analysis, DCMA Check #10, and Planning Horizon. The resource string field is retained for backward compatibility only.
Can I omit duration_days?
Yes — it defaults to 0 (milestone behavior). Explicitly set duration_days: 0 for milestones, and task_type: "milestone" to ensure correct exclusion from DCMA checks.
What happens to unrecognized fields?
They are silently ignored. This maximizes compatibility when your scheduling tool adds tool-specific fields to exports.
Can I mix predecessor formats in the same task?
Yes — simple strings, rich strings, and object format can all appear in the same predecessors array. All are normalized to the same internal DependencyLink representation.
{
"predecessors": [
"T1",
"T2FS+5 d",
{"task_id": "T3", "relationship_type": "SS", "lag_days": -2}
]
}
Should I use task_type or the exclusion arrays?
Either works — task_type on individual tasks is more portable (the classification travels with the task). The schedule-level arrays (loe_task_ids, etc.) are useful when you can't modify individual task objects. Import APIs populate both automatically. If both are set on the same task, task_type takes precedence.
Can I use different time units?
No — all durations must be in working days. Fractional days are supported: 0.5 = 4 hours, 0.125 = 1 hour (assuming 8-hour workday).
What is status_date vs target_finish_date?
status_date: The data date — the "as of" date for all progress data. Think of it as "what we knew on this date." Required for DCMA Checks #9, #11, #14.target_finish_date: The contractual or management target for project completion. Used in DCMA Check #13 (CPLI calculation).
Related Documentation
Support
- Contact: Contact Form
- Try it: Interactive Playground
- Explore: API Reference
Last Updated: March 2026 Schema Version: v1.3.0 Maintained By: Bellator Engineering Team Standards Compliance: PMBOK 8, DCMA PAM 200.1, GAO-16-89G, NDIA PASEG