# Quickstart

This flow uploads photos, creates a test order, and retrieves it.

## 1. Get a Test API key

Create or copy a Test key in
[API key settings](https://account.legitgrails.com/settings/integrations) with
`orders:write` and `orders:read`.

Live and Test keys use the same base URL:

```text
https://api.legitgrails.com/v1/integrations
```

Send the key as `Authorization: Bearer YOUR_TEST_API_KEY` in each
request.

## 2. Resolve catalog codes

List categories, then find a compatible brand, available answer time, and photo
requirements. This example uses Gucci bags:

```bash
curl --fail-with-body --silent --show-error \
  "https://api.legitgrails.com/v1/integrations/catalog/categories?locale=en" \
  --header "Authorization: Bearer YOUR_TEST_API_KEY"

curl --fail-with-body --silent --show-error \
  "https://api.legitgrails.com/v1/integrations/catalog/brands?category_code=bag&search=gucci" \
  --header "Authorization: Bearer YOUR_TEST_API_KEY"

curl --fail-with-body --silent --show-error \
  "https://api.legitgrails.com/v1/integrations/catalog/answer_times?brand_code=gucci&category_code=bag" \
  --header "Authorization: Bearer YOUR_TEST_API_KEY"

curl --fail-with-body --silent --show-error \
  "https://api.legitgrails.com/v1/integrations/catalog/photo_indexes?brand_code=gucci&category_code=bag" \
  --header "Authorization: Bearer YOUR_TEST_API_KEY"
```

Catalog arrays are returned in `data`. Use their exact `code` values, select an
answer time with `available: true`, and provide each required photo without
exceeding its `photo_limit`. See [Catalog](/catalog) for models and other query
options.

## 3. Upload photos

Upload the photos required by the selected photo indexes. Send each file as a
`photos` part to `POST /photos`:

```bash
curl --fail-with-body --silent --show-error \
  --request POST "https://api.legitgrails.com/v1/integrations/photos" \
  --header "Authorization: Bearer YOUR_TEST_API_KEY" \
  --form "photos=@./overall.jpg" \
  --form "photos=@./serial-number.jpg"
```

The HTTP `200` response contains one result per file. Use the URL only when
`status` is `uploaded`:

```json
[
  {
    "status": "uploaded",
    "url": "https://media.legitgrails.com/uploads/tusd/example-overall",
    "original_name": "overall.jpg"
  },
  {
    "status": "uploaded",
    "url": "https://media.legitgrails.com/uploads/tusd/example-serial",
    "original_name": "serial-number.jpg"
  }
]
```

An individual result can instead have `status: "failed"`, an `error`, and no
`url`. Retry or replace that file before creating the order. Use each successful
URL with the corresponding catalog `index_code`.

## 4. Create an order

```bash
curl --fail-with-body --silent --show-error \
  --request POST "https://api.legitgrails.com/v1/integrations/orders" \
  --header "Authorization: Bearer YOUR_TEST_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "brand_code": "gucci",
    "category_code": "bag",
    "answer_time": 720,
    "mock_outcome": "authentic",
    "photos": [
      {
        "url": "https://media.legitgrails.com/uploads/tusd/example-overall",
        "index_code": "overall-picture"
      },
      {
        "url": "https://media.legitgrails.com/uploads/tusd/example-serial",
        "index_code": "serial-number"
      }
    ]
  }'
```

A successful request returns a response like this:

```json
{
  "id": "<order-id>",
  "status": "completed",
  "due_date": "2026-08-04T22:30:00.000Z"
}
```

Persist `id`; you will use it to retrieve the order and submit replacement
photos if requested.

## 5. Retrieve the order

Use the returned order ID:

```bash
curl --fail-with-body --silent --show-error \
  "https://api.legitgrails.com/v1/integrations/orders/<order-id>?locale=en" \
  --header "Authorization: Bearer YOUR_TEST_API_KEY"
```

```json
{
  "id": "<order-id>",
  "status": "completed",
  "outcome": "authentic",
  "due_date": "2026-08-04T22:30:00.000Z",
  "updated_at": "2026-08-04T10:30:04.000Z"
}
```

Drive your workflow from `status` and `outcome`. See [Orders](/orders) for every
lifecycle response and [Photos](/photos) for the `update-photos` flow.

## Move to Live

For a live order, keep the same base URL, remove `mock_outcome`, and replace the
Test API key with a Live API key that has the required scopes. The key selects
the environment.

Poll `GET /orders/{id}` or use [webhooks](/webhooks) for completed and
photo-update notifications.

Continue with [Integration setup](/integration-setup) and the
[API Reference](/api).
