Ashby · Arazzo Workflow

Ashby Attach a Resume to a Candidate

Version 1.0.0

Mint a presigned upload handle, attach the uploaded resume, and verify the file.

1 workflow 1 source API 1 provider
View Spec View on GitHub ATSApplicant Tracking SystemRecruitingTalent AcquisitionSourcingCRMSchedulingAnalyticsHiringHR TechAIArazzoWorkflows

Provider

ashby-hq

Workflows

candidate-resume-upload
Create a file upload handle, attach the resume to a candidate, verify it.
Requests a presigned upload handle scoped to CandidateResume, binds the uploaded file to the candidate as their resume, and confirms the attachment by resolving the stored file handle to a url.
3 steps inputs: candidateId, contentLength, contentType, filename outputs: candidateId, resumeFileName, resumeHandle, resumeUrl
1
createUploadHandle
fileCreateFileUploadHandle
Ask Ashby for a presigned upload target scoped to the CandidateResume context. The response carries the presigned url and form fields for the out-of-band multipart POST, plus the encrypted handle that identifies the file to Ashby once it lands.
2
attachResume
candidateUploadResume
Bind the uploaded file to the candidate as their resume. This step assumes the file has already been POSTed as multipart/form-data to the presigned url from the previous step; that upload goes directly to object storage and is not part of the Ashby JSON API.
3
resolveResumeUrl
fileInfo
Resolve the stored resume handle to a downloadable url, confirming the file is attached and readable. Ashby file urls are short lived, so this call is the correct way to fetch a resume rather than caching a url.

Source API Descriptions

Arazzo Workflow Specification

Raw ↑
arazzo: 1.0.1
info:
  title: Ashby Attach a Resume to a Candidate
  summary: Mint a presigned upload handle, attach the uploaded resume, and verify the file.
  description: >-
    Ashby does not accept resume bytes on its JSON API. Instead the integrator
    asks Ashby for a presigned upload target, POSTs the file to that target out
    of band, and then hands the returned handle back to Ashby to bind the file to
    a candidate. This workflow covers the two API calls that bracket that upload
    plus a read-back that resolves a fresh download url, which is the part
    integrators most often get wrong. Every step spells out its request inline so
    the flow can be read and executed without opening the underlying OpenAPI
    description.
  version: 1.0.0
sourceDescriptions:
- name: ashbyApi
  url: ../openapi/ashby-openapi.yml
  type: openapi
workflows:
- workflowId: candidate-resume-upload
  summary: Create a file upload handle, attach the resume to a candidate, verify it.
  description: >-
    Requests a presigned upload handle scoped to CandidateResume, binds the
    uploaded file to the candidate as their resume, and confirms the attachment
    by resolving the stored file handle to a url.
  inputs:
    type: object
    required:
    - candidateId
    - filename
    - contentType
    - contentLength
    properties:
      candidateId:
        type: string
        description: The id of the candidate to attach the resume to.
      filename:
        type: string
        description: The name of the resume file being uploaded, including extension.
      contentType:
        type: string
        description: The MIME type of the resume file (e.g. application/pdf).
      contentLength:
        type: integer
        description: The size of the resume file in bytes.
  steps:
  - stepId: createUploadHandle
    description: >-
      Ask Ashby for a presigned upload target scoped to the CandidateResume
      context. The response carries the presigned url and form fields for the
      out-of-band multipart POST, plus the encrypted handle that identifies the
      file to Ashby once it lands.
    operationId: fileCreateFileUploadHandle
    requestBody:
      contentType: application/json
      payload:
        fileUploadContext: CandidateResume
        filename: $inputs.filename
        contentType: $inputs.contentType
        contentLength: $inputs.contentLength
    successCriteria:
    - condition: $statusCode == 200
    - condition: $response.body#/success == true
    outputs:
      resumeHandle: $response.body#/results/handle
      uploadUrl: $response.body#/results/url
      uploadFields: $response.body#/results/fields
  - stepId: attachResume
    description: >-
      Bind the uploaded file to the candidate as their resume. This step assumes
      the file has already been POSTed as multipart/form-data to the presigned
      url from the previous step; that upload goes directly to object storage and
      is not part of the Ashby JSON API.
    operationId: candidateUploadResume
    requestBody:
      contentType: application/json
      payload:
        candidateId: $inputs.candidateId
        resumeHandle: $steps.createUploadHandle.outputs.resumeHandle
    successCriteria:
    - condition: $statusCode == 200
    - condition: $response.body#/success == true
    outputs:
      candidateId: $response.body#/results/id
      storedResumeHandle: $response.body#/results/resumeFileHandle/handle
      resumeFileName: $response.body#/results/resumeFileHandle/name
  - stepId: resolveResumeUrl
    description: >-
      Resolve the stored resume handle to a downloadable url, confirming the file
      is attached and readable. Ashby file urls are short lived, so this call is
      the correct way to fetch a resume rather than caching a url.
    operationId: fileInfo
    requestBody:
      contentType: application/json
      payload:
        fileHandle: $steps.attachResume.outputs.storedResumeHandle
    successCriteria:
    - condition: $statusCode == 200
    - condition: $response.body#/success == true
    outputs:
      resumeUrl: $response.body#/results/url
  outputs:
    candidateId: $steps.attachResume.outputs.candidateId
    resumeHandle: $steps.attachResume.outputs.storedResumeHandle
    resumeFileName: $steps.attachResume.outputs.resumeFileName
    resumeUrl: $steps.resolveResumeUrl.outputs.resumeUrl