# Convert a drawing to SVG

> Convert a technical drawing into a layered SVG vector file, ready for tech packs and cutting. Delivered as one SVG file.

**Endpoint:** `POST https://api.refabric.com/v1/tasks/image.to_svg` · **Task:** `image.to_svg` · **Scope:** `tasks:run` · **Category:** Production prep

Send a technical drawing of a garment and get it back as a layered SVG vector file, ready for a tech pack or for cutting. A shape that could not be assigned to a part keeps a layer of its own whose name contains `Unassigned`, and the result tells you to check those layers.

## Quick start

```python
import os
import time
import requests

headers = {"Authorization": f"Key {os.environ['REFABRIC_API_KEY']}"}

job = requests.post(
    "https://api.refabric.com/v1/tasks/image.to_svg",
    headers=headers,
    json={
        "image": "art:4b7e02",
    },
).json()
print(job["job_id"])

while True:
    status = requests.get(job["status_url"], headers=headers).json()
    if status["lifecycle"] == "terminal":
        break
    time.sleep(5)

print(requests.get(job["result_url"], headers=headers).json())
```

```javascript
const headers = {
  Authorization: `Key ${process.env.REFABRIC_API_KEY}`,
  "Content-Type": "application/json",
};

const job = await fetch("https://api.refabric.com/v1/tasks/image.to_svg", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "image": "art:4b7e02"
  }),
}).then((r) => r.json());
console.log(job.job_id);

let status = job;
while (status.lifecycle !== "terminal") {
  await new Promise((r) => setTimeout(r, 5000));
  status = await fetch(job.status_url, { headers }).then((r) => r.json());
}

console.log(await fetch(job.result_url, { headers }).then((r) => r.json()));
```

```bash
curl -X POST "https://api.refabric.com/v1/tasks/image.to_svg" \
  -H "Authorization: Key $REFABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: wait=60" \
  -d '{"image":"art:4b7e02"}'
```

## Input schema

- `image` (string, _required_, pattern: ^(https://|art:|file:).+$) — The technical drawing to convert into a layered SVG, as one string: a URL, a file from an earlier result (`art:…` or its url — an `image.to_sketch` drawing works best) or an upload (`file:…`).
  Example: `art:4b7e02`

## Required-fields example

```json
{
  "image": "art:4b7e02"
}
```

## Full example

```json
{
  "image": "art:4b7e02"
}
```

## Output schema

- `files` (array<object>, _optional_) — One `image/svg+xml` file: the drawing as a layered vector document.
- `summary` (object, _optional_) — Sent only when some shapes need a look: its `warnings` then say which check to make before cutting.
  - `warnings` (array<object>, _optional_) — `{code: "svg_needs_review"}` when some shapes could not be assigned to a part: each is on a layer of its own whose name contains "Unassigned" — check those layers before cutting.

## Response example

```json
{
  "job_id": "7a1c2e3f00004000800000000000001d",
  "lifecycle": "queued",
  "status_url": "http://v3-api.refabric.com/v1/jobs/7a1c2e3f00004000800000000000001d",
  "result_url": "http://v3-api.refabric.com/v1/jobs/7a1c2e3f00004000800000000000001d/result",
  "cancel_url": "http://v3-api.refabric.com/v1/jobs/7a1c2e3f00004000800000000000001d/cancel"
}
```

## Result example

```json
{
  "job_id": "7a1c2e3f00004000800000000000001d",
  "files": [
    {
      "file": "art:8e1b01",
      "url": "https://files.example.com/image.to_svg/1.svg",
      "media_type": "image/svg+xml",
      "task": "image.to_svg",
      "job_id": "7a1c2e3f00004000800000000000001d",
      "created_at": "2026-10-01T09:42:55Z"
    }
  ],
  "has_more": false,
  "summary": {
    "warnings": [
      {
        "code": "svg_needs_review",
        "field": null,
        "message": "Some shapes of the SVG are on layers whose names contain `Unassigned`."
      }
    ]
  }
}
```

The drawing comes from `image.to_sketch`. `summary.warnings` is empty when every shape found its layer; here some did not and are on the `Unassigned` layer.

## Built for

- Tech-pack flats
- Files for cutting
- Editable line art from a sketch

## What you get

- One SVG file: the drawing as a layered vector document.
- A `summary` with an `svg_needs_review` warning when some shapes are on layers whose names contain `Unassigned`.

## Specs

- **Input formats:** Images, each one string: a URL, an upload (`file:…`) or a file from an earlier result (`art:…`). Upload types and sizes: `GET /v1/meta` `limits.upload`.
- **Input count:** `image`: one
- **Output format:** Files: each one line with its `url` and its `media_type`, in the job's result.
- **Outputs per job:** One file per job.

## Errors

- `field_not_accepted`
- `invalid_request`
- `not_found`
- `permission_denied`
- `insufficient_credits`
- `processing_failed`
- `internal`

## Related

- `image.to_sketch` — It runs before: its result is this input.

## For agents and code generation

- https://api.refabric.com/v1/tasks/image.to_svg/llms.txt
- https://api.refabric.com/v1/tasks/image.to_svg/openapi.json
- GET https://api.refabric.com/v1/tasks/image.to_svg
