Skip to main content
POST
/
parse
Parse features
curl --request POST \
  --url https://api.bedrock.cv/parse \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "sheet_id": "sht_01JABCD123",
  "features": [
    "symbols"
  ],
  "options": {
    "symbols": {
      "count": true
    }
  }
}
'
{
  "job_id": "job_01JABCD123",
  "type": "parse",
  "status": "Completed",
  "target": {
    "type": "sheet",
    "id": "sht_01JABCD123"
  },
  "results": {
    "legend": [
      {
        "block_id": "blk_01JABCD200",
        "symbols_detected": 24,
        "symbols_with_graphic": 18,
        "symbols": [
          {
            "feature_id": "ftr_01JABCD300",
            "label": "duplex_receptacle",
            "description": "DUPLEX RECEPTACLE",
            "has_graphic": true
          }
        ]
      }
    ],
    "symbols": [
      {
        "label": "duplex_receptacle",
        "description": "DUPLEX RECEPTACLE",
        "legend_feature_id": "ftr_01JABCD300",
        "instance_count": 4,
        "instances": [
          {
            "feature_id": "ftr_01JABCD400",
            "block_id": "blk_01JABCD100",
            "bounds": {
              "x_min": 333,
              "y_min": 207,
              "x_max": 345,
              "y_max": 222
            },
            "confidence": 0.694
          }
        ]
      }
    ],
    "summary": {
      "total_symbols_searched": 5,
      "total_instances_found": 21
    }
  },
  "created_at": "2024-01-15T10:00:00Z",
  "completed_at": "2024-01-15T10:01:30Z"
}
Parse answers “what is on this sheet?” by running detection and extraction tasks that populate the Drawing Index with structured features, metadata, and relationships.

Supported Features

The features array selects which tasks to run.
FeatureStatusDescription
symbolsAvailableLegend-driven symbol detection (doors, windows, fixtures, MEP equipment)
legendComing soonLegend block parsing (standalone)
roomsComing soonRoom boundary detection and labeling
gridComing soonGrid line and axis detection
scheduleComing soonTable and schedule extraction
notesComing soonGeneral and key notes extraction
title_blockComing soonTitle block metadata extraction
Only symbols is currently accepted by the API. Requesting a “coming soon” feature will return a validation error.

Target Options

Parse from an existing sheet, block, drawing, or an uploaded file:
TargetDescription
sheet_idParse from an existing sheet in the system
block_idParse a specific block directly (requires legend_block_id)
drawing_idParse all sheets in a drawing (auto-detects legends)
file_idParse from an uploaded PDF file (creates Drawing + Sheets automatically)

Parsing from Uploaded Files

For new documents, use the file upload flow:
  1. Upload the file via POST /files to get a signed upload URL
  2. Upload the PDF to the signed URL
  3. Confirm the upload via POST /files/{file_id}/confirm
  4. Start parsing via POST /parse with file_id
  5. Poll or stream for results
{
  "file_id": "fil_01JABCD111",
  "features": ["symbols"]
}
Parsing will automatically render PDF pages, create Drawing and Sheet records, detect blocks, then run symbol detection.

Symbol Detection

Symbol detection is the primary feature extraction pipeline. It is always legend-driven: every drawing set defines its own symbols in its legend blocks, and detection uses those definitions as the source of truth. Doors, windows, hatching patterns, and MEP equipment (valves, fixtures, etc.) are all symbols. They appear in the drawing’s legend and are detected via this pipeline.

Pipeline

When you request features: ["symbols"], the pipeline runs:
  1. Parse legend blocks - detect each symbol graphic in the legend with its bounding box, label, and description
  2. Crop symbol templates - extract each legend symbol as an image crop (the exemplar)
  3. Template match on view blocks - find instances of each legend symbol across plan views using tiled image matching
  4. Verify with embeddings - filter false positives using DINOv2 embedding similarity
  5. Cross-symbol NMS - resolve overlapping detections from different symbol types using LLM-based reasoning
  6. Link results - create defined_by relations from each detected symbol back to its legend entry
{
  "sheet_id": "sht_xxx",
  "features": ["symbols"]
}
For block-level parsing, provide a legend_block_id so the pipeline knows which legend to use:
{
  "block_id": "blk_xxx",
  "features": ["symbols"],
  "options": {
    "symbols": {
      "legend_block_id": "blk_yyy"
    }
  }
}

Matching Capabilities

The matching engine handles symbols printed at different scales across sheets (0.5x - 2.0x range). Each detection includes a confidence score (0-1) indicating how closely it matches the legend symbol template.

Current Limitations

  • Target symbols of scale range of 0.5x - 2.0x relative to the legend template size
  • Does not account for “suffix text” associated with a symbol (e.g., circuit numbers next to receptacles). The matcher will attempt to match the text as part of the symbol graphic, which can reduce confidence or cause misses.
  • Detections are skipped for symbols smaller than 10px wide or 10px high when rendered at 300 DPI
  • Does not reliably detect symbols where the stroke thickness differs drastically between the plan view and the legend template

Incremental Webhooks

Parse fires incremental webhooks as each stage completes, so you can process results as they arrive rather than waiting for the entire job. See Webhooks for payload details. Legend parsed (parse.child.completed with child_job_type: "vision.legend.parse"): Fired when a legend block finishes parsing. Includes the list of symbols detected in that legend:
{
  "type": "parse.child.completed",
  "data": {
    "job_id": "job_01JABCD125",
    "parent_job_id": "job_01JABCD123",
    "child_job_type": "vision.legend.parse",
    "status": "completed",
    "target": { "type": "block", "id": "blk_01JABCD200" },
    "results": {
      "block_id": "blk_01JABCD200",
      "symbols_detected": 24,
      "symbols_with_graphic": 18,
      "symbols": [
        {
          "feature_id": "ftr_01JABCD300",
          "label": "duplex_receptacle",
          "description": "DUPLEX RECEPTACLE",
          "has_graphic": true
        }
      ]
    }
  }
}
Block symbols matched (parse.block.completed): Fired when a view block finishes symbol detection. Includes per-block detection results:
{
  "type": "parse.block.completed",
  "data": {
    "job_id": "job_01JABCD126",
    "parse_job_id": "job_01JABCD123",
    "block_id": "blk_01JABCD100",
    "status": "completed",
    "results": {
      "symbols": [
        {
          "label": "duplex_receptacle",
          "description": "DUPLEX RECEPTACLE",
          "instance_count": 4,
          "instances": [
            {
              "feature_id": "ftr_01JABCD400",
              "bounds": { "x_min": 333, "y_min": 207, "x_max": 345, "y_max": 222 },
              "confidence": 0.694
            }
          ]
        }
      ],
      "summary": {
        "total_symbols_searched": 5,
        "total_instances_found": 21
      }
    }
  }
}

Result Payload

When the parse job completes, the results contain the combined symbol detections across all blocks:
{
  "legend": [
    {
      "block_id": "blk_01JABCD200",
      "symbols_detected": 24,
      "symbols_with_graphic": 18,
      "symbols": [
        {
          "feature_id": "ftr_01JABCD300",
          "label": "duplex_receptacle",
          "description": "DUPLEX RECEPTACLE (NEW DEVICE, PROVIDE BACKBOX & WIRING)",
          "has_graphic": true
        }
      ]
    }
  ],
  "symbols": [
    {
      "label": "duplex_receptacle",
      "description": "DUPLEX RECEPTACLE (NEW DEVICE, PROVIDE BACKBOX & WIRING)",
      "legend_feature_id": "ftr_01JABCD300",
      "instance_count": 4,
      "instances": [
        {
          "feature_id": "ftr_01JABCD400",
          "block_id": "blk_01JABCD100",
          "bounds": { "x_min": 333, "y_min": 207, "x_max": 345, "y_max": 222 },
          "confidence": 0.694
        }
      ]
    }
  ],
  "summary": {
    "total_symbols_searched": 5,
    "total_instances_found": 21
  }
}
FieldDescription
legend[]Per-legend-block results array
legend[].block_idLegend block ID
legend[].symbols_detectedTotal symbols found in this legend block
legend[].symbols_with_graphicSymbols with a visual graphic (excludes text-only entries)
legend[].symbols[].feature_idFeature ID of the legend entry
legend[].symbols[].has_graphicWhether the symbol has a visual graphic for matching
symbols[].legend_feature_idReference to the legend entry feature
symbols[].instances[].boundsPixel coordinates within the parent block image
symbols[].instances[].confidenceScore (0-1) indicating how closely the detection matches the legend symbol template
summary.total_symbols_searchedUnique symbol types with at least one detection
summary.total_instances_foundTotal detections across all blocks

Authorizations

Authorization
string
header
required

API key prefixed with sk_. Example: Authorization: Bearer sk_xxx

Headers

X-API-Version
string
default:2026-01-01

API version

Body

application/json
features
enum<string>[]
required
Available options:
symbols
sheet_id
string
file_id
string
block_id
string
drawing_id
string
options
object

Response

Completed job result (returned when polling or via webhook).

Completed parse job result with symbol detections.

job_id
string
Example:

"job_01JABCD123"

type
string
Example:

"parse"

status
string
Example:

"Completed"

target
object
results
object

Combined symbol detection results across all blocks.

created_at
string<date-time>
completed_at
string<date-time>