PDF to Visual Struct
Overview
PDF to Visual Struct converts a PDF page into Codia's Visual Element Schema: a hierarchical JSON tree of typed UI elements with bounding boxes, layout configs, and style specs. The schema is the same format that powers Codia Studio, so downstream consumers — Figma importers, code generators, visual QA pipelines — can work against a single, stable data shape.
Endpoint
https://api.codia.ai/v1/open/pdf_to_designAuthentication is via bearer token. Get a key at codia.ai/dashboard/developer.
Request
The request is multipart/form-data.
| Field | Type | Required | Description |
|---|---|---|---|
pdf_file | file | yes | The PDF file to convert. Single file per request. |
page_no | string | yes | Zero-indexed page number to convert. Loop client-side for multi-page conversion. |
Example
curl 'https://api.codia.ai/v1/open/pdf_to_design' \
-H 'Authorization: Bearer {codia_api_key}' \
-H 'Content-Type: application/json' \
--form 'pdf_file=@"xx.pdf"' \
--form 'page_no="0"'Response
{
"configuration": {
"scalingFactor": 1,
"baseWidth": 1940,
"measurementUnit": "px"
},
"pages": [
{
"visualElement": { /* root element */ }
}
],
"size": {
"height": 1080,
"width": 1940
}
}Top-level fields
| Field | Description |
|---|---|
configuration.baseWidth | Reference width used when solving layout. Scale bounding boxes against this when rendering at a different viewport width. |
configuration.measurementUnit | Coordinate unit — typically px. |
configuration.scalingFactor | Pre-applied scaling factor. Usually 1. |
size.width, size.height | The solved page canvas in the base coordinate system. |
pages[].visualElement | The root element of the page tree. Walk childElements recursively. |
Visual Element Schema
Each node in the tree has the same shape:
{
"elementId": "pdf_page_1",
"elementName": "PDF Document Page",
"elementType": "Panel",
"displayName": "First Page",
"displayOrder": 0,
"boundingBox": [0, 0, 595, 842],
"layoutConfig": {
"positionMode": "Normal",
"flexibleMode": "Absolute"
},
"styleConfig": {
"widthSpec": { "sizing": "FIXED", "value": 595 },
"heightSpec": { "sizing": "FIXED", "value": 842 },
"backgroundSpec": {
"type": "COLOR",
"backgroundColor": { "rgbValues": [255, 255, 255] }
}
},
"processingMeta": {
"surfaceArea": 501490,
"detectionScore": 0.92,
"textContainerized": false
},
"childElements": []
}Field reference
| Field | Description |
|---|---|
elementId | Stable identifier within this response. Not globally unique across pages. |
elementType | Typed element class: Panel, Text, Image, Icon, Button, Table, Chart, and 50+ more. |
boundingBox | [x, y, width, height] in base coordinates. |
layoutConfig.positionMode | Normal (flow) or Absolute. |
layoutConfig.flexibleMode | Row, Column, or Absolute — mirrors Figma auto-layout semantics. |
styleConfig.widthSpec.sizing | FIXED, FILL_CONTAINER, or HUG_CONTENT. |
styleConfig.backgroundSpec | Background paint — color, gradient, or image. |
processingMeta.detectionScore | Detector confidence, 0.0 – 1.0. Filter low-confidence nodes before downstream use. |
childElements | Array of child Visual Elements. Depth-first traversal reveals the full hierarchy. |
Limits
| Setting | Default |
|---|---|
| Max file size | 50 MB |
| Max pages per document | 100 |
| Max requests per minute | Plan-dependent — see pricing. |
| Typical latency per page | 600 ms – 2 s |
Supported input
- Text-native PDFs (exported from design tools, office suites, or generated programmatically) — highest fidelity.
- Scanned PDFs — OCR is applied automatically; expect more noise on low-resolution scans.
- Password-protected PDFs are not supported. Unlock before uploading.
Common patterns
Multi-page conversion
Loop page_no from 0 to the document length, in parallel up to the concurrency limit of your plan:
const pages = await Promise.all(
pageNumbers.map((n) => fetch(ENDPOINT, buildRequest(file, n))),
)Filter low-confidence nodes
function prune(node, minScore = 0.6) {
node.childElements = (node.childElements || [])
.filter((c) => c.processingMeta.detectionScore >= minScore)
.map((c) => prune(c, minScore))
return node
}Round-trip to Figma
Because layoutConfig mirrors Figma auto-layout, the tree can be imported as auto-layout frames directly. Use the PDF to Design Figma plugin if you don't want to build the importer yourself.
FAQ
Can I convert every page in one call?
Not in a single call — the endpoint is per-page. Loop and parallelize on your side.
How accurate is the conversion?
Accuracy depends on source quality, PDF structure, scan clarity, and layout complexity. Scanned legal forms and hand-annotated inputs are harder; always inspect processingMeta.detectionScore.
Are fonts preserved?
Font names, sizes, weights, and colors are preserved in styleConfig. Rendering the preserved font requires the font to be installed where you consume the output.
Is there an SDK?
No SDK is required — the API is plain HTTP + JSON. An official SDK is on the roadmap.
Can I deploy this on-premises?
Yes, for enterprise plans. Contact [email protected].
Next steps
- Visual Struct — same schema, image input.
- Remove BG — transparent-background images for compositing into rendered output.
- Full endpoint reference at /api#convert-pdf-to-design.