Skip to content

Import API Guide

Convert Microsoft Project and Primavera P6 schedules into normalized JSON with intelligent auto-classification

Available to: Starter tier and above — Import APIs convert tool-specific formats (.mpp, .xer) into the Normalized Schedule Schema used by all analysis endpoints.


Overview

The Import APIs transform native scheduling tool formats into Bellator's platform-agnostic Normalized Schedule Schema. This enables you to:

  • Analyze schedules from any tool — MS Project, Primavera P6, or hand-crafted JSON all work with the same analysis endpoints
  • Auto-detect task types — Milestones, LOE, summaries, and planning packages are automatically identified
  • Use naming conventions — Prefix-based classification (e.g., SM-, LOE-, PP-) enables DCMA compliance without custom fields
  • Preserve metadata — WBS codes, resources, baselines, constraints, and calendars are extracted when available
  • Get transparent conversion reports — Detailed mapping statistics and warnings for every import

Supported Formats

Format Endpoint File Extension Notes
Microsoft Project POST /api/v1/import/mpp .mpp (exported as XML) Save as XML in MS Project before uploading
Primavera P6 POST /api/v1/import/xer .xer Standard XER export from P6

MS Project .mpp binary files must be saved as XML first. In MS Project: File → Save As → XML Format.


Import Workflow

Basic Import Flow

graph LR
    A[Native File] -->|Upload| B[Import API]
    B -->|Parse| C[Extract Fields]
    C -->|Auto-Classify| D[Detect Task Types]
    D -->|Prefix Scan| E[Apply Name Prefixes]
    E -->|Validate| F[Normalized JSON]
    F -->|Use with| G[Any Analysis API]

Quick Example

curl -X POST "https://api.bellatorsi.com/api/v1/import/mpp" \
  -H "x-api-key: YOUR_API_KEY" \
  -F "[email protected]" \
  -F "auto_classify_task_types=true" \
  -F "use_prefix_classification=true"
import requests

url = "https://api.bellatorsi.com/api/v1/import/mpp"
headers = {"x-api-key": "YOUR_API_KEY"}
files = {"file": open("project.xml", "rb")}
data = {
    "auto_classify_task_types": True,
    "use_prefix_classification": True
}

response = requests.post(url, headers=headers, files=files, data=data)
normalized = response.json()["data"]["normalized_schedule"]

# Use normalized schedule with any analysis endpoint
health_response = requests.post(
    "https://api.bellatorsi.com/api/v1/health/score",
    headers=headers,
    json=normalized
)
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('auto_classify_task_types', 'true');
formData.append('use_prefix_classification', 'true');

const response = await fetch('https://api.bellatorsi.com/api/v1/import/mpp', {
  method: 'POST',
  headers: { 'x-api-key': 'YOUR_API_KEY' },
  body: formData
});

const { data } = await response.json();
const normalized = data.normalized_schedule;

// Use with analysis endpoints
const healthResponse = await fetch('https://api.bellatorsi.com/api/v1/health/score', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(normalized)
});

Auto-Classification

The Import APIs automatically detect special task types from native file metadata. This happens before prefix classification.

What Gets Auto-Detected

  • Milestones:
    • MS Project: <Milestone>1</Milestone> flag or duration_days = 0
    • P6: task_type = "TT_Mile" or "TT_FinMile"
  • Summaries:
    • MS Project: <Summary>1</Summary> flag (WBS parent tasks)
    • P6: task_type = "TT_WBS" (WBS summary)
  • Level of Effort:
    • MS Project: Not available natively (use prefix classification)
    • P6: task_type = "TT_LOE"
  • Resource Dependent:
    • MS Project: Not available natively
    • P6: task_type = "TT_Rsrc" (mapped to loe in normalized schema)

Auto-Classification Behavior

// MS Project task with native milestone flag
<Task>
  <UID>42</UID>
  <Name>Project Kickoff</Name>
  <Milestone>1</Milestone>
  <Duration>PT0H0M0S</Duration>
</Task>

// Normalized output (auto-classified)
{
  "id": "42",
  "name": "Project Kickoff",
  "duration_days": 0,
  "task_type": "milestone"  // ← Auto-detected from <Milestone>1
}

Prefix-Based Classification

Prefix classification enables full DCMA compliance without requiring custom fields in your scheduling tool. It's inspired by the NDIA Planning and Scheduling Excellence Guide (PASEG) naming conventions.

When Prefix Classification Fires

Prefix detection happens after native type detection and only when:

  1. ✅ use_prefix_classification: true (the default)
  2. ✅ Task does NOT already have a meaningful type from native flags
  3. ✅ Task name starts with a recognized prefix + hyphen

If a task already has a native type (e.g., P6 TT_LOE) and also has a matching prefix, the native type wins and a warning is issued.

Supported Prefixes

Prefix Assigned Type Example Task Name PASEG Reference
SM- Schedule Margin SM-Integration Buffer § 4.5 — Schedule Margin
LOE- Level of Effort LOE-Project Management § 4.3 — Level of Effort
PP- Planning Package PP-Future Phase 3 § 4.1 — Planning Package
SLPP- Summary Level Planning Package SLPP-Phase 3 Expansion § 4.2 — Summary Level PP
AE- Apportioned Effort AE-QA Oversight § 4.4 — Apportioned Effort
SVT- Schedule Visibility SVT-Client Approval Gate § 4.6 — Schedule Visibility
START- Start Anchor START-Project Begin Internal
FINISH- / END- Finish Anchor FINISH-Delivery Complete Internal

Prefix Matching Rules:

  • Case-insensitive — SM-, sm-, and Sm- all match
  • Hyphen required — SM or SM_ do NOT match
  • SLPP evaluated first — Prevents partial match with PP-
  • Original name preserved — The full name including prefix is stored for traceability

Real-World Example

// Your MS Project schedule (no custom fields needed)
Tasks:
  - "SM-PDR Schedule Margin" (duration: 10 days)
  - "LOE-Program Management" (duration: 180 days)
  - "PP-Phase 3 Planning" (duration: 30 days)
  - "Design Propulsion System" (duration: 45 days)

// After import with use_prefix_classification: true
{
  "tasks": [
    {
      "id": "1",
      "name": "SM-PDR Schedule Margin",
      "duration_days": 10,
      "task_type": "schedule_margin"  // ← Auto-classified from SM- prefix
    },
    {
      "id": "2",
      "name": "LOE-Program Management",
      "duration_days": 180,
      "task_type": "loe"  // ← Auto-classified from LOE- prefix
    },
    {
      "id": "3",
      "name": "PP-Phase 3 Planning",
      "duration_days": 30,
      "task_type": "planning_package"  // ← Auto-classified from PP- prefix
    },
    {
      "id": "4",
      "name": "Design Propulsion System",
      "duration_days": 45,
      "task_type": "task"  // ← No prefix, remains default task type
    }
  ],
  "schedule_margin_task_ids": ["1"],
  "loe_task_ids": ["2"],
  "planning_package_task_ids": ["3"]
}

Why Use Prefix Classification?

Without Prefix Classification:

  • Create custom fields in MS Project
  • Manually tag each special task type
  • Export custom field data
  • Risk losing metadata in tool migrations

With Prefix Classification:

  • ✅ Use standard task naming conventions
  • ✅ Self-documenting schedules
  • ✅ Works across any scheduling tool
  • ✅ DCMA/PASEG compliant out of the box
  • ✅ Survives copy/paste and tool migrations

Conflict Handling

If a task has both a native type AND a matching prefix:

// P6 task with native LOE type and LOE- prefix
P6 Task:
  Name: "LOE-Project Management"
  task_type: "TT_LOE"  // Native P6 type

// Import behavior
{
  "id": "42",
  "name": "LOE-Project Management",
  "task_type": "loe"  // ← Native type wins
}

// Warning issued
{
  "type": "prefix_classification_conflict",
  "severity": "warning",
  "task_id": "42",
  "message": "Task 'LOE-Project Management' has native type 'loe' and a matching LOE- prefix. Native type wins; prefix preserved in task name."
}

MS Project Import

File Preparation

Microsoft Project binary .mpp files must be saved as XML before uploading:

  1. Open your .mpp file in MS Project
  2. File → Save As
  3. Select XML Format (*.xml)
  4. Save with a new filename (e.g., project.xml)
  5. Upload the .xml file to /api/v1/import/mpp

What Gets Extracted

The MPP importer extracts:

  • Core Fields:
    • Task UID, Name, Duration
    • Dependencies (FS, SS, FF, SF)
    • Milestone and Summary flags
    • WBS codes
    • Constraint types and dates
  • Progress Fields:
    • Percent Complete (auto-selected)
    • Actual Start/Finish
    • Baseline Start/Finish
    • Physical Percent Complete
  • Resource Fields:
    • Resource assignments
    • Resource names
    • Work and Material resources
  • Calendar Fields:
    • Working hours per day
    • Working days per week
    • Project start date

Percent Complete Auto-Selection

MS Project stores three percent complete fields. The importer uses resource-aware selection:

Condition Field Used Rationale
Task has Work/Material resources assigned PercentWorkComplete EVM-bearing work progress
Task is unresourced PercentComplete Duration-based progress
Override with percent_complete_source: "physical" PhysicalPercentComplete Manual EVM entry

Physical Percent Complete is always preserved separately in the physical_percent_complete field, regardless of which field is mapped to percent_complete.

MPP Import Options

{
  "file": "<file upload>",
  "auto_classify_task_types": true,        // Auto-detect milestones/summaries
  "use_prefix_classification": true,       // Enable prefix-based detection
  "percent_complete_source": "auto",       // "auto" | "duration" | "work" | "physical"
  "include_custom_fields": false,          // Extract custom field metadata
  "auto_detect_start_finish": true         // Auto-detect start/finish anchors
}

Primavera P6 Import

File Preparation

Export from Primavera P6 as XER format:

  1. Open your project in P6
  2. File → Export → XER
  3. Select scope (entire project or specific WBS)
  4. Save as .xer file
  5. Upload to /api/v1/import/xer

What Gets Extracted

The XER importer extracts:

  • Core Fields:
    • Activity ID, Name, Duration
    • Dependencies with lags
    • Task type codes (TT_Mile, TT_LOE, etc.)
    • WBS hierarchy
    • Activity codes
  • Progress Fields:
    • Physical Percent Complete
    • Actual Start/Finish
    • Remaining Duration
    • Forecast Start/Finish (reend_date)
  • Resource Fields:
    • Resource assignments
    • Budgeted units
    • Actual units
  • Calendar Fields:
    • Calendar definitions
    • Working hours
    • Holidays

Native Task Type Mapping

P6's native task types are automatically mapped:

P6 Code Normalized Type Notes
TT_Task task Standard discrete activity
TT_Mile milestone Milestone
TT_FinMile milestone Finish milestone
TT_LOE loe Level of Effort
TT_Rsrc loe Resource Dependent (mapped to LOE)
TT_WBS summary WBS Summary

P6 does not have native codes for Schedule Margin, Planning Packages, or Apportioned Effort. Use prefix classification to detect these types.

XER Import Options

{
  "file": "<file upload>",
  "auto_classify_task_types": true,        // Auto-detect from P6 task_type codes
  "use_prefix_classification": true,       // Enable prefix-based detection
  "include_activity_codes": true,          // Extract activity code metadata
  "auto_detect_start_finish": true,        // Auto-detect start/finish anchors
  "preserve_wbs_hierarchy": true           // Maintain WBS parent-child relationships
}

Import Options

Common Options (Both MPP and XER)

  • auto_classify_task_types: Automatically populate task types from native file flags (MS Project Milestone/Summary, P6 task_type codes).
  • use_prefix_classification: Enable name-prefix-based task type detection (SM-, LOE-, PP-, etc.). Fires only when native type is not set.
  • auto_detect_start_finish: Auto-detect project start and finish tasks from dependency topology. Start tasks have no predecessors; finish tasks are not predecessors to any other task.

MPP-Specific Options

  • percent_complete_source: Which MS Project percent complete field to use: "auto" (resource-aware), "duration" (PercentComplete), "work" (PercentWorkComplete), or "physical" (PhysicalPercentComplete).
  • include_custom_fields: Extract custom field metadata from the XML. Reported in processing_metadata_internal.custom_fields_detected.

XER-Specific Options

  • include_activity_codes: Extract P6 activity code assignments. Useful for categorization and filtering.
  • preserve_wbs_hierarchy: Maintain WBS parent-child relationships in the output. WBS summaries are marked with task_type: "summary".

Field Mapping

Constraint Type Mapping

Both importers normalize constraint codes to the canonical set:

MS Project Primavera P6 Normalized
As Soon As Possible CS_ASAP ASAP
As Late As Possible CS_ALAP ALAP
Start No Earlier Than CS_SNET SNET
Finish No Earlier Than CS_FNET FNET
Start No Later Than CS_SNLT SNLT
Finish No Later Than CS_FNLT FNLT
Must Start On CS_MSO MSO
Must Finish On CS_MFO MFO

Relationship Type Mapping

Display Name MS Project Primavera P6 Normalized
Finish-to-Start 1 PR_FS FS
Start-to-Start 2 PR_SS SS
Finish-to-Finish 3 PR_FF FF
Start-to-Finish 0 PR_SF SF

Duration Conversion

All durations are converted to working days:

  • MS Project: PT<H>H<M>M<S>S → days (e.g., PT80H0M0S = 10 days at 8hr/day)
  • P6: Target duration in days → working days (uses calendar info)

Common Patterns

Pattern: Import → Analyze → Store

import requests

# Step 1: Import native file
import_response = requests.post(
    "https://api.bellatorsi.com/api/v1/import/xer",
    headers={"x-api-key": "YOUR_API_KEY"},
    files={"file": open("construction.xer", "rb")},
    data={"use_prefix_classification": True}
)

normalized = import_response.json()["data"]["normalized_schedule"]

# Step 2: Run health score analysis
health_response = requests.post(
    "https://api.bellatorsi.com/api/v1/health/score",
    headers={"x-api-key": "YOUR_API_KEY"},
    json=normalized
)

# Step 3: Store results in your database
import json
db.schedules.insert({
    "schedule_data": normalized,
    "health_score": health_response.json()["score"],
    "import_date": "2026-04-16"
})

Pattern: Prefix-Based DCMA Compliance

# Name your tasks using DCMA/PASEG prefixes
Tasks in MS Project:
  ✅ SM-Integration Margin (10 days)
  ✅ LOE-Program Management (180 days)
  ✅ PP-Phase 3 TBD (40 days)
  ✅ Design Foundation (30 days)
  ✅ Pour Concrete (5 days)

# Import with prefix classification
response = requests.post(
    "https://api.bellatorsi.com/api/v1/import/mpp",
    headers={"x-api-key": "YOUR_API_KEY"},
    files={"file": open("project.xml", "rb")},
    data={"use_prefix_classification": True}
)

# Schedule margin, LOE, and PP are auto-excluded from DCMA checks
dcma_response = requests.post(
    "https://api.bellatorsi.com/api/v1/health/dcma-14-point",
    headers={"x-api-key": "YOUR_API_KEY"},
    json=response.json()["data"]["normalized_schedule"]
)

Pattern: Batch Import with Error Handling

import os
import requests

def import_schedule(file_path):
    """Import schedule with comprehensive error handling."""
    try:
        with open(file_path, "rb") as f:
            response = requests.post(
                "https://api.bellatorsi.com/api/v1/import/xer",
                headers={"x-api-key": os.getenv("BELLATOR_API_KEY")},
                files={"file": f},
                data={"use_prefix_classification": True},
                timeout=30
            )
        
        response.raise_for_status()
        data = response.json()["data"]
        
        # Check for warnings
        if data.get("warnings"):
            print(f"Import warnings for {file_path}:")
            for warning in data["warnings"]:
                print(f"  - {warning['type']}: {warning['message']}")
        
        return data["normalized_schedule"]
    
    except requests.exceptions.HTTPError as e:
        print(f"HTTP error importing {file_path}: {e.response.status_code}")
        print(e.response.json())
        return None
    except Exception as e:
        print(f"Error importing {file_path}: {e}")
        return None

# Batch import
schedules = []
for xer_file in os.listdir("./schedules"):
    if xer_file.endswith(".xer"):
        schedule = import_schedule(f"./schedules/{xer_file}")
        if schedule:
            schedules.append(schedule)

print(f"Successfully imported {len(schedules)} schedules")

Troubleshooting

Common Issues

  • 422 Unprocessable Entity - XML parsing error
    Cause: Invalid MS Project XML format
    Fix: Ensure you saved as XML (not binary .mpp). Re-export from MS Project as XML.
  • 422 Unprocessable Entity - No tasks found
    Cause: Empty schedule or WBS-only file
    Fix: Ensure your schedule contains actual tasks (not just WBS summaries). Check XER export scope in P6.
  • Warning: prefix_classification_conflict
    Cause: Task has both native type and matching prefix
    Fix: This is informational only. Native type wins. Remove prefix from task name if redundant, or ignore warning.
  • Missing baseline dates
    Cause: Baseline not set in source tool
    Fix: Set baseline in MS Project (Project -> Set Baseline) or P6 before exporting.
  • Duration conversions seem wrong
    Cause: Non-standard working hours per day
    Fix: Default is 8 hours/day. If your project uses 10-hour days, multiply normalized duration_days by 0.8.

Import Validation Checklist

Before importing, verify your source file:

  • MS Project: Saved as XML (not binary .mpp)
  • P6: Exported as XER (not PM XML unless using /import/pmxml in future)
  • Schedule contains tasks (not just WBS summaries)
  • Dependencies are defined (for meaningful CPM analysis)
  • Baseline is set (if using baseline comparison APIs)
  • Resources are assigned (if using resource analysis APIs)
  • Task names use prefixes if custom fields unavailable (SM-, LOE-, etc.)

Getting Help

Review the import response for detailed diagnostics:

{
  "data": {
    "parse_summary": {
      "source_format": "xer",
      "tasks_imported": 245,
      "dependencies_imported": 312,
      "fields_populated": ["id", "name", "duration_days", "predecessors", "..."],
      "fields_missing": ["baseline_start", "baseline_finish"]
    },
    "warnings": [
      {
        "type": "missing_baseline",
        "severity": "warning",
        "message": "No baseline dates found. Baseline comparison APIs will not work."
      }
    ]
  }
}

Still stuck? Contact support with your import response JSON.


Last Updated: April 16, 2026 · Schema Version: 1.3.0

Was this page helpful?

Your feedback helps us improve docs, reference pages, and Playground flows.

Topic: Import Guide · Page: /docs/import-guide

TermsPrivacyContact

Schedule analysis guidance. Not legal advice. You remain responsible for contract and agency compliance.