API Reference

GraphQL Endpoint

GQL Endpoint

We also have a GraphQL endpoint which is authorised using a bearer token and can be used to access crew and job data. Learn more about GraphQL over http here.

You have access to the following:

type Query {
  companyCrewAll(input: CompanyCrewAllInput): CompanyCrewAllResponse
  companyCrewOne(crewId: Int!): CompanyCrew!
  companyJobs(input: CompanyJobsInput): CompanyJobsResponse
  companyCrewJobs(input: CompanyCrewJobsInput): CompanyCrewJobsResponse
  companyLeavers(input: CompanyLeaversInput): CompanyLeaversResponse!
}

type Mutation {
  updateCompanyCrew(input: UpdateCompanyCrewInput!): UpdateCompanyCrewResponse!
  updateProfileDataTypes(
    input: UpdateProfileDataTypesInput!
  ): UpdateProfileDataTypesResponse!
  createCrew(input: CreateCrewInput!): CreateCrewResponse!
}

As a GQL endpoint, it is self-documenting if you have an API key.

Prior to access, here is the associated schema for planning purposes:

type Query {
  companyCrewAll(input: CompanyCrewAllInput): CompanyCrewAllResponse
  companyCrewOne(crewId: Int!): CompanyCrew!
  companyJobs(input: CompanyJobsInput): CompanyJobsResponse
  companyCrewJobs(input: CompanyCrewJobsInput): CompanyCrewJobsResponse
  companyLeavers(input: CompanyLeaversInput): CompanyLeaversResponse!
}

type Mutation {
  updateCompanyCrew(input: UpdateCompanyCrewInput!): UpdateCompanyCrewResponse!
  updateProfileDataTypes(
    input: UpdateProfileDataTypesInput!
  ): UpdateProfileDataTypesResponse!
  createCrew(input: CreateCrewInput!): CreateCrewResponse!
}

type UpdateCompanyCrewResponse {
  success: Boolean!
  """
  Errors object has next structure:
  {
  [property: [String!]!]
  }
  """
  errors: Map
  errorCodes: Map
}

input UpdateCompanyCrewInput {
  """
  crewId or crewEmail must be set
  """
  crewId: Int
  crewEmail: String
  update: CompanyCrewUpdate!
}

type UpdateProfileDataTypesResponse {
  success: Boolean!
  """
  Errors object has next structure:
  {
  [property: [String!]!]
  }
  """
  errors: Map
  errorCodes: Map
}

input UpdateProfileDataTypesInput {
  profileId: ID!
  updates: [UpdateProfileDataTypeInput!]!
}

type CreateCrewResponse {
  success: Boolean!
  """
  Errors object has next structure:
  {
  [property: [String!]!]
  }
  """
  errors: Map
  errorCodes: Map
  crewIds: [ID!]
}

input CreateCrewInput {
  crew: [CompanyCrewCreate!]!
}

input UpdateProfileDataTypeInput {
  """
  id or uniqueId must be set
  """
  id: ID
  uniqueId: String
  update: ProfileDataTypeUpdate!
}

input ProfileDataTypeUpdate {
  uniqueId: String
}

input CompanyCrewCreate {
  email: String!
  uniqueId: String
  firstName: String
  lastName: String
  title: String
  userStatus: UserStatus!
  roleTypes: [String!]
  tags: [CrewTag!]
  skills: [CrewSkill!]
  attributes: [CrewAttribute!]
  profile: CrewProfile
}

input CompanyCrewUpdate {
  roleTypes: [String!]
  status: String @deprecated(reason: "Use userStatus instead")
  userStatus: UserStatus
  tags: [CrewTag!]
  uniqueId: String
}

input CrewProfile {
  id: ID!
  dataTypes: [CrewDataTypeInput!]
}

input CrewAttribute {
  """
  id or name must be set
  """
  id: ID
  name: String
  """
  For multiple choice attributes, multiple values can be specified, otherwise only one value is allowed
  """
  values: [String!]
}

input CrewSkill {
  name: String!
  photoProofURL: String
}

input CrewTag {
  """
  id or name must be set
  """
  id: ID
  name: String
}

input CompanyCrewAllInput {
  """
  Filters company crew based on different criteria
  """
  filter: CompanyCrewAllFilter
  """
  Pagination page. Default value is 1
  """
  page: Int = 1
  """
  Number of items per page. Default value is 100 and maximum is 1000
  """
  perPage: Int = 100
}

type CompanyCrewAllResponse {
  """
  Paginated list of returned crew.
  """
  paginatedList: [CompanyCrewInList!]!

  """
  Pagination pager with total count and current page
  """
  pager: Pager
}

input CompanyCrewAllFilter {
  statusIn: [UserStatus!]
  employmentTypeIn: [EmploymentType!]
  """
  Filters crew by full_name (first_name + last_name) or email or unique_id or phone
  """
  search: String
  updatedAfter: Time
}

"""
Company Crew Data
Is a combination of Company Specific and Shared Crew Data
"""
type CompanyCrewInList implements CompanyCrewData {
  """
  'crewId' is an alias to 'userId'
  """
  crewId: ID!
  title: String!
  firstName: String!
  lastName: String!
  email: String!
  birthDay: Date
  phone: String!
  avatar: String!
  gender: Gender!
  status: UserStatus!
  statusUpdatedAt: Time!
  biography: String! @deprecated(reason: "Use profiles instead")
  experience: String! @deprecated(reason: "Use profiles instead")
  workCapacity: String! @deprecated(reason: "Use profiles instead")
  employmentType: EmploymentType! @deprecated(reason: "Use profiles instead")
  cv: String! @deprecated(reason: "Use profiles instead")
  travelAbility: String! @deprecated(reason: "Use profiles instead")
  disability: String! @deprecated(reason: "Use profiles instead")
  linkedIdURL: String! @deprecated(reason: "Use profiles instead")
  twitterURL: String! @deprecated(reason: "Use profiles instead")
  facebookURL: String! @deprecated(reason: "Use profiles instead")
  instagramURL: String! @deprecated(reason: "Use profiles instead")
  uniqueId: String!
  bankNumber: String!
  sortCode: String!
  taxCode: String!
  city: String!
  address: String!
  address2: String!
  postCode: String!
  longitude: Float
  latitude: Float
  updatedAt: Time!
  registeredAt: Time
  countrySpecificData: CountrySpecificData!
  firstJobStartDate: Date
  profiles: [ProfileCrewData!]!
  roleTypes: [String]!
  tags: [Tag!]!
}

"""
Company Crew Data
Additionally to company crew data, have a lot of relational data.
"""
type CompanyCrew implements CompanyCrewData {
  """
  'crewId' is an alias to 'userId'
  """
  crewId: ID!
  title: String!
  firstName: String!
  lastName: String!
  email: String!
  birthDay: Date
  phone: String!
  avatar: String!
  gender: Gender!
  status: UserStatus!
  statusUpdatedAt: Time!
  biography: String! @deprecated(reason: "Use profiles instead")
  experience: String! @deprecated(reason: "Use profiles instead")
  workCapacity: String! @deprecated(reason: "Use profiles instead")
  employmentType: EmploymentType! @deprecated(reason: "Use profiles instead")
  cv: String! @deprecated(reason: "Use profiles instead")
  travelAbility: String! @deprecated(reason: "Use profiles instead")
  disability: String! @deprecated(reason: "Use profiles instead")
  linkedIdURL: String! @deprecated(reason: "Use profiles instead")
  twitterURL: String! @deprecated(reason: "Use profiles instead")
  facebookURL: String! @deprecated(reason: "Use profiles instead")
  instagramURL: String! @deprecated(reason: "Use profiles instead")
  uniqueId: String!
  bankNumber: String!
  sortCode: String!
  taxCode: String!
  city: String!
  address: String!
  address2: String!
  postCode: String!
  longitude: Float
  latitude: Float
  updatedAt: Time!
  registeredAt: Time
  countrySpecificData: CountrySpecificData!
  alerts: [UserAlert]
  firstJobStartDate: Date
  profiles: [ProfileCrewData!]!
  roleTypes: [String]!
  tags: [Tag!]!
}

type ProfileCrewData {
  profileId: ID!
  name: String!
  dataTypes: [CrewDataType!]!
}

type CrewDataType {
  id: ID!
  uniqueId: String
  category: DTCategory!
  type: DTType!
  title: String!
  description: String!
  answer: CrewAnswer
}

input CrewDataTypeInput {
  """
  id or uniqueId must be set
  """
  id: ID
  uniqueId: String
  answer: [String!]
}

enum DTCategory {
  ACCOUNT_DATA
  DATA
  CONTENT
}

enum DTType {
  SHORT_ANSWER
  PARAGRAPH
  FILE_UPLOAD
  DROPDOWN
  MULTIPLE_CHOICE
  CHECKBOXES
  SIMPLE_AGREEMENT
  EMAIL
  PHONE_NUMBER
  DATE_PICKER
  ADDRESS
  WEB_LINK
}

union CrewAnswer = CrewAnswerValue | CrewAnswerValues

type CrewAnswerValue {
  value: String!
}

type CrewAnswerValues {
  values: [CrewAnswerValue]!
}

interface CompanyCrewData {
  crewId: ID!
  title: String!
  firstName: String!
  lastName: String!
  email: String!
  birthDay: Date
  phone: String!
  avatar: String!
  gender: Gender!
  status: UserStatus!
  statusUpdatedAt: Time!
  biography: String! @deprecated(reason: "Use profiles instead")
  experience: String! @deprecated(reason: "Use profiles instead")
  workCapacity: String! @deprecated(reason: "Use profiles instead")
  employmentType: EmploymentType! @deprecated(reason: "Use profiles instead")
  cv: String! @deprecated(reason: "Use profiles instead")
  travelAbility: String! @deprecated(reason: "Use profiles instead")
  disability: String! @deprecated(reason: "Use profiles instead")
  linkedIdURL: String! @deprecated(reason: "Use profiles instead")
  twitterURL: String! @deprecated(reason: "Use profiles instead")
  facebookURL: String! @deprecated(reason: "Use profiles instead")
  instagramURL: String! @deprecated(reason: "Use profiles instead")
  uniqueId: String!
  bankNumber: String!
  sortCode: String!
  taxCode: String!
  city: String!
  address: String!
  address2: String!
  postCode: String!
  longitude: Float
  latitude: Float
  updatedAt: Time!
  registeredAt: Time
  countrySpecificData: CountrySpecificData!
  firstJobStartDate: Date
  profiles: [ProfileCrewData!]!
  roleTypes: [String]!
  tags: [Tag!]!
}

"""
User Status is a specific company
"""
enum UserStatus {
  APPLICATION_IN_PROGRESS
  APPLICANT
  APPROVED
  ACTIVE
  PAUSED
  WAITING_LIST
  INVITED
  DECLINED
  SUSPENDED
  DELETED
}

"""
Crew emplyment type in a company.
DEPRECATED: employment types are now replaced by profiles
Works in legacy mode: employment type is now defined from profile name
To be removed in the future.
"""
enum EmploymentType {
  INCOMPLETE
  EMPLOYED
  SELF_EMPLOYED
}

enum Gender {
  MALE
  FEMALE
  OTHER
}

type UserAlert {
  id: Int!
  text: String!
  createdBy: CreatedBy
  updatedAt: Time!
  createdAt: Time!
}

type CreatedBy {
  userId: Int!
  firstName: String!
  lastName: String!
  avatar: String!
}

type CountrySpecificData {
  countryId: Int!
  code: String!
  name: String!
  values: [CrewCountryValue!]!
}

type CrewCountryValue {
  id: Int!
  name: String!
  value: String!
}

type Tag {
  id: Int!
  name: String!
}

input CompanyLeaversInput {
  """
  Filters company crew based on different criteria
  """
  filter: CompanyLeaversFilter
  """
  Pagination page. Dafault value is 1
  """
  page: Int = 1
  """
  Number of items per page. Dafault value is 100 and maximum is 1000
  """
  perPage: Int = 100
}

input CompanyLeaversFilter {
  statusIn: [LeaverStatus!]
  employmentTypeIn: [EmploymentType!]
  updatedAfter: Time
}

type CompanyLeaversResponse {
  """
  Paginated list of returned crew.
  """
  paginatedList: [CompanyLeaversInList!]!

  """
  Pagination pager with total count and current page
  """
  pager: Pager
}

"""
Company Crew Leaver Data
Crew leaver information that can be used to match company records when a user is suspended or deletes their account
"""
type CompanyLeaversInList implements CompanyCrewLeaverData {
  crewId: ID!
  employmentType: EmploymentType!
  workforceId: String!
  status: LeaverStatus!
  updatedAt: Time!
  registeredAt: Time
}

interface CompanyCrewLeaverData {
  crewId: ID!
  workforceId: String!
  status: LeaverStatus!
  updatedAt: Time!
  registeredAt: Time
  employmentType: EmploymentType
}

"""
Leaver Status is a specific company
"""
enum LeaverStatus {
  SUSPENDED
  DELETED
}

input CompanyJobsInput {
  """
  Filters company crew based on different criteria
  """
  filter: CompanyJobsFilter
  """
  Pagination page. Default value is 1
  """
  page: Int = 1
  """
  Number of items per page. Default value is 100 and maximum is 100
  """
  perPage: Int = 100
}

type CompanyJobsResponse {
  """
  Paginated list of returned jobs.
  """
  paginatedList: [Job!]!

  """
  Pagination pager with total count and current page
  """
  pager: Pager
}

input CompanyJobsFilter {
  jobIds: [ID!]
  fromRange: Time
  toRange: Time
  crewJobStatus: [CrewJobStatus]
}

input CompanyCrewJobsInput {
  """
  Filters company crew based on different criteria
  """
  filter: CompanyCrewJobsFilter
  """
  Pagination page. Default value is 1
  """
  page: Int = 1
  """
  Number of items per page. Default value is 100 and maximum is 100
  """
  perPage: Int = 100
}

type CompanyCrewJobsResponse {
  """
  Paginated list of returned jobs.
  """
  paginatedList: [CrewJobExtended!]!

  """
  Pagination pager with total count and current page
  """
  pager: Pager
}

input CompanyCrewJobsFilter {
  crewJobIds: [ID!]
  fromRange: Time
  toRange: Time
  crewJobStatus: [CrewJobStatus]
}

type Board {
  id: ID
  name: String
  color: String
}

"""
Company Job Data
Get published jobs
"""
type Job {
  id: ID
  address: String
  board: Board
  color: String
  date: Date
  description: String
  locationShortName: String
  multiDayJobId: ID
  title: String
  groupId: ID
  roles: [Role!]
  labels: [Label!]
}

"""
Job Label
"""
type Label {
  id: ID
  name: String
  type: LabelType
}

"""
Job Role
"""
type Role {
  ageRestriction: Int
  breakPeriod: Int
  breakPeriodPaid: Boolean
  crewJobs: [CrewJobSlim]
  end: Time
  expenses: Float
  feeType: FeeType
  id: ID
  labels: [Label!]
  linkedId: String
  name: String
  requiredCrewCount: Int
  salary: Float
  start: Time
  subsistence: Float
  total: Float
  visibleOnJobBoard: Boolean
}

interface CrewJob {
  breakPeriod: Int
  breakPeriodPaid: Boolean
  crewId: ID
  feeType: FeeType
  expenses: Float
  id: ID
  salary: Float
  status: CrewJobStatus
  subsistence: Float
  total: Float
}

"""
Crew Job
"""
type CrewJobSlim implements CrewJob {
  breakPeriod: Int
  breakPeriodPaid: Boolean
  crewId: ID
  feeType: FeeType
  expenses: Float
  id: ID
  salary: Float
  status: CrewJobStatus
  subsistence: Float
  total: Float
}

type CrewJobExtended implements CrewJob {
  activity: CrewJobActivity
  jobId: ID
  roleId: ID
  board: Board
  breakPeriod: Int
  breakPeriodPaid: Boolean
  crewId: ID
  end: Time
  expenses: Float
  feeType: FeeType
  id: ID
  salary: Float
  status: CrewJobStatus
  start: Time
  subsistence: Float
  total: Float
}

type CrewJobActivity {
  application: String
  checkedInAt: Time
  checkedOutAt: Time
  checkInSentAt: Time
  confirmAttendanceSentAt: Time
  hasConfirmedAttendance: Boolean
  confirmedAttendanceAt: Boolean
  markedAsAbsentByAdminAt: Time
  isCheckedIn: Boolean
  isReserved: Boolean
  isShortlisted: Boolean
  isSupervisor: Boolean
  wasBooked: Boolean
  approvedByAdminAt: Time
  sequence: Int
}

enum FeeType {
  PER_HOUR
  PER_JOB
  NO_FEE
}

enum LabelType {
  CUSTOM
  CLIENT
  PROJECT_NUMBER
}

enum CrewJobStatus {
  PENDING
  APPROVED
  CANCELLED_BY_ADMIN
  CANCELLED_BY_FREELANCER
  CANCELLED_BY_SYSTEM
  INVITED
}

scalar Map

"""
Datetime string in ISO 8601 format like "2020-11-18T12:21:14+00:00" or "2020-11-18T12:21:14Z"
"""
scalar Time

type MutationResponse {
  success: Boolean!
  error: String
}

"""
Date is a just a string like '2019-03-14'
"""
scalar Date

"""
A pagination Pager
"""
type Pager {
  """
  Current pagination page
  """
  currentPage: Int!

  """
  Total number of pagination pages
  """
  pageCount: Int!

  """
  Maximum number of records per pagination page
  """
  perPage: Int!

  """
  Total number of records
  """
  totalCount: Int!
}

Test request using cURL:

curl 'https://api.liveforce.co/0.2/gql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: file://' -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkxvZjZpRm9EbWlGWHctSzA5Nkd4MyJ9.eyJodHRwczovL3N0YWdpbmcubGl2ZWZvcmNlLmNvL3Byb3h5L2NvbXBhbnktaWQiOiIxNzkiLCJpc3MiOiJodHRwczovL2xpdmVmb3JjZS5ldS5hdXRoMC5jb20vIiwic3ViIjoieXNWcVRZV2t6RFlYb1MxOFFWV2xJemRIS0dqVVJzREFAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vc3RhZ2luZy5saXZlZm9yY2UuY28vcHJveHkvIiwiaWF0IjoxNjM1NzA1MzMyLCJleHAiOjE2MzU3OTE3MzIsImF6cCI6InlzVnFUWVdrekRZWG9TMThRVldsSXpkSEtHalVSc0RBIiwic2NvcGUiOiJyZWFkOnBheW1lbnRfcmVwb3J0cyByZWFkOmNvbXBhbnlfY3Jld19kYXRhIHdyaXRlOmNvbXBhbnlfY3Jld19kYXRhIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.X7gQWmonqxa6Y_BWhfr75M-bHfiGI89SYAsFmazZC2ta1mh8Pd6Ji-HLtVpM1nyM29eza81KezjXpLB18Ur5yEAxg1XTxGdvpOnRPqiB8wDGykpMW3r0j70_MqNqGDsfwj_0Bt8iBnjn9IkeFQFtbrIqigki2R1jljYnZX2fguFl1sa-Ff6Q0xR5D2fc8tIwC5_WtrQ1ZTbkaDksjwAGUr_riOFY8QtTU4zYc_AWlwv6zZgXoVmh9QZhnf5qWh3GLdamXm-BwvgQRiohXMqymTva6H6vY3_fVmu_gVnIwIwRmMqzW4_H_IvCj-S48Be2fDQ-6S3XhA-ZpAbbfOs6Sg' --data-binary '{"query":"# Write your query or mutation here\nquery CompanyCrewAllByPage {\n  companyCrewAll(input: { page: 1, perPage: 100 }) {\n    paginatedList {\n      title\n      firstName\n      lastName\n      email\n      phone\n    }\n    pager {\n      pageCount\n      perPage\n  currentPage\n    }\n  }\n}\n"}' --compressed

Or using Postman:

query Query {
    companyCrewAll(input: { page: 1 perPage: 200 filter: { statusIn: [ACTIVE] } }) {
        paginatedList {
            crewId
            email
            tags {
                id
                name
            }
        }
    }
}