Job basics (v3)

A Job resource represents a job posting (also referred to as a "job listing" or "job requisition"). A job belongs to a Company that is the hiring entity responsible for the job.

A Job can be manipulated using the create, update, and deletion methods, and is accessed using the list and get methods. It can take up to 5 mins for the Cloud Talent Solution index to reflect changes.

Jobs are contained within the scope of a service account. Only search requests authenticated using the credentials of a particular service account can be used to access the content of these jobs.

For easy troubleshooting and triaging, synchronize the Cloud Talent Solution job index with your own job index, and maintain a relation between the name generated by Cloud Talent Solution as well as the unique job identifier in your system. As jobs change or are introduced into your system, the appropriate CRUD call should be sent to Cloud Talent Solution in real time to ensure these changes are reflected immediately. The Cloud Talent Solution index must be added to the existing job ingestion pipeline.

Create a job

To create a job, see Quickstart: Create companies and jobs guide for more details.

Java

For more on installing and creating a Cloud Talent Solution client, see Cloud Talent Solution Client Libraries.


/** Create a job. */
public static Job createJob(Job jobToBeCreated) throws IOException {
  try {
    CreateJobRequest createJobRequest = new CreateJobRequest().setJob(jobToBeCreated);

    Job jobCreated =
        talentSolutionClient
            .projects()
            .jobs()
            .create(DEFAULT_PROJECT_ID, createJobRequest)
            .execute();
    System.out.println("Job created: " + jobCreated);
    return jobCreated;
  } catch (IOException e) {
    System.out.println("Got exception while creating job");
    throw e;
  }
}

Python

For more on installing and creating a Cloud Talent Solution client, see Cloud Talent Solution Client Libraries.

def create_job(client_service, job_to_be_created):
    try:
        request = {"job": job_to_be_created}
        job_created = (
            client_service.projects()
            .jobs()
            .create(parent=parent, body=request)
            .execute()
        )
        print("Job created: %s" % job_created)
        return job_created
    except Error as e:
        print("Got exception while creating job")
        raise e

Go

For more on installing and creating a Cloud Talent Solution client, see Cloud Talent Solution Client Libraries.


// createJob create a job as given.
func createJob(w io.Writer, projectID string, jobToCreate *talent.Job) (*talent.Job, error) {
	ctx := context.Background()

	client, err := google.DefaultClient(ctx, talent.CloudPlatformScope)
	if err != nil {
		return nil, fmt.Errorf("google.DefaultClient: %w", err)
	}
	// Create the jobs service client.
	service, err := talent.New(client)
	if err != nil {
		return nil, fmt.Errorf("talent.New: %w", err)
	}

	parent := "projects/" + projectID
	req := &talent.CreateJobRequest{
		Job: jobToCreate,
	}
	job, err := service.Projects.Jobs.Create(parent, req).Do()
	if err != nil {
		return nil, fmt.Errorf("Failed to create job %q, Err: %w", jobToCreate.RequisitionId, err)
	}
	return job, err
}

Required fields

The following fields are required during Job creation and update:

  • companyName: The resource name of the company listing the job, such as projects/[PROJECT_ID]/companies/[COMPANY_ID].

  • requisitionId: The requisition ID, also referred to as the posting ID, assigned by the client to identify a job. This field is intended to be used by clients for client identification and requisition tracking. The maximum number of allowed characters is 225.

    The uniqueness of a job posting is determined using a combination of the requisitionID, the companyName, and the locale of the job. If a job is created with a specific key of these attributes, this key is stored in the Cloud Talent Solution index and no other jobs with these same fields can be created until the job is deleted.

  • title: The title of the job, such as "Software Engineer." The maximum number of allowed characters is 500.

    To fix the problem of missed search results due to non-standard job titles, Cloud Talent Solution leverages all the provided fields in the Job to understand the context of the job and internally store a "clean" title of the job. When a search request is sent to the service, the query of the search is also cleaned, and the ontologies are used to map the cleaned query to relevant clean jobs.

  • description: The description of the job, which typically includes a multi-paragraph description of the company and related information. Separate fields are provided on the job object for responsibilities, qualifications, and other job characteristics. Use of these separate job fields is recommended.

    This field accepts and sanitizes HTML input, and accepts bold, italic, ordered list, and unordered list markup tags. The maximum number of allowed characters is 100,000.

One of the following:

  • applicationInfo.uris[]: The URL(s) of the application page(s).

  • applicationInfo.emails[]: Email address(es) to which resumes or applications should be sent.

  • applicationInfo.instruction: Application instructions, such as "Mail your application to ...". This field accepts and sanitizes HTML input, and accepts bold, italic, ordered list, and unordered list markup tags. The maximum number of allowed characters is 3,000.

Commonly used fields

  • postingExpireTime: The time, based on the timestamp, when the job posting expires. After the time occurs, the job is marked as expired, and won't appear in search results. This date should be before 2100/12/31 in UTC timezone. Invalid dates (such as past dates) are ignored. The default date when the job expires is 30 days after the job creation time in UTC time zone.

    The content of expired jobs can still be retrieved up to 60 days after the job has expired by using the GET operator. After this 60 day deadline, the job won't be returned through a GET operation.

  • addresses[]: Location(s) where the job is hiring. Providing the full street address(es) of the hiring location is recommended to enable better API results, including job searches by commute time. The maximum number of allowed characters is 500. More information about addresses[] is available in the Best practices section below.

  • promotionValue: A value greater than 0 defines this job as a "featured job" which is returned only in job searches of type FEATURED_JOBS. Higher values are returned higher in the featured search results. See Featured Jobs for more information.

Custom fields

  • customAttributes: This field stores up to 100 custom attributes used to store custom data about the job. These fields can be filtered against using a search request specifying the jobQuery field of a job search request. Additionally, any of these fields can be set in the keywordSearchableJobCustomAttributes attribute of the company, so a search term that has an exact match in any of the fields in keywordSearchableJobCustomAttributes returns any job that includes the match.

Update a job

Update Job without fieldMask

Java

For more on installing and creating a Cloud Talent Solution client, see Cloud Talent Solution Client Libraries.


/** Update a job. */
public static Job updateJob(String jobName, Job jobToBeUpdated) throws IOException {
  try {
    UpdateJobRequest updateJobRequest = new UpdateJobRequest().setJob(jobToBeUpdated);
    Job jobUpdated =
        talentSolutionClient.projects().jobs().patch(jobName, updateJobRequest).execute();
    System.out.println("Job updated: " + jobUpdated);
    return jobUpdated;
  } catch (IOException e) {
    System.out.println("Got exception while updating job");
    throw e;
  }
}

Python

For more on installing and creating a Cloud Talent Solution client, see Cloud Talent Solution Client Libraries.

def update_job(client_service, job_name, job_to_be_updated):
    try:
        request = {"job": job_to_be_updated}
        job_updated = (
            client_service.projects()
            .jobs()
            .patch(name=job_name, body=request)
            .execute()
        )
        print("Job updated: %s" % job_updated)
        return job_updated
    except Error as e:
        print("Got exception while updating job")
        raise e

Go

For more on installing and creating a Cloud Talent Solution client, see Cloud Talent Solution Client Libraries.


// updateJob update a job with all fields except name.
func updateJob(w io.Writer, jobName string, jobToUpdate *talent.Job) (*talent.Job, error) {
	ctx := context.Background()

	client, err := google.DefaultClient(ctx, talent.CloudPlatformScope)
	if err != nil {
		return nil, fmt.Errorf("google.DefaultClient: %w", err)
	}
	// Create the jobs service client.
	service, err := talent.New(client)
	if err != nil {
		return nil, fmt.Errorf("talent.New: %w", err)
	}

	req := &talent.UpdateJobRequest{
		Job: jobToUpdate,
	}
	job, err := service.Projects.Jobs.Patch(jobName, req).Do()
	if err != nil {
		return nil, fmt.Errorf("Failed to update job %s: %w", jobName, err)
	}

	return job, err
}

Update Job with fieldMask

Java

For more on installing and creating a Cloud Talent Solution client, see Cloud Talent Solution Client Libraries.


/** Update a job. */
public static Job updateJobWithFieldMask(String jobName, String fieldMask, Job jobToBeUpdated)
    throws IOException {
  try {
    UpdateJobRequest updateJobRequest =
        new UpdateJobRequest().setUpdateMask(fieldMask).setJob(jobToBeUpdated);
    Job jobUpdated =
        talentSolutionClient.projects().jobs().patch(jobName, updateJobRequest).execute();
    System.out.println("Job updated: " + jobUpdated);
    return jobUpdated;
  } catch (IOException e) {
    System.out.println("Got exception while updating job");
    throw e;
  }
}

Python

For more on installing and creating a Cloud Talent Solution client, see Cloud Talent Solution Client Libraries.

def update_job_with_field_mask(client_service, job_name, job_to_be_updated, field_mask):
    try:
        request = {"job": job_to_be_updated, "update_mask": field_mask}
        job_updated = (
            client_service.projects()
            .jobs()
            .patch(name=job_name, body=request)
            .execute()
        )
        print("Job updated: %s" % job_updated)
        return job_updated
    except Error as e:
        print("Got exception while updating job with field mask")
        raise e

Go

For more on installing and creating a Cloud Talent Solution client, see Cloud Talent Solution Client Libraries.


// updateJobWithMask updates a job by name with specific fields.
// mask is a comma separated list top-level fields of talent.Job.
func updateJobWithMask(w io.Writer, jobName string, mask string, jobToUpdate *talent.Job) (*talent.Job, error) {
	ctx := context.Background()

	client, err := google.DefaultClient(ctx, talent.CloudPlatformScope)
	if err != nil {
		return nil, fmt.Errorf("google.DefaultClient: %w", err)
	}
	// Create the jobs service client.
	service, err := talent.New(client)
	if err != nil {
		return nil, fmt.Errorf("talent.New: %w", err)
	}

	req := &talent.UpdateJobRequest{
		Job:        jobToUpdate,
		UpdateMask: mask,
	}
	job, err := service.Projects.Jobs.Patch(jobName, req).Do()
	if err != nil {
		log.Fatalf("Failed to update job %s with field mask %s, Err: %v", jobName, mask, err)
	}

	return job, err
}

Best practices

Location fields

Whenever possible, we recommend providing the street address of a job in the addresses[] field. This helps with location detection and relevance. When a street-level address isn't available, enter as much information as possible. Addresses are supported up to the country level. Region designations (such as "Pacific Northwest") are not supported.

Cloud Talent Solution uses the data in the addresses[] field to populate the (output only) derivedInfo.locations[] field. When a full address isn't provided, the service uses other signals, such as the company name, to determine if a more complete address can be inferred for the job posting.

For example, if the location of a software job is specified as Mountain View, and the company to which the job is associated is Google, the service looks up the company object to see if a better street address is provided in the headquartersAddress field and if that street address is in the same city as the job posting. If so, the service understands that the job is "likely" at that street address and fills in the derivedInfo.locations[] field appropriately.

If company address data isn't available, the service uses a combination of proprietary knowledge and job/company information to inform the derivedInfo.locations[] field.

Because the derivedInfo.locations[] value is a best-guess effort, you may wish to use the derivedInfo.locations[] data, or the addresses field, when displaying the job address.

A job posting may have no more than 50 locations associated with it. If a job has more locations, you can split the job into multiple jobs each with a unique requisitionId (e.g. 'ReqA' , 'ReqA-1', 'ReqA-2', etc.) since having multiple jobs with the same requisitionId, , companyName and languageCode is not allowed. If the original requisitionId must be preserved, a CustomAttribute should be used for storage. It's recommended you group the locations closest to each other in the same job for a better search experience.

Supported addresses

Any address that is recognized by the Google Maps Geocoding API (in the formattedAddress field) is accepted by Cloud Talent Solution. The service returns a 400 error if you attempt to create a job or execute a search using an unrecognized address.

If a business address is listed incorrectly in the Google Maps Geocoding API, file a bug to have it corrected. Corrections may take up to 5 days to take effect.

Address autocompletion

Cloud Talent Solution does not provide autocomplete suggestions for locations. Use the Google Maps Places API, or other similar location services, to populate autocomplete suggestions.

Statewide, nationwide, and telecommute jobs

Jobs can be specified as statewide, nationwide, or telecommute, using the postingRegion field of the Job resource.

  • ADMINISTRATIVE_AREA and NATION jobs are returned for any search whose location exists inside the state/country of the job posting. For example, if a ADMINISTRATIVE_AREA job has a location of "WA, USA" it is returned for searches whose LocationFilter specifies "Seattle".

  • TELECOMMUTE jobs are returned in any location-related search, but are treated as less relevant. They can be targeted in a search by setting the telecommutePreference flag to TELECOMMUTE_ALLOWED in the search's LocationFilter.