Skip to main content

Advertiser & Invoicing Companies, Brands, and User Mapping

This guide explains how to create advertiser companiesinvoicing 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 & 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.

You want to create… What it is in the API How
An advertiser company A media partner with the ADVERTISER role POST /v1/media-partners with "roles": ["ADVERTISER"]
An invoicing company A media partner with the INVOICE role POST /v1/media-partners with "roles": ["INVOICE"]
A company that is both A media partner with both roles POST /v1/media-partners with "roles": ["ADVERTISER", "INVOICE"]
brand media brand that belongs to a media partner POST /v1/media-partners/{mediaPartnerId}/brands
user ↔ company/brand link user mapping POST /v1/user-mapping

Available roles: ADVERTISERINVOICE

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 & headers

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

Header Required Value Notes
Authorization Yes Bearer <jwt> JWT access token.
Use-Keycloak-Auth Yes true Required on all /v1 endpoints.
Content-Type For POST/DELETE with a body application/json

Example request line and headers:

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

{{@315}}


{{@316}}


Connect users to media partners

user mapping grants a user access to a company/brand combination. Each mapping entry requires an advertiserCompanyId and a brandIdinvoiceCompanyId is optional.

Create a user mapping

POST /v1/user-mapping

Request body — CreateUserMappingRequest

FieldTypeRequiredDescription
userstring (1–255)YesUser identifier (e.g. email or username).
mappingsarray of Mapping SchemaYesAt least one mapping entry.

Mapping Schema

FieldTypeRequiredDescription
advertiserCompanyIdinteger (≥ 1)YesThe advertiser company to grant access to.
invoiceCompanyIdintegerNoRestrict the mapping to a specific invoicing company.
brandIdinteger (≥ 1)YesThe brand to grant access to.
{
  "user": "jane.doe@partner.example",
  "mappings": [
    {
      "advertiserCompanyId": 4021,
      "invoiceCompanyId": 4022,
      "brandId": 8801
    @317}}
  ]
}

Responses

StatusMeaning
201User mapping created.
400Invalid input (e.g. missing advertiserCompanyId or brandId).
401 / 403Not authenticated / not allowed.

List users with mappings

GET /v1/user-mapping?limit=50&offset=0
ParameterInRequiredTypeDescription
limitqueryNointegerMax results (≤ 100).
offsetqueryNointegerResults to skip.
searchqueryNostringLoose match on user identifier.
advertiserCompanyIdqueryNointegerOnly users mapped to this advertiser company.
invoiceCompanyIdqueryNointegerOnly users mapped to this invoice company.
brandIdqueryNointegerOnly users mapped to this brand.

The response includes a Record-Count header with the total number of matches.

Response — array of UserMapping Schema

[
  { "user": "jane.doe@partner.example", "mappingCount": 3 }
]

List a single user's mappings

GET /v1/user-mapping/{user}
ParameterInRequiredTypeDescription
userpathYesstringThe user identifier.
limit / offsetqueryNointegerPagination.
advertiserCompanyIdqueryNointegerFilter by advertiser company.
invoiceCompanyIdqueryNointegerFilter by invoice company.
brandIdqueryNointegerFilter by brand.

Response — array of Mapping Schema

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

Delete a user mapping

DELETE /v1/user-mapping

Request body — DeleteUserMappingRequest

FieldTypeRequiredDescription
userstring (1–255)YesThe user identifier.
advertiserCompanyIdinteger (≥ 1)Advertiser company of the mapping to remove.
invoiceCompanyIdintegerInvoice company of the mapping to remove.
brandIdinteger (≥ 1)Brand of the mapping to remove.
{
  "user": "jane.doe@partner.example",
  "advertiserCompanyId": 4021,
  "invoiceCompanyId": 4022,
  "brandId": 8801
}

Responds 200 when the mapping is deleted.


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

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

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

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

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
[
  { "advertiserCompanyId": 4021, "invoiceCompanyId": 4022, "brandId": 8801 }
]

Error handling

Errors are returned as an RFC 7807 ProblemDetail object.

{
  "type": "about:blank",
  "title": "Bad Request",
  "status": 400,
  "detail": "roles must not be empty",
  "instance": "/api/v1/media-partners"
}
Status Meaning
400 Bad Request — invalid input or parameters.
401 Unauthorized — authentication required or invalid token.
403 Forbidden — authenticated but not allowed to access this resource.
404 Not Found — resource not found.
422 Unprocessable Entity — the request was understood but could not be processed.
500 Internal Server Error — unexpected failure.

Schema reference

CreateMediaPartnerRequest · MediaPartner Schema

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

CreateMediaBrandRequest · MediaBrand Schema

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

AdvertiserCompany Schema

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

Brand Schema

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

CreateUserMappingRequest Schema

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

UserMapping Schema

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