# AI sign designer quickstart

Upload an image, start a paid AI sign design, and download its SVG, EPS, and PDF files.

- Source URL: https://www.signcustomiser.com/help/api/guides/ai-sign-designer/
- Markdown URL: https://www.signcustomiser.com/help/api/guides/ai-sign-designer.md

## Guide

Use this guide to make a sign design from an image with the AI sign designer. You can use the API or an AI agent. Each design that the AI sign designer delivers uses one credit. A design that fails uses no credit.

You need Bash, `curl` and `jq` for the API steps. Your file must be a PNG, JPEG, WebP or AVIF image, an SVG file or a PDF file.

## Before you start

- The AI sign design API must be available for your Store. If it is not available, each request in this guide gets a 404 response.
- Your Store must have one or more AI credits.
- The AI sign designer sends your image to external AI image providers to make the design.

## 1. Create a key

Open the Store in Sign Customiser. Go to **Tools & Settings > API Tokens**. Create a key with these scopes:

- `ai_sign_designs:read`
- `ai_sign_designs:write`

A key that you created before does not get these scopes. Create a new key. See [Authentication and key lifecycle](/help/api/guides/authentication/) for more information about keys.

## 2. Set the base URL and key

```bash
set -o pipefail
: "${SIGN_CUSTOMISER_API_BASE:=https://web.signcustomiser.com}"
read -rsp "Sign Customiser API key: " SIGN_CUSTOMISER_API_KEY
printf '\n'
export SIGN_CUSTOMISER_API_BASE SIGN_CUSTOMISER_API_KEY
```

## 3. Read the capabilities

```bash
curl --fail-with-body --silent --show-error \
  --header "Accept: application/json" \
  --header "Authorization: Bearer ${SIGN_CUSTOMISER_API_KEY}" \
  "${SIGN_CUSTOMISER_API_BASE}/api/v3/ai-sign-design-capabilities" | jq
```

Make sure that `data.available` is `true`. `data.credits.available_units` shows the credits that you can use. `data.source` shows the file limits.

## 4. Declare the image

Tell the API the file name, the media type and the exact size in bytes. For a JPEG, WebP or AVIF file, change `content_type` to `image/jpeg`, `image/webp` or `image/avif`. For an SVG file, use `image/svg+xml` and the file name extension `.svg`. For a PDF file, use `application/pdf` and the file name extension `.pdf`. A PNG, JPEG, WebP, AVIF or SVG file must be 5,242,880 bytes or less. A PDF file must be 26,214,400 bytes or less. Each side of an image must be 8,192 pixels or less. The image must have 16,777,216 pixels or less. The AI sign designer changes an AVIF file, an SVG file, or the first page of a PDF file, to a PNG image. These limits apply to that image.

```bash
IMAGE=shopfront-logo.png
SOURCE=$(curl --fail-with-body --silent --show-error \
  --request POST \
  --header "Accept: application/json" \
  --header "Content-Type: application/json" \
  --header "Authorization: Bearer ${SIGN_CUSTOMISER_API_KEY}" \
  --header "Idempotency-Key: $(uuidgen)" \
  --data "$(jq -n --arg name "$IMAGE" --argjson size "$(wc -c < "$IMAGE")" \
    '{filename: $name, content_type: "image/png", byte_size: $size}')" \
  "${SIGN_CUSTOMISER_API_BASE}/api/v3/ai-sign-design-sources")
SOURCE_ID=$(jq -r '.data.id' <<<"$SOURCE")
```

The response contains `data.upload_target`. The target is valid for 10 minutes. Only the first response contains the target. If you lose it, declare the image again with a new `Idempotency-Key`.

## 5. Upload the image

Send the file to the target. Use the method and all the headers in `upload_target`.

```bash
HEADERS=()
while IFS= read -r HEADER; do
  HEADERS+=(--header "$HEADER")
done < <(jq -r '.data.upload_target.headers | to_entries[] | "\(.key): \(.value)"' <<<"$SOURCE")
curl --fail-with-body --silent --show-error \
  --request "$(jq -r '.data.upload_target.method' <<<"$SOURCE")" \
  "${HEADERS[@]}" \
  --upload-file "$IMAGE" \
  "$(jq -r '.data.upload_target.url' <<<"$SOURCE")"
```

The image stays available for a design for 24 hours.

## 6. Start the design

This step holds one credit. Set `product_family` to `neon`, `channel_letter` or `metal_cut_out`.

```bash
JOB=$(curl --fail-with-body --silent --show-error \
  --request POST \
  --header "Accept: application/json" \
  --header "Content-Type: application/json" \
  --header "Authorization: Bearer ${SIGN_CUSTOMISER_API_KEY}" \
  --header "Idempotency-Key: $(uuidgen)" \
  --data "$(jq -n --arg id "$SOURCE_ID" '{source_file: {id: $id}, product_family: "neon"}')" \
  "${SIGN_CUSTOMISER_API_BASE}/api/v3/ai-sign-design-jobs")
JOB_ID=$(jq -r '.data.id' <<<"$JOB")
```

The API gives an SVG, an EPS and an Illustrator-compatible PDF. To get only the SVG, add `"output_formats": ["svg"]`.

An image can start one design only. If you send the same request again with the same `Idempotency-Key`, you get the same job. You do not use a second credit.

## 7. Wait for the design

Read the job until `data.status` is `delivered` or `failed`. Wait for the number of seconds in `data.poll_after_seconds` between each read.

```bash
while :; do
  JOB=$(curl --fail-with-body --silent --show-error \
    --header "Accept: application/json" \
    --header "Authorization: Bearer ${SIGN_CUSTOMISER_API_KEY}" \
    "${SIGN_CUSTOMISER_API_BASE}/api/v3/ai-sign-design-jobs/${JOB_ID}")
  STATUS=$(jq -r '.data.status' <<<"$JOB")
  case "$STATUS" in delivered | failed) break ;; esac
  sleep "$(jq -r '.data.poll_after_seconds // 5' <<<"$JOB")"
done
echo "$STATUS"
```

| `status` | Meaning | Credit (`charge.state`) |
| --- | --- | --- |
| `queued` | The design did not start yet. | `reserved` |
| `processing` | The AI sign designer makes the design. | `reserved` |
| `delivered` | The design is ready. | `charged` |
| `failed` | The AI sign designer did not make a design, or it could not read your file. | `released`, after `reserved` for a short time |

When `status` is `failed`, read `data.error`. If `data.error.code` is `source_rejected`, the AI sign designer could not read your file. This can happen to an SVG or a PDF file that the AI sign designer cannot change to an image, to an SVG file that has a script or an unsafe feature, to an image that is damaged, and to a file that you replaced after you started the design (`source_changed`). `data.error.verification_failure_code` gives the reason. No credit is used. Correct the file, declare a new source, upload the file and start a new design.

## 8. Download the files

Do this step only when `STATUS` is `delivered`. Each ready file in `data.result.files` has a `download_url`. This link needs no API key and no login. You can give it to a manufacturer.

```bash
curl --fail --location --silent --show-error \
  --output "${JOB_ID}.svg" \
  "$(jq -r '.data.result.files.svg.download_url' <<<"$JOB")"
```

- The files are not drawn at the physical size of the sign. Scale the artwork to `data.result.assessed_dimensions`.
- Read `data.result.advisories` before you send a design to production.

If the EPS or the PDF has `state: failed`, send `POST /api/v3/ai-sign-design-jobs/{job_id}/exports` with a new `Idempotency-Key`. This retry is free. Each job has 3 retries.

## Use an AI agent

Claude Code and the OpenAI Codex and ChatGPT plugins can do the same steps with the hosted MCP server. Connect the agent with the [connection guide](/help/mcp/guides/connect/). Approve **View AI sign designs** and **Use the AI sign designer**. If you connected the agent before, connect it again.

Then ask the agent to make a design from your image. The agent uses these tools:

1. `get_ai_sign_design_capabilities`
2. `create_ai_sign_design_source`, and then it uploads the image to the target
3. `create_ai_sign_design_job`
4. `get_ai_sign_design_job`
5. `retry_ai_sign_design_job_exports`, if a conversion fails

`create_ai_sign_design_job` uses a credit. The agent must send `confirm: true` and `max_credits: 1`. The agent gives you the `download_url` of each file.

## When a request fails

| Response | What to do |
| --- | --- |
| 409 `insufficient_credits` | Add credits to the Store. |
| 409 `source_already_consumed` | Declare and upload the file again. |
| 422 `source_rejected` | The file failed the first check. `verification_failure_code` gives the reason. Correct the file, declare a new source and upload the file again. |
| 429 `ai_sign_design_capacity_reached` | Wait for the time in `Retry-After`. Then send the same request again. |
| 503 `ai_sign_designer_unavailable` | The AI sign designer is not available for the Store now. Try again later. |

See [Errors and retries](/help/api/guides/errors-and-retries/) for all error responses.
