> ## Documentation Index
> Fetch the complete documentation index at: https://docs.makelocalads.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a photoshoot

> Generate product photos from a reusable LocalAds template.

A photoshoot applies the ordered shots in a template to one of your products.
Generation runs asynchronously, and each template shot consumes one credit.

## Before you start

You need:

* an API key with `photoshoots:generate`
* a product with at least one image
* enough credits for every shot in the selected template

The product and template must belong to the same brand.

## 1. Choose a template

List the photoshoot templates available to the product's brand:

```bash theme={null}
curl "https://makelocalads.com/api/v1/templates?brand_id=1423f915-beca-4c53-a5e4-7c8c99537be9&limit=20" \
  --header "Authorization: Bearer $LOCALADS_API_KEY"
```

```json theme={null}
{
  "data": [
    {
      "id": "photoshoot-shot-pack:38b66c64-e76f-483f-a185-2d377ee2c5eb",
      "brand_id": "1423f915-beca-4c53-a5e4-7c8c99537be9",
      "title": "Studio essentials",
      "preview_url": "https://cdn.example.com/template-preview.jpg",
      "shot_count": 4,
      "created_at": "2026-07-20T10:00:00.000Z",
      "updated_at": "2026-07-20T10:05:00.000Z"
    }
  ],
  "next_cursor": null
}
```

Retrieve one template to inspect its ordered shots and output dimensions:

```bash theme={null}
curl "https://makelocalads.com/api/v1/templates/photoshoot-shot-pack%3A38b66c64-e76f-483f-a185-2d377ee2c5eb" \
  --header "Authorization: Bearer $LOCALADS_API_KEY"
```

## 2. Start the photoshoot

```bash theme={null}
curl --request POST \
  --url https://makelocalads.com/api/v1/photoshoots \
  --header "Authorization: Bearer $LOCALADS_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "product_id": "a1516a75-9be5-461a-93af-c1896a0a3127",
    "template_id": "photoshoot-shot-pack:38b66c64-e76f-483f-a185-2d377ee2c5eb"
  }'
```

For production integrations, you can optionally include an `Idempotency-Key`
header. If a network failure makes you retry a request, reuse the same key to
avoid creating and charging for a duplicate photoshoot:

```bash theme={null}
--header "Idempotency-Key: photoshoot-order-1042"
```

Omitting the header creates a new photoshoot on every request.

LocalAds returns `202 Accepted` with the durable photoshoot resource:

```json theme={null}
{
  "id": "e8766ffd-66f7-47c9-86bc-0d93e6868d06",
  "brand_id": "1423f915-beca-4c53-a5e4-7c8c99537be9",
  "product_id": "a1516a75-9be5-461a-93af-c1896a0a3127",
  "template_id": "photoshoot-shot-pack:38b66c64-e76f-483f-a185-2d377ee2c5eb",
  "status": "queued",
  "outputs": [
    {
      "id": "19025a65-5395-41c9-af90-d7cca7fb6421",
      "position": 1,
      "status": "queued",
      "image_url": null,
      "width": null,
      "height": null
    }
  ],
  "created_at": "2026-07-24T15:00:00.000Z",
  "updated_at": "2026-07-24T15:00:00.000Z"
}
```

## 3. Retrieve results

Poll the URL in the `Location` response header:

```bash theme={null}
curl https://makelocalads.com/api/v1/photoshoots/e8766ffd-66f7-47c9-86bc-0d93e6868d06 \
  --header "Authorization: Bearer $LOCALADS_API_KEY"
```

Completed outputs appear while the remaining shots continue:

```json theme={null}
{
  "id": "e8766ffd-66f7-47c9-86bc-0d93e6868d06",
  "brand_id": "1423f915-beca-4c53-a5e4-7c8c99537be9",
  "product_id": "a1516a75-9be5-461a-93af-c1896a0a3127",
  "template_id": "photoshoot-shot-pack:38b66c64-e76f-483f-a185-2d377ee2c5eb",
  "status": "in_progress",
  "outputs": [
    {
      "id": "19025a65-5395-41c9-af90-d7cca7fb6421",
      "position": 1,
      "status": "completed",
      "image_url": "https://cdn.example.com/generated-shot-1.png",
      "width": 1024,
      "height": 1024
    },
    {
      "id": "4f52bad2-2da3-4b36-93ac-03788f35daca",
      "position": 2,
      "status": "in_progress",
      "image_url": null,
      "width": null,
      "height": null
    }
  ],
  "created_at": "2026-07-24T15:00:00.000Z",
  "updated_at": "2026-07-24T15:00:04.000Z"
}
```

Stop polling when the photoshoot status is `completed`, `failed`, or
`canceled`. Use backoff between requests rather than polling continuously.
