openapi: 3.0.3 info: title: Truto Unified ATS API description: >- The Truto Unified ATS API provides a single normalized interface for reading and writing applicant tracking system data across 27 ATS providers including Greenhouse, Lever, Workable, SmartRecruiters, Ashby, Teamtailor, BambooHR, Jobvite, and more. Covers the full recruiting lifecycle with 17 unified resources. All data is accessed in real-time via pass-through to the underlying ATS. Schema can be customized using JSONata mappings. version: 1.0.0 contact: url: https://truto.one/docs/api-reference/unified-ats-api servers: - url: https://api.truto.one/unified/ats description: Truto Unified ATS API security: - bearerAuth: [] tags: - name: Jobs description: Job postings and open positions - name: Candidates description: Candidate profiles and contact information - name: Applications description: Job applications linking candidates to jobs - name: Interviews description: Interview events and scheduling - name: Offers description: Job offers extended to candidates - name: Departments description: Organizational departments - name: Users description: ATS users and recruiters paths: /jobs: get: operationId: listJobs summary: List jobs description: >- List job postings from the connected ATS provider. Returns normalized job data including title, department, location, status, and associated stages. tags: - Jobs security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IntegratedAccountId' - name: status in: query description: Filter jobs by status. required: false schema: type: string enum: - open - closed - draft - name: department_id in: query description: Filter jobs by department ID. required: false schema: type: string - name: cursor in: query required: false schema: type: string - name: limit in: query required: false schema: type: integer default: 20 maximum: 100 responses: '200': description: List of jobs. content: application/json: schema: $ref: '#/components/schemas/JobListResponse' '401': $ref: '#/components/responses/Unauthorized' /jobs/{id}: get: operationId: getJob summary: Get job description: Retrieve a single job posting by ID. tags: - Jobs security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IntegratedAccountId' - name: id in: path required: true schema: type: string responses: '200': description: Job posting details. content: application/json: schema: $ref: '#/components/schemas/Job' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /candidates: get: operationId: listCandidates summary: List candidates description: List candidate profiles from the connected ATS provider. tags: - Candidates security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IntegratedAccountId' - name: cursor in: query required: false schema: type: string - name: limit in: query required: false schema: type: integer default: 20 responses: '200': description: List of candidates. content: application/json: schema: $ref: '#/components/schemas/CandidateListResponse' '401': $ref: '#/components/responses/Unauthorized' /candidates/{id}: get: operationId: getCandidate summary: Get candidate description: Retrieve a single candidate by ID. tags: - Candidates security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IntegratedAccountId' - name: id in: path required: true schema: type: string responses: '200': description: Candidate profile. content: application/json: schema: $ref: '#/components/schemas/Candidate' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /applications: get: operationId: listApplications summary: List applications description: >- List job applications from the connected ATS provider. Each application links a candidate to a specific job and tracks their progress through interview stages. tags: - Applications security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IntegratedAccountId' - name: job_id in: query description: Filter applications by job ID. required: false schema: type: string - name: candidate_id in: query description: Filter applications by candidate ID. required: false schema: type: string - name: status in: query description: Filter by application status. required: false schema: type: string enum: - active - rejected - hired - withdrawn - name: cursor in: query required: false schema: type: string - name: limit in: query required: false schema: type: integer default: 20 responses: '200': description: List of applications. content: application/json: schema: $ref: '#/components/schemas/ApplicationListResponse' '401': $ref: '#/components/responses/Unauthorized' /offers: get: operationId: listOffers summary: List offers description: List job offers extended to candidates from the connected ATS provider. tags: - Offers security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IntegratedAccountId' - name: application_id in: query description: Filter offers by application ID. required: false schema: type: string - name: status in: query description: Filter offers by status. required: false schema: type: string enum: - draft - sent - accepted - declined - rescinded - name: cursor in: query required: false schema: type: string - name: limit in: query required: false schema: type: integer default: 20 responses: '200': description: List of offers. content: application/json: schema: $ref: '#/components/schemas/OfferListResponse' '401': $ref: '#/components/responses/Unauthorized' /departments: get: operationId: listDepartments summary: List departments description: List departments from the connected ATS provider. tags: - Departments security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IntegratedAccountId' - name: cursor in: query required: false schema: type: string - name: limit in: query required: false schema: type: integer default: 20 responses: '200': description: List of departments. content: application/json: schema: $ref: '#/components/schemas/DepartmentListResponse' '401': $ref: '#/components/responses/Unauthorized' components: securitySchemes: bearerAuth: type: http scheme: bearer description: Tenant Bearer token from the Truto dashboard. parameters: IntegratedAccountId: name: integrated_account_id in: query required: true description: >- The ID of the integrated account (connected ATS provider instance) to query. Required for all Unified API requests. schema: type: string responses: Unauthorized: description: Authentication failed or token is invalid. content: application/json: schema: $ref: '#/components/schemas/Error' NotFound: description: Resource not found. content: application/json: schema: $ref: '#/components/schemas/Error' schemas: Job: type: object description: A normalized job posting from the connected ATS provider. properties: id: type: string description: Unified job identifier. remoteId: type: string description: Job identifier in the source ATS. title: type: string description: Job title. status: type: string enum: - open - closed - draft description: Job posting status. departmentId: type: string description: Department identifier. officeId: type: string description: Office or location identifier. description: type: string description: Job description content. jobType: type: string enum: - full_time - part_time - contract - temporary - intern description: Type of position. remoteAllowed: type: boolean description: Whether remote work is permitted. hiringManagerId: type: string description: Identifier of the hiring manager. openedAt: type: string format: date-time description: Timestamp when the job was opened. closedAt: type: string format: date-time description: Timestamp when the job was closed. createdAt: type: string format: date-time updatedAt: type: string format: date-time JobListResponse: type: object properties: data: type: array items: $ref: '#/components/schemas/Job' nextCursor: type: string Candidate: type: object description: A normalized candidate profile from the connected ATS provider. properties: id: type: string description: Unified candidate identifier. remoteId: type: string description: Candidate identifier in the source ATS. firstName: type: string lastName: type: string email: type: string format: email description: Primary email address. phone: type: string description: Phone number. location: type: string description: Candidate location. source: type: string description: How the candidate was sourced (e.g., LinkedIn, referral, job board). tags: type: array items: type: string description: Tags or labels applied to the candidate. createdAt: type: string format: date-time updatedAt: type: string format: date-time CandidateListResponse: type: object properties: data: type: array items: $ref: '#/components/schemas/Candidate' nextCursor: type: string Application: type: object description: A job application linking a candidate to a job with current stage information. properties: id: type: string description: Unified application identifier. remoteId: type: string candidateId: type: string description: Identifier of the applying candidate. jobId: type: string description: Identifier of the applied-to job. status: type: string enum: - active - rejected - hired - withdrawn description: Current application status. currentStageId: type: string description: Identifier of the current interview stage. rejectReasonId: type: string description: Reason for rejection, if rejected. source: type: string description: Application source channel. appliedAt: type: string format: date-time description: Timestamp when the application was submitted. createdAt: type: string format: date-time updatedAt: type: string format: date-time ApplicationListResponse: type: object properties: data: type: array items: $ref: '#/components/schemas/Application' nextCursor: type: string Offer: type: object description: A job offer extended to a candidate. properties: id: type: string remoteId: type: string applicationId: type: string description: Identifier of the associated application. status: type: string enum: - draft - sent - accepted - declined - rescinded startDate: type: string format: date description: Proposed start date. closedAt: type: string format: date-time createdAt: type: string format: date-time updatedAt: type: string format: date-time OfferListResponse: type: object properties: data: type: array items: $ref: '#/components/schemas/Offer' nextCursor: type: string Department: type: object description: A department from the ATS provider. properties: id: type: string remoteId: type: string name: type: string parentId: type: string createdAt: type: string format: date-time updatedAt: type: string format: date-time DepartmentListResponse: type: object properties: data: type: array items: $ref: '#/components/schemas/Department' nextCursor: type: string Error: type: object properties: error: type: string message: type: string