# Results

A completed conversion's files: download one, preview it, read its figures and shapes.

### Download a file of the result

`GET /v1/conversions/{id}/download`

A short-lived URL for one of the result's files: `format` names one of `result.formats` by id (absent, the web default). Served from the storage domain as an attachment, never inline from this origin: SVG is an active document format. Allowed once the conversion's IMAGE is unlocked, on every plan; then every format and re-download is free. A locked image answers 402 `unlock_required` (this GET never spends). `as` takes the format as a print-ready PDF (`pdf`, a design file's of outlines, never its `editableText` twin) or a picture (`png`, a web file's with a preview, `size` px on its long side): made from the stored result on first ask, after the unlock check.

| Field | In | Type | Required | What |
| --- | --- | --- | --- | --- |
| `id` | path | id | yes |  |
| `format` | query | string | no | A format's id from `result.formats`; the web default when left out. |
| `as` | query | one of `svg`, `pdf`, `png` | no |  |
| `size` | query | one of `2048`, `4096`, `8192` | no | With `as=png`: the picture's long side in px. |
| `variant` | query | id | no | A recolor of the result (POST /conversions/{id}/variants): the file with those colors, every format but `currentColor`. |

```bash
curl https://api.vecsnap.com/v1/conversions/00000000-0000-4000-8000-000000000000/download \
  -H "Authorization: Bearer $VECSNAP_API_KEY"
```

Answer 200:

```json
{
  "url": "https://files.vecsnap.com/…",
  "expiresIn": 1,
  "filename": "logo",
  "format": "example"
}
```

Answer 402:

```json
{
  "error": {
    "code": "unlock_required",
    "message": "This image is not unlocked yet, so its files do not download.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

Answer 404:

```json
{
  "error": {
    "code": "not_found",
    "message": "There is nothing at that id for this caller.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

Answer 409:

```json
{
  "error": {
    "code": "conversion_failed",
    "message": "The conversion ended without a result.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

| Status | Code | What to do |
| --- | --- | --- |
| 402 | `unlock_required` | Unlock it (1 credit, once per image), then download. |
| 404 | `not_found` | Check the id. Another account's objects read as not found too. |
| 404 | `variant_not_found` | Use a variant id this result listed. |
| 409 | `conversion_failed` | Convert the image again. Converting is free. |
| 409 | `not_in_test_mode` | Use a live key for it, or test the conversion and its SVG files. |
| 409 | `not_ready` | Wait for it to finish (a webhook, the events stream, or a read), then ask again. |
| 409 | `result_outdated` | Convert the image again. |
| 429 | `rate_limited` | Wait the Retry-After seconds, then send it again. |
| 502 | `derive_failed` | Try again. The coarser picture still shows. |

Every other refusal it may answer: `format_unavailable` (400), `invalid_id` (400), `invalid_request` (400), `invalid_api_key` (401), `unauthenticated` (401), `account_required` (403), `email_unverified` (403), `plan_required` (403), `account_exists` (409), `email_refused` (422), `internal_error` (500), `auth_unavailable` (503).

### Preview the result

`GET /v1/conversions/{id}/preview`

A short-lived URL for a web file's rendered PNG, on EVERY tier: the free tier is the product demo, a full-quality conversion, this preview and its figures, with the SVG withheld. Served inline (a PNG is inert). `format` names a web file of `result.formats` that is not `currentColor` (its background kept or dropped); absent, the web default's. 2048 px on its long side, at the drawing's own aspect. `layer=outline`: the anchor-point view at the same size, lying exactly on it (black hairlines and squares on transparency).

| Field | In | Type | Required | What |
| --- | --- | --- | --- | --- |
| `id` | path | id | yes |  |
| `format` | query | string | no | A web file's id; the web default when left out. |
| `layer` | query | one of `outline` | no |  |

```bash
curl https://api.vecsnap.com/v1/conversions/00000000-0000-4000-8000-000000000000/preview \
  -H "Authorization: Bearer $VECSNAP_API_KEY"
```

Answer 200:

```json
{
  "url": "https://files.vecsnap.com/…",
  "expiresIn": 1
}
```

Answer 404:

```json
{
  "error": {
    "code": "not_found",
    "message": "There is nothing at that id for this caller.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

Answer 409:

```json
{
  "error": {
    "code": "conversion_failed",
    "message": "The conversion ended without a result.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

Answer 429:

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests in a short time.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

| Status | Code | What to do |
| --- | --- | --- |
| 404 | `not_found` | Check the id. Another account's objects read as not found too. |
| 409 | `conversion_failed` | Convert the image again. Converting is free. |
| 409 | `not_in_test_mode` | Use a live key for it, or test the conversion and its SVG files. |
| 409 | `not_ready` | Wait for it to finish (a webhook, the events stream, or a read), then ask again. |
| 409 | `result_outdated` | Convert the image again. |
| 429 | `rate_limited` | Wait the Retry-After seconds, then send it again. |
| 502 | `derive_failed` | Try again. The coarser picture still shows. |

Every other refusal it may answer: `format_unavailable` (400), `invalid_id` (400), `invalid_request` (400), `layer_unavailable` (400), `invalid_api_key` (401), `unauthenticated` (401), `email_unverified` (403), `plan_required` (403), `account_exists` (409), `email_refused` (422), `internal_error` (500), `auth_unavailable` (503).

### Tiles of a deeper zoom

`POST /v1/conversions/{id}/tiles`

Every tier, like the preview: pictures of the file, never the SVG. Level L draws the drawing 2048·2^L px long, cut into 512-px squares (1 ≤ L ≤ 3); a tile is [x, y] within the square grid of its level. Missing tiles are made first, then served from storage.

| Field | In | Type | Required | What |
| --- | --- | --- | --- | --- |
| `id` | path | id | yes |  |
| `layer` | body | string | yes | `outline` or `outline-2x` (the anchor-point view drawn for a 1× or 2× screen), a web file's id, or `ids-{format}` (that web file's Shapes ID picture, GET /conversions/{id}/shapes). |
| `level` | body | integer, 1 to 3 | yes |  |
| `tiles` | body | array of array of any | yes |  |
| `variant` | body | id, or null | no | A recolor of the result: a web file's tiles with its colors (never the outline's). |
| `palette` | body | integer, 2 to 24, or null | no | A redraw's preview count (GET /conversions/{id}/palette): a web file's tiles with the drawing merged into its colors. Never with `variant`. |

```bash
curl -X POST https://api.vecsnap.com/v1/conversions/00000000-0000-4000-8000-000000000000/tiles \
  -H "Authorization: Bearer $VECSNAP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"layer":"outline","level":1,"tiles":[[0,0]]}'
```

Answer 200:

```json
{
  "layer": "outline",
  "level": 0,
  "variant": "00000000-0000-4000-8000-000000000000",
  "palette": 0,
  "tiles": [
    {
      "x": 0,
      "y": 0,
      "url": "https://files.vecsnap.com/…"
    }
  ],
  "expiresIn": 1
}
```

Answer 404:

```json
{
  "error": {
    "code": "not_found",
    "message": "There is nothing at that id for this caller.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

Answer 409:

```json
{
  "error": {
    "code": "conversion_failed",
    "message": "The conversion ended without a result.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

Answer 429:

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests in a short time.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

| Status | Code | What to do |
| --- | --- | --- |
| 404 | `not_found` | Check the id. Another account's objects read as not found too. |
| 404 | `variant_not_found` | Use a variant id this result listed. |
| 409 | `conversion_failed` | Convert the image again. Converting is free. |
| 409 | `not_in_test_mode` | Use a live key for it, or test the conversion and its SVG files. |
| 409 | `not_ready` | Wait for it to finish (a webhook, the events stream, or a read), then ask again. |
| 409 | `original_not_kept` | Upload the file again. |
| 409 | `result_outdated` | Convert the image again. |
| 429 | `rate_limited` | Wait the Retry-After seconds, then send it again. |
| 502 | `derive_failed` | Try again. The coarser picture still shows. |

Every other refusal it may answer: `invalid_id` (400), `invalid_options` (400), `invalid_request` (400), `invalid_tiles` (400), `malformed_body` (400), `invalid_api_key` (401), `unauthenticated` (401), `email_unverified` (403), `plan_required` (403), `account_exists` (409), `email_refused` (422), `internal_error` (500), `auth_unavailable` (503).

### The original image

`GET /v1/conversions/{id}/original`

A short-lived URL for the image the conversion was made from: the upload, kept with its result for the comparison (deleted with the result or the account, never in the shared cache). While it waits or runs, the upload itself, so a client can show the image being converted. Served inline, as the type its bytes proved at upload. A result made before originals were kept, a running conversion whose upload is gone, or a TIFF (which no browser but Safari draws) has none: 404 `original_unavailable`.

| Field | In | Type | Required | What |
| --- | --- | --- | --- | --- |
| `id` | path | id | yes |  |

```bash
curl https://api.vecsnap.com/v1/conversions/00000000-0000-4000-8000-000000000000/original \
  -H "Authorization: Bearer $VECSNAP_API_KEY"
```

Answer 200:

```json
{
  "url": "https://files.vecsnap.com/…",
  "expiresIn": 1
}
```

Answer 404:

```json
{
  "error": {
    "code": "not_found",
    "message": "There is nothing at that id for this caller.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

Answer 409:

```json
{
  "error": {
    "code": "conversion_failed",
    "message": "The conversion ended without a result.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

| Status | Code | What to do |
| --- | --- | --- |
| 404 | `not_found` | Check the id. Another account's objects read as not found too. |
| 404 | `original_unavailable` | Show its redraw instead. |
| 409 | `conversion_failed` | Convert the image again. Converting is free. |

Every other refusal it may answer: `invalid_id` (400), `invalid_api_key` (401), `unauthenticated` (401), `email_unverified` (403), `plan_required` (403), `account_exists` (409), `email_refused` (422), `rate_limited` (429), `internal_error` (500), `auth_unavailable` (503).

### The result's facts

`GET /v1/conversions/{id}/facts`

Every tier: the engine's facts of the default file, in the ENGINE's names (the same object the site's examples show): the counts a layers panel would sum (anchor points, paths, circles, rectangles, rings, strokes, repeats, elements, the words kept as text) and every color the file draws with what it paints and its share of the frame.

| Field | In | Type | Required | What |
| --- | --- | --- | --- | --- |
| `id` | path | id | yes |  |

```bash
curl https://api.vecsnap.com/v1/conversions/00000000-0000-4000-8000-000000000000/facts \
  -H "Authorization: Bearer $VECSNAP_API_KEY"
```

Answer 200:

```json
{
  "summary": {
    "anchor_points": 0,
    "circles": 0,
    "rects": 0,
    "rings": 0,
    "paths": 0,
    "strokes": 0,
    "uses": 0,
    "definitions": 0,
    "elements": 0,
    "words": [
      "example"
    ],
    "colors": 0,
    "gradients": 0
  },
  "colors": [
    {
      "key": "#1f6feb",
      "roles": [
        "fill"
      ],
      "area": 0
    }
  ],
  "ground": "#1f6feb"
}
```

Answer 404:

```json
{
  "error": {
    "code": "not_found",
    "message": "There is nothing at that id for this caller.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

Answer 409:

```json
{
  "error": {
    "code": "conversion_failed",
    "message": "The conversion ended without a result.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

Answer 429:

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests in a short time.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

| Status | Code | What to do |
| --- | --- | --- |
| 404 | `not_found` | Check the id. Another account's objects read as not found too. |
| 409 | `conversion_failed` | Convert the image again. Converting is free. |
| 409 | `not_in_test_mode` | Use a live key for it, or test the conversion and its SVG files. |
| 409 | `not_ready` | Wait for it to finish (a webhook, the events stream, or a read), then ask again. |
| 409 | `result_outdated` | Convert the image again. |
| 429 | `rate_limited` | Wait the Retry-After seconds, then send it again. |
| 502 | `derive_failed` | Try again. The coarser picture still shows. |

Every other refusal it may answer: `invalid_id` (400), `invalid_api_key` (401), `unauthenticated` (401), `email_unverified` (403), `plan_required` (403), `account_exists` (409), `email_refused` (422), `internal_error` (500), `auth_unavailable` (503).

### The result's shapes

`GET /v1/conversions/{id}/shapes`

Every tier, like the preview: a web file's shapes in the engine's order, and a link to its ID PICTURE at the preview's size: every pixel's color − 1 is the shape on top there, transparent where none is, never a blended pixel. Decode it with color conversion and premultiplying off. Its deeper zoom: POST /conversions/{id}/tiles with the layer `ids-{format}`. Made on the first ask, then served.

| Field | In | Type | Required | What |
| --- | --- | --- | --- | --- |
| `id` | path | id | yes |  |
| `format` | query | string | no | A web file's id; the default web file when left out. |

```bash
curl https://api.vecsnap.com/v1/conversions/00000000-0000-4000-8000-000000000000/shapes \
  -H "Authorization: Bearer $VECSNAP_API_KEY"
```

Answer 200:

```json
{
  "format": "example",
  "width": 1,
  "height": 1,
  "rows": [
    {
      "index": 0,
      "kind": "example",
      "ground": false,
      "points": 0,
      "paint": "#1f6feb",
      "box": [
        0,
        0,
        0,
        0
      ],
      "neighbors": [
        0
      ]
    }
  ],
  "picture": "https://files.vecsnap.com/…",
  "expiresIn": 1
}
```

Answer 404:

```json
{
  "error": {
    "code": "not_found",
    "message": "There is nothing at that id for this caller.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

Answer 409:

```json
{
  "error": {
    "code": "conversion_failed",
    "message": "The conversion ended without a result.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

Answer 429:

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests in a short time.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

| Status | Code | What to do |
| --- | --- | --- |
| 404 | `not_found` | Check the id. Another account's objects read as not found too. |
| 409 | `conversion_failed` | Convert the image again. Converting is free. |
| 409 | `not_in_test_mode` | Use a live key for it, or test the conversion and its SVG files. |
| 409 | `not_ready` | Wait for it to finish (a webhook, the events stream, or a read), then ask again. |
| 409 | `result_outdated` | Convert the image again. |
| 429 | `rate_limited` | Wait the Retry-After seconds, then send it again. |
| 502 | `derive_failed` | Try again. The coarser picture still shows. |

Every other refusal it may answer: `format_unavailable` (400), `invalid_id` (400), `invalid_request` (400), `invalid_api_key` (401), `unauthenticated` (401), `email_unverified` (403), `plan_required` (403), `account_exists` (409), `email_refused` (422), `internal_error` (500), `auth_unavailable` (503).

---
This page: https://vecsnap.com/docs/api/results
