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

# Get Upload URL

Use this API to mint a short-lived signed URL for uploading a file up to 30 MB. Use it for the by-reference ingestion flow: get the URL, PUT the raw file bytes to it with a `Content-Type` header matching the `mimeType` you sent, then pass the returned `fileRef` to [Ingest Knowledge](/docs/api-reference/rest-apis/v2/memory/knowledge/ingest).

# Endpoint

`POST https://api.velt.dev/v2/memory/knowledge/upload-url`

Rate limit: 100 requests per minute per API key.

# Headers

<ParamField header="x-velt-api-key" type="string" required>
  Your API key.
</ParamField>

<ParamField header="x-velt-auth-token" type="string" required>
  Your [Auth Token](/docs/security/auth-tokens).
</ParamField>

# Body

#### Params

<ParamField body="data" type="object" required>
  <Expandable title="properties">
    <ParamField body="mimeType" type="string" required>
      One of the supported types: `application/pdf`, `text/csv`, `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`, or `text/plain`.
    </ParamField>

    <ParamField body="fileSize" type="integer" required>
      File size in bytes. Maximum 30 MB (31,457,280 bytes).
    </ParamField>

    <ParamField body="fileName" type="string">
      1 to 255 characters.
    </ParamField>

    <ParamField body="organizationId" type="string">
      Scope the source to one organization.
    </ParamField>

    <ParamField body="documentId" type="string">
      Scope the source to one document. Requires `organizationId`.
    </ParamField>
  </Expandable>
</ParamField>

<Note>
  A workspace can hold at most 50 outstanding upload URLs. Past that, this call returns `RESOURCE_EXHAUSTED`. Each URL holds a slot until you ingest its `fileRef`, so request URLs only for files you are about to upload. This endpoint also rejects unrecognized fields, so a misspelled key returns `INVALID_ARGUMENT`.
</Note>

## **Example Requests**

#### Request an upload URL for a PDF

```JSON theme={null}
{
  "data": {
    "mimeType": "application/pdf",
    "fileSize": 8421376,
    "fileName": "brand-guidelines.pdf"
  }
}
```

# Response

Upload the raw file bytes to `uploadUrl` with an HTTP `PUT`. Set the `Content-Type` header to the same `mimeType` you passed to this endpoint. The signed URL is bound to that value, so a `PUT` with a missing or different `Content-Type` is rejected before it reaches Velt.

Then pass `fileRef` to Ingest Knowledge, repeating the same `organizationId` and `documentId` you sent here. A scope mismatch returns `PERMISSION_DENIED`. The URL expires at `expiresAt` (epoch ms), 15 minutes after it is minted.

#### Success Response

```JSON theme={null}
{
  "result": {
    "uploadUrl": "https://storage.googleapis.com/...signed...",
    "fileRef": "gs://bucket/path/original.pdf",
    "expiresAt": 1731432600000
  }
}
```

#### Failure Response

```JSON theme={null}
{
  "error": {
    "message": "ERROR_MESSAGE",
    "status": "INVALID_ARGUMENT"
  }
}
```

<ResponseExample>
  ```js theme={null}
  {
    "result": {
      "uploadUrl": "https://storage.googleapis.com/...signed...",
      "fileRef": "gs://bucket/path/original.pdf",
      "expiresAt": 1731432600000
    }
  }
  ```
</ResponseExample>
