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

# Upload a File (v3)

> Upload a file using the new v3 API endpoint

## File Upload Process

The v3 file upload API provides a secure two-step process for uploading files to Tela's storage:

1. **Request an upload URL** - Call the `/v3/files` endpoint to get a temporary upload URL
2. **Upload your file** - Use the returned upload URL to upload your file content directly

## Step 1: Get Upload URL

First, request a temporary upload URL by providing the filename:

<CodeGroup>
  ```typescript TypeScript theme={null}
  const response = await fetch('https://api.tela.com/v3/files', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_TOKEN',
      'x-compatibility-date': '2025-07-23',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      fileName: 'test.txt'
    })
  })

  const { id, uploadUrl } = await response.json()
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
    'https://api.tela.com/v3/files',
    headers={
      'Authorization': 'Bearer YOUR_API_TOKEN',
      'x-compatibility-date': '2025-07-23'
    },
    json={
      'fileName': 'test.txt'
    }
  )

  data = response.json()
  file_id = data['id']
  upload_url = data['uploadUrl']
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.tela.com/v3/files \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "x-compatibility-date: 2025-07-23" \
    -H "Content-Type: application/json" \
    -d '{"fileName": "test.txt"}'
  ```
</CodeGroup>

The response will include:

* `id`: The unique identifier for your file
* `uploadUrl`: A temporary URL to upload your file content

## Step 2: Upload File Content

Use the `uploadUrl` from the previous step to upload your file content:

<CodeGroup>
  ```typescript TypeScript theme={null}
  // For browser environments
  const file = new File(['Hello, world!'], 'test.txt', { type: 'text/plain' })

  await fetch(uploadUrl, {
    method: 'PUT',
    headers: {
      'Content-Type': file.type // Explicitly set Content-Type
    },
    body: file
  })

  // For Node.js environments
  const blob = new Blob(['Hello, world!'], { type: 'text/plain' })

  await fetch(uploadUrl, {
    method: 'PUT',
    headers: {
      'Content-Type': 'text/plain'
    },
    body: blob
  })
  ```

  ```python Python theme={null}
  # For file upload
  with open('test.txt', 'rb') as file:
      requests.put(
          upload_url,
          headers={
              'Content-Type': 'text/plain'  # Explicitly set Content-Type
          },
          data=file
      )

  # For in-memory content
  import io
  file_content = b'Hello, world!'
  file_like = io.BytesIO(file_content)

  requests.put(
      upload_url,
      headers={
          'Content-Type': 'text/plain'
      },
      data=file_like
  )
  ```

  ```bash cURL theme={null}
  # Upload a file
  curl -X PUT "UPLOAD_URL_FROM_PREVIOUS_STEP" \
    -H "Content-Type: text/plain" \
    --data-binary @test.txt

  # Or upload binary content
  curl -X PUT "UPLOAD_URL_FROM_PREVIOUS_STEP" \
    -H "Content-Type: application/pdf" \
    --data-binary @document.pdf
  ```
</CodeGroup>

<Note>
  The upload URL is temporary and will expire after a short period. Make sure to upload your file promptly after receiving the URL.
</Note>

## Using the File ID

After successfully uploading your file, you can use the UUID returned in Step 1 to reference the file in other API endpoints:

<CodeGroup>
  ```typescript TypeScript theme={null}
  // Retrieve file metadata
  const fileData = await fetch(`https://api.tela.com/v3/files/${id}`, {
    headers: {
      'Authorization': 'Bearer YOUR_API_TOKEN',
      'x-compatibility-date': '2025-07-23'
    }
  }).then(res => res.json())
  ```

  ```python Python theme={null}
  # Retrieve file metadata
  response = requests.get(
    f'https://api.tela.com/v3/files/{file_id}',
    headers={
      'Authorization': 'Bearer YOUR_API_TOKEN',
      'x-compatibility-date': '2025-07-23'
    }
  )
  file_data = response.json()
  ```
</CodeGroup>

## Request Headers

### Required Headers

* `Authorization`: Bearer token for authentication
* `x-compatibility-date`: API version compatibility date (e.g., `2025-07-23`)

### Content Types

When uploading the file content in Step 2, set the appropriate `Content-Type` header:

* `text/plain` for text files
* `application/json` for JSON files
* `image/png`, `image/jpeg` for images
* `application/pdf` for PDF files
* And other standard MIME types as needed

<Warning>
  While some HTTP clients may attempt to infer the Content-Type from the file, it's best practice to explicitly set the Content-Type header to ensure proper file handling. This is especially important for binary files and when the file extension doesn't match the actual content type.
</Warning>

## Complete Example

Here's a complete example showing the entire file upload process:

<CodeGroup>
  ```typescript TypeScript theme={null}
  async function uploadFile(file: File) {
    // Step 1: Get upload URL
    const response = await fetch('https://api.tela.com/v3/files', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_API_TOKEN',
        'x-compatibility-date': '2025-07-23',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ fileName: file.name })
    })

    const { id, uploadUrl } = await response.json()
    console.log(`File ID: ${id}`) // e.g., 3fa85f64-5717-4562-b3fc-2c963f66afa6

    // Step 2: Upload file content
    await fetch(uploadUrl, {
      method: 'PUT',
      headers: {
        'Content-Type': file.type || 'application/octet-stream'
      },
      body: file
    })

    console.log('File uploaded successfully!')
    return id
  }

  // Usage - Browser
  const file = new File(['Hello, world!'], 'test.txt', { type: 'text/plain' })
  const fileId = await uploadFile(file)

  // Usage - From file input
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement
  if (fileInput.files?.[0]) {
    const fileId = await uploadFile(fileInput.files[0])
  }
  ```

  ```python Python theme={null}
  import requests
  import mimetypes

  def upload_file(file_path):
      # Step 1: Get upload URL
      file_name = file_path.split('/')[-1]
      response = requests.post(
          'https://api.tela.com/v3/files',
          headers={
              'Authorization': 'Bearer YOUR_API_TOKEN',
              'x-compatibility-date': '2025-07-23'
          },
          json={'fileName': file_name}
      )
      
      data = response.json()
      file_id = data['id']  # e.g., 3fa85f64-5717-4562-b3fc-2c963f66afa6
      upload_url = data['uploadUrl']
      print(f'File ID: {file_id}')
      
      # Step 2: Upload file content
      content_type, _ = mimetypes.guess_type(file_path)
      if not content_type:
          content_type = 'application/octet-stream'
      
      with open(file_path, 'rb') as file:
          requests.put(
              upload_url,
              headers={'Content-Type': content_type},
              data=file
          )
      
      print('File uploaded successfully!')
      return file_id

  # Usage
  file_id = upload_file('test.txt')

  # Or with in-memory content
  import io
  def upload_bytes(file_name, content_bytes, content_type='application/octet-stream'):
      # ... (Step 1 same as above)
      
      requests.put(
          upload_url,
          headers={'Content-Type': content_type},
          data=io.BytesIO(content_bytes)
      )
      return file_id
  ```
</CodeGroup>

## Using Uploaded Files in Completions

After uploading files, you can use them in your canvas completions with the `vault://` URL scheme:

<CodeGroup>
  ```typescript TypeScript theme={null}
  // Using a single uploaded file
  const completion = await tela.completions.create({
    canvasId: process.env.TELA_CANVAS_ID,
    variables: {
      document: { file_url: `vault://3fa85f64-5717-4562-b3fc-2c963f66afa6` }
    }
  })

  // Using multiple uploaded files
  const completion2 = await tela.completions.create({
    canvasId: process.env.TELA_CANVAS_ID,
    variables: {
      documents: [
        { file_url: `vault://3fa85f64-5717-4562-b3fc-2c963f66afa6` },
        { file_url: `vault://550e8400-e29b-41d4-a716-446655440000` },
        { file_url: 'https://example.com/public-file.pdf' } // Mix vault and public URLs
      ]
    }
  })
  ```

  ```python Python theme={null}
  # Using a single uploaded file
  completion = client.completions.create(
      canvas_id=TELA_CANVAS_ID,
      variables={
          "document": {"file_url": f"vault://3fa85f64-5717-4562-b3fc-2c963f66afa6"}
      }
  )

  # Using multiple uploaded files
  completion2 = client.completions.create(
      canvas_id=TELA_CANVAS_ID,
      variables={
          "documents": [
              {"file_url": f"vault://3fa85f64-5717-4562-b3fc-2c963f66afa6"},
              {"file_url": f"vault://550e8400-e29b-41d4-a716-446655440000"},
              {"file_url": "https://example.com/public-file.pdf"}  # Mix vault and public URLs
          ]
      }
  )
  ```
</CodeGroup>

<Note>
  The `vault://` URL scheme provides secure access to your uploaded files. These URLs can only be accessed within your workspace context and are ideal for processing sensitive documents.
</Note>


## OpenAPI

````yaml POST /v3/files
openapi: 3.0.1
info:
  title: Tela API
  license:
    name: MIT
  version: 1.0.0
servers:
  - url: https://api.tela.com
security: []
paths:
  /v3/files:
    post:
      description: Create a temporary upload URL for file upload (v3 API)
      parameters:
        - name: x-compatibility-date
          in: header
          required: true
          schema:
            type: string
            format: date
          description: API version compatibility date (e.g., 2025-07-23)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                fileName:
                  type: string
                  description: The name of the file to upload
              required:
                - fileName
              example:
                fileName: test.txt
      responses:
        '200':
          description: Successful creation of upload URL
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: Unique identifier for the uploaded file
                  uploadUrl:
                    type: string
                    description: Temporary URL to upload the file content
                required:
                  - id
                  - uploadUrl
                example:
                  id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                  uploadUrl: https://file-upload-temporary.example.com/upload?token=xyz
        '400':
          description: Bad request - Invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized - Invalid or missing bearer token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearerAuth: []
components:
  schemas:
    Error: {}
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT or UUID

````