Phase 4: Managing job ads

The retired Job Posting API had a REST-based interface for managing SEEK job ads. The SEEK API allows you to manage SEEK job ads through GraphQL queries and mutations. The following documentation compares examples of each type of action (create, update, expire and get) in the Job Posting API with the equivalent in the SEEK API.

Recommendations for migration

There are two recommended ways of scaling usage of the SEEK API to all of your SEEK hirers.

1. Build a brand new integration

Recruitment software often has the ability to post job ads to multiple job boards at the same time for a single job requisition. If this applies to your software, you can create an entirely new job board and integration for the SEEK API. This also facilitates the creation of a new user experience to match up with any new value propositions within the SEEK API.

2. Use the SEEK API for new jobs

If you would like to maintain your current integration patterns and migrate to use the SEEK API, build your new SEEK API integration to be run in parallel with your Job Posting API integration, not for a direct changeover. New jobs will be posted and managed via the SEEK API, while older jobs will continue to use the Job Posting API integration until they are closed. There is currently no method of migrating jobs posted via the Job Posting API to the SEEK API.

Data structure comparison

This table compares the data structures of a job ad in the Job Posting API with the SEEK API PositionProfile  object.
Although most fields have equivalents in the SEEK API, their validation rules can diverge significantly. For example, if a hirer isn’t configured to link out to an external apply form, the Job Posting API would silently ignore an applicationFormUrl while the SEEK API will respond with BAD_USER_INPUT. You should test your SEEK API integration to ensure it still handles invalid or conflicting inputs correctly.
Job Posting API field
Deprecated
id
profileId.value
thirdParties.advertiserId
positionOrganizations[].id.value
thirdParties.agentId
advertisementType
postingInstructions[].seekAnzAdvertisementType
jobTitle
positionTitle
searchJobTitle
location.id + location.areaId
positionLocation[].id.value
subclassificationId
jobCategories[].id.value
workType
seekAnzWorkTypeCode
salary.type
offeredRemunerationPackage.basisCode
salary.minimum
offeredRemunerationPackage.ranges[].minimumAmount.value
salary.maximum
offeredRemunerationPackage.ranges[].maximumAmount.value
salary.details
offeredRemunerationPackage.descriptions
jobSummary
positionFormattedDescriptions[] (of description SearchSummary)
advertisementDetails
positionFormattedDescriptions[] (of description AdvertisementDetails)
contact
Contact details will be set under positionOpening
video.url
seekVideo.url
video.position
seekVideo.position
applicationEmail
Use Optimised Apply to programmatically retrieve candidate applications
applicationFormUrl
postingInstructions[].applicationMethods[].applicationUri.url
endApplicationUrl
screenId
Use SEEK API questionnaires
jobReference
seekHirerJobReference
agentJobReference
seekBillingReference
template
standout.logoId
Use postingInstructions[].brandingId
standout.brandingId
postingInstructions[].brandingId
bullets
positionFormattedDescriptions[] (of description SearchBulletPoint)
recruiter.fullName
positionOpening.postingRequester.personContacts.name.formattedName
recruiter.email
positionOpening.postingRequester.personContacts.communication.email.address
recruiter.teamName
additionalProperties
  • Graduate: Include seniority in your positionTitle or positionFormattedDescriptions[]
  • ResidentsOnly: Include requirement in your positionFormattedDescriptions[] or via SEEK API questionnaires
expiryDate
postingInstructions[].end
state
State is now based on postingInstructions start and end dates.
creationId
postingInstructions[].idempotencyId; see idempotency

Migrating endpoints to the SEEK API

The SEEK API has a number of equivalent queries & mutations for posting and managing job ads. The following examples assume your Job Posting API integration had already migrated to object identifiers.
Description
Job Posting API endpoint
SEEK API operation
POST /advertisement
PUT /advertisement/<id>
PATCH /advertisement/<id>
GET /advertisement/<id>
GET /advertisement
Deprecated. Use webhooks to receive events when positions are posted.
GET /advertisement?advertiserId=<id>

Create an advertisement

Job Posting API
POST to /advertisement with a body of the job ad contents.
Request
Copy
POST /advertisement
Host: adposting-integration.cloud.seek.com.au

{
  "thirdParties": {
    "advertiserId": "seekAnzPublicTest:organization:seek:93WyyF1h"
  },
  "advertisementType": "Classic",
  "jobTitle": "Associate Developer",
  "location": {
    "id": "seekAnzPublicTest:location:seek:QVS62e6K"
  },
  "subclassificationId": "seekAnzPublicTest:jobCategory:seek:2EFstqFvP",
  "workType": "PartTime",
  "salary": {
    "type": "HourlyRate",
    "minimum": 70,
    "maximum": 85
  },
  "jobSummary": "Start your software development career with a dynamic & growing team",
  "advertisementDetails": "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.",
  "contact": {
    "name": "Mary Manager",
    "phone": "03 8517 4100",
    "email": "mary.manager@example.com"
  },
  "creationId": "6eaeb58c-cc38-4b0e-8353-daa3011f1ece"
}
SEEK API
MutationVariables
mutation ($input: PostPositionInput!) {
  postPosition(input: $input) {
    ... on PostPositionPayload_Success {
      positionOpening {
        documentId {
          value
        }
      }
      positionProfile {
        profileId {
          value
        }
      }
    }
    ... on PostPositionPayload_Conflict {
      conflictingPositionProfile {
        profileId {
          value
        }
      }
      conflictingPositionOpening {
        documentId {
          value
        }
      }
    }
  }
}
For more general information, see the documentation on posting a job ad in the Job Posting use case.

Update an advertisement

Job Posting API
PUT to /advertisement/{advertisementId} with a body of the job ad contents.
Request
Copy
PUT /advertisement/8e2fde50-bc5f-4a12-9cfb-812e50500184
Host: adposting-integration.cloud.seek.com.au

{
  "thirdParties": {
    "advertiserId": "seekAnzPublicTest:organization:seek:93WyyF1h"
  },
  "advertisementType": "Premium",
  "jobTitle": "Lead Developer",
  "location": "seekAnzPublicTest:location:seek:QVS62e6K",
  "subclassificationId": "seekAnzPublicTest:jobCategory:seek:2EFstqFvP",
  "workType": "FullTime",
  "salary": {
    "type": "AnnualPackage",
    "minimum": 100000,
    "maximum": 130000,
    "details": "Up to $130k excluding super"
  },
  "jobSummary": "Experienced software developer wanted to lead an existing team.",
  "advertisementDetails": "<p>Acme Inc is looking for an experienced software developer with management experience to lead their cloud transformation.</p><p>You should bring your passion for both technology and people to this exciting role.</p>",
  "standout": {
    "bullets": [
      "Line management required",
      "Need experience with cloud deployments",
      "Competitive benefits packages"
    ]
  },
  "video": {
    "url": "https://www.youtube.com/embed/Q3UvigPHCjI",
    "position": "Above"
  }
}
SEEK API
MutationVariables
mutation ($input: UpdatePostedPositionProfileInput!) {
  updatePostedPositionProfile(input: $input) {
    positionProfile {
      profileId {
        value
      }
    }
  }
}
For more general information, see the documentation on updating a job ad in the Job Posting use case.

Expire an advertisement

Job Posting API
PATCH to /advertisement/{advertisementId} with a body describing the field to modify.
Request
Copy
PATCH /advertisement/8e2fde50-bc5f-4a12-9cfb-812e50500184
Host: adposting-integration.cloud.seek.com.au

[
  {
    "op": "replace",
    "path": "state",
    "value": "Expired"
  }
]
SEEK API
The SEEK API supports automatically closing job ads on the end date specified in their posting instructions. This can be provided when posting or updating a job ad. SEEK strongly recommends using automatic closure instead of scheduled events within your software.
While the updatePostedPositionProfile mutation  mostly behaves like an HTTP PUT, omitting the UpdatePostingInstructionInput.end  field will preserve the existing end date like an HTTP PATCH. See the documentation on updating a job ad in the Job Posting use case for more information.
You can explicitly close job ads earlier using the GraphQL closePostedPositionProfile mutation  with input of ClosePostedPositionProfileInput .
MutationVariables
mutation ($input: ClosePostedPositionProfileInput!) {
  closePostedPositionProfile(input: $input) {
    positionProfile {
      profileId {
        value
      }
    }
  }
}
For more general information, see the documentation on closing a job ad in the Job Posting use case.

Get an advertisement

Job Posting API
GET to /advertisement/{advertisementId}.
RequestResponse
Copy
GET /advertisement/1c855f8d-86a9-44f4-b7ab-250e01ff8a77
Host: adposting-integration.cloud.seek.com.au
SEEK API
GraphQL positionProfile query  with a required id input.
GraphQLVariablesResponse
query ($id: String!) {
  positionProfile(id: $id) {
    profileId {
      value
    }
    positionOrganizations {
      id {
        value
      }
      name
      seekAnzAdvertiserId
    }
    positionOpening {
      postingRequester {
        personContacts {
          name {
            formattedName
          }
          communication {
            email {
              address
            }
          }
        }
      }
    }
    positionTitle
    positionLocation {
      id {
        value
      }
      name
    }
    jobCategories {
      id {
        value
      }
      name
    }
    positionFormattedDescriptions {
      descriptionId {
        value
      }
      content
    }
    seekHirerJobReference
    seekAnzWorkTypeCode
    offeredRemunerationPackage {
      basisCode
      ranges {
        minimumAmount {
          value
          currency
        }
        maximumAmount {
          value
          currency
        }
        intervalCode
      }
      descriptions
    }
    seekVideo {
      url
      seekAnzPositionCode
    }
    postingInstructions {
      seekAnzAdvertisementType
      applicationMethods {
        applicationUri {
          url
        }
      }
      brandingId
      start
      end
    }
    positionUri
  }
}
For more general information, see the documentation on querying a job ad in the Job Posting use case.

Get all advertisements

Job Posting API
GET to /advertisement.
Request
Copy
GET /advertisement
Host: adposting-integration.cloud.seek.com.au
SEEK API
It’s not possible to enumerate all advertisements for an integration partner in the SEEK API. You can only get all advertisements for a particular hirer using positionOpenings query .
You can also be notified when a job ad goes live with the PositionProfilePosted event , which is detailed in the next phase.

Get all advertisements for an advertiser

Job Posting API
GET to /advertisement?advertiserId={advertiserID}.
Request
Copy
GET /advertisement?advertiserId=10000
Host: adposting-integration.cloud.seek.com.au
SEEK API
GraphQL positionOpenings query  with a required hirerId input. The positionOpenings query returns a paginated list of PositionOpening  objects. You can select fields from its nested PositionOpening.paginatedPositionProfiles  to retrieve information about a subset of its job ads.
QueryVariables
query ($hirerId: String!) {
  positionOpenings(hirerId: $hirerId) {
    edges {
      node {
        statusCode
        paginatedPositionProfiles {
          edges {
            node {
              profileId {
                value
              }
            }
          }
          pageInfo {
            hasNextPage
            endCursor
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
For more general information, see the documentation on position openings in the Job Posting use case.

Exit criteria

In order to move to the next phase, you will need to have completed the following:
Criteria
Description
Existing integration maintained
Hirer can continue to manage jobs posted via the Job Posting API
Job ad posted successfully
Hirer can successfully post a job ad via the SEEK API
Job ad updated successfully
Hirer can successfully update a job ad via the SEEK API
Job ad closed successfully
Hirer can successfully close a job ad via the SEEK API
Job ad viewed successfully
Hirer can view job ad details via the SEEK API
Job ads listed successfully
Hirer can see a list of their job ads posted via the SEEK API