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

# Get Upload URL

> Get a presigned URL for direct file upload to cloud storage.

## Authentication & Scope

Requires authentication. No specific ability required.

## Overview

Before uploading documents to Raydocs, you need to obtain a signed URL that allows direct upload to cloud storage. This two-step process:

1. **Get signed URL** - This endpoint returns a presigned S3 URL
2. **Upload file** - PUT your file directly to the URL (no auth header needed)

<Tip>
  This approach enables efficient, direct-to-storage uploads without proxying through the API server.
</Tip>

## Request

```http theme={null}
POST /vapor/signed-storage-url HTTP/1.1
Host: api.raydocs.com
Authorization: Bearer <token>
Content-Type: application/json

{
  "content_type": "application/pdf",
  "visibility": "private"
}
```

### Body Parameters

| Parameter      | Type   | Required | Description                                                          |
| -------------- | ------ | -------- | -------------------------------------------------------------------- |
| `content_type` | string | Yes      | MIME type of the file (`application/pdf`, `image/png`, `image/jpeg`) |
| `visibility`   | string | No       | Storage visibility (default: `private`)                              |

### Supported File Types

| Type | Content-Type      |
| ---- | ----------------- |
| PDF  | `application/pdf` |
| PNG  | `image/png`       |
| JPEG | `image/jpeg`      |

## Response

`200 OK` – Signed URL details.

```json theme={null}
{
  "url": "https://s3.amazonaws.com/bucket/tmp/abc123-def456-ghi789...",
  "key": "tmp/abc123-def456-ghi789-invoice.pdf",
  "headers": {}
}
```

### Response Fields

| Field     | Type   | Description                                     |
| --------- | ------ | ----------------------------------------------- |
| `url`     | string | Presigned S3 URL for file upload                |
| `key`     | string | File key to use in subsequent API calls         |
| `headers` | object | Additional headers to include in upload request |

## Upload the File

After receiving the signed URL, upload your file directly:

```http theme={null}
PUT https://s3.amazonaws.com/bucket/tmp/abc123... HTTP/1.1
Content-Type: application/pdf

<binary file data>
```

<Warning>
  Do **not** include the `Authorization` header when uploading to the signed URL. The signature in the URL provides authentication.
</Warning>

## Complete Example

<CodeGroup>
  ```python Python theme={null}
  import requests

  # Step 1: Get signed URL
  api_url = "https://api.raydocs.com"
  headers = {"Authorization": "Bearer <token>"}

  response = requests.post(
      f"{api_url}/vapor/signed-storage-url",
      headers=headers,
      json={
          "content_type": "application/pdf",
          "visibility": "private"
      }
  )
  upload_data = response.json()

  # Step 2: Upload file to S3
  with open("invoice.pdf", "rb") as f:
      requests.put(
          upload_data["url"],
          data=f,
          headers={"Content-Type": "application/pdf"}
      )

  # Step 3: Use the key in batch create
  file_key = upload_data["key"]
  print(f"File uploaded with key: {file_key}")
  ```

  ```javascript Node.js theme={null}
  const axios = require('axios');
  const fs = require('fs');

  async function uploadFile(filePath) {
    const apiUrl = 'https://api.raydocs.com';
    const token = '<token>';

    // Step 1: Get signed URL
    const { data: uploadData } = await axios.post(
      `${apiUrl}/vapor/signed-storage-url`,
      {
        content_type: 'application/pdf',
        visibility: 'private'
      },
      {
        headers: { Authorization: `Bearer ${token}` }
      }
    );

    // Step 2: Upload file to S3
    const fileBuffer = fs.readFileSync(filePath);
    await axios.put(uploadData.url, fileBuffer, {
      headers: { 'Content-Type': 'application/pdf' }
    });

    // Step 3: Return the key for use in batch create
    return uploadData.key;
  }
  ```

  ```bash cURL theme={null}
  # Step 1: Get signed URL
  UPLOAD_DATA=$(curl -s -X POST "https://api.raydocs.com/vapor/signed-storage-url" \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -d '{"content_type": "application/pdf", "visibility": "private"}')

  UPLOAD_URL=$(echo $UPLOAD_DATA | jq -r '.url')
  FILE_KEY=$(echo $UPLOAD_DATA | jq -r '.key')

  # Step 2: Upload file to S3
  curl -X PUT "$UPLOAD_URL" \
    -H "Content-Type: application/pdf" \
    --data-binary @invoice.pdf

  echo "File key: $FILE_KEY"
  ```
</CodeGroup>

## Next Steps

After uploading files, use the file keys to create sessions:

<CardGroup cols={2}>
  <Card title="Batch Create Sessions" icon="layer-group" href="/api-reference/sessions/batch-create">
    Create sessions with auto-extract from uploaded files
  </Card>

  <Card title="API Cookbook" icon="book" href="/guides/api-cookbook">
    Complete end-to-end example
  </Card>
</CardGroup>


## OpenAPI

````yaml post /vapor/signed-storage-url
openapi: 3.0.1
info:
  title: Raydocs API
  description: REST API for document extraction with AI-powered data parsing
  version: 1.0.0
servers:
  - url: https://api.raydocs.com
security:
  - bearerAuth: []
tags:
  - name: Workspaces
    description: Create and manage workspaces.
  - name: Workspace Users
    description: Manage users within a workspace.
  - name: Extraction Templates
    description: Define extraction schemas and settings.
  - name: Extraction Sessions
    description: Manage extraction jobs and documents.
  - name: Batch Operations
    description: Bulk operations on sessions.
  - name: Documents
    description: Upload and manage source documents.
  - name: Workflows
    description: Discover workflow runs and read their public outputs.
  - name: Results
    description: Access extraction results.
paths:
  /vapor/signed-storage-url:
    post:
      tags:
        - Documents
      summary: Get Signed Upload URL
      description: >-
        Get a presigned S3 URL for direct file upload. Upload your file to the
        returned URL, then use the key in batch create.
      operationId: getSignedUploadUrl
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - content_type
              properties:
                content_type:
                  type: string
                  description: MIME type of the file
                  example: application/pdf
                visibility:
                  type: string
                  enum:
                    - private
                    - public
                  default: private
      responses:
        '200':
          description: Signed URL generated
          content:
            application/json:
              schema:
                type: object
                properties:
                  url:
                    type: string
                    format: uri
                    description: Presigned S3 URL for file upload (PUT)
                  key:
                    type: string
                    description: File key to use in batch create
                  headers:
                    type: object
                    description: Additional headers to include in upload request
        '403':
          description: Forbidden
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >
        Personal Access Token created from the Raydocs dashboard.

        Include in the Authorization header: `Bearer <your_token>`

        See [API Keys](/api-reference/api-keys) for token creation and
        management.

````