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

# Campaigns

> Review user acquisition campaigns in PNLight, including ad spend, install costs, postbacks, and campaign-level revenue, conversion, and cohort analytics.

Campaigns show acquisition performance for paid traffic. Use manual campaigns when the traffic source is not connected through an ad network account.

## Use the campaigns page

<Steps>
  <Step title="Open Campaigns">
    Select a project and open **Campaigns**.
  </Step>

  <Step title="Review synced campaigns">
    Check campaign names, network or account data, and enabled status.
  </Step>

  <Step title="Update costs">
    Enter or review costs when spend data needs correction.
  </Step>

  <Step title="Configure postbacks">
    Set postback behavior for campaigns that need event delivery.
  </Step>

  <Step title="Use campaign filters">
    Filter analytics and customer views by campaign when you need channel-level analysis.
  </Step>
</Steps>

## Manual campaigns

Manual campaigns let you track traffic from ad networks, affiliate partners, newsletters, influencers, or any other source that can use a campaign URL. PNLight records the click, redirects the user to your destination URL, attributes users when the app reports the click, and sends postbacks for matched events.

Manual campaigns are different from synced Facebook campaigns:

| Area              | Manual campaign                                                    | Synced Facebook campaign                                                                                                     |
| ----------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| Campaign creation | You create the campaign in PNLight.                                | PNLight syncs campaigns from Facebook.                                                                                       |
| Spend             | You enter costs manually or import a CSV file.                     | PNLight can sync spend from Facebook.                                                                                        |
| Postbacks         | You configure system and app event postback URLs on the campaign.  | Campaigns can inherit postbacks and Facebook event mapping from the connected network account, or override them when needed. |
| Tracking URL      | PNLight generates a campaign-specific URL with `pnlAdsCampaignId`. | PNLight generates an account URL with Facebook macros.                                                                       |

Use [Ad networks](/dashboard/ad-networks) for Facebook setup.

## Create a manual campaign

<Steps>
  <Step title="Open Campaigns">
    Select a project and open **Campaigns**.
  </Step>

  <Step title="Create the campaign">
    Click **New Campaign**.
  </Step>

  <Step title="Enter campaign details">
    Add **Campaign Name**, **Start date**, and **End date**. Use the same date range you plan to review in spend and cohort reports.
  </Step>

  <Step title="Save the campaign">
    Click **Create**.
  </Step>

  <Step title="Open campaign settings">
    Open the campaign from the table.
  </Step>

  <Step title="Set the redirect URL">
    Enter **Redirect URL override**. This is where PNLight sends the click after it records it.
  </Step>

  <Step title="Copy the campaign URL">
    Copy **URL for your Ad** and use it as the destination URL in your ad network or partner system.
  </Step>
</Steps>

<Warning>
  A manual campaign must have **Redirect URL override** before you use **URL for your Ad** in live traffic. Without a redirect URL, PNLight cannot send the click onward.
</Warning>

## Configure the ad URL

The manual campaign URL includes `pnlAdsCampaignId`. PNLight uses that value to connect clicks, installs, events, costs, postbacks, and analytics to the campaign.

Add the parameters your traffic source can provide to the generated URL. PNLight stores those parameters with the click and forwards them to the redirect URL.

```text theme={null}
https://pnlight.example/api/v1/ads/click?pnlAdsCampaignId=CAMPAIGN_ID&sub_id={click_id}&partner=network_a&placement={placement}
```

Use stable parameter names that you can reuse in postbacks, such as `sub_id`, `click_id`, `partner`, `creative`, `placement`, or `utm_campaign`.

When PNLight redirects the user, it keeps the campaign URL parameters and adds `deep_link_value` with the PNLight click ID. Your app or deep-link handler can use that value when it needs to associate the install with the click.

<Tip>
  If your traffic source already appends tracking parameters, keep them on **URL for your Ad**. They become available for postback URL substitution.
</Tip>

## Configure postbacks

Postbacks send event notifications from PNLight back to an ad network, affiliate platform, or internal tracking endpoint. PNLight sends postbacks only for users attributed to the campaign.

Open a manual campaign and use the postback sections:

| Section                     | Use it for                                                     |
| --------------------------- | -------------------------------------------------------------- |
| **System Events Postbacks** | Built-in PNLight events, such as install, purchase, or refund. |
| **App Events Postbacks**    | Custom SDK events sent from your app with `logEvent`.          |

For each postback, enter:

| Field            | Description                                                                                                   |
| ---------------- | ------------------------------------------------------------------------------------------------------------- |
| **Event name**   | The PNLight event that should trigger the postback. For app events, use the exact event name sent by the SDK. |
| **Postback Url** | The full postback endpoint URL. PNLight calls this URL when the event is recorded for an attributed user.     |
| **Single Use**   | Sends the app event postback only once per user, campaign, and event name. Use it for one-time conversions.   |

### Substitute parameters in postback URLs

Use placeholders in query parameter values when the receiving system needs values from the original click URL.

```text theme={null}
https://network.example/postback?click_id={{sub_id}}&event=purchase&pnl_click_id={{pnlClickId}}
```

PNLight replaces:

| Placeholder                                              | Value                                                                          |
| -------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `{{pnlClickId}}`                                         | The PNLight click ID for the matched user.                                     |
| `{{sub_id}}`, `{{click_id}}`, or another click parameter | The value with the same name from the original campaign URL.                   |
| AppsFlyer parameters                                     | Values from the AppsFlyer attribution payload when AppsFlyer wins attribution. |

Placeholders are replaced only inside query parameter values. Missing values stay unchanged in the final URL, so check the receiving system for unreplaced placeholders during testing.

## Inherit or override synced campaign delivery settings

Synced Facebook campaigns can inherit delivery settings from the connected network account. This keeps postbacks and event mapping consistent across many campaigns.

Use **Override** on the campaign when one campaign needs a different setup for:

* System event postbacks.
* App event postbacks.
* Facebook event mapping.

## Enter campaign costs manually

Manual campaign costs power spend, CPI, CPT, CAC, ROI, ROAS, and cohort payback views. Enter costs after you create the campaign.

<Steps>
  <Step title="Open the campaign">
    Open **Campaigns** and select the manual campaign.
  </Step>

  <Step title="Set the reporting range">
    Update **Start date** and **End date** if the campaign dates changed. Save the campaign before you edit daily costs.
  </Step>

  <Step title="Choose the cost dates">
    Use the date picker in **Costs data** to choose the dates you want to edit.
  </Step>

  <Step title="Enter daily spend">
    Fill the cost amount for each day. Use the copy action next to a day to fill future dates with the same amount.
  </Step>

  <Step title="Use monthly or total distribution">
    Enter a month total or full campaign total when you want PNLight to distribute spend across the selected dates.
  </Step>

  <Step title="Save the campaign">
    Save the form to update analytics and campaign metrics.
  </Step>
</Steps>

You can also click **Import from CSV**. Use a two-column CSV file with `date,cost` rows and no header row. Dates must use `YYYY-MM-DD`, and costs must be decimal currency values.

```csv theme={null}
2026-06-01,125.50
2026-06-02,130.00
2026-06-03,118.75
```

## Verify the setup

After you save the campaign, test the full flow before buying traffic:

* Open **URL for your Ad** with sample parameters and confirm that it redirects to **Redirect URL override**.
* Confirm the redirected URL includes the parameters you expect.
* Install or open the app from the test flow and confirm the user appears in **Customers** with the campaign attribution.
* Trigger one system event or app event that has a postback.
* Open the customer profile and check whether the postback was sent.
* Review **Campaigns**, **Analytics**, and **Cohorts** to confirm spend, installs, revenue, and ROAS use the campaign.

## Common checks

* Manual campaigns use **URL for your Ad** with the correct `pnlAdsCampaignId`.
* Synced campaigns come from the correct ad network and account.
* Manual campaigns have **Redirect URL override** before live traffic starts.
* Disabled campaigns are excluded from filters and analytics where expected.
* Costs match the reporting period you are reviewing.
* Postback event names match the system event or SDK app event you want to send.
* Event mappings are configured on the ad network or campaign when Facebook Conversions API depends on them.
