# Advertiser & Invoicing Companies, Brands, and User Mapping

This guide explains how to create **advertiser companies**, **invoicing companies**, and **brands** in Adhese through the Campaign API, and how to **connect (map) users** to those companies and brands.

All endpoints live under the Adhese API and are versioned with a `/v1` prefix. The server base path is `/api`, so a full path looks like `/api/v1/media-partners` and `/v1/user-mapping`.

## Key concepts &amp; terminology

In Adhese, an advertiser company and an invoicing company are **the same underlying entity — a *media partner*** — distinguished by the **roles** assigned to it. A single media partner can hold one or more roles at the same time.

<table id="bkmrk-you-want-to-create%E2%80%A6-"><thead><tr><th>You want to create…</th><th>What it is in the API</th><th>How</th></tr></thead><tbody><tr><td>An **advertiser company**</td><td>A media partner with the `ADVERTISER` role</td><td>`POST /v1/media-partners` with `"roles": ["ADVERTISER"]`</td></tr><tr><td>An **invoicing company**</td><td>A media partner with the `INVOICE` role</td><td>`POST /v1/media-partners` with `"roles": ["INVOICE"]`</td></tr><tr><td>A company that is **both**</td><td>A media partner with both roles</td><td>`POST /v1/media-partners` with `"roles": ["ADVERTISER", "INVOICE"]`</td></tr><tr><td>A **brand**</td><td>A *media brand* that belongs to a media partner</td><td>`POST /v1/media-partners/{mediaPartnerId}/brands`</td></tr><tr><td>A **user ↔ company/brand link**</td><td>A *user mapping*</td><td>`POST /v1/user-mapping`</td></tr></tbody></table>

**Available roles:** `ADVERTISER`, `INVOICE`

> **Note.** The read-only endpoints `GET /v1/advertiser-companies` and `GET /v1/brands` expose the same entities from the campaign-booking perspective (used when creating or editing a campaign). Their `id` values are the media-partner and media-brand ids you create below.

---

## Authentication &amp; headers

Every request is authenticated with a **Bearer JWT** and must carry the Keycloak auth header.

<table id="bkmrk-header-required-valu" style="width: 100%;"><thead><tr><th style="width: 16.926%;">Header</th><th style="width: 26.9357%;">Required</th><th style="width: 20.3814%;">Value</th><th style="width: 35.7569%;">Notes</th></tr></thead><tbody><tr><td style="width: 16.926%;">`Authorization`</td><td style="width: 26.9357%;">Yes</td><td style="width: 20.3814%;">`Bearer <jwt>`</td><td style="width: 35.7569%;">JWT access token.</td></tr><tr><td style="width: 16.926%;">`Use-Keycloak-Auth`</td><td style="width: 26.9357%;">Yes</td><td style="width: 20.3814%;">`true`</td><td style="width: 35.7569%;">Required on all `/v1` endpoints.</td></tr><tr><td style="width: 16.926%;">`Content-Type`</td><td style="width: 26.9357%;">For `POST`/`DELETE` with a body</td><td style="width: 20.3814%;">`application/json`</td><td style="width: 35.7569%;">—</td></tr></tbody></table>

Example request line and headers:

```http
POST /api/v1/media-partners
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Use-Keycloak-Auth: true
Content-Type: application/json
```

{{@315}}

---

{{@316}}

---

{{@317}}

---

## End-to-end walkthrough

Create an advertiser company, an invoicing company, and a brand, then give a user access to them.

**1. Create the advertiser company**

```json
POST /v1/media-partners

{
  "name": "Acme Beverages",
  "roles": ["ADVERTISER"],
  "externalKey": "acme-bev"
}
```

The response will give you its id → assume `4021`.

**2. Create the invoicing company**

```json
POST /v1/media-partners

{
  "name": "Acme Beverages Billing BV",
  "roles": ["INVOICE"],
  "externalKey": "acme-bev-billing"
}
```

The response will give you its id → assume `4022`.

**3. Create a brand under the advertiser company**

```json
POST /v1/media-partners/4021/brands

{
  "name": "Acme Cola",
  "externalKey": "acme-cola"
}
```

The response will give you its id → assume `8801`.

**4. Map the user to the company + brand**

```json
POST /v1/user-mapping

{
  "user": "jane.doe@partner.example",
  "mappings": [
    { "advertiserCompanyId": 4021, "invoiceCompanyId": 4022, "brandId": 8801 }
  ]
}
```

**5. Verify the mapping**

```
GET /v1/user-mapping/jane.doe@partner.example
```

```json
[
  { "advertiserCompanyId": 4021, "invoiceCompanyId": 4022, "brandId": 8801 }
]
```

---

## Error handling

Errors are returned as an [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) `ProblemDetail` object.

```json
{
  "type": "about:blank",
  "title": "Bad Request",
  "status": 400,
  "detail": "roles must not be empty",
  "instance": "/api/v1/media-partners"
}
```

<table id="bkmrk-status-meaning-400-b"><thead><tr><th>Status</th><th>Meaning</th></tr></thead><tbody><tr><td>`400`</td><td>Bad Request — invalid input or parameters.</td></tr><tr><td>`401`</td><td>Unauthorized — authentication required or invalid token.</td></tr><tr><td>`403`</td><td>Forbidden — authenticated but not allowed to access this resource.</td></tr><tr><td>`404`</td><td>Not Found — resource not found.</td></tr><tr><td>`422`</td><td>Unprocessable Entity — the request was understood but could not be processed.</td></tr><tr><td>`500`</td><td>Internal Server Error — unexpected failure.</td></tr></tbody></table>

---

## Schema reference

**CreateMediaPartnerRequest** · **MediaPartner Schema**

```json
{
  "id": 4021,
  "name": "string",
  "roles": ["ADVERTISER", "INVOICE", "INTERMEDIARY", "MEDIA"],
  "externalKey": "string",
  "subsystemExternalIds": { "subsystem": "externalId" },
  "active": true
}
```

**CreateMediaBrandRequest** · **MediaBrand Schema**

```json
{
  "id": 8801,
  "name": "string",
  "externalKey": "string",
  "subsystemExternalIds": { "subsystem": "externalId" },
  "active": true
}
```

**AdvertiserCompany Schema**

```json
{
  "id": 4021,
  "name": "string",
  "active": true,
  "externalId": "string",
  "subsystemExternalIds": { "subsystem": "externalId" }
}
```

**Brand Schema**

```json
{ "id": 8801, "name": "string" }
```

**CreateUserMappingRequest Schema**

```json
{
  "user": "string",
  "mappings": [
    { "advertiserCompanyId": 4021, "invoiceCompanyId": 4022, "brandId": 8801 }
  ]
}
```

**UserMapping Schema**

```json
{ "user": "string", "mappingCount": 3 }
```