Codia

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

POSThttps://api.codia.ai/v1/open/pdf_to_design

Authentication is via bearer token. Get a key at codia.ai/dashboard/developer.

Request

The request is multipart/form-data.

FieldTypeRequiredDescription
pdf_filefileyesThe PDF file to convert. Single file per request.
page_nostringyesZero-indexed page number to convert. Loop client-side for multi-page conversion.

Example

bash
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

json
{ "configuration": { "scalingFactor": 1, "baseWidth": 1940, "measurementUnit": "px" }, "pages": [ { "visualElement": { /* root element */ } } ], "size": { "height": 1080, "width": 1940 } }

Top-level fields

FieldDescription
configuration.baseWidthReference width used when solving layout. Scale bounding boxes against this when rendering at a different viewport width.
configuration.measurementUnitCoordinate unit — typically px.
configuration.scalingFactorPre-applied scaling factor. Usually 1.
size.width, size.heightThe solved page canvas in the base coordinate system.
pages[].visualElementThe root element of the page tree. Walk childElements recursively.

Visual Element Schema

Each node in the tree has the same shape:

json
{ "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

FieldDescription
elementIdStable identifier within this response. Not globally unique across pages.
elementTypeTyped element class: Panel, Text, Image, Icon, Button, Table, Chart, and 50+ more.
boundingBox[x, y, width, height] in base coordinates.
layoutConfig.positionModeNormal (flow) or Absolute.
layoutConfig.flexibleModeRow, Column, or Absolute — mirrors Figma auto-layout semantics.
styleConfig.widthSpec.sizingFIXED, FILL_CONTAINER, or HUG_CONTENT.
styleConfig.backgroundSpecBackground paint — color, gradient, or image.
processingMeta.detectionScoreDetector confidence, 0.01.0. Filter low-confidence nodes before downstream use.
childElementsArray of child Visual Elements. Depth-first traversal reveals the full hierarchy.

Limits

SettingDefault
Max file size50 MB
Max pages per document100
Max requests per minutePlan-dependent — see pricing.
Typical latency per page600 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:

js
const pages = await Promise.all( pageNumbers.map((n) => fetch(ENDPOINT, buildRequest(file, n))), )

Filter low-confidence nodes

js
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