---
title: "Get Project"
method: GET
path: "/api/v1/projects/{project_id}"
tags: ["projects"]
---

# Get Project

`GET /api/v1/projects/{project_id}`

Get a single project with its parts eagerly loaded.

## Path parameters

- `project_id` string, uuid, required

## Response `200`

Successful Response

- ProjectDetailResponse — Full project representation with nested parts. Used by GET /projects/{id} to return the project along with its associated parts in a single response.
  - `id` string, uuid, required
  - `name` string, required
  - `description` string, nullable
  - `notes` string, nullable
  - `status` string, required
  - `priority` string, required
  - `target_delivery_date` string, date, nullable
  - `shipping_address_id` string, uuid, nullable
  - `user_id` string, uuid, required
  - `parts` PartSummaryInProject[]
    - `id` string, uuid, required
    - `name` string, required
    - `description` string, nullable
    - `required_quantity` integer, required
    - `machining_process_id` string, uuid, nullable
    - `material_id` string, uuid, nullable
    - `finishing_id` string, uuid, nullable
    - `custom_material_name` string, nullable
    - `custom_finishing_name` string, nullable
    - `coating_id` string, uuid, nullable
    - `coating_color` string, nullable
    - `coating_spec` string, nullable
    - `custom_coating_name` string, nullable
    - `general_tolerance` string, nullable
    - `edge_break_default` string, nullable
    - `coating_value` string, nullable
    - `coating_label` string, nullable
    - `finishing_value` string, nullable
    - `finishing_label` string, nullable
    - `material_value` string, nullable
    - `material_label` string, nullable
    - `machining_process_value` string, nullable
    - `machining_process_label` string, nullable
    - `effective_coating_value` string, nullable
    - `effective_coating_color` string, nullable
    - `effective_coating_label` string, nullable
    - `effective_finishing_value` string, nullable
    - `effective_finishing_label` string, nullable
    - `drawing_file_name` string, nullable
    - `drawing_file_size` integer, nullable
    - `drawing_analysis` object, nullable
    - `spec_proposal` object, nullable
    - `versions` PartVersionStatus[]
      - `id` string, uuid, required
      - `is_latest` boolean, required
      - `status` string, required
      - `processing_step` string, nullable
      - `latest_run_id` string, uuid, nullable
      - `analysis_milestone` string, nullable
      - `analysis_authority` string, nullable
      - `analysis_seq` integer, nullable
      - `preliminary_price` PreliminaryPriceResponse — Compact public projection of a run-only Lane A pricing result. Unknown fields are deliberately ignored so internal raw-midpoint and component-audit telemetry can never leak through REST or SSE serialization.
        - `status` 'ready' | 'abstained', required
        - `authority` 'preliminary'
        - `non_payable` true
        - `currency` 'USD'
        - `unit_price` PreliminaryPriceRange — Inclusive USD price interval calibrated for holdout coverage.
          - `low` number, required
          - `high` number, required
        - `total_price` PreliminaryPriceRange — Inclusive USD price interval calibrated for holdout coverage.
          - `low` number, required
          - `high` number, required
        - `quantity` integer, nullable
        - `cohort` string, nullable
        - `assumptions` string[]
        - `missing_inputs` string[]
        - `abstention_reason` 'missing_specs' | 'unsupported_process_material' | 'multi_body_or_assembly' | 'context_unavailable' | 'identity_unavailable' | 'stock_out_of_envelope' | 'implausible_fill' | 'machine_or_setup_ambiguous' | 'pending_drawing' | 'custom_spec' | 'low_primitive_confidence' | 'calibration_unavailable' | 'cohort_disabled' | 'inputs_changing', nullable
        - `model_version` string, required
        - `pricing_config_generation` string, required
        - `calibration_version` string, nullable
        - `calibration_hash` string, nullable
        - `pricing_input_hash` string, required
        - `generated_at` string, date-time, required
      - `file_format` string, nullable
      - `thumbnail_url` string, nullable
      - `dfm_score` string, nullable
      - `unit_price_mid` number, nullable
      - `has_ai_synthesis` boolean
      - `has_dfm_results` boolean
      - `analysis_status` 'not_started' | 'pending_cad' | 'computing' | 'complete' | 'failed' — Single source of truth for deterministic DFM/pricing readiness. Replaces the fragile inference from ``dfm_pending`` + ``process_dfm_results`` + ``ai_dfm_synthesis``. See ``.claude/plans/active/dfm-cost-stuck-state-elimination.md``. NOT_STARTED: No specs set yet. PENDING_CAD: Specs set, CAD pipeline still running — finalize will pick up. COMPUTING: DFM rule engine / pricing refresh in flight. COMPLETE: DFM and pricing written; AI/Ollie synthesis is optional. FAILED: See ``analysis_error_message`` + ``analysis_failed_step``.
      - `analysis_error_message` string, nullable
      - `analysis_failed_step` string, nullable
      - `analysis_last_transition_at` string, date-time, nullable
      - `updated_at` string, date-time, required
    - `latest_dfm_results` object, nullable
    - `finish` FinishResponse — Computed unified finish view of a Part for the frontend. All fields default to ``None`` / empty so a part with no finish set serialises cleanly. ``category`` distinguishes mechanical surface finish from bath/coating; ``color_options`` is empty for mechanical finishes and color-locked platings.
      - `id` string, uuid, nullable — Underlying ``Dropdown.id`` (either finishing_id or coating_id).
      - `slug` string, nullable — Underlying ``Dropdown.value`` slug.
      - `label` string, nullable — Human-readable label for the finish.
      - `category` 'finishing' | 'coating', nullable — Whether this finish is mechanical or a coating bath.
      - `color` string, nullable — Currently selected color name (e.g. 'Black', 'Custom'). Mirrors ``Part.coating_color``.
      - `color_options` ColorOption[] — Available colors for this finish. Empty list means no color picker (mechanical finish or color-locked plating).
        - `name` string, required — Display name of the color (e.g. 'Black')
        - `surcharge` number — Per-part USD adder when this color is selected.
      - `default_color` string, nullable — Pre-selected color when this finish is chosen.
      - `custom_color_surcharge` number, nullable — One-time USD adder when the user picks 'Custom' RAL/Pantone. None disables the Custom path.
      - `custom_name` string, nullable — Free-text custom finish descriptor (mirrors ``Part.custom_coating_name``).
      - `spec` string, nullable — MIL-spec / drawing callout (mirrors ``Part.coating_spec``).
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `submitted_at` string, date-time, nullable
  - `order_placed_at` string, date-time, nullable
  - `expected_delivery_date_min` string, date, nullable
  - `expected_delivery_date_max` string, date, nullable

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/prototyping/apis/prototyping-io-api.md) · [All operations](https://skmtc.dev/prototyping/apis/prototyping-io-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/prototyping/prototyping-io-api/revisions/f4a0079fbb57/schema)
