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

# Placements

> Placements are how you tune fill, match quality, and UX — one of the biggest levers on revenue.

A **placement** is a named slot in your UI where an ad can appear. Placements are a first-class concept in Gravity because they're where three things come together:

1. **Fill** — is there a campaign that wants to serve here?
2. **Match quality** — how relevant is what we serve to the conversation?
3. **UX** — how does the ad feel in your product?

Those three tradeoffs are almost always the biggest lever on revenue for a given AI platform. Placements are how you operate on them.

## Why placements matter

* **Per-slot economics.** The dashboard reports impressions, CTR, and revenue per `placement_id`. You'll see a `below_response` slot earn very differently from a `right_response` sidebar. That's actionable — you learn which spots in your UI carry their weight.
* **Scoped experimentation.** Gravity can run [experiments](/ai-platforms/experiments) targeted to a specific placement. Test a new format in your right rail without touching your primary in-flow slot.
* **Auto-optimization.** The engine learns which ad formats work best per placement over time, and leans into the winners. This only works if you've declared the slots in the first place.
* **Fill-rate tuning.** Different placements tolerate different fill rates. A page-level `bottom_page` slot might want 95% fill (low relevance bar); an `inline_response` slot might want 40% fill (only serve when the match is strong). Separate placements let you set different policies.

## Standard placement types

| Placement         | Typical use                                              |
| ----------------- | -------------------------------------------------------- |
| `below_response`  | Under the assistant's message — most common in chat UIs. |
| `above_response`  | Pinned above the response. Use sparingly.                |
| `inline_response` | Inline within the response stream (markdown).            |
| `left_response`   | Sidebar to the left of the response.                     |
| `right_response`  | Sidebar to the right.                                    |
| `search_result`   | Within a search results list.                            |
| `top_page`        | Static page-level header.                                |
| `bottom_page`     | Static page-level footer.                                |
| `left_page`       | Persistent left rail.                                    |
| `right_page`      | Persistent right rail.                                   |
| `center_page`     | Centered, full-width slot.                               |

## Creating placements in the dashboard

The dashboard under **AI platforms → Placements** lets you register the slots in your UI by `placement_id`. This is also where per-slot reporting lives and where you configure any placement-scoped experiments we run on your traffic.

You don't strictly need to register a placement before sending it — the engine will happily serve to a new `placement_id` on first sight — but declaring them up front makes dashboard reporting cleaner and unlocks per-slot experiments.

## `placement_id` — your slot name

Every placement needs a `placement_id` that identifies the specific slot:

```ts theme={null}
const { ads } = await gravity.getAds(req, messages, [
  { placement: 'below_response', placement_id: 'chat-main' },
  { placement: 'right_response', placement_id: 'chat-sidebar' },
  { placement: 'bottom_page',    placement_id: 'footer' },
]);
```

Pick any stable string. `'chat-main'`, `'mobile-footer'`, `'search-result-3'` — whatever maps to the spot in your UI. Use it consistently; your dashboard reports revenue and CTR per `placement_id`.

## Up to 10 per request

You can request ads for up to 10 placements in one call. They share the same auction, so there's no rate-limit penalty to asking for everything on a page.

## No-fill is normal

If the engine has no matching campaign for a slot, that slot returns `null` (or the array index is absent). Always render conditionally:

```tsx theme={null}
{ads[0] && <GravityAd ad={ads[0]} variant="card" />}
```

The fill rate depends on:

* How relevant your content is to active campaigns
* The `relevancy` threshold you set — see [request-ads → relevancy tradeoff](/ai-platforms/request-ads#relevancy-tradeoff)
* Advertiser budget availability at the moment

You can tune fill rate up by lowering the relevancy threshold on the `Gravity` constructor — but be aware tighter matches tend to convert better.

## Next

<Card title="Experiments" icon="flask" href="/ai-platforms/experiments">
  How Gravity runs placement-scoped experiments on your traffic.
</Card>
