> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kombo.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Attachments

> Get CVs, cover letters and other candidate files from the ATS.

Fetch a candidate's files from the ATS **on demand**, or have Kombo **sync**
every candidate's files into your own bucket.

## Which one to use

| | On-demand | Synced |
| - | - | - |
| **Endpoints** | [Get candidate attachments](/ats/v1/get-candidates-candidate-id-attachments), [get application attachments](/ats/v1/get-applications-application-id-attachments) | [Get attachments](/ats/v1/get-attachments) |
| **Calls the ATS** | On every request | During the sync only |
| **Requests you make** | One per candidate or application | One paginated list for all files |
| **Where the file is** | A link Kombo hosts (`data_url`), valid for 7 days | Your bucket, where you decide when to process and delete it |
| **Plan** | All plans | Enterprise, in beta |
| **Supported integrations** | Most ATS integrations | A growing list, see the [endpoint reference](/ats/v1/get-attachments) |

**On-demand** fits when you need the files of a few candidates at a time. For
the CVs of all your candidates, use **synced**. Doing that on demand means one
request per candidate, each counting against the ATS rate limit, and you have to
queue and retry them yourself.

## On-demand attachments

[Get candidate attachments](/ats/v1/get-candidates-candidate-id-attachments)
returns all files of a candidate.
[Get application attachments](/ats/v1/get-applications-application-id-attachments)
returns the files of one application, or the candidate's files if the ATS
doesn't store them per application. Both call the ATS when you ask and return a
`data_url` that stays valid for 7 days.

Both need the `Read document attachments` permission in your
[scope configuration](https://app.kombo.dev/scope-config).

## Synced attachments

<Note>
  Synced attachments are in **beta** and available on the Enterprise plan, for a
  limited set of integrations so far (see the [endpoint
  reference](/ats/v1/get-attachments)). Reach out to your account manager or
  [support](mailto:support@kombo.dev) to enable them for your environment.
</Note>

During the sync, Kombo lists each candidate's attachments, downloads the files
it doesn't hold yet and writes them into your bucket. An attachment shows up in
the API once its file is stored, so every attachment you read points to a file
that exists.

```mermaid theme={null}
sequenceDiagram
    participant ATS
    participant K as Kombo
    participant B as Your bucket
    participant YS as Your system

    Note over ATS,B: During the sync
    K->>ATS: List the candidate's attachments
    K->>ATS: Download new files
    K->>B: Write each file

    Note over K,YS: Whenever you need the files
    YS->>K: GET /ats/attachments
    K-->>YS: Attachments with content_ref
    YS->>B: Read the files with your own credentials
```

### Setup

Once enabled, we connect your bucket together with you and turn on the
attachments model for your environment. On your side, enable the
`Read document attachments` permission in your
[scope configuration](https://app.kombo.dev/scope-config).

### Reading synced attachments

[Get attachments](/ats/v1/get-attachments) returns each attachment with a
`content_ref` pointing to its file in your bucket:

```json theme={null}
{
  "id": "EYJjhMQT3LtVKXnTbnRT8s6U",
  "remote_id": "1001",
  "candidate_id": "BTbkvY2w5ou3z3hdwuKcKzDh",
  "application_id": "H5daSm8e85Dmvmne3wLeCPhX",
  "type": "CV",
  "file_name": "Frank Doe CV.pdf",
  "content_ref": {
    "type": "s3",
    "bucket": "acme-kombo-attachments",
    "key": "kombo/ats_attachments/integrations/greenhousev3:BsUP8fPMzHDo/candidates/BTbkvY2w5ou3z3hdwuKcKzDh/EYJjhMQT3LtVKXnTbnRT8s6U"
  },
  "remote_created_at": "2024-01-15T09:30:00.000Z",
  "remote_updated_at": "2024-01-15T09:30:00.000Z",
  "changed_at": "2024-01-15T09:30:00.000Z",
  "remote_deleted_at": null
}
```

`content_ref.key` is the full object key, including your prefix, so read the
file with it directly. `application_id` is `null` when the ATS files the
attachment under the candidate rather than one application.

Use `updated_after` to only
[fetch new attachments](/ats/getting-started/fetching-data), and
`candidate_ids` or `application_ids` to narrow them down. Filtering by
`application_ids` excludes files that hang off the candidate directly.

### What lands in your bucket

```
<prefix>/ats_attachments/integrations/<integration_id>/candidates/<candidate_id>/<attachment_id>
```

Each object keeps the original file name and content type, and carries the
Kombo IDs as object metadata: `kombo-attachment-id`, `kombo-candidate-id`,
`kombo-integration-id`, and `kombo-application-id` when the file belongs to an
application.

### Deletions

When an attachment or its candidate is deleted in the ATS, or the candidate
falls out of your [upstream filter](/ats/features/upstream-filtering), the
attachment gets a `remote_deleted_at` (pass `include_deleted=true` to see it).
14 days later Kombo removes the file from your bucket and anonymizes the
attachment. Deleting an integration removes its whole folder after the same 14
days.

### Supported storage

Any S3-compatible storage works: Amazon S3, Cloudflare R2, DigitalOcean Spaces,
MinIO and others. Let us know if you need a different provider.

<CardGroup cols={2}>
  <Card title="Get attachments" icon="paperclip" href="/ats/v1/get-attachments">
    The endpoint reference for synced attachments.
  </Card>

  <Card title="Reading applicants" icon="user-magnifying-glass" href="/ats/implementation-guide/reading-applicants">
    Read candidates, applications and their files for AI screening.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.