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

# Upload Large Media Files

> For file uploads greater than 10 MB, obtain a presigned URL to upload a file

export const HeaderAPI = ({noProfileKey, profileKeyRequired}) => <>
    <ParamField header="Authorization" type="string" required>
      <a href="/apis/overview#authorization">API Key</a> of the Primary Profile.
      <br />
      <br />
      Format: <code>Authorization: Bearer API_KEY</code>
    </ParamField>
    {!noProfileKey && (profileKeyRequired ? <ParamField header="Profile-Key" type="string" required>
          <a href="/apis/overview#profile-key-format">Profile Key</a> of a User Profile.
          <br />
          <br />
          Format: <code>Profile-Key: PROFILE_KEY</code>
        </ParamField> : <ParamField header="Profile-Key" type="string">
          <a href="/apis/overview#profile-key-format">Profile Key</a> of a User Profile.
          <br />
          <br />
          Format: <code>Profile-Key: PROFILE_KEY</code>
        </ParamField>)}
  </>;

export const PlansAvailable = ({plans = [], maxPackRequired}) => {
  let displayPlans = plans;
  if (plans && plans.length === 1) {
    const lowerCasePlan = plans[0].toLowerCase();
    if (lowerCasePlan === "basic") {
      displayPlans = ["Basic", "Premium", "Business", "Enterprise"];
    } else if (lowerCasePlan === "business") {
      displayPlans = ["Business", "Enterprise"];
    } else if (lowerCasePlan === "premium") {
      displayPlans = ["Premium", "Business", "Enterprise"];
    }
  }
  return <Note>
Available on {displayPlans.length === 1 ? "the " : ""}
{displayPlans.join(", ").replace(/\b\w/g, l => l.toUpperCase())}{" "}
{displayPlans.length > 1 ? "plans" : "plan"}.

{maxPackRequired && <span onClick={() => window.open('https://www.ayrshare.com/docs/additional/maxpack', '_self')} className="flex items-center mt-2 cursor-pointer">
 <span className="px-1.5 py-0.5 rounded text-sm" style={{
    backgroundColor: '#C264B6',
    color: 'white',
    fontSize: '12px'
  }}>
   Max Pack required
 </span>
</span>}
</Note>;
};

<PlansAvailable plans={["premium"]} maxPackRequired={false} />

For file uploads greater than 10 MB, obtain a presigned URL to upload a file.

<ul class="custom-bullets">
  <li>Maximum file upload size 5 GB.</li>
  <li>Upload presigned URL valid for 30 minutes after being generated.</li>

  <li>
    Access URL available for 30 days after uploaded. All published posts are unaffected at the
    social networks. Scheduled posts beyond that time frame will result in errors at time of
    publishing.
  </li>
</ul>

<Tip>If you already have your media accessible by an external URL, such as an S3 bucket, you can skip uploading the files to Ayrshare. Just POST to the `/post` endpoint with your externally accessible URL in the `mediaURLs` body parameter and your file will automatically be uploaded.</Tip>

## Header Parameters

<HeaderAPI noProfileKey={true} />

## Query Parameters

<ParamField query="fileName" type="string">
  If the contentType is not present, then a full file name with extension is required.

  Name of the file to be uploaded. Must include an extension such as .png, .jpg, .mov, .mp4, etc.
</ParamField>

<ParamField query="contentType" type="string">
  The content-type of the media being uploaded. Valid formats include: `mp4`, `mov`, `png`, `jpg`, or `jpeg`.

  For example, if the file is a Quicktime .mov file, then the contentType should be `mov`.

  If not present, application/octet-stream will be used.
</ParamField>

<RequestExample>
  ```bash cURL theme={"system"}
  curl \
  -H "Authorization: Bearer [API Key]" \
  -X GET https://api.ayrshare.com/api/media/uploadUrl?fileName=test.mov&contentType=mov
  ```

  ```javascript JavaScript theme={"system"}
  const API_KEY = "Your API Key";

  fetch("https://api.ayrshare.com/api/media/uploadUrl?fileName=test.mov&contentType=mov", {
        method: "GET",
        headers: {
          "Authorization": `Bearer ${API_KEY}`
        }
      })
        .then((res) => res.json())
        .then((json) => console.log(json))
        .catch(console.error);
  ```

  ```python Python theme={"system"}
  import requests

  headers = {'Authorization': 'Bearer [API_KEY]'}

  r = requests.get('https://api.ayrshare.com/api/media/uploadUrl?fileName=test.mov&contentType=mov', headers=headers)

  print(r.json())
  ```

  ```php PHP theme={"system"}
  <?php
  require 'vendor/autoload.php';    // Composer auto-loader using Guzzle. See .../guzzlephp.org/en/stable/overview.html

  $client = new GuzzleHttp\Client();
  $res = $client->request(
      'GET',
      'https://api.ayrshare.com/api/media/uploadUrl?fileName=test.mov&contentType=mov',
      [
          'headers' => [
              'Content-Type'      => 'application/json',
              'Authorization'     => 'Bearer API_KEY'
          ]
      ]
  );

  echo json_encode(json_decode($res->getBody()), JSON_PRETTY_PRINT);
  ```

  ```csharp C# theme={"system"}
  using System;
  using System.Net.Http;
  using System.Threading.Tasks;
  using System.Web;

  namespace MediaUploadUrlGETRequest_csharp
  {
      class MediaUploadUrl
      {
          static async Task Main(string[] args)
          {
              string API_KEY = "API_KEY";
              string baseUrl = "https://api.ayrshare.com/api/media/uploadUrl";

              // Build URL with query parameters
              var uriBuilder = new UriBuilder(baseUrl);
              var query = HttpUtility.ParseQueryString(string.Empty);
              query["fileName"] = "test.mov";
              query["contentType"] = "mov";
              uriBuilder.Query = query.ToString();

              using (var client = new HttpClient())
              {
                  client.DefaultRequestHeaders.Add("Authorization", "Bearer " + API_KEY);

                  try
                  {
                      HttpResponseMessage response = await client.GetAsync(uriBuilder.Uri);
                      response.EnsureSuccessStatusCode();
                      string responseBody = await response.Content.ReadAsStringAsync();
                      Console.WriteLine(responseBody);
                  }
                  catch (HttpRequestException e)
                  {
                      Console.WriteLine($"Error: {e.Message}");
                  }
              }
          }
      }
  }
  ```
</RequestExample>

## Response Details

<ul class="custom-bullets">
  <li>`accessUrl` is the URL to access the media file after upload.</li>

  <li>
    `contentType` is the content-type set for the media being upload. Use this in the *Content-Type*
    header when uploading the media.
  </li>

  <li>`uploadUrl` is the URL used to *PUT* the media file. Please see below.</li>
</ul>

### Additional Endpoint Examples

The process to upload larger files:

<ul class="custom-bullets">
  <li>
    Obtain an `uploadURL` and `accessURL` via the `/media/uploadUrl` endpoint. Please see above.
  </li>

  <li>Upload the file via a *PUT* with *Content-Type* set to the returned `contentType`.</li>
  <li>Upload the media by using the `--upload-file` with a media file and the `uploadUrl`.</li>
  <li>On a successful upload, a `200` response will be returned.</li>

  <li>
    After uploading the media file, POST to the `/post` endpoint with the `accessUrl` in the
    `mediaUrls` body parameter.
  </li>

  <li>
    **The presigned upload URL may only be uploaded to once**. If you sent a bad file you must
    create a new upload URL. No error response will occur if the file is not successfully uploaded.
    See below of [verifying the URL exists](/apis/media/verify-media-url).
  </li>
</ul>

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X PUT \
  -H 'Content-Type: video/mp4' \
  --upload-file LOCAL_FILE_PATH uploadUrl
  ```

  ```javascript JavaScript theme={"system"}
  const fs = require("fs").promises;
  const uploadFileToSignedUrl = async (signedUrl, filePath) => {
      try {
        const fileBuffer = await fs.readFile(filePath);
        const response = await fetch(signedUrl, {
          method: "PUT",
          body: fileBuffer,
          headers: {
            "Content-Type": "video/mp4"
          }
        });

        if (response.ok) {
          console.log("File upload successful:", response.status);
        } else {
          console.error("File upload failed:", response.status);
        }
      } catch (error) {
        console.error("Error uploading file:", error);
      }
  };

  // Use the signed URL generated from the previous step
  const signedUrl = "SIGNED_URL";
  const filePath = "LOCAL_FILE_PATH";

  uploadFileToSignedUrl(signedUrl, filePath);
  ```

  ```python Python theme={"system"}
  import requests

  def upload_file_to_signed_url(signed_url, file_path):
      try:
          with open(file_path, 'rb') as file:
              response = requests.put(signed_url, data=file, headers={'Content-Type': 'video/mp4'})

          if response.ok:
              print("File upload successful:", response.status_code)
          else:
              print("File upload failed:", response.status_code)
      except Exception as error:
          print("Error uploading file:", error)

  # Use the signed URL generated from the previous step
  signed_url = "SIGNED_URL"
  file_path = "LOCAL_FILE_PATH"

  upload_file_to_signed_url(signed_url, file_path)
  ```

  ```php PHP theme={"system"}
  <?php

  function uploadFileToSignedUrl($signedUrl, $filePath) {
      try {
          $fileHandle = fopen($filePath, 'rb');
          if ($fileHandle === false) {
              throw new Exception('Cannot open the file');
          }

          $ch = curl_init($signedUrl);

          curl_setopt($ch, CURLOPT_PUT, true);
          curl_setopt($ch, CURLOPT_INFILE, $fileHandle);
          curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePath));
          curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: video/mp4'));
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

          $response = curl_exec($ch);
          $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

          if ($httpCode == 200) {
              echo "File upload successful: " . $httpCode;
          } else {
              echo "File upload failed: " . $httpCode;
          }

          fclose($fileHandle);
          curl_close($ch);
      } catch (Exception $e) {
          echo "Error uploading file: " . $e->getMessage();
      }
  }

  // Use the signed URL generated from the previous step
  $signedUrl = "SIGNED_URL";
  $filePath = "LOCAL_FILE_PATH";

  uploadFileToSignedUrl($signedUrl, $filePath);
  ?>

  ```

  ```csharp C# theme={"system"}
  using System;
  using System.Net.Http;
  using System.IO;
  using System.Threading.Tasks;

  class Program
  {
      static async Task Main(string[] args)
      {
          string signedUrl = "SIGNED_URL"; // Replace with your signed URL
          string filePath = "LOCAL_FILE_PATH"; // Replace with your file path

          try
          {
              await UploadFileToSignedUrl(signedUrl, filePath);
          }
          catch (Exception ex)
          {
              Console.WriteLine("Error uploading file: " + ex.Message);
          }
      }

      static async Task UploadFileToSignedUrl(string signedUrl, string filePath)
      {
          using (var client = new HttpClient())
          using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
          using (var content = new StreamContent(fileStream))
          {
              content.Headers.Add("Content-Type", "video/mp4");

              var response = await client.PutAsync(signedUrl, content);

              if (response.IsSuccessStatusCode)
              {
                  Console.WriteLine("File upload successful: " + response.StatusCode);
              }
              else
              {
                  Console.WriteLine("File upload failed: " + response.StatusCode);
              }
          }
      }
  }

  ```

  ```java Java theme={"system"}
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;
  import java.net.http.HttpRequest.BodyPublishers;
  import java.nio.file.Path;
  import java.io.IOException;
  import java.nio.file.Files;

  public class FileUploader {

      public static void main(String[] args) {
          String signedUrl = "SIGNED_URL"; // Replace with your signed URL
          String filePath = "LOCAL_FILE_PATH"; // Replace with your file path

          try {
              uploadFileToSignedUrl(signedUrl, filePath);
          } catch (IOException | InterruptedException e) {
              System.out.println("Error uploading file: " + e.getMessage());
          }
      }

      private static void uploadFileToSignedUrl(String signedUrl, String filePath) throws IOException, InterruptedException {
          HttpClient client = HttpClient.newHttpClient();
          HttpRequest request = HttpRequest.newBuilder()
                  .uri(URI.create(signedUrl))
                  .header("Content-Type", "image/jpg")
                  .PUT(BodyPublishers.ofFile(Path.of(filePath)))
                  .build();

          HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

          if (response.statusCode() == 200) {
              System.out.println("File upload successful: " + response.statusCode());
          } else {
              System.out.println("File upload failed: " + response.statusCode());
          }
      }
  }

  ```
</CodeGroup>

Please be sure that the `contentType` set when creating the `uploadUrl` matches the Content-Type and the file type when PUTing the file.
For example, if you set the `contentType` to "image/png" when creating the `uploadUrl`, be sure to set the `Content-Type: image/png` and the uploaded file ends in `.png`.

On a successful upload, a `200` response will be returned.

### Example Upload File Binary in Node.js

Here is an example of uploading a binary media file using Node with JavaScript:

```javascript theme={"system"}
const fs = require("fs");
const request = require("request");

const API_KEY = "Your API Key";
const fileName = "test.png";
const endpoint = `https://api.ayrshare.com/api/media/uploadUrl?fileName=${fileName}&contentType=png`;

const run = async () => {
  request.get(
    {
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${API_KEY}`
      },
      url: endpoint
    },
    (err, res, body) => {
      if (err) {
        return console.error(err);
      }

      const json = JSON.parse(body);
      console.log("Upload URL:", json);

      return fs.createReadStream(`./${fileName}`).pipe(
        request.put(
          json.uploadUrl,
          {
            headers: {
              "Content-Type": json.contentType
            }
          },
          (err, httpsResponse, body) => {
            if (err) {
              console.error("err", err);
            } else {
              console.log(body);
            }
          }
        )
      );
    }
  );
};

run();
```

### Example Upload Binary File in Postman

You may also use Postman to upload the binary file to the `uploadUrl`.

In Postman:

1. Select the HTTP Method `PUT`.
2. Paste your `uploadUrl` in the url field. Note, the url will expire after an hour and may only be used once. If you make a call and it fails, you must regenerate the `uploadUrl`.
3. In *Headers* set the `Content-Type` to be the content type returned in the /uploadUrl endpoint. For example: `Content-Type: image/png`.
4. Select *Body -> binary* and select the file to upload.
5. Press **Send**.
6. **Important**: No return response will occur, so you should check if the upload was successful by opening the `accessUrl` returned from the /uploadUrl endpoint in a browser. You may also use the [verify URL endpoint](/apis/media/verify-media-url).

<img class="center" src="https://mintcdn.com/ayrshare-docs/Nmrhj2Gh7WSf62Bh/images/apis/validate/postman%20binary.webp?fit=max&auto=format&n=Nmrhj2Gh7WSf62Bh&q=85&s=ca3def769242814afb17a58d9268667f" alt="Postman Binary Upload" width="1536" height="189" data-path="images/apis/validate/postman binary.webp" />

<Card title="Postman Sample JSON File" icon="file" href="/files/Large Media File Upload.postman_collection.json" horizontal />

<ResponseExample>
  ```javascript 200: An upload URL and access URL theme={"system"}
  {
      "accessUrl": "https://media.ayrshare.com/Aswmfs3dIEbwLSdhTlV2/test.mp4",
      "contentType": "video/mp4",
      "uploadUrl": "https://storage.googleapis.com/..."
  }
  ```

  ```json 400: Bad Request Error getting signed URL theme={"system"}
  {
    "action": "upload",
    "status": "error",
    "code": 301,
    "message": "The provided content-type 'movd' is not recognized."
  }
  ```
</ResponseExample>
