Skip to content
pic2CAD

For developers

Picture to CAD, from your own code

Turn your pictures into CAD blocks, ready as DXF, SVG and PNG, straight from your own scripts and tools. Flat 0.75 € per conversion, your first key comes with 5 free ones, and it is its own prepaid wallet, separate from your web credits.

Start in 3 steps

1. Create your key

Open /account/api and create a key. It takes an email, nothing else, and you get 5 free conversions to try it.

2. Send a picture

POST a JPEG, PNG or WebP up to 10 MB. One picture per request, 0.75 € per conversion.

3. Poll and download

Check the result every 3 to 5 seconds. Once it's done, download the DXF, SVG and PNG, free and as often as you like.

curl
curl -X POST https://pic2cad.ai/api/v1/convert \
  -H "Authorization: Bearer p2c_live_..." \
  -F "image_file=@chair.jpg"

Technical reference

Everything above is enough to get going. Open a section below only if you need the details.

The full loop in three calls: start a conversion, poll it, download the file.

curl
curl -X POST https://pic2cad.ai/api/v1/convert \
  -H "Authorization: Bearer $PIC2CAD_API_KEY" \
  -F "image_file=@chair.jpg"
# -> 202 { "id": "cm3x...", "status": "processing", "balance_eur": 24.25, ... }
#    X-Api-Charge-Cents: 75

curl https://pic2cad.ai/api/v1/conversions/cm3x... \
  -H "Authorization: Bearer $PIC2CAD_API_KEY"
# -> { "id": "cm3x...", "status": "complete", "files": { "dxf": "..." }, ... }

curl -L -o chair.dxf \
  https://pic2cad.ai/api/v1/conversions/cm3x.../files/dxf \
  -H "Authorization: Bearer $PIC2CAD_API_KEY"
python
import os, time, requests

API = "https://pic2cad.ai/api/v1"
HEAD = {"Authorization": f"Bearer {os.environ['PIC2CAD_API_KEY']}"}

with open("chair.jpg", "rb") as f:
    job = requests.post(f"{API}/convert", headers=HEAD,
                        files={"image_file": f}).json()

while True:
    time.sleep(5)
    state = requests.get(f"{API}/conversions/{job['id']}", headers=HEAD).json()
    if state["status"] != "processing":
        break

if state["status"] == "complete":
    dxf = requests.get(state["files"]["dxf"], headers=HEAD)
    open("chair.dxf", "wb").write(dxf.content)
else:
    print(state["error"]["message"])
node
import fs from "node:fs/promises";

const API = "https://pic2cad.ai/api/v1";
const head = { Authorization: `Bearer ${process.env.PIC2CAD_API_KEY}` };

const form = new FormData();
form.append("image_file", new Blob([await fs.readFile("chair.jpg")]), "chair.jpg");

const job = await fetch(`${API}/convert`, { method: "POST", headers: head, body: form })
  .then((r) => r.json());

let state;
do {
  await new Promise((r) => setTimeout(r, 5000));
  state = await fetch(`${API}/conversions/${job.id}`, { headers: head }).then((r) => r.json());
} while (state.status === "processing");

if (state.status === "complete") {
  const dxf = await fetch(state.files.dxf, { headers: head });
  await fs.writeFile("chair.dxf", Buffer.from(await dxf.arrayBuffer()));
}

Starts a conversion. Returns 202 with the conversion id straight away; the work runs in the background. Send the picture as multipart/form-data in the image_file field, with any options as extra form fields.

FieldTypeDefaultWhat it does
image_filefilerequiredThe picture, as multipart/form-data. JPEG, PNG or WebP, up to 10 MB.
titlestringProject NNName of the conversion. It becomes the download filename.
detailedbooleantrueMaximum detail. Set false for simplified linework with no facial detail.
modestringaccurateaccurate keeps the pose and perspective of your picture. elevation redraws the subject as a flat orthographic block for plans.
viewstringautoElevation mode only: auto, front, side, back, top. Ignored in accurate mode.
aspectstring3:4Frame of the drawing: 1:1, 3:4, 4:3, 9:16, 16:9.
height_mminteger1700 / 1000Real-world height of the subject in millimetres. The DXF comes out at that scale. If omitted, elevation mode defaults to 1700, accurate mode to 1000 (a fixed reference block).
json
{
  "id": "cm3x...",
  "status": "processing",
  "balance_eur": 24.25,
  "conversions_remaining": 32
}

The X-Api-Charge-Cents header reports what this request took out of your API balance, in cents: 75 for a normal conversion.

Poll this until status is terminal. It is processing, complete or failed. The files object only appears once all three formats are ready.

json
{
  "id": "cm3x...",
  "status": "complete",
  "title": "Oak chair",
  "files": {
    "dxf": "https://pic2cad.ai/api/v1/conversions/cm3x.../files/dxf",
    "svg": "https://pic2cad.ai/api/v1/conversions/cm3x.../files/svg",
    "png": "https://pic2cad.ai/api/v1/conversions/cm3x.../files/png"
  },
  "balance_eur": 24.25,
  "conversions_remaining": 32
}

A failed conversion carries an error object, and the 0.75 € is already back in your balance.

json
{
  "id": "cm3x...",
  "status": "failed",
  "title": "Oak chair",
  "error": {
    "code": "unprocessable_picture",
    "message": "We couldn't turn this picture into a drawing. Your balance was refunded ..."
  },
  "balance_eur": 25.00,
  "conversions_remaining": 33
}

Formats: dxf, svg, png. Same Bearer key as everything else. The URLs never expire and downloading is always free, so you can fetch the same drawing as often as you need.

FormatWhat you get
dxfThe CAD deliverable: R2018, splines, Outer / Inner / Fill on separate layers, in millimetres at the scale you asked for.
svgPlain vector, opens in Illustrator or InDesign to change line weight and colour.
pngCropped silhouette with a transparent background: black outline, white fill.

Asking for a file before the conversion is complete returns 409 conversion_not_ready. Every download sets a Content-Disposition filename built from the conversion title.

Who you are and how much API balance you have left. Call it once at startup, then track it from balance_eur and conversions_remaining on every conversion response, which are always authoritative.

curl
curl https://pic2cad.ai/api/v1/account \
  -H "Authorization: Bearer $PIC2CAD_API_KEY"

{
  "email": "you@studio.com",
  "balance_eur": 24.25,
  "conversions_remaining": 32,
  "price_per_conversion_eur": 0.75,
  "auto_top_up": { "enabled": true, "below_eur": 5, "amount_eur": 25 }
}

auto_top_up mirrors what you configured in your account: while enabled is true, the balance is topped up on its own before it runs out. It reports nothing about your web credits or web subscription, because neither one pays for API conversions.

Every error returns the same envelope, and nothing is kept for a failed request.

json
{
  "errors": [
    {
      "code": "insufficient_api_balance",
      "title": "Insufficient API balance",
      "detail": "..."
    }
  ]
}
HTTPCodeMeaning
401unauthorizedMissing, invalid, or revoked key.
402insufficient_api_balanceNot enough API balance. Top up in your account.
403account_suspendedThe account is suspended.
404not_foundNo such conversion on your account.
409conversion_not_readyFiles requested before the conversion finished.
413payload_too_largeThe picture is over 10 MB.
422invalid_imageUndecodable or unsupported picture.
422invalid_parametersA parameter value is out of range.
429rate_limitedSlow down. Honour Retry-After.
500internal_errorOur side broke. Nothing charged.

Retry guidance: back off exponentially on 5xx, wait the Retry-After seconds on a 429, and do not retry a 4xx unchanged.

10 conversions per minute per key, 120 per minute on the read endpoints. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 adds Retry-After. Limits are per key, so separate keys for separate environments keeps a batch job from starving your app.

FAQ

DXF, SVG, PNG from a single conversion. The DXF is R2018 with splines on Outer, Inner and Fill layers, the SVG is plain vector, and the PNG has a transparent background.
No. They are two separate wallets. Web credits and web subscriptions never pay for API conversions, and API balance is never spent by the browser app. Top up your API balance in your account.
No. If a conversion fails on our side, the 0.75 € goes straight back into your balance. There are no free retries on top of that: every call you make is charged, so retries cost the same as any other conversion.
Conversions return 402 insufficient_api_balance until you top up. Top up any time from 10 € to 100 €, or turn on automatic top-up so a batch job never stops halfway.

Use with Claude or another AI agent

Building a script or agent that should call pic2CAD on its own? Two ways to plug it in, pick whichever your agent supports.

Connect the pic2CAD server to Claude

Run this once and Claude can convert pictures, check on them, and download the files on its own. Works the same way with any other agent that speaks MCP.

terminal
claude mcp add --transport http pic2cad https://pic2cad.ai/api/mcp --header "Authorization: Bearer YOUR_API_KEY"

If your agent doesn't support MCP

Copy this into Claude or any AI coding agent instead: it has the base address, how to authenticate, the four calls it needs, and how to check on a conversion, so it can drive the API without you explaining anything else.

prompt
You can convert pictures into CAD-ready files (DXF, SVG, PNG) using the pic2CAD API.

Base URL: https://pic2cad.ai/api/v1
Auth: send this header on every request: Authorization: Bearer YOUR_API_KEY

Calls available:
1. POST /convert: send a picture (multipart/form-data, field "image_file") to start a conversion. Returns an id.
2. GET /conversions/{id}: check status ("processing", "complete", or "failed"). Poll every 3 to 5 seconds until it is no longer "processing".
3. GET /conversions/{id}/files/{format}: download a finished file once status is "complete". format is "dxf", "svg", or "png".
4. GET /account: check remaining balance and how many conversions it still pays for.

Keep YOUR_API_KEY private: never print it, log it, share it, or commit it to a file.
By creating an API key you agree to the terms and the licence. Need higher volume or something custom? Talk to us. Questions? pic2cad@gmail.com