---
title: "The Advertisements facade — Advertisements for Laravel | Roundly"
description: "The whole API on one facade — lifecycle verbs, serving queries, rendering, and a for($ad) handle for placements and tracking."
url: https://roundly-consulting.com/open-source/docs/advertisements-for-laravel/facade
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Advertisements for Laravel](https://roundly-consulting.com/open-source/docs/advertisements-for-laravel.md)

# The Advertisements facade

RoundlyConsulting\\Advertisements\\Facades\\Advertisements is the recommended entry point. Its root is RoundlyConsulting\\Advertisements\\AdvertisementManager, which resolves an action from the container for every operation — so a host binding for an action applies to the facade too. The lifecycle verbs are flat:

```php
use RoundlyConsulting\Advertisements\DataTransferObjects\AdvertisementData;
use RoundlyConsulting\Advertisements\Facades\Advertisements;
use RoundlyConsulting\Money\Money;

$ad = Advertisements::create(new AdvertisementData(
    name: 'Vintage road bike',
    price: Money::ofMajor('250.00', 'EUR'),
    category: 'bikes',
    author: $user,                  // any Eloquent model (polymorphic author)
));

Advertisements::publish($ad);                  // live now → AdvertisementPublished
Advertisements::publish($ad, now()->addWeek()); // scheduled → AdvertisementPublished
Advertisements::unpublish($ad);                // back to draft → AdvertisementUnpublished
Advertisements::expire($ad);                   // → AdvertisementExpired
Advertisements::archive($ad);                  // → AdvertisementArchived
Advertisements::delete($ad);                   // soft delete → AdvertisementDeleted
```

Serving is flat as well; everything about one ad — its placements and its tracking — hangs off the for($ad) handle:

```php
// Serving
Advertisements::in('sidebar')->get();                 // active ads in a placement
Advertisements::targetedIn('sidebar', request())->get(); // … that target the viewer
Advertisements::random('sidebar');                    // ?Advertisement
echo Advertisements::render($ad, 'sidebar');          // the creative, or the text ad

// One ad's scoped API
Advertisements::for($ad)->placements()->sync(['sidebar', 'header']);
Advertisements::for($ad)->runsIn('sidebar');          // true
Advertisements::for($ad)->track('sidebar')->impression();
```

## Every method

| Method | Returns | What it does |
| --- | --- | --- |
| `create($data)` | `Advertisement` | Create an ad from an AdvertisementData. |
| `update($ad, $data)` | `Advertisement` | Overwrite the ad from an AdvertisementData. |
| `publish($ad, ?$at = null)` | `Advertisement` | Publish now, or schedule for a future instant. |
| `unpublish($ad)` | `Advertisement` | Back to draft; clears published\_at. |
| `expire($ad, ?$at = null)` | `Advertisement` | Expire now, or set a future expiry. |
| `archive($ad)` | `Advertisement` | Archive without deleting. |
| `delete($ad)` | `bool` | Soft delete. |
| `query()` | `Builder` | A fresh builder for the configured model. |
| `active()` | `Builder` | query()->active(). |
| `in($placement)` | `Builder` | Active ads in a placement (model, id or slug). |
| `targetedIn($placement, $viewer = null)` | `Builder` | Active ads in a placement that match the viewer’s location. |
| `random($placement = null)` | `?Advertisement` | One random active ad, optionally per placement. |
| `render($ad, $placement, $attributes = [])` | `HtmlString` | The creative for a placement, or the text ad. |
| `for($ad)` | `AdvertisementHandle` | One ad’s scoped API — placements and tracking. |
| `for($ad)->placements()->attach / detach / sync($placements)` | `Advertisement` | Add, remove or replace placements; the ad comes back with placements reloaded. |
| `for($ad)->runsIn($placement)` | `bool` | Whether the ad is attached to the placement. |
| `for($ad)->track(?$placement)->impression(?$data) / ->click(?$data)` | `?AdvertisementEvent` | Record an impression or a click of a live ad; null when buffered. |
| `fake()` | `AdvertisementsFake` | Swap in the recording fake for tests. |

- for($ad)->track() refuses an ad that isn’t live right now — draft, scheduled, expired or archived — with AdvertisementNotActive, and track($placement) refuses a placement the ad doesn’t run in with AdvertisementNotInPlacement. track() with no placement records without one.
- Recording returns the persisted AdvertisementEvent, or null when tracking.buffered queues it.
- render() goes through the bound CreativeRenderer — a responsive <img> when an image creative exists, the text ad otherwise.
- The model methods — $ad->publish(), unpublish(), expire(), archive(), delete() and renderCreative() — are sugar over the same manager, so they fire the same events and Advertisements::fake() records them.

The facade alias is registered globally unless register\_facade\_alias is false; the facade class itself always works.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/advertisements-for-laravel.md)
