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

# Targeting

> Look up geo targets and manage the customer-list audiences that campaigns target.

Use these routes to find the values that a campaign's targeting fields accept. `geo_targets` takes location IDs for countries, regions, and DMAs from the geo-target catalog. `include_audience_ids` and `exclude_audience_ids` take the IDs of customer lists that you upload. Set these fields with [`POST /advertiser-dashboard/campaigns`](https://docs.trygravity.com/api-reference/advertiser/campaigns#post-/advertiser-dashboard/campaigns) or [`PATCH /advertiser-dashboard/campaigns/{campaign_id}`](https://docs.trygravity.com/api-reference/advertiser/campaigns#patch-/advertiser-dashboard/campaigns/campaign_id).

## GET `/advertiser-dashboard/geo-targets`

Search the geo-target catalog, page through it, or resolve a batch of location IDs. The catalog has countries, regions, and DMAs. Results are ordered by target type, country code, name, and location ID.

**q** `string`

Matches a case-insensitive part of `name` or `canonical_name`, or an exact `location_id` or `country_code`.

**country\_code** `string`

Show only one country (ISO 3166-1 alpha-2).

**target\_type** `string`

Show only `country`, `region`, or `dma` entries.

**location\_ids** `string`

A comma-separated list of location IDs to resolve, at most 500. When you send it, Gravity ignores `q`, `country_code`, `target_type`, and `cursor`. The items keep the order that you asked for, and IDs that aren't in the catalog go to `not_found`.

**limit** `integer` (default: 50)

The page size. Gravity clamps it to the range 1 to 1000 and returns the value it used.

**cursor** `string`

The `next_cursor` value from the previous page.

| Field | Description |
| - | - |
| `total` | The number of entries that match your filters, on all pages. |
| `limit` | The page size after clamping. |
| `offset` | The position of the first item of this page. |
| `has_more` / `next_cursor` | Send `next_cursor` as `cursor` to get the next page. It's `null` on the last page. |
| `not_found` | For a `location_ids` lookup only: the requested IDs that aren't in the catalog. |

`AR`, `CL`, `CO`, `PE`, `UY`, `IL`, `SA`, and `TR` are Gravity country aliases, not catalog location IDs. A campaign accepts them in `geo_targets` and targets the whole country. A cursor that Gravity didn't return, or more than 500 `location_ids`, returns `422`.

```bash Request theme={null}
curl "https://platform.trygravity.com/advertiser-dashboard/geo-targets?q=california&target_type=region" \
  -H "X-API-Key: YOUR_API_KEY"
```

```json Response theme={null}
{
  "items": [
    {
      "location_id": "2000043",
      "name": "California",
      "canonical_name": "California, United States",
      "country_code": "US",
      "target_type": "region"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0,
  "has_more": false,
  "next_cursor": null,
  "not_found": []
}
```

## GET `/advertiser-dashboard/geo-targets/{location_id}`

Resolve one location ID. The response is one catalog entry, in the same shape as an item above. If the ID isn't a supported country, region, or DMA, the response is `404`.

## POST `/advertiser-dashboard/audiences/custom-list`

Upload a customer list as a new audience. Send a `multipart/form-data` body. Gravity hashes emails and phone numbers when it reads the file and doesn't store the raw values. The response is `201` with the new audience.

**file** `file` *required*

A UTF-8 CSV file of emails, phone numbers, or SHA-256 hashes, one value in each cell. Separate values with commas or new lines. A first row of column headers (for example `email` or `phone`) is optional. When a header names a column as email or phone, Gravity reads the hashed values in that column as that type. At most 20 MB and 500,000 identifiers.

**name** `string`

The audience name, at most 255 characters. If you leave it out, Gravity makes a name from the file name.

Gravity matches the list against its users in a background job that runs every hour. Until then, `size` and `last_materialized_at` are `null`.

| Status | Cause |
| - | - |
| `400` | The file isn't UTF-8 text, the multipart body isn't valid, or the file has no valid identifiers. |
| `409` | The account already has 100 uploaded lists. Delete one first. |
| `411` | The request has no `Content-Length` header. |
| `413` | The file is larger than 20 MB, or it has more than 500,000 identifiers. |
| `422` | The `file` field is missing, or the name is longer than 255 characters. |
| `429` | The account uploaded more than 20 lists in the last hour. |

```bash Request theme={null}
curl -X POST https://platform.trygravity.com/advertiser-dashboard/audiences/custom-list \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "name=Past customers" \
  -F "file=@customers.csv"
```

```json Response 201 theme={null}
{
  "id": "6b1f0c9e-4d2a-4f53-9a77-1c2d3e4f5a6b",
  "account_id": "acct-789",
  "name": "Past customers",
  "source": "custom_list",
  "lookback_days": 180,
  "rule": {
    "identifier_count": 1200,
    "email_hashes": 1000,
    "phone_hashes": 200,
    "skipped_rows": 3,
    "filename": "customers.csv"
  },
  "size": null,
  "last_materialized_at": null,
  "created_at": "2026-10-28T12:00:00Z",
  "updated_at": "2026-10-28T12:00:00Z",
  "delivery_status": {
    "status": "not_requested",
    "ready": false,
    "eligible_uses": [],
    "error": null
  }
}
```

## GET `/advertiser-dashboard/audiences`

List the audiences of your account, newest first. Each item has the same shape as the upload response. Archived audiences aren't in the list. Besides uploaded lists (`custom_list`), `source` can be `ad_clicks`, `conversions`, `site_visits`, `ad_views`, `clicked_no_conversion`, `conversion_event`, or `composite` for audiences made in the dashboard.

## GET `/advertiser-dashboard/audiences/{audience_id}`

Get one audience with its `delivery_status`. After you attach an uploaded list to a campaign, check this status until `ready` is `true`.

| `delivery_status` field | Description |
| - | - |
| `status` | `not_requested`, `pending`, `processing`, `ready`, `error`, or `archived`. |
| `ready` | `true` when the delivery network can use the list. |
| `eligible_uses` | The uses that the network allows for the list after it's ready: `exclusion`, `inclusion`, or `bid_multiplier`. |
| `error` | The reason when `status` is `error`. |

If the audience isn't in your account, the response is `404`.

## DELETE `/advertiser-dashboard/audiences/{audience_id}`

Archive an audience and remove it from the targeting of every campaign that uses it. The response is `204`. If the audience isn't in your account, the response is `404`.


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