> ## 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.

# How the API works

> The flow every LocalAds integration follows, and the rules every request shares.

Every LocalAds flow follows the same five steps. Do the first three once per
product, then start as many creative jobs as you want.

<Steps>
  <Step title="Create a brand">
    One brand per website. [Brands](/setup/brands)
  </Step>

  <Step title="Create a product">
    From a product page URL or images. LocalAds reads it, and the product
    becomes `ready`. [Products](/setup/products)
  </Step>

  <Step title="Pick an audience">
    Audiences are generated and saved automatically. Campaigns and UGC videos
    are made for the one you pick. [Audiences](/setup/audiences)
  </Step>

  <Step title="Start a creative job">
    An ad campaign, listing images, a photoshoot, ChatGPT ads, or a UGC
    video. It answers `202 Accepted` with the job's id.
  </Step>

  <Step title="Poll until completed">
    Read the finished creatives from the response. [Polling](/concepts/polling)
  </Step>
</Steps>

| Step | Calls |
| - | - |
| 1. Brand | `GET /brands`, `POST /brands` |
| 2. Product | `POST /products`, `GET /products/{product_id}` |
| 3. Audience | `GET /products/{product_id}/audiences` |
| 4. Creative job | `POST /campaigns`, `POST /photoshoots`, `POST /amazon-listing-images`, `POST /chatgpt-ad-groups`, `POST /videos` |
| 5. Results | the job's `Location` URL, and `GET /creatives` |

## The rules every request shares

* **Base URL.** `https://makelocalads.com/api/v1`. Every request is HTTPS.
* **Authentication.** An organization API key in the `Authorization` bearer
  header. See [Authentication](/authentication).
* **JSON.** Requests and responses are JSON. Errors use
  `application/problem+json` with a `code` and a `request_id`. See
  [Errors and retries](/concepts/errors).
* **Asynchronous work.** A generation request answers `202 Accepted` with the
  job's id and a `Location` header, then runs in the background. See
  [Jobs and lifecycle](/concepts/jobs-and-lifecycle).
* **Idempotent starts.** Generation requests accept an `Idempotency-Key`
  header, so a retry after a network failure never starts and charges for a
  second job. See [Idempotent requests](/concepts/idempotency).
* **Spending caps.** Every request that spends credits accepts `max_credits`,
  and is refused with `422` instead of going over. See
  [Credits and spending](/concepts/credits-and-spending).
