Display the Enhanced Job Posting panel

The Enhanced Job Posting panel displays a job posting form with all fields required to post a SEEK job ad pre-filled with details from a job requisition provided by your software. It allows hirers to review and edit the pre-filled form before posting.The panel provides an event your software can trigger which will save the hirer’s job ad as a draft. This draft can then be queried, previewed, or posted to SEEK.

Before you begin

Review the getting started documentation if you’re new to panels in the SEEK API.Enhanced Job Posting follows our standard browser support policy.

Step 1: Include the panel

Add the following script tag to the page where you want to insert the panel for Enhanced Job Posting:
HTML
Copy
<script
  type="text/javascript"
  src="https://integration.seek.com/panels/SeekApi.js"
></script>
This will expose a SeekApi.render function which renders the Enhanced Job Posting panel.

Step 2: Render the panel

The render function must be called on page load and whenever the properties of the job requisition change. For example, if the hirer updates the job title of the requisition, you must re-render the panel to reflect changes. Re-rendering a mounted panel does not start a new session: unsaved hirer edits are preserved, and the panel only prompts when a changed requisition value conflicts with a field the hirer has already edited.
JavaScript
Copy
const { dispatchEvent } = SeekApi.render(
  containerNode,
  'enhancedJobPosting',
  props
);
SeekApi.render will return an object containing the dispatchEvent function, which you can use to trigger the draft to be saved. See manage drafts for further details.We recommend your containerNode spans the full width of your UI for the best user experience.

Props

Prop
Type
Description
getAuthToken
() => Promise<string>
Function to retrieve a browser token for the SEEK API. Each invocation must request and return a newly issued token for the current hirer.
position
object
The current job requisition. Pass every value your software has collected that corresponds to a panel field.
See position below.
draftPositionProfileId
stringoptional
Resumes a create-scoped or edit-scoped draft. Provide this whenever the hirer continues from a saved draft.
positionProfileId
stringoptional
The posted position profile to edit. Required when starting or resuming an edit-scoped flow. Must not be supplied with a create-scoped draft. See create and edit modes.
locale
stringoptional
Overrides browser-derived localisation, for example en-AU. Supported locales are outlined in the content localisation documentation. An unsupported value fails panel load. When omitted, the panel uses the browser locale if supported, otherwise the posting market’s default locale.
panelOverrides
objectoptional
An overrides object to modify specific parts of the panel’s behaviour.
The panel is loaded with default options when this field is omitted.
See panelOverrides below.
zIndexOffset
numberoptional
The panel renders modals at z-index: 300 and notifications at z-index: 400. To ensure they display correctly, render the panel at a z-index below 300. If this isn’t possible, use zIndexOffset to raise the panel’s modals and notifications above your application’s interface.

Create and edit modes

The combination of draftPositionProfileId and positionProfileId selects the panel mode:
draftPositionProfileId included
positionProfileId included
Result
Start create mode from the current requisition.
Start edit mode for that live job. The live job must have status Active.
Resume a create-scoped draft. An edit-scoped draft without its live-job ID is rejected.
Resume edit mode on a draft saved for the live job. A create-scoped draft, or an edit-scoped draft for a different live job, is rejected.
When both IDs form a valid edit resume, the draft supplies the initial form values and positionProfileId retains update scope.Continue to supply the job requisition values to the panel regardless of the mode. Some fields that are included in the job requisition may not be visible or editable by the hirer in the panel, but they can still be updated on the job ad by creating a draft and posting it. See panel overrides for examples of some hidden fields.The panel will fail to load when provided with invalid required values, overrides, authorization or identity mismatches.

position prop

The position prop aligns to the structure of the PostPositionInput type used in Classic Job Posting, with differences to accommodate the Enhanced Job Posting panel:
  • Many mandatory fields from PostPositionInput are optional in the position prop. When omitted the fields will be inferred or defaulted by the panel for the hirer to edit.
  • Validation to optional fields will not return errors to your system or prevent the panel from displaying. Instead, the panel will use defaults or otherwise allow the hirer to resolve. For example:
    • Where an input violates maximum / minimum lengths, the panel will attempt to display the input with a validation error.
    • Where fields expecting set values are supplied with unrecognised values, a default option will be inferred or displayed as not selected.
  • positionLocation should be provided as a formatted address (for example, 60 Cremorne St, Cremorne VIC 3121) and country code (for example, AU) which the SEEK location will be inferred from.
  • A SEEK job category will be inferred from the provided position values if an OID is not provided in the jobCategories argument.
  • ATS Screening Questions can be passed directly into the panel to create a questionnaire when the job is posted. Alternatively an interactive form can be provided to allow the hirer to add their own questions.
You must provide values for all matching position fields that are collected from the hirer in your software, to avoid users needing to enter the same information multiple times.For the full schema of the position see Position input.
JavaScript
Copy
const { dispatchEvent } = SeekApi.render(
  document.getElementById('seekPanelContainer'),
  'enhancedJobPosting',
  {
    getAuthToken: async () => {
      // Do not implement caching in your `getAuthToken` implementation.
      // The panel will internally memoise the response.
      const token = await fetchAuthToken();
      return token;
    },

    position: {
      positionOpening: {
        postingRequester: {
          roleCode: 'Company',
          id: 'seekAnzPublicTest:organization:seek:93WyyF1h',
          personContacts: [
            {
              communication: {
                email: [{ address: 'mary.manager@example.com' }],
                phone: [{ formattedNumber: '03 8517 4100' }],
                address: [
                  {
                    extendedLines: [{ type: 'Apartment', value: 'line 1' }],
                    line: 'line 2',
                    countrySubDivisions: [{ type: 'State', value: 'Vic' }],
                    geoLocation: { latitude: 0, longitude: 0 },
                    formattedAddress: 'line 3',
                    countryCode: 'AU',
                    postalCode: '1234',
                    city: 'Melbourne'
                  }
                ]
              },
              name: {
                family: 'Manager',
                given: 'Mary',
                formattedName: 'Mary Manager'
              },
              roleCode: 'HiringManager'
            }
          ]
        },
        statusCode: 'Active'
      },

      basePositionProfile: {
        positionTitle: 'Associate Developer',
        positionOrganizations: ['seekAnzPublicTest:organization:seek:93WyyF1h'],
        positionLocation: [
          {
            address: {
              formattedAddress: '1 Cremorne St, Cremorne, VIC 3550',
              countryCode: 'AU',
              postalCode: '3550'
            }
          }
        ],
        seekAnzWorkTypeCode: 'FullTime',
        seekWorkArrangementCodes: ['OnSite'],
        jobCategories: [{ name: 'Developers/Programmers' }],
        offeredRemunerationPackage: {
          basisCode: 'Salaried',
          descriptions: ['$50,000 - $60,000 per year'],
          ranges: [
            {
              minimumAmount: { value: 50_000, currency: 'AUD' },
              maximumAmount: { value: 60_000, currency: 'AUD' },
              intervalCode: 'Year'
            }
          ]
        },
        positionFormattedDescriptions: [
          {
            descriptionId: 'AdvertisementDetails',
            content:
              'A newly created role for an ambitious <b>junior</b> or <b>graduate</b> developer. Be part of a great team in the Bendigo area.'
          },
          {
            descriptionId: 'SearchSummary',
            content:
              'Start your software development career with a dynamic & growing team'
          },
          {
            descriptionId: 'SearchBulletPoint',
            content: 'Great team in the Bendigo area'
          },
          {
            descriptionId: 'SearchBulletPoint',
            content: 'Career progression opportunities'
          },
          {
            descriptionId: 'SearchBulletPoint',
            content: 'Free coffee & snacks'
          }
        ],
        postingInstructions: [
          {
            applicationMethods: [
              { applicationUri: { url: 'https://au.seek.com/apply' } }
            ],
            end: '2000-01-01T14:00:00.000Z'
          }
        ],
        seekApplicationQuestionnaire: {
          interactiveQuestionnaire: {
            seekPrivacyPolicy: {
              url: 'https://au.seek.com/privacy',
              descriptionHtml: 'Do you agree to the privacy policy?'
            }
          }
        },
        seekBillingReference: 'JOB-123',
        seekHirerJobReference: 'JOB-AB-123',
        seekPartnerMetadata: null,
        seekVideo: {
          url: 'https://www.youtube.com/watch?v=aAgePQvHBQM'
        }
      }
    }
  }
);

panelOverrides prop

Prop
Type
Description
fieldVisibility
objectoptional
Use fieldVisibility to manually toggle the visibility of some fields from their default settings.
Visible fields allow the hirer to edit the field directly within the panel. Hidden will require your system to manage the value of the field within your software. The corresponding fields in the position profile are automatically updated when passed as a prop to the panel if they are hidden from hirers.
fieldVisibility.seekHirerJobReference
stringoptional
Whether to display the seekHirerJobReference field in the panel.
The seekHirerJobReference field is an optional free-text job reference, and is hidden from hirers by default. It is recommended to be controlled by your software.
Currently, the following values are defined:
- DISPLAY
fieldVisibility.seekBillingReference
stringoptional
Whether to hide the seekBillingReference field in the panel.
The seekBillingReference field is an optional free-text billing reference, and is visible to hirers by default.
Currently, the following values are defined:
- HIDE
allowedApplyTypes
string[]optional
Overrides the application methods the hirer can select in create mode. When present, the array must contain at least one of soa, and linkout. An empty or invalid list fails panel load.
soa in this override is an explicit declaration that your software receives and manages applications, so soa is offered even when the hirer does not have ApplicationExport. Other values only restrict options that are already capable.
This override does not change the read-only application method of an existing live job.
Posting instructions
Copy
panelOverrides: {
  fieldVisibility: {
    seekHirerJobReference: 'DISPLAY',
    seekBillingReference: 'HIDE',
  },
  allowedApplyTypes: ['soa', 'linkout']
},

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 must request a new token for the current hirer on every invocation. Returning a previously issued token is not allowed. position.basePositionProfile.positionOrganizations must contain exactly one organization ID. That ID, position.positionOpening.postingRequester.id, and the hirer ID on the browser token must all match, and the hirer must have a Job Posting relationship. If a user switches to a different SEEK hirer account in your posting form, re-render the panel with the new hirer ID in both of those fields, and ensure that subsequent invocations of getAuthToken request a newly issued token for the new hirer ID.
  3. Your backend authenticates and authorizes the user.Your software is responsible for verifying that the user is authorized 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:enhanced-job-posting, mutate:enhanced-job-posting 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.
HTTP
Copy
POST https://graphql.seek.com/auth/token HTTP/2
Authorization: Bearer PARTNER_TOKEN_HERE
Content-Type: application/json
User-Agent: YourPartnerService/1.2.3
{
  "hirerId": "seekAnzPublicTest:organization:seek:93WyyF1h",
  "scope": "query:enhanced-job-posting mutate:enhanced-job-posting",
  "userId": "317665"
}