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

> ## Agent Instructions
> - Base URLs: models `https://api.aisa.one/v1` (Gemini GenerateContent: `https://api.aisa.one/v1beta`); data APIs `https://api.aisa.one/apis/v1`. The `servers` of each operation in https://aisa.one/openapi.yaml is authoritative.
> - Auth: `Authorization: Bearer $AISA_API_KEY`. Never print, log, or commit the key.
> - MCP (preferred for agents): `https://mcp.aisa.one/mcp`, signed in with OAuth, so there is no key to paste.
> - Agent Skill: `npx skills add AIsa-team/agent-skills --skill aisa`. Fallback with the AIsa CLI: `aisa skills install aisa`.
> - Spending: docs, https://aisa.one/models, https://aisa.one/api, `/v1/models`, and MCP `search`, `list_categories`, `get_details`, `batch_quote`, and the `account` operation are free. Quote the exact calls before running them (MCP `batch_quote`, CLI `aisa quote --json`). If the quote reports `auto_execute_eligible: true`, run it unless the user set a tighter limit or asked only for a quote. Otherwise, tell the user in one message the planned calls, the quoted price, and a total USD budget for the task, then wait for approval. Direct HTTP calls follow the stricter rule at https://aisa.one/docs/get-started/cli.md#direct-http-fallback. Do not make paid calls to test availability. Full rule: https://aisa.one/llms.txt

# Create a standalone ad group

> Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates an ad set (ad group) that can spend from its own or its campaign's budget. Creates an empty ad group under an existing campaign, ready for ads to be added later. The ad group is created WITHOUT an ad (Google Ads compliance row C.190). Ads join it later via `adSetId` on POST /apis/v1/ads/create. Supports Google Ads and Reddit Ads; every other platform returns 501. Reddit Ads (`platform: reddit`)

<!-- aisa-pricing:start -->
A request reference price is not currently available; use a request quote where supported. Account-specific pricing and final settlement may differ.
<!-- aisa-pricing:end -->

## Request contract

* **Method and path:** POST /apis/v1/ads/ad-sets
* **Availability:** enabled
* **Request URL template:** `https://api.aisa.one/apis/v1/ads/ad-sets`
* **connectionId:** query; required
* **X-Aisa-Confirm:** header; optional
* **Idempotency-Key:** header; optional
* **Runtime facts:** fe60122939c67dc98a3a6ac6b97bd5c326b526105150c8959304dd2160d4dd09

[Complete OpenAPI definition](https://aisa.one/docs/reference-contracts/aisa-ads.json)

Effective request and pricing declaration (including authentication and referenced schemas):

```json theme={null}
{
  "operationId": "post_aisa_ads_apis_v1_ads_ad_sets",
  "method": "POST",
  "path": "/apis/v1/ads/ad-sets",
  "servers": [
    {
      "url": "https://api.aisa.one"
    }
  ],
  "parameters": [
    {
      "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
      "in": "query",
      "name": "connectionId",
      "required": true,
      "schema": {
        "pattern": "^adc_[0-9A-Za-z]+$",
        "type": "string"
      }
    },
    {
      "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
      "in": "header",
      "name": "X-Aisa-Confirm",
      "required": false,
      "schema": {
        "enum": [
          "spend"
        ],
        "type": "string"
      }
    },
    {
      "description": "Passed to the ad platform integration: a retry with the same key returns the first result instead of acting twice. AIsa never retries a write for you.",
      "in": "header",
      "name": "Idempotency-Key",
      "required": false,
      "schema": {
        "maxLength": 191,
        "minLength": 1,
        "type": "string"
      }
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "example": {
          "campaignId": "1234567890",
          "connectionId": "adc_7f3k2m9q",
          "name": "Winter launch"
        },
        "schema": {
          "additionalProperties": true,
          "properties": {
            "adAccountId": {
              "description": "Platform ad account ID: the Google customer ID (digits only, only required when the connection has more than one) or the Reddit ad account id (required).",
              "type": "string"
            },
            "bidAmount": {
              "description": "Reddit only. Bid cap in currency units, sent with bidStrategy.",
              "exclusiveMinimum": 0,
              "type": "number"
            },
            "bidStrategy": {
              "description": "Reddit only. Defaults to LOWEST_COST_WITHOUT_CAP. Not accepted under campaign budget optimization.",
              "enum": [
                "LOWEST_COST_WITHOUT_CAP",
                "LOWEST_COST_WITH_BID_CAP",
                "COST_CAP"
              ],
              "type": "string"
            },
            "budgetAmount": {
              "description": "Reddit only. Budget of the new ad group, in the ad account's currency units. Required when the campaign has no campaign budget; 400 under campaign budget optimization, where the campaign budget funds the ad group.",
              "exclusiveMinimum": 0,
              "type": "number"
            },
            "budgetType": {
              "description": "Reddit only. Sent together with budgetAmount.",
              "enum": [
                "daily",
                "lifetime"
              ],
              "type": "string"
            },
            "campaignId": {
              "description": "Platform campaign ID the ad group is created under (numeric on Google). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
              "type": "string"
            },
            "connectionId": {
              "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            },
            "customerId": {
              "description": "Google only. Alias of adAccountId, kept for existing callers",
              "type": "string"
            },
            "endDate": {
              "description": "Reddit only. ISO 8601 end of the ad group. Defaults to the campaign end.",
              "type": "string"
            },
            "maxCpc": {
              "description": "Max CPC of the new ad group, in the account's currency units. Send it when the campaign uses Manual CPC: Google gives an ad group without one a 0.01 bid.",
              "exclusiveMinimum": 0,
              "type": "number"
            },
            "name": {
              "maxLength": 255,
              "minLength": 1,
              "type": "string"
            },
            "optimizationGoal": {
              "description": "Reddit only. VIDEO_VIEW_6S (default) or VIDEO_VIEW_15S on a video views campaign.",
              "type": "string"
            },
            "platform": {
              "description": "\"google\" and \"reddit\" are implemented; every other value returns 501. Filled from the connection when omitted.",
              "enum": [
                "facebook",
                "instagram",
                "tiktok",
                "linkedin",
                "pinterest",
                "google",
                "twitter",
                "openai",
                "reddit",
                "meta",
                "x"
              ],
              "type": "string"
            },
            "promotedObject": {
              "description": "Reddit only. The pixel and the conversion event the ad group optimizes toward.",
              "properties": {
                "customEventType": {
                  "description": "Conversion event (PURCHASE, LEAD, SIGN_UP, ADD_TO_CART, PAGE_VISIT). Required on a conversions campaign.",
                  "type": "string"
                },
                "pixelId": {
                  "description": "Reddit pixel id. Defaults to the ad account's first pixel.",
                  "type": "string"
                }
              },
              "type": "object"
            },
            "startDate": {
              "description": "Reddit only. ISO 8601 start of the ad group. Defaults to now, or to the campaign start when it is in the future.",
              "type": "string"
            },
            "status": {
              "default": "PAUSED",
              "enum": [
                "ACTIVE",
                "PAUSED"
              ],
              "type": "string"
            },
            "targeting": {
              "description": "Normalized, platform-agnostic ad-targeting spec. Every field is optional; an empty object targets the platform's default broadest audience.",
              "properties": {
                "ageMax": {
                  "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                  "maximum": 100,
                  "minimum": 13,
                  "type": "integer"
                },
                "ageMin": {
                  "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                  "maximum": 100,
                  "minimum": 13,
                  "type": "integer"
                },
                "audienceExclude": {
                  "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "audienceInclude": {
                  "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "behaviors": {
                  "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                  "items": {
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "id"
                    ],
                    "type": "object"
                  },
                  "type": "array"
                },
                "cities": {
                  "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                  "items": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "properties": {
                          "distanceUnit": {
                            "description": "Required if radius is set.",
                            "enum": [
                              "mile",
                              "kilometer"
                            ],
                            "type": "string"
                          },
                          "key": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "radius": {
                            "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                            "type": "number"
                          }
                        },
                        "required": [
                          "key"
                        ],
                        "type": "object"
                      }
                    ]
                  },
                  "type": "array"
                },
                "communities": {
                  "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                  "items": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "type": "array"
                },
                "companySizes": {
                  "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "conversationKeywords": {
                  "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                  "items": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "type": "array"
                },
                "countries": {
                  "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "countryGroups": {
                  "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                  "items": {
                    "enum": [
                      "africa",
                      "asia",
                      "europe",
                      "north_america",
                      "south_america",
                      "oceania",
                      "central_america",
                      "caribbean",
                      "eea",
                      "euro_area",
                      "nafta",
                      "mercosur",
                      "afta",
                      "apec",
                      "gcc",
                      "cisfta",
                      "emerging_markets",
                      "itunes_app_store",
                      "android_free_store",
                      "android_paid_store"
                    ],
                    "type": "string"
                  },
                  "type": "array"
                },
                "customLocations": {
                  "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                  "items": {
                    "properties": {
                      "address": {
                        "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                        "type": "string"
                      },
                      "distanceUnit": {
                        "enum": [
                          "mile",
                          "kilometer"
                        ],
                        "type": "string"
                      },
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "name": {
                        "type": "string"
                      },
                      "radius": {
                        "description": "Positive radius around the point.",
                        "type": "number"
                      }
                    },
                    "required": [
                      "distanceUnit",
                      "latitude",
                      "longitude",
                      "radius"
                    ],
                    "type": "object"
                  },
                  "type": "array"
                },
                "excludedCommunities": {
                  "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                  "items": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "type": "array"
                },
                "excludedConversationKeywords": {
                  "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                  "items": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "type": "array"
                },
                "excludedLocations": {
                  "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                  "properties": {
                    "cities": {
                      "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                      "items": {
                        "properties": {
                          "distanceUnit": {
                            "description": "Required if radius is set.",
                            "enum": [
                              "mile",
                              "kilometer"
                            ],
                            "type": "string"
                          },
                          "key": {
                            "type": "string"
                          },
                          "radius": {
                            "description": "Radius around the excluded city. Requires distanceUnit.",
                            "type": "number"
                          }
                        },
                        "required": [
                          "key"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "countries": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "countryGroups": {
                      "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                      "items": {
                        "enum": [
                          "africa",
                          "asia",
                          "europe",
                          "north_america",
                          "south_america",
                          "oceania",
                          "central_america",
                          "caribbean",
                          "eea",
                          "euro_area",
                          "nafta",
                          "mercosur",
                          "afta",
                          "apec",
                          "gcc",
                          "cisfta",
                          "emerging_markets",
                          "itunes_app_store",
                          "android_free_store",
                          "android_paid_store"
                        ],
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "customLocations": {
                      "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                      "items": {
                        "properties": {
                          "address": {
                            "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                            "type": "string"
                          },
                          "distanceUnit": {
                            "enum": [
                              "mile",
                              "kilometer"
                            ],
                            "type": "string"
                          },
                          "latitude": {
                            "maximum": 90,
                            "minimum": -90,
                            "type": "number"
                          },
                          "longitude": {
                            "maximum": 180,
                            "minimum": -180,
                            "type": "number"
                          },
                          "name": {
                            "type": "string"
                          },
                          "radius": {
                            "description": "Positive radius around the point.",
                            "type": "number"
                          }
                        },
                        "required": [
                          "distanceUnit",
                          "latitude",
                          "longitude",
                          "radius"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "neighborhoods": {
                      "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                      "items": {
                        "properties": {
                          "key": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "key"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "places": {
                      "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                      "items": {
                        "properties": {
                          "key": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "key"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "regions": {
                      "items": {
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "key"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "zips": {
                      "items": {
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "key"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                },
                "gender": {
                  "description": "Restrict by gender. 'all' (default) targets everyone.",
                  "enum": [
                    "all",
                    "male",
                    "female"
                  ],
                  "type": "string"
                },
                "incomeTier": {
                  "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                  "enum": [
                    "top_5",
                    "top_10",
                    "top_10_25",
                    "top_25_50"
                  ],
                  "type": "string"
                },
                "industries": {
                  "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "interests": {
                  "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                  "items": {
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "id"
                    ],
                    "type": "object"
                  },
                  "type": "array"
                },
                "jobFunctions": {
                  "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "languages": {
                  "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "metros": {
                  "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                  "items": {
                    "properties": {
                      "key": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "key"
                    ],
                    "type": "object"
                  },
                  "type": "array"
                },
                "regions": {
                  "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                  "items": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "key"
                        ],
                        "type": "object"
                      }
                    ]
                  },
                  "type": "array"
                },
                "seniorities": {
                  "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "skills": {
                  "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                "userDevice": {
                  "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                  "items": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "minItems": 1,
                  "type": "array"
                },
                "userOs": {
                  "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                  "items": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "minItems": 1,
                  "type": "array"
                },
                "workEmployers": {
                  "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                  "items": {
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "id"
                    ],
                    "type": "object"
                  },
                  "type": "array"
                },
                "workIndustries": {
                  "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                  "items": {
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "id"
                    ],
                    "type": "object"
                  },
                  "type": "array"
                },
                "workPositions": {
                  "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                  "items": {
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "id"
                    ],
                    "type": "object"
                  },
                  "type": "array"
                },
                "zips": {
                  "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                  "items": {
                    "properties": {
                      "key": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "key"
                    ],
                    "type": "object"
                  },
                  "type": "array"
                }
              },
              "type": "object"
            }
          },
          "required": [
            "campaignId",
            "name"
          ],
          "type": "object"
        }
      }
    },
    "required": true
  },
  "x-aisa-status": "enabled",
  "x-aisa-pricing": {
    "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
    "kind": "no_customer_charge"
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "scheme": "bearer",
        "type": "http"
      }
    }
  }
}
```

## Cost and request rules

A request reference price is not currently available; use a request quote where supported. Account-specific pricing and final settlement may differ.

Published reference values are not an account-specific quote or a settled charge. For endpoints supporting X-AISA-Cost-Mode: quote, obtain a free quote for your exact request before execution; reconcile the settled cost with response metadata and Usage Logs. USD amounts use 1,000,000 integer micro-USD per dollar.


## OpenAPI

````yaml reference-contracts/aisa-ads.json POST /apis/v1/ads/ad-sets
openapi: 3.1.0
info:
  description: ''
  title: AIsa Ads
  version: '1'
  x-aisa-capabilities:
    idempotency: Idempotency-Key
    max_price: X-AISA-Max-Price-USD
    quote:
      header: X-AISA-Cost-Mode
      value: quote
  x-aisa-configured-paths: []
  x-aisa-document:
    facts_hash: fe60122939c67dc98a3a6ac6b97bd5c326b526105150c8959304dd2160d4dd09
    generator_version: '3'
    protocol_version: '1'
    schema_version: '1'
    composer_version: '27'
    response_pending: []
    document_hash: sha256:ba353f59e89e1ebabe0e301d8ef57d3cbfa6bb406a8c591ee9c3833d64b60520
  x-aisa-plans:
    builder: 1
    display_plan: payg
    payg: 1
    similarweb_payg: 1
    team: 1
    version: e70a0959cd1b93b84ae16dffd7a538273ddb9c1d46277b82823c37ff1b6bc0fb
  x-aisa-provider: aisa-ads
  x-aisa-catalogs:
    aisa-ads:
      title: AIsa Ads
      description: ''
      x-aisa-document:
        facts_hash: fe60122939c67dc98a3a6ac6b97bd5c326b526105150c8959304dd2160d4dd09
        generator_version: '3'
        protocol_version: '1'
        schema_version: '1'
      x-aisa-plans:
        builder: 1
        display_plan: payg
        payg: 1
        similarweb_payg: 1
        team: 1
        version: e70a0959cd1b93b84ae16dffd7a538273ddb9c1d46277b82823c37ff1b6bc0fb
      x-aisa-capabilities:
        idempotency: Idempotency-Key
        max_price: X-AISA-Max-Price-USD
        quote:
          header: X-AISA-Cost-Mode
          value: quote
servers:
  - url: https://api.aisa.one
security:
  - bearerAuth: []
paths:
  /apis/v1/ads/ad-sets:
    post:
      summary: Create a standalone ad group
      description: >-
        Ad Campaigns. Can spend money or change spend: needs the ads:spend scope
        and X-Aisa-Confirm: spend; without the header the request is refused
        with confirmation_required and nothing is sent. Creates an ad set (ad
        group) that can spend from its own or its campaign's budget. Creates an
        empty ad group under an existing campaign, ready for ads to be added
        later. The ad group is created WITHOUT an ad (Google Ads compliance row
        C.190). Ads join it later via `adSetId` on POST /apis/v1/ads/create.
        Supports Google Ads and Reddit Ads; every other platform returns 501.
        Reddit Ads (`platform: reddit`)


        <!-- aisa-pricing:start -->

        A request reference price is not currently available; use a request
        quote where supported. Account-specific pricing and final settlement may
        differ.

        <!-- aisa-pricing:end -->
      operationId: post_aisa_ads_apis_v1_ads_ad_sets
      parameters:
        - description: >-
            The ads connection (adc_...) the request runs on: one of yours, from
            GET /apis/v1/ads/connections. On a request with a JSON body it may
            be sent as a top-level body member instead.
          in: query
          name: connectionId
          required: true
          schema:
            pattern: ^adc_[0-9A-Za-z]+$
            type: string
        - description: >-
            Required with the value "spend" when the request can spend money or
            change spend. Without it the request is refused with 409
            confirmation_required, which describes what would happen; nothing is
            sent to the ad platform.
          in: header
          name: X-Aisa-Confirm
          required: false
          schema:
            enum:
              - spend
            type: string
        - description: >-
            Passed to the ad platform integration: a retry with the same key
            returns the first result instead of acting twice. AIsa never retries
            a write for you.
          in: header
          name: Idempotency-Key
          required: false
          schema:
            maxLength: 191
            minLength: 1
            type: string
      requestBody:
        content:
          application/json:
            example:
              campaignId: '1234567890'
              connectionId: adc_7f3k2m9q
              name: Winter launch
            schema:
              additionalProperties: true
              properties:
                adAccountId:
                  description: >-
                    Platform ad account ID: the Google customer ID (digits only,
                    only required when the connection has more than one) or the
                    Reddit ad account id (required).
                  type: string
                bidAmount:
                  description: >-
                    Reddit only. Bid cap in currency units, sent with
                    bidStrategy.
                  exclusiveMinimum: 0
                  type: number
                bidStrategy:
                  description: >-
                    Reddit only. Defaults to LOWEST_COST_WITHOUT_CAP. Not
                    accepted under campaign budget optimization.
                  enum:
                    - LOWEST_COST_WITHOUT_CAP
                    - LOWEST_COST_WITH_BID_CAP
                    - COST_CAP
                  type: string
                budgetAmount:
                  description: >-
                    Reddit only. Budget of the new ad group, in the ad account's
                    currency units. Required when the campaign has no campaign
                    budget; 400 under campaign budget optimization, where the
                    campaign budget funds the ad group.
                  exclusiveMinimum: 0
                  type: number
                budgetType:
                  description: Reddit only. Sent together with budgetAmount.
                  enum:
                    - daily
                    - lifetime
                  type: string
                campaignId:
                  description: >-
                    Platform campaign ID the ad group is created under (numeric
                    on Google). Must be yours: it is checked through the
                    connection before the request is sent, and an id that is not
                    yours answers not_found.
                  type: string
                connectionId:
                  description: >-
                    The ads connection (adc_...), when not sent as the
                    connectionId query parameter.
                  pattern: ^adc_[0-9A-Za-z]+$
                  type: string
                customerId:
                  description: Google only. Alias of adAccountId, kept for existing callers
                  type: string
                endDate:
                  description: >-
                    Reddit only. ISO 8601 end of the ad group. Defaults to the
                    campaign end.
                  type: string
                maxCpc:
                  description: >-
                    Max CPC of the new ad group, in the account's currency
                    units. Send it when the campaign uses Manual CPC: Google
                    gives an ad group without one a 0.01 bid.
                  exclusiveMinimum: 0
                  type: number
                name:
                  maxLength: 255
                  minLength: 1
                  type: string
                optimizationGoal:
                  description: >-
                    Reddit only. VIDEO_VIEW_6S (default) or VIDEO_VIEW_15S on a
                    video views campaign.
                  type: string
                platform:
                  description: >-
                    "google" and "reddit" are implemented; every other value
                    returns 501. Filled from the connection when omitted.
                  enum:
                    - facebook
                    - instagram
                    - tiktok
                    - linkedin
                    - pinterest
                    - google
                    - twitter
                    - openai
                    - reddit
                    - meta
                    - x
                  type: string
                promotedObject:
                  description: >-
                    Reddit only. The pixel and the conversion event the ad group
                    optimizes toward.
                  properties:
                    customEventType:
                      description: >-
                        Conversion event (PURCHASE, LEAD, SIGN_UP, ADD_TO_CART,
                        PAGE_VISIT). Required on a conversions campaign.
                      type: string
                    pixelId:
                      description: >-
                        Reddit pixel id. Defaults to the ad account's first
                        pixel.
                      type: string
                  type: object
                startDate:
                  description: >-
                    Reddit only. ISO 8601 start of the ad group. Defaults to
                    now, or to the campaign start when it is in the future.
                  type: string
                status:
                  default: PAUSED
                  enum:
                    - ACTIVE
                    - PAUSED
                  type: string
                targeting:
                  description: >-
                    Normalized, platform-agnostic ad-targeting spec. Every field
                    is optional; an empty object targets the platform's default
                    broadest audience.
                  properties:
                    ageMax:
                      description: >-
                        Maximum age. Same per-platform application and clamping
                        as ageMin.
                      maximum: 100
                      minimum: 13
                      type: integer
                    ageMin:
                      description: >-
                        Minimum age. Applied on Meta, TikTok, Pinterest,
                        LinkedIn, X and Google Search/Display (Google excludes
                        the age ranges outside the request). Rejected with 400
                        on OpenAI, Reddit and Google Performance Max / Demand
                        Gen.
                      maximum: 100
                      minimum: 13
                      type: integer
                    audienceExclude:
                      description: >-
                        Platform audience IDs to exclude; same ID formats as
                        audienceInclude. Not supported on OpenAI (400). Must be
                        yours: it is checked through the connection before the
                        request is sent, and an id that is not yours answers
                        not_found.
                      items:
                        type: string
                      type: array
                    audienceInclude:
                      description: >-
                        Platform audience IDs to include, as returned by GET
                        /apis/v1/ads/audiences: Meta: custom audience ids.
                        TikTok: audience ids. Pinterest: customer list ids.
                        LinkedIn: segment ids (the platformAudienceId from GET
                        /apis/v1/ads/audiences). Must be yours: it is checked
                        through the connection before the request is sent, and
                        an id that is not yours answers not_found.
                      items:
                        type: string
                      type: array
                    behaviors:
                      description: >-
                        Behaviour entities from
                        /apis/v1/ads/targeting/search?dimension=behavior (Meta,
                        TikTok and LinkedIn). On TikTok they target people who,
                        in the picked categories:
                      items:
                        properties:
                          id:
                            type: string
                          name:
                            type: string
                        required:
                          - id
                        type: object
                      type: array
                    cities:
                      description: >-
                        City targeting. Optional `radius` + `distanceUnit`
                        extend beyond the city limits; both must be set together
                        or both omitted. `radius` is only honoured on platforms
                        whose capability map allows city radius (Meta).
                      items:
                        oneOf:
                          - type: string
                          - properties:
                              distanceUnit:
                                description: Required if radius is set.
                                enum:
                                  - mile
                                  - kilometer
                                type: string
                              key:
                                type: string
                              name:
                                type: string
                              radius:
                                description: >-
                                  Radius around the city. Requires distanceUnit.
                                  Meta enforces a minimum city radius (~17 km /
                                  10 mi); smaller values resolve to a 0-size
                                  audience and the ad fails at launch.
                                type: number
                            required:
                              - key
                            type: object
                      type: array
                    communities:
                      description: >-
                        Reddit only (400 elsewhere). Subreddits to target, by
                        name, with or without the `r/` prefix (e.g.
                        `['marketing', 'r/startups']`), as returned by
                        /apis/v1/ads/targeting/search?dimension=community.
                      items:
                        minLength: 1
                        type: string
                      type: array
                    companySizes:
                      description: >-
                        LinkedIn B2B only. Single-letter size codes (A to I), or
                        the full urn:li:staffCountRange:* URN from
                        /apis/v1/ads/targeting/search?dimension=companySize.
                      items:
                        type: string
                      type: array
                    conversationKeywords:
                      description: >-
                        Reddit only (400 elsewhere). Keywords that place the ad
                        in Reddit conversations about them, as returned by
                        /apis/v1/ads/targeting/search?dimension=conversationKeyword.
                      items:
                        minLength: 1
                        type: string
                      type: array
                    countries:
                      description: ISO 3166-1 alpha-2 country codes (e.g. ['US']).
                      items:
                        type: string
                      type: array
                    countryGroups:
                      description: >-
                        Meta only. Continents and trade blocs
                        (`geo_locations.country_groups`), for targeting a whole
                        region without listing its countries. Combines with
                        `countries` rather than replacing it, and is also
                        accepted under `excludedLocations`.
                      items:
                        enum:
                          - africa
                          - asia
                          - europe
                          - north_america
                          - south_america
                          - oceania
                          - central_america
                          - caribbean
                          - eea
                          - euro_area
                          - nafta
                          - mercosur
                          - afta
                          - apec
                          - gcc
                          - cisfta
                          - emerging_markets
                          - itunes_app_store
                          - android_free_store
                          - android_paid_store
                        type: string
                      type: array
                    customLocations:
                      description: >-
                        Point-radius (lat/lng) targeting (Meta custom_locations
                        / Google proximity). Honoured on Meta and Google;
                        ignored on platforms without radius support.
                      items:
                        properties:
                          address:
                            description: >-
                              Optional label, sent to Meta as `address_string`.
                              latitude/longitude take precedence for the pin
                              location.
                            type: string
                          distanceUnit:
                            enum:
                              - mile
                              - kilometer
                            type: string
                          latitude:
                            maximum: 90
                            minimum: -90
                            type: number
                          longitude:
                            maximum: 180
                            minimum: -180
                            type: number
                          name:
                            type: string
                          radius:
                            description: Positive radius around the point.
                            type: number
                        required:
                          - distanceUnit
                          - latitude
                          - longitude
                          - radius
                        type: object
                      type: array
                    excludedCommunities:
                      description: >-
                        Reddit only (400 elsewhere). Subreddits to exclude,
                        named like `communities`.
                      items:
                        minLength: 1
                        type: string
                      type: array
                    excludedConversationKeywords:
                      description: >-
                        Reddit only (400 elsewhere). Conversation keywords to
                        keep the ad away from.
                      items:
                        minLength: 1
                        type: string
                      type: array
                    excludedLocations:
                      description: >-
                        Geo to exclude from the audience. Mirrors the inclusion
                        geo shape. Meta (excluded_geo_locations): excluded
                        cities can carry a radius catchment, and excluded custom
                        (lat/lng) pins are supported.
                      properties:
                        cities:
                          description: >-
                            Cities to exclude. Optional `radius` +
                            `distanceUnit` exclude a catchment around the city
                            (both must be set together or both omitted); Meta
                            honours the radius on excluded cities.
                          items:
                            properties:
                              distanceUnit:
                                description: Required if radius is set.
                                enum:
                                  - mile
                                  - kilometer
                                type: string
                              key:
                                type: string
                              radius:
                                description: >-
                                  Radius around the excluded city. Requires
                                  distanceUnit.
                                type: number
                            required:
                              - key
                            type: object
                          type: array
                        countries:
                          items:
                            type: string
                          type: array
                        countryGroups:
                          description: >-
                            Meta only. Continents and trade blocs to exclude
                            (`excluded_geo_locations.country_groups`).
                          items:
                            enum:
                              - africa
                              - asia
                              - europe
                              - north_america
                              - south_america
                              - oceania
                              - central_america
                              - caribbean
                              - eea
                              - euro_area
                              - nafta
                              - mercosur
                              - afta
                              - apec
                              - gcc
                              - cisfta
                              - emerging_markets
                              - itunes_app_store
                              - android_free_store
                              - android_paid_store
                            type: string
                          type: array
                        customLocations:
                          description: >-
                            Point-radius (lat/lng) pins to exclude (Meta
                            excluded_geo_locations.custom_locations). Mirrors
                            the inclusion customLocations shape.
                          items:
                            properties:
                              address:
                                description: >-
                                  Optional label, sent to Meta as
                                  `address_string`. latitude/longitude take
                                  precedence for the pin location.
                                type: string
                              distanceUnit:
                                enum:
                                  - mile
                                  - kilometer
                                type: string
                              latitude:
                                maximum: 90
                                minimum: -90
                                type: number
                              longitude:
                                maximum: 180
                                minimum: -180
                                type: number
                              name:
                                type: string
                              radius:
                                description: Positive radius around the point.
                                type: number
                            required:
                              - distanceUnit
                              - latitude
                              - longitude
                              - radius
                            type: object
                          type: array
                        neighborhoods:
                          description: >-
                            Named neighbourhood areas to exclude. `key` from
                            /apis/v1/ads/targeting/search.
                          items:
                            properties:
                              key:
                                type: string
                            required:
                              - key
                            type: object
                          type: array
                        places:
                          description: >-
                            Named points of interest to exclude. `key` from
                            /apis/v1/ads/targeting/search.
                          items:
                            properties:
                              key:
                                type: string
                            required:
                              - key
                            type: object
                          type: array
                        regions:
                          items:
                            properties:
                              key:
                                type: string
                              name:
                                type: string
                            required:
                              - key
                            type: object
                          type: array
                        zips:
                          items:
                            properties:
                              key:
                                type: string
                              name:
                                type: string
                            required:
                              - key
                            type: object
                          type: array
                      type: object
                    gender:
                      description: Restrict by gender. 'all' (default) targets everyone.
                      enum:
                        - all
                        - male
                        - female
                      type: string
                    incomeTier:
                      description: >-
                        Normalized household-income tier (ZIP/percentile based).
                        Meta and TikTok express all four. Google maps only
                        `top_10` (its INCOME_RANGE_90_UP); other tiers on
                        Google, and any income tier on LinkedIn / X / Pinterest,
                        are rejected.
                      enum:
                        - top_5
                        - top_10
                        - top_10_25
                        - top_25_50
                      type: string
                    industries:
                      description: >-
                        LinkedIn B2B only. Industry URN id fragments, or the
                        full urn:li:industry:* URN from
                        /apis/v1/ads/targeting/search?dimension=industry.
                      items:
                        type: string
                      type: array
                    interests:
                      description: >-
                        Interest entities from
                        /apis/v1/ads/targeting/search?dimension=interest. Each
                        carries the platform's opaque id.
                      items:
                        properties:
                          id:
                            type: string
                          name:
                            type: string
                        required:
                          - id
                        type: object
                      type: array
                    jobFunctions:
                      description: >-
                        LinkedIn B2B only. Function URN id fragments, or the
                        full urn:li:function:* URN from
                        /apis/v1/ads/targeting/search?dimension=jobFunction.
                      items:
                        type: string
                      type: array
                    languages:
                      description: >-
                        Language codes restricting the audience by language.
                        Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest
                        and Reddit; rejected with 400 on OpenAI. A code the
                        platform cannot target returns 400 listing the ones it
                        can.
                      items:
                        type: string
                      type: array
                    metros:
                      description: >-
                        DMA / metro-area targeting. `key` is the platform's
                        metro ID (e.g. Meta `DMA:807`).
                      items:
                        properties:
                          key:
                            type: string
                          name:
                            type: string
                        required:
                          - key
                        type: object
                      type: array
                    regions:
                      description: >-
                        Region/state targeting. `key` is the platform location
                        ID from
                        /apis/v1/ads/targeting/search?dimension=geo&geoType=region.
                        An entry may also be that id as a plain string
                        (`"20321"` is `{ key: "20321" }`).
                      items:
                        oneOf:
                          - type: string
                          - properties:
                              key:
                                type: string
                              name:
                                type: string
                            required:
                              - key
                            type: object
                      type: array
                    seniorities:
                      description: >-
                        LinkedIn B2B only. Seniority URN id fragments, or the
                        full urn:li:seniority:* URN from
                        /apis/v1/ads/targeting/search?dimension=seniority.
                      items:
                        type: string
                      type: array
                    skills:
                      description: >-
                        LinkedIn B2B only. Member skills (e.g. Python,
                        Recruiting): skill URN id fragments, or the full
                        urn:li:skill:* URN from
                        /apis/v1/ads/targeting/search?dimension=skill. Values
                        are ORed; the facet is ANDed with the other facets.
                      items:
                        type: string
                      type: array
                    userDevice:
                      description: >-
                        Meta only. Device models such as iPhone. Emitted as
                        user_device. May also be supplied inside targeting.
                      items:
                        minLength: 1
                        type: string
                      minItems: 1
                      type: array
                    userOs:
                      description: >-
                        Meta only. Operating systems and version ranges, such as
                        iOS_ver_14.0_and_above or Android. Emitted as user_os.
                        May also be supplied inside targeting.
                      items:
                        minLength: 1
                        type: string
                      minItems: 1
                      type: array
                    workEmployers:
                      description: >-
                        Meta only. Employer entities from
                        /apis/v1/ads/targeting/search?dimension=workEmployer.
                      items:
                        properties:
                          id:
                            type: string
                          name:
                            type: string
                        required:
                          - id
                        type: object
                      type: array
                    workIndustries:
                      description: >-
                        Meta only. Work-industry entities from
                        /apis/v1/ads/targeting/search?dimension=workIndustry.
                        Not interchangeable with the LinkedIn `industries` URN
                        fragments.
                      items:
                        properties:
                          id:
                            type: string
                          name:
                            type: string
                        required:
                          - id
                        type: object
                      type: array
                    workPositions:
                      description: >-
                        Meta only. Job title entities from
                        /apis/v1/ads/targeting/search?dimension=workPosition.
                        Not interchangeable with the LinkedIn `jobTitles` URN
                        fragments.
                      items:
                        properties:
                          id:
                            type: string
                          name:
                            type: string
                        required:
                          - id
                        type: object
                      type: array
                    zips:
                      description: >-
                        Postal/ZIP targeting. `key` is the platform's postal
                        location ID (e.g. Meta `US:94304`). Supported on Meta,
                        Google, TikTok, Pinterest, X.
                      items:
                        properties:
                          key:
                            type: string
                          name:
                            type: string
                        required:
                          - key
                        type: object
                      type: array
                  type: object
              required:
                - campaignId
                - name
              type: object
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                properties:
                  adSetId:
                    description: Platform id of the new ad group
                    type: string
                  campaignId:
                    type: string
                type: object
          description: Ad group created
        default:
          content:
            application/json:
              schema:
                properties:
                  error:
                    properties:
                      code:
                        type:
                          - string
                          - 'null'
                      details:
                        additionalProperties: {}
                        type:
                          - object
                          - 'null'
                      message:
                        type:
                          - string
                          - 'null'
                      param:
                        type:
                          - string
                          - 'null'
                      retryHint:
                        type:
                          - string
                          - 'null'
                      retryable:
                        type:
                          - boolean
                          - 'null'
                      type:
                        type:
                          - string
                          - 'null'
                    type:
                      - object
                      - 'null'
                type: object
          description: Error. The code field is stable; see the error catalog.
components:
  securitySchemes:
    bearerAuth:
      scheme: bearer
      type: http

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.