b2_upload_file

Uploads one file to B2, returning its unique file ID.

Request

The upload request is a POST. The file name and other parameters are in the request headers, and the file to be uploaded is the request body.

URL Path

Use the b2_get_upload_url operation to get a URL you can use to upload files. The URL it returns will contain your bucket ID and the upload destination, and will look something like this:

https://pod-000-1007-13.backblaze.com/b2api/v1/b2_upload_file/4a48fe8875c6214145260818/c001_v0001007_t0042

Request HTTP Headers

Authorization

required

An upload authorization token, from b2_get_upload_url.

X-Bz-File-Name

required

The name of the file, in percent-encoded UTF-8. For example, spaces should be replaced with %20. For more information, see Files for requirements on file names and String Encoding for how to encode strings.

Content-Type

required

The MIME type of the content of the file, which will be returned in the Content-Type header when downloading the file. Use the Content-Type b2/x-auto to automatically set the stored Content-Type post upload. In the case where a file extension is absent or the lookup fails, the Content-Type is set to application/octet-stream. The Content-Type mappings can be perused here.

Content-Length

required

The number of bytes in the file being uploaded. Note that this header is required; you cannot leave it out and just use chunked encoding.
When sending the SHA1 checksum at the end, the Content-Length should be set to the size of the file plus the 40 bytes of hex checksum.

X-Bz-Content-Sha1

required

The SHA1 checksum of the content of the file. B2 will check this when the file is uploaded, to make sure that the file arrived correctly. It will be returned in the X-Bz-Content-Sha1 header when the file is downloaded.
You may optionally provide the SHA1 at the end of the upload. See the section on Uploading.

X-Bz-Info-src_last_modified_millis

optional

If the original source of the file being uploaded has a last modified time concept, Backblaze recommends using this spelling of one of your ten X-Bz-Info-* headers (see below). Using a standard spelling allows different B2 clients and the B2 web user interface to interoperate correctly. The value should be a base 10 number which represents a UTC time when the original source file was last modified. It is a base 10 number of milliseconds since midnight, January 1, 1970 UTC. This fits in a 64 bit integer such as the type "long" in the programming language Java. It is intended to be compatible with Java's time long. For example, it can be passed directly into the Java call Date.setTime(long time).

X-Bz-Info-b2-content-disposition

optional

If this is present, B2 will use it as the value of the 'Content-Disposition' header when the file is downloaded (unless it's overridden by a value given in the download request). The value must match the grammar specified in RFC 6266 (except that parameter names that contain an '*' are not allowed).

X-Bz-Info-*

optional

Up to 10 of these headers may be present. The * part of the header name is replaced with the name of a custom field in the file information stored with the file, and the value is an arbitrary UTF-8 string, percent-encoded. The same info headers sent with the upload will be returned with the download. The header name is case insensitive.

The following HTTP headers must not be included in the b2_upload_file request:

  • Cache-Control
  • Content-Disposition
  • Content-Encoding
  • Content-Language
  • Content-Location
  • Content-Language
  • Content-Range
  • Expires

The file name and file info must fit, along with the other necessary headers, within a 7,000 byte limit. This limit applies to the fully encoded HTTP header line, including the carriage-return and newline. See Files for further details about HTTP header size limit.

Request HTTP Message Body Parameters

There are no JSON parameters allowed. The file to be uploaded is the message body and is not encoded in any way. It is not URL encoded. It is not MIME encoded.

Response

Response HTTP Status 200

File successfully uploaded. The JSON response will contain:

fileId

The unique identifier for this version of this file. Used with b2_get_file_info, b2_download_file_by_id, and b2_delete_file_version.

fileName

The name of this file, which can be used with b2_download_file_by_name.

accountId

Your account ID.

bucketId

The bucket that the file is in.

contentLength

The number of bytes stored in the file.

contentSha1

The SHA1 of the bytes stored in the file.

contentType

The MIME type of the file.

fileInfo

The custom information that was uploaded with the file. This is a JSON object, holding the name/value pairs that were uploaded with the file.

action

Always "upload".

uploadTimestamp

This is a UTC time when this file was uploaded. It is a base 10 number of milliseconds since midnight, January 1, 1970 UTC. This fits in a 64 bit integer such as the type "long" in the programming language Java. It is intended to be compatible with Java's time long. For example, it can be passed directly into the java call Date.setTime(long time).

Response Errors

File not uploaded. If possible the server will return a JSON error structure. Errors include:

status

code

message

400

bad_request

Request path is null

400

bad_request

Request path should look like: /b2api/v1/b2_upload_file/<bucketId>/c000_v0001004_t1234

401

missing_auth_token

Authorization token is missing

401

expired_auth_token

Authorization token has expired

401

bad_auth_token

Invalid authorization token

401

bad_auth_token

Authorization token for wrong cluster

403

cap_exceeded

Usage cap exceeded.

405

method_not_allowed

Only POST is supported, not <method>

408

request_timeout

The service timed out reading the uploaded file

503

service_unavailable

<various>

Some errors returned mean that you must call b2_get_upload_url again to get a new upload URL and authorization token. See Uploading for details.

Sample Code

Code

FILE_TO_UPLOAD=typing_test.txt
MIME_TYPE=text/plain
SHA1_OF_FILE=$(openssl dgst -sha1 $FILE_TO_UPLOAD | awk '{print $2;}')
UPLOAD_URL=... # from b2_get_upload_url call
UPLOAD_AUTHORIZATION_TOKEN=... # from b2_get_upload_url call

curl \
    -H "Authorization: $UPLOAD_AUTHORIZATION_TOKEN" \
    -H "X-Bz-File-Name: $FILE_TO_UPLOAD" \
    -H "Content-Type: $MIME_TYPE" \
    -H "X-Bz-Content-Sha1: $SHA1_OF_FILE" \
    -H "X-Bz-Info-Author: unknown" \
    --data-binary "@$FILE_TO_UPLOAD" \
    $UPLOAD_URL

Output

{
    "fileId" : "4_h4a48fe8875c6214145260818_f000000000000472a_d20140104_m032022_c001_v0000123_t0104",
    "fileName" : "typing_test.txt",
    "accountId" : "d522aa47a10f",
    "bucketId" : "4a48fe8875c6214145260818",
    "contentLength" : 46,
    "contentSha1" : "bae5ed658ab3546aee12f23f36392f35dba1ebdd",
    "contentType" : "text/plain",
    "fileInfo" : {
       "author" : "unknown"
    }
}

Code

import java.io.*;
import java.util.*;
import javax.json.*;
import java.net.HttpURLConnection;
import java.net.URL;

String uploadUrl = ""; // Provided by b2_get_upload_url
String uploadAuthorizationToken = ""; // Provided by b2_get_upload_url
String fileName = ""; // The name of the file you are uploading
String contentType = ""; // The content type of the file
String sha1 = ""; // SHA1 of the file you are uploading
byte[] fileData;
HttpURLConnection connection = null;
String json = null;
try {
    URL url = new URL(uploadUrl);
    connection = (HttpURLConnection)url.openConnection();
    connection.setRequestMethod("POST");
    connection.setRequestProperty("Authorization", uploadAuthorizationToken);
    connection.setRequestProperty("Content-Type", contentType);
    connection.setRequestProperty("X-Bz-File-Name", fileName);
    connection.setRequestProperty("X-Bz-Content-Sha1", sha1);
    connection.setDoOutput(true);
    DataOutputStream writer = new DataOutputStream(connection.getOutputStream());
    writer.write(fileData);
    String jsonResponse = myInputStreamReader(connection.getInputStream());
    System.out.println(jsonResponse);
} catch (Exception e) {
    e.printStackTrace();
} finally {
    connection.disconnect();
}

static public String myInputStreamReader(InputStream in) throws IOException {
    InputStreamReader reader = new InputStreamReader(in);
    StringBuilder sb = new StringBuilder();
    int c = reader.read();
    while (c != -1) {
        sb.append((char)c);
        c = reader.read();
    }
    reader.close();
    return sb.toString();
}

Output

{
    "fileId" : "4_h4a48fe8875c6214145260818_f000000000000472a_d20140104_m032022_c001_v0000123_t0104",
    "fileName" : "typing_test.txt",
    "accountId" : "d522aa47a10f",
    "bucketId" : "4a48fe8875c6214145260818",
    "contentLength" : 46,
    "contentSha1" : "bae5ed658ab3546aee12f23f36392f35dba1ebdd",
    "contentType" : "text/plain",
    "fileInfo" : {
       "author" : "unknown"
    }
}

Code

import json
import urllib2
import hashlib

upload_url = "" # Provided by b2_get_upload_url
upload_authorization_token = "" # Provided by b2_get_upload_url
file_data = "Now, I am become Death, the destroyer of worlds."
file_name = "oppenheimer_says.txt"
content_type = "text/plain"
sha1_of_file_data = hashlib.sha1(file_data).hexdigest()

headers = {
    'Authorization' : upload_authorization_token,
    'X-Bz-File-Name' :  file_name,
    'Content-Type' : content_type,
    'X-Bz-Content-Sha1' : sha1_of_file_data
    }
request = urllib2.Request(upload_url, file_data, headers)

response = urllib2.urlopen(request)
response_data = json.loads(response.read())
response.close()

Output

{
    "fileId" : "4_h4a48fe8875c6214145260818_f000000000000472a_d20140104_m032022_c001_v0000123_t0104",
    "fileName" : "typing_test.txt",
    "accountId" : "d522aa47a10f",
    "bucketId" : "4a48fe8875c6214145260818",
    "contentLength" : 46,
    "contentSha1" : "bae5ed658ab3546aee12f23f36392f35dba1ebdd",
    "contentType" : "text/plain",
    "fileInfo" : {
       "author" : "unknown"
    }
}

Code

import Foundation

let uploadUrl = "" // Provided by b2_get_upload_url
let uploadAuthorizationToken = "" // Provided by b2_get_upload_url
let fileName = "" // The name of the file you are uploading
let contentType = "" // The content type of the file
let sha1 = "" // SHA1 of the file you are uploading
if let fileData = NSData(contentsOfURL: "<a_file_url>") {
    let session = NSURLSession.sharedSession()
    let request = NSMutableURLRequest(URL: NURL(uploadUrl)!)
    request.HTTPMethod = "POST"
    request.addValue(uploadAuthorizationToken, forHTTPHeaderField: "Authorization")
    request.addValue(fileName, forHTTPHeaderField: "X-Bz-File-Name")
    request.addValue(contentType, forHTTPHeaderField: "Content-Type")
    request.addValue(sha1, forHTTPHeaderField: "X-Bz-Content-Sha1")
    let task = session.uploadTaskWithRequest(request, fromData: uploadData, completionHandler:{ (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
        if data != nil {
            requestData = data
        }
    })
    task.resume()
}

Output

{
    "fileId" : "4_h4a48fe8875c6214145260818_f000000000000472a_d20140104_m032022_c001_v0000123_t0104",
    "fileName" : "typing_test.txt",
    "accountId" : "d522aa47a10f",
    "bucketId" : "4a48fe8875c6214145260818",
    "contentLength" : 46,
    "contentSha1" : "bae5ed658ab3546aee12f23f36392f35dba1ebdd",
    "contentType" : "text/plain",
    "fileInfo" : {
       "author" : "unknown"
    }
}

Code

require 'json'
require 'net/http'
require 'digest/sha1'

upload_url = "" # Provided by b2_get_upload_url
local_file = "" # File to be uploaded
upload_authorization_token = "" # Provided by b2_get_upload_url
file_name = "" # The name of the file you are uploading
content_type = ""  # The content type of the file
sha1 = "" # SHA1 of the file you are uploading
uri = URI(upload_url)
req = Net::HTTP::Post.new(uri)
req.add_field("Authorization","#{upload_authorization_token}")
req.add_field("X-Bz-File-Name","#{file_name}")
req.add_field("Content-Type","#{content_type}")
req.add_field("X-Bz-Content-Sha1","#{sha1}")
req.add_field("Content-Length",File.size(local_file))
req.body = File.read(local_file)
http = Net::HTTP.new(req.uri.host, req.uri.port)
http.use_ssl = (req.uri.scheme == 'https')
res = http.start {|http| http.request(req)}
case res
when Net::HTTPSuccess then
    res.body
when Net::HTTPRedirection then
    fetch(res['location'], limit - 1)
else
    res.error!
end

Output

{
    "fileId" : "4_h4a48fe8875c6214145260818_f000000000000472a_d20140104_m032022_c001_v0000123_t0104",
    "fileName" : "typing_test.txt",
    "accountId" : "d522aa47a10f",
    "bucketId" : "4a48fe8875c6214145260818",
    "contentLength" : 46,
    "contentSha1" : "bae5ed658ab3546aee12f23f36392f35dba1ebdd",
    "contentType" : "text/plain",
    "fileInfo" : {
       "author" : "unknown"
    }
}

Code

using System;
using System.Net;
using System.Text;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;

String uploadAuthorizationToken = "UPLOAD_AUTHORIZATION_TOKEN"; //Provided by b2_get_upload_url
String contentType = "CONTENT_TYPE"; //Type of file i.e. image/jpeg, audio/mpeg...
String filePath = "FILE_PATH"; //File path of desired upload 
String fileName = "FILE_NAME"; //Desired name for the file
String sha1Str = "SHA_1"; //Sha1 verification for the file

// Read the file into memory and take a sha1 of the data.
FileInfo fileInfo = new FileInfo(filePath);
byte[] bytes = File.ReadAllBytes(filePath);
SHA1 sha1 = SHA1.Create();
// NOTE: Loss of precision. You may need to change this code if the file size is larger than 32-bits.
byte[] hashData = sha1.ComputeHash(bytes, 0, (int)fileInfo.Length);
StringBuilder sb = new StringBuilder();
foreach (byte b in hashData)
{
	sb.Append(b.ToString("x2"));
}
sha1Str = sb.ToString();

// Send over the wire
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uploadUrl);
webRequest.Method = "POST";
webRequest.Headers.Add("Authorization", uploadAuthorizationToken);
webRequest.Headers.Add("X-Bz-File-Name", fileName);
webRequest.Headers.Add("X-Bz-Content-Sha1", sha1Str);
webRequest.ContentType = contentType;
using (var stream = webRequest.GetRequestStream())
{
	stream.Write(bytes, 0, bytes.Length);
	stream.Close();
}
WebResponse response = (HttpWebResponse)webRequest.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
response.Close();
Console.WriteLine(responseString);

Output

{
    "fileId" : "4_h4a48fe8875c6214145260818_f000000000000472a_d20140104_m032022_c001_v0000123_t0104",
    "fileName" : "typing_test.txt",
    "accountId" : "d522aa47a10f",
    "bucketId" : "4a48fe8875c6214145260818",
    "contentLength" : 46,
    "contentSha1" : "bae5ed658ab3546aee12f23f36392f35dba1ebdd",
    "contentType" : "text/plain",
    "fileInfo" : {
       "author" : "unknown"
    }
}

Code

$file_name = "file.txt";
$my_file = "<path-to-file>" . $file_name;
$handle = fopen($my_file, 'r');
$read_file = fread($handle,filesize($my_file));

$upload_url = ""; // Provided by b2_get_upload_url
$upload_auth_token = ""; // Provided by b2_get_upload_url
$bucket_id = "";  // The ID of the bucket
$content_type = "text/plain";
$sha1_of_file_data = sha1_file($my_file);

$session = curl_init($upload_url);

// Add read file as post field
curl_setopt($session, CURLOPT_POSTFIELDS, $read_file); 

// Add headers
$headers = array();
$headers[] = "Authorization: " . $upload_auth_token;
$headers[] = "X-Bz-File-Name: " . $file_name;
$headers[] = "Content-Type: " . $content_type;
$headers[] = "X-Bz-Content-Sha1: " . $sha1_of_file_data;
curl_setopt($session, CURLOPT_HTTPHEADER, $headers); 

curl_setopt($session, CURLOPT_POST, true); // HTTP POST
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);  // Receive server response
$server_output = curl_exec($session); // Let's do this!
curl_close ($session); // Clean up
echo ($server_output); // Tell me about the rabbits, George!

Output

{
    "fileId" : "4_h4a48fe8875c6214145260818_f000000000000472a_d20140104_m032022_c001_v0000123_t0104",
    "fileName" : "typing_test.txt",
    "accountId" : "d522aa47a10f",
    "bucketId" : "4a48fe8875c6214145260818",
    "contentLength" : 46,
    "contentSha1" : "bae5ed658ab3546aee12f23f36392f35dba1ebdd",
    "contentType" : "text/plain",
    "fileInfo" : {
       "author" : "unknown"
    }
}