Ad Selection Panel

Browser support

The Ad Selection Panel tracks our standard browser support policy.

Step 1: Include the panel

Add the following script tag to the page where you want to insert the Ad Selection Panel:
This will expose a SeekApi.render function which renders an instance of a panel within a specified DOM element.

Step 2: Render the panel

The render function must be called on page load and whenever the properties of the positionProfile object change. For example, if the hirer selects a new location, you must re-render the panel to reflect updated products and pricing.
SeekApi.render(containerNode, 'adSelection', props);
The Ad Selection Panel will render to fit the width of the supplied containerNode. We recommend your containerNode spans the full width of your UI for the best user experience, as up to four ad products may be displayed to hirers.


() => Promise<string>
Function to retrieve a browser token for the SEEK API
(event) => void
bullet | tooltip
default: bullet
How the panel should display selling points of each product
AdvertisementProducts_PositionProfileInput  When editing an existing job ad, this must include the profileId of the job being updated
The product ID stored in a job ad draft
default: false
Whether the panel should display a validation error when there is no selected product
Specifies the locale to display content in e.g., en-AU. Set this prop to override the default localisation behaviour based on users browser preferences. Supported locales are outlined in the content localisation documentation.


SeekApi.render(document.getElementById('seekPanelContainer'), 'adSelection', {
  getAuthToken: async () => {
    // Do not implement caching in your `getAuthToken` implementation.
    // The panel will internally memoise the response.
    const token = await fetchAuthToken();

    return token;

  onChange: (event) => {
    const { selectedProduct } = event;

    // Persist `` in memory for use in job posting mutations.

    // Display form inputs for features supported by the selected product.

    if (selectedProduct?.features.branding) {
      // Show brand selection.
    } else {
      // Hide brand selection.

    if (selectedProduct?.features.searchBulletPoints) {
      // Show the number of bullet point input fields indicated by `limit`.
    } else {
      // Hide all bullet point input fields.

  sellingPointsDisplay: 'bullet',

  positionProfile: {
    // Ad products and their pricing vary based on these classifiers.
    jobCategories: 'seekAnzPublicTest:jobCategory:seek:27HXTkNXh',
    positionLocation: 'seekAnzPublicTest:location:seek:W7NggeKH',
    positionOrganizations: 'seekAnzPublicTest:organization:seek:93WyyF1h',
    positionTitle: 'Software Engineer',

    // Salary details let us indicate how each ad product is likely to perform.
    offeredRemunerationPackage: {
      basisCode: 'Salaried',
      descriptions: ['Up to $70,000 per year + bonus'],
      ranges: [
          intervalCode: 'Year',
          minimumAmount: { currency: 'AUD', value: 40000 },
          maximumAmount: { currency: 'AUD', value: 70000 }
    seekAnzWorkTypeCode: 'FullTime',

    // The position profile ID must be provided when editing a job ad.
    profileId: undefined

  // The product ID stored in a job ad draft.
  selectedAdvertisementProductId: undefined,

  // Set this to true if the hirer tries to post the job ad before they have
  // selected an ad product (i.e. no `` persisted in memory).
  showFormValidationError: false

Step 3: Handle browser token requests

  1. The panel loads and invokes the getAuthToken function passed to it.
  2. Your frontend requests a browser token from your backend.
    The getAuthToken function should request a new token for the hirer ID in positionProfile.positionOrganizations. If a user switches to a different SEEK hirer account in your posting form, your software should re-render the panel with the new hirer ID in positionProfile.positionOrganizations, and ensure that subsequent invocations of getAuthToken will request a token for the new hirer ID.
  3. Your backend authenticates and authorises the user.
    Your software is responsible for verifying that the user is authorised to access a given hirer ID. A user must not be able to request a browser token for an arbitrary organization that they do not belong to.
  4. Your backend requests a browser token from the SEEK API for the appropriate hirer ID and query:ad-products query:organizations scope.
  5. Your backend responds with the browser token.
  6. Your frontend returns the browser token from the getAuthToken function.
  7. The panel can now make requests to the GraphQL endpoint.
Authorization: Bearer PARTNER_TOKEN_HERE
Content-Type: application/json
User-Agent: YourPartnerService/1.2.3
  "hirerId": "seekAnzPublicTest:organization:seek:93WyyF1h",
  "scope": "query:ad-products query:organizations",
  "userId": "317665"

Step 4: Handle ad product selection

When a hirer selects an ad product, the onChange callback you provided within your props will be invoked with the below parameters.

onChange callback

object | null
The selected product ID to persist in memory for posting, previewing or updating the job ad
The selected ad product label, this should only be used for display purposes
The features available for the selected ad product
object | null
Whether the ad product supports branding
Whether the logo of the brand will be displayed on the job ad
Whether the cover image of the brand will be displayed on the job ad
object | null
Whether the ad product supports search bullet points
The number of bullet point input fields to display in your posting workflow
object | null
The price of the ad product, this should only be used if your software supports budgeting
object | null
The human readable pricing summary of the ad product
object | null
The three-letter ISO 4217 currency code of the ad product price
object | null
The ad product price in the minor unit of the currency, excluding tax

Managing variable job ads

Due to the variable nature of SEEK’s product ladder, the panel returns an ephemeral that references a product quoted at that point in time. When a hirer selects a product and your software propagates its identifier to post or update a job ad, SEEK will scan recent ad selection contexts for a match and attempt to lock in the exact quoted product features and pricing.
Ad products presented to a hirer are only valid within the context of the workflow that they were executing at the time. Product IDs cannot be persisted long term; they should not be stored alongside a posted job ad for subsequent update workflows or to otherwise build a hardcoded mapping.
Handling drafts
The may be temporarily stored in a job ad draft. When the hirer resumes their posting workflow from the draft at a later date, this previous product ID must not be directly used to post the job ad. Instead, pass the previous product ID to the Ad Selection Panel render function as the selectedAdvertisementProductId. The panel will then pre-select an equivalent ad product and return new product IDs that can be used to post the job ad.
Handling edits
When a hirer edits an existing job ad, the profileId of the job being updated must be provided to the panel to show the correct ad products and pricing. The panel will default to selecting the appropriate ad product based on the existing job ad details.
Additionally, the product ID used to initially post the job ad must not be used again when calling updatePostedPositionProfile . Instead, always use the most recent emitted through the onChange callback to update the job ad.
Stale product ID errors
When executing mutations such as updatePostedPositionProfile , you might encounter errors similar to:
  "errors": [
      "message": "Invalid posting instructions",
      "extensions": {
        "code": "BAD_USER_INPUT",
        "invalidFields": {
          "/input/positionProfile/postingInstructions/0/seekAdvertisementProductId": "No longer valid; refresh the available ad products for this job ad"
This can indicate an underlying implementation issue, for instance:
  1. A product ID from a draft has been stored for too long and was used to post the job ad.
  2. A product ID used to initially post a job ad has been used again to update the ad.
  3. The panel was rendered without a profileId when editing an existing job ad, resulting in the selected product ID being invalid for an update.
To resolve these scenarios, check that all job posting flows refresh the product ID correctly prior to posting. This can be achieved by ensuring the panel is rendered before posting with the full positionProfile object passed in (including the profileId for existing ads) and using the latest in the mutation to post or update the job ad.

Supporting features

When a hirer selects an ad product, your software should conditionally display form inputs for the additional job ad features it enables. The available features are passed to the onChange callback.
See features for ad products for a detailed walkthrough.

Step 5: Post the job ad

When the hirer is ready to post or update the job ad, provide the persisted above in the posting instruction seekAdvertisementProductId field on the postPosition , postPositionProfileForOpening  or updatePostedPositionProfile  job posting mutations.
When a hirer submits a job posting form in your software, toggle the showFormValidationError prop to true. The panel will display a validation error if an ad product has not yet been selected.