🚀 Simplify your work by integrating Haufe Copilot via API
Guides

Use Your Own Documents

Learn how to upload text documents and integrate them to enable your assistant to deliver context-aware responses based on the content of your files.

You can upload files so the Copilot can use them as additional context when generating answers. This guide walks you through the full lifecycle of a file.

Supported File Types

TypeMIME Type
PDFapplication/pdf
Word (DOCX)application/vnd.openxmlformats-officedocument.wordprocessingml.document
Excel (XLSX)application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
CSVtext/csv
Plain Texttext/plain

Maximum file size: 10 MB.

Get a Signed Upload URL

Request a pre-signed URL to upload your file. The API returns a file_id and a file_url you can use to PUT the file content.

GET https://api.haufe.ai/agents/v1/files/signed-url

Query Parameters

ParameterTypeRequiredDescription
filenamestringYesName of the file including extension
persistbooleanNoWhen true (default), the file is stored permanently. When false, the file is automatically deleted after 24 hours.
Get a signed upload URL
curl --request GET \
  --url "https://api.haufe.ai/agents/v1/files/signed-url?filename=report.pdf&persist=true" \
  --header 'api-key: <API_KEY>' \
  --header 'user-id: <USER_ID>'

Response

{
  "file_url": "https://example-bucket.s3.amazonaws.com/example-file.txt",
  "expires_in": 600,
  "file_id": "123e4567-e89b-12d3-a456-426614174000",
  "file_limits": {
    "max_size": 10485760,
    "allowed_types": [
      "text/csv",
      "text/plain",
      "application/pdf",
      "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    ]
  }
}
info

The signed URL expires after the time indicated by expires_in (typically 600 seconds). Request a new URL if the upload is not completed in time.

Upload the File

Use the returned file_url to upload the file content via a PUT request.

Upload the file
curl --request PUT \
  --url "<FILE_URL>" \
  --header 'Content-Type: application/pdf' \
  --data-binary @report.pdf
warning

Make sure the Content-Type header matches one of the allowed_types returned in the signed URL response. Uploading a file with an unsupported type will result in a processing error.

Check Processing Status

After uploading, the file is processed asynchronously. Check the status to confirm it is ready to use.

GET https://api.haufe.ai/agents/v1/files/{file_id}/status

Check processing status
curl --request GET \
  --url "https://api.haufe.ai/agents/v1/files/<FILE_ID>/status" \
  --header 'api-key: <API_KEY>' \
  --header 'user-id: <USER_ID>'

Response

{
  "processing_status": "PROCESSED",
  "warnings": {
    "length": false,
    "infected": false,
    "empty": false
  }
}
info

Poll this endpoint until processing_status is PROCESSED or FAILED before referencing the file in messages. On FAILED, inspect the processing_steps and validation_steps arrays in the response to identify the cause. Even on PROCESSED, check the warnings object — empty: true means no text could be extracted.

Verify the Upload

List All Files

Retrieve a paginated list of all persisted files associated with your user. Only files uploaded with persist=true are included; temporary files (persist=false) do not appear in this list.

GET https://api.haufe.ai/agents/v1/files

Query Parameters

ParameterTypeRequiredDescription
pageintegerNoPage number (1-based). Defaults to 1
limitintegerNoNumber of files per page (1–100). Defaults to 30
List all files
curl --request GET \
  --url "https://api.haufe.ai/agents/v1/files?page=1&limit=30" \
  --header 'api-key: <API_KEY>' \
  --header 'user-id: <USER_ID>'
Response
{
  "files": [
    {
      "file_id": "9c3e00fe-1b42-413a-bf44-39ad9491ad86",
      "file_name": "report.pdf"
    },
    {
      "file_id": "cbfe557e-144e-43f3-823f-d72be00084a2",
      "file_name": "expenses.xlsx"
    }
  ],
  "page": 1,
  "limit": 30,
  "total": 2
}

Retrieve File Content

Fetch the extracted text content of a specific file to confirm it was processed correctly.

GET https://api.haufe.ai/agents/v1/files/{file_id}

Retrieve file content
curl --request GET \
  --url "https://api.haufe.ai/agents/v1/files/<FILE_ID>" \
  --header 'api-key: <API_KEY>' \
  --header 'user-id: <USER_ID>'

The endpoint returns the extracted text content of the file as a plain string.

Use with Chat Completions

Once a file has been successfully processed, you can reference it in a single stateless request. Add the file as an attachments entry on a user message:

warning

The top-level user_id must match the user-id header you used during file upload. Do not set user_id on the attachment itself. At most 1 attachment per message is allowed.

Chat completions with attachment
curl --request POST \
  --url https://api.haufe.ai/agents/v1/chat/completions \
  --header 'content-type: application/json' \
  --header 'api-key: <API_KEY>' \
  --data '{
    "assistant_id": "<ASSISTANT_ID>",
    "user_id": "<USER_ID>",
    "messages": [
      {
        "role": "user",
        "content": "Summarize the attached report.",
        "attachments": [
          {
            "file_id": "<FILE_ID>"
          }
        ]
      }
    ],
    "meta_data": {
      "user_data": {
        "licence": "<LICENSE_ID>"
      }
    }
  }'

Use with Threads

For conversational workflows, create a thread, post a message with the attachment, and run the thread to get a response.

warning

The user_id on the thread must match the user-id header you used during file upload. Do not set user_id on the attachment itself. At most 1 attachment per message is allowed.

1. Create a thread:

Create a thread with user_id
curl --request POST \
  --url https://api.haufe.ai/agents/v1/threads \
  --header 'content-type: application/json' \
  --header 'api-key: <API_KEY>' \
  --data '{
    "assistant_id": "<ASSISTANT_ID>",
    "user_id": "<USER_ID>"
  }'

2. Post a message with the attachment:

Thread message with attachment
curl --request POST \
  --url "https://api.haufe.ai/agents/v1/threads/<THREAD_ID>/messages" \
  --header 'content-type: application/json' \
  --header 'api-key: <API_KEY>' \
  --data '{
    "role": "user",
    "content": "Summarize the attached report.",
    "attachments": [
      {
        "file_id": "<FILE_ID>"
      }
    ]
  }'

3. Run the thread:

Run the thread
curl --request POST \
  --url "https://api.haufe.ai/agents/v1/threads/<THREAD_ID>/run" \
  --header 'content-type: application/json' \
  --header 'api-key: <API_KEY>' \
  --data '{
    "meta_data": {
      "user_data": {
        "licence": "<LICENSE_ID>"
      }
    }
  }'

Delete a File

Remove a file that is no longer needed. Once deleted, the file cannot be referenced in new messages and is no longer used for response generation in threads that previously contained it.

DELETE https://api.haufe.ai/agents/v1/files/{file_id}

Delete a file
curl --request DELETE \
  --url "https://api.haufe.ai/agents/v1/files/<FILE_ID>" \
  --header 'api-key: <API_KEY>' \
  --header 'user-id: <USER_ID>'

Returns 204 No Content on success with an empty response body.

Next Steps

On this page