The CADLens API turns DWG, DXF, and DWF files into structured JSON your code can render, diff, and route.
This is a REST API. Authenticate with a bearer API key, upload a file, poll the job until it finishes (or wait for a webhook), then read a JSON document with vector entities, layers, drawing metadata, and a rendered PNG preview.
All endpoints live under the /v1 path prefix. Stable formats: DWG, DXF, DWF. Beta formats: PDF, DWFx, DGN (V7). File size limit is 10 MB on the free plan, up to 100 MB on paid plans. The file type is verified by magic bytes, not the extension.
Request beta access at cadlens.co. Once approved (within 48 h), sign in to the dashboard to create and copy your cadl_… key — the full key is shown only once. Stash it in your environment as CADLENS_KEY. See Authentication for the rules.
Multipart upload to /v1/parse with a file field (up to your plan limit — 10 MB on free). The response is a job — in the default async mode its status is PENDING until the worker picks it up.
Either poll GET /v1/jobs/{jobId} until status === "COMPLETED", or skip polling and use webhooks. Then GET /v1/jobs/{jobId}/result to read the parsed JSON and preview URL.
!
Upload limit is 10 MB on the free plan (higher on paid plans). Accepted formats: DWG, DXF, DWF (stable) and PDF, DWFx, DGN V7 (beta). See errors for the codes returned when a file is rejected.
Every request to the parse and jobs endpoints uses a bearer API key in the Authorization header:
Authorization: Bearer cadl_<48 hex characters>
Keys are created in the dashboard and start with the prefix cadl_. The full key is shown once at creation — store it securely; only the first few characters (the key prefix) are visible afterwards. Revoking a key in the dashboard takes effect immediately. A request with a missing, malformed, revoked, or expired key returns 401.
!
Never call CADLens from a browser. Anything you POST from fetch() in the front-end leaks your key. Proxy through your backend.
Upload a CAD file as multipart/form-data. Every parse returns both vector JSON and a rendered PNG preview. In the default async mode the response is 202 with a job_id and status PENDING — poll GET /v1/jobs/{jobId} or use a webhook until the job is COMPLETED.
Accepted formats: DWG, DXF, DWF (stable) and PDF, DWFx, DGN V7 (beta). Maximum file size depends on your plan — 10 MB on the free tier, up to 100 MB on paid plans. The type is verified by magic bytes, not the file extension.
Read the current status of a job. Idempotent and not counted against your quota — safe to poll. status is one of PENDING, PROCESSING, COMPLETED, or FAILED. imageUrl is a signed PNG URL once COMPLETED, otherwise null.
Returns the parsed document: vectorJson (a flat array of entities), layersJson, metadata, and a signed imageUrl. Available only once the job is COMPLETED — calling it earlier returns 400 "Job result is not yet available".
Returns a JSON object with imageUrl — a signed S3 URL to the rendered PNG preview, valid for one hour. The same URL is also included in the job and result responses. Available only once the job is COMPLETED.
Permanently deletes the job and its stored artifacts (vector JSON and the rendered PNG). Returns 204 No Content on success, or 404 if the job does not exist for your API key. This cannot be undone.
A worked example of a single parse, end to end. Follow the three steps alongside — upload a file, poll the job until it's COMPLETED, then read the result.
Upload.POST /v1/parse with your file returns a job_id and status PENDING.
Poll.GET /v1/jobs/{jobId} until the status is COMPLETED (or FAILED).
Read.GET /v1/jobs/{jobId}/result returns the vector JSON, layers, metadata, and a preview URL.
i
This is a read-only example. To run requests interactively against your own account, open the Playground in your dashboard after creating an API key.
Polling. Call GET /v1/jobs/{jobId} until status is COMPLETED or FAILED. Use exponential backoff starting around 250ms and capped at ~4s — the example alongside does this. Polling does not count against your usage quota. Prefer a webhook if you'd rather not poll.
When a job is COMPLETED, its result describes the drawing in four parts: the vectors (every geometric entity), the layers they belong to, file-level metadata, and a rendered preview image. The shape alongside shows the top-level keys.
The vectorJson array holds the drawing's geometry. Every entity records the layer it belongs to, its colour, and a small set of points describing its shape — all coordinates are 2D points in the drawing's own units. The entity type mirrors the original CAD object. The common types you'll encounter:
Skip polling. Pass webhookUrl when you call /v1/parse, or save an endpoint in the dashboard (up to two per account). CADLens then POSTs a JSON event as the job progresses and finishes. The request carries User-Agent: CADLens-Webhook/1.0 and a JSON body.
Your endpoint should respond 2xx within 10 seconds. A non-2xx (or timeout) is retried up to 3 times with exponential backoff (~2s, 4s, 8s, capped at 30s); after that the delivery is recorded as exhausted.
Deliveries to a saved endpoint are signed. Each request carries X-CADLens-Signature: t=<ts>,v1=<hmac> and a X-CADLens-Timestamp header. Recompute the HMAC-SHA256 of <timestamp>.<raw request body> using your endpoint's signing secret (shown once when you create the endpoint) and compare it to the v1 value; reject requests whose timestamp is too old to stop replays.
i
As a belt-and-suspenders practice, on job.completed re-fetch GET /v1/jobs/{jobId}/result with your API key to read the authoritative result.
Errors return a flat JSON object with a human-readable error message and, sometimes, a programmatic code. Request-validation failures use a slightly richer shape — { "error": "Validation error", "details": { fieldErrors, formErrors } }. The HTTP status carries the category.
Usage is metered as a monthly quota per plan. Each successful parse counts as one request; failed parses and read calls (get job, result, image, list) do not count. The counter resets at the start of each calendar month (UTC).
Field
Type
Description
Free
optional
50 / mo
Trial and hobby use.
Starter
optional
500 / mo
Small projects.
Growth
optional
2,000 / mo
Early production.
Pro
optional
10,000 / mo
Higher-volume apps.
Business
optional
40,000 / mo
High volume.
Enterprise
optional
Unlimited
No monthly cap.
Once you hit your plan's limit, POST /v1/parse returns 429 Too Many Requests with a message like Monthly limit of N requests reached for PLAN plan until the next monthly reset or a plan upgrade.
Need more? Upgrade your plan in the dashboard, or email [email protected] for Enterprise.
Quota exceeded
{
"error": "Monthly limit of 50 requests reached for FREE plan"
}
Result documents return vectorJson (typed entities), layersJson with per-layer counts, drawing metadata with a boundingBox, and a signed PNG preview URL.
2026-05
added
Webhooks: job.processing, job.completed, and job.failed events, delivered to a per-parse webhookUrl or a saved endpoint.
2026-05
added
Format support: DWG, DXF, DWF, DWFx, Bentley DGN V7, and CAD-bearing PDF, validated by magic bytes up to 100 MB.