Perform multiple related mutations using GraphQL aliases

Use ID aliases to perform multiple related operations in a single GraphQL mutation

Skedulo GraphQL mutations support subsequent operations depending on the result of previous operations. When a record is inserted, its generated ID can be mapped to an ID “alias”, which can then be used in a subsequent insert, update or get operation.

This enables compound operations within a single request, reducing complexity and ensuring data integrity.

You can define an idAlias variable as a placeholder for the ID of an inserted record, which can then be used when inserting, updating or getting a related record.

Example use cases:

  • Create an account and associate it with an existing contact in a single request
  • Create a job and a job offer, and assign it to multiple resources in a single request
  • Create a job and one or more job allocations and get the status of the job in a single request

Create a job and a job offer, then assign resources the offer

The following GraphQL mutation includes multiple actions:

  • insertJobs - creates a new job.
  • insertJobOffers - creates a job offer for the job created in the first part of the mutation.
  • insertResourceJobOffers - assigns the job offer to two resources. Note the operation keys rjo1 and rjo2 are required.

After inserting the records, use the Notifications API to notify resources about the offer.

mutation createJobWithOfferAndAssignResources {
  schema {
    insertJobs(input: {
      RegionId: "00036206-7555-4280-b1b7-86d566437391"
      Start: "2025-08-02T00:00:00+00:00"
      End: "2025-08-02T01:30:00+00:00"
      Duration: 90
      Address: "123 High St, Springfield 12345"
      Description: "New Job testing Aliases"
    }, idAlias: "NEW_JOB_ID")
      
    insertJobOffers(input: {
      JobId: "NEW_JOB_ID"
    }, idAlias: "NEW_JOB_OFFER_ID")
      
    rjo1: insertResourceJobOffers(input: {
      JobOfferId: "NEW_JOB_OFFER_ID"
      ResourceId: "0005a7e9-b1aa-44da-937f-310b921b75cc"
    })

    rjo2: insertResourceJobOffers(input: {
      JobOfferId: "NEW_JOB_OFFER_ID"
      ResourceId: "0005b5a9-0822-4f25-9ec0-74ae4d53b626"
    })
  }
}

The successful response is shown below:

{
  "data": {
    "schema": {
      "insertJobs": "0014d653-af0d-4c73-b15d-e77afee2be01",
      "insertJobOffers": "00237199-0e4c-434c-a4c1-86f9326c59e5",
      "rjo1": "002427a8-036f-4024-91d3-740bd816c4eb",
      "rjo2": "00246206-7555-4280-b1b7-86d566437391"
    }
  }
}

Create an account and associate it with an existing contact

mutation createAccountAndLinkContact {
  schema {
    insertAccounts(idAlias: "NEW_ACCOUNT", input: {
      Name: "ACME Inc"
    })
    
    updateContacts(input: {
      UID: "0004ed67-8b8a-455e-bcaf-20611a468eae"
      AccountId: "NEW_ACCOUNT"
    })
  }
}

Create jobs and allocations then get status of jobs

The GraphQL mutation below creates two new jobs, then creates one job allocation for the first job and two allocations for the second job. Finally, it gets the resulting statuses of the jobs.

Ensure the RegionId and ResourceId values correspond to valid IDs in your Skedulo tenant.

mutation createJobsWithAllocations {
  schema {
    job1: insertJobs(idAlias: "NEW_JOB_ID1", input: {
      RegionId: "0003ed32-5be6-4a8c-b8bb-2c8bb2d9f83c"
      Start: "2025-10-31T00:00:00+00:00"
      End: "2025-10-31T01:30:00+00:00"
      Duration: 90
      Quantity: 2
      Address: "123 High St, Springfield 12345"
      Description: "Insert jobs and allocations example 1"
    })
      
    ja1: insertJobAllocations(input: {
      ResourceId: "00050d78-7df0-49ec-b3da-8fc53817157f"
      JobId: "NEW_JOB_ID1"
    })

    job2: insertJobs(idAlias: "NEW_JOB_ID2", input: {
      RegionId: "0003ed32-5be6-4a8c-b8bb-2c8bb2d9f83c"
      Start: "2025-10-31T05:00:00+00:00"
      End: "2025-10-31T06:30:00+00:00"
      Duration: 90
      Quantity: 2
      Address: "99 Smith St, Springfield 12345"
      Description: "Insert jobs and allocations example 2"
    })

    ja2: insertJobAllocations(input: {
      ResourceId: "00050d78-7df0-49ec-b3da-8fc53817157f"
      JobId: "NEW_JOB_ID2"
    })

    ja3: insertJobAllocations(input: {
      ResourceId: "000511e4-6b53-4845-8904-3e396eed620f"
      JobId: "NEW_JOB_ID2"
    })

    jobStatus1: getJobs(id: "NEW_JOB_ID1") {
      JobStatus
    }

    jobStatus2: getJobs(id: "NEW_JOB_ID2") {
      JobStatus
    }
  }
}

This returns a response in the format below. Notice the statuses of the jobs are different because only one job has its full quantity of allocations.

{
  "data": {
    "schema": {
      "job1": "0014fc0e-206d-4276-a569-953c393c3387",
      "ja1": "00181c45-fa49-4f69-8038-238c46f54b02",
      "job2": "0014b1d3-41b3-4a94-9fe5-03c2f89ccf43",
      "ja2": "00187c65-fa0e-4236-aa71-1183dfb9e5e8",
      "ja3": "00184ca3-de28-4632-8918-739aeb2c3d0f",
      "jobStatus1": {
        "JobStatus": "Pending Allocation"
      },
      "jobStatus2": {
        "JobStatus": "Pending Dispatch"
      }
    }
  }
}