NAV Navbar

Arc

cURL Node Python Java

Arc API Reference

Welcome to Arc's API documentation!

This page documents Arc's REST API, which provides programmatic access to Arc's object storage service via an Amazon S3 compatible API.

As Arc's API is compatible with Amazon S3's API, this document closely mirrors S3's API documentation.

Authentication

const AWS = require('aws-sdk')
const s3 = new AWS.S3({
    s3ForcePathStyle: true,
    endpoint: 'https://storage.arc.io',
    accessKeyId: '<YOUR_ARC_ACCESS_KEY>',
    secretAccessKey: '<YOUR_ARC_SECRET_KEY>',
})
from boto3.session import Session

session = Session(
    aws_access_key_id='<YOUR_ARC_ACCESS_KEY>',
    aws_secret_access_key='<YOUR_ARC_SECRET_KEY>',
)

# Use the resource for high level operations.
s3 = session.resource('s3', endpoint_url='https://storage.arc.io')

# Use the client for low level operations.
client = s3.meta.client
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

BasicAWSCredentials awsCreds = (
    new BasicAWSCredentials("<YOUR_ARC_ACCESS_KEY>", "<YOUR_ARC_SECRET_KEY>");
AmazonS3 s3 = AmazonS3ClientBuilder.standard()
    .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
    .withEndpointConfiguration(
        new EndpointConfiguration("https://storage.arc.io", "us-east-1"))
    .build();

Arc uses API keys to authenticate requests. You can find your API key in the Portal.

API keys are not required for HEAD Object or GET Object API endpoints. While Arc is in alpha, all objects are publicly readable by default. Other API endpoints require authentication.

Signing requests manually can prove tedious and error prone, so we recommend the use of software to handle authentication for you. Because Arc's API is compabitible with Amazon S3, existing S3-compatible tools and libraries work beautifully.

Arc's Portal is also an easy way to complete simple bucket and object management in a nice GUI.

If you want to create API requests yourself, they must be signed with your API keys. See Amazon's documentation on Signing and Authenticating REST Requests here to learn how.

API Reference

GET Service

curl \
  -H "Date: <date>" \
  -H "Authorization: <AUTHENTICATION_STRING>" \
  "https://storage.arc.io"
const AWS = require('aws-sdk')

const s3 = new AWS.S3()
s3.listBuckets((err, data) => {
    if (err) console.log(err, err.stack)
    else     console.log(data)
})
import boto3

s3 = boto3.resource('s3')
bucket_iterator = s3.buckets.all()
import java.util.List;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;

final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
List<Bucket> buckets = s3.listBuckets();

List all buckets owned by the requestor.

403 Forbidden is returned if the request is unauthorized.

Request Syntax

GET / HTTP/1.1
Host: storage.arc.io
Date: <date>
Authorization: <authentication string>
Content-Length: <request body length>

Response Elements

Name Description
Bucket Container for bucket information.
Buckets Container for one or more buckets.
CreationDate Date the bucket was created.
ListAllMyBucketsResult Container for response.
Name The bucket's name.

Response Example

HTTP/1.1 200 OK
Content-Length: 648
Content-Type: application/xml
Date: Fri, 19 Feb  2014 10:00:00 GMT

<?xml version='1.0' encoding='utf-8'?>
<ListAllMyBucketsResult xmlns='http://doc.s3.amazonaws.com/2006-03-01'>
  <Buckets>
    <Bucket>
      <Name>MyBucket</Name>
      <CreationDate>2009-12-16T18:36:25.369Z</CreationDate>
    </Bucket>
  </Buckets>
</ListAllMyBucketsResult>

DELETE Bucket

curl \
  -X DELETE \
  -H "Date: <date>" \
  -H "Authorization: <authentication string>" \
  "https://storage.arc.io/<bucket>"
const AWS = require('aws-sdk')

const s3 = new AWS.S3()
const params = {
    Bucket: 'bucket',
}
s3.deleteBucket(params, (err, data) => {
    if (err) console.log(err, err.stack)
    else     console.log(data)
})
import boto3

s3 = boto3.resource('s3')
bucket = s3.Bucket('bucket')
bucket.delete()
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
s3.deleteBucket("bucket");

Delete a bucket.

409 Conflict is returned if the bucket isn't empty. Buckets must be empty to be deleted.

404 Not Found is returned if the bucket doesn't exist.

Request Syntax

DELETE /<bucket> HTTP/1.1
Host: storage.arc.io
Date: <date>
Authorization: <authentication string>
Content-Length: <request body length>

Response Example

HTTP/1.1 204 No Content
Date: Fri, 19 Feb  2014 10:00:00 GMT
Expires: Fri, 19 Feb  2014 10:00:00 GMT

GET Bucket (List Objects)

curl \
  -H "Date: <date>" \
  -H "Authorization: <authentication string>" \
  "https://storage.arc.io/<bucket>?list-type=2&prefix=prefix&delimiter=/"
const AWS = require('aws-sdk')

const s3 = new AWS.S3()
const params = {
    Bucket: 'bucket',
    Delimiter: '/',
    Prefix: 'prefix',
}
s3.listObjectsV2(params, (err, data) => {
    if (err) console.log(err, err.stack)
    else     console.log(data)
})
import boto3

client = boto3.client('s3')
response = client.list_objects_v2(
    Bucket='bucket',
    Delimiter='/',
    Prefix='prefix',
)
import java.util.List;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ListObjectsV2Result;
import com.amazonaws.services.s3.model.S3ObjectSummary;

final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
ListObjectsV2Result result = s3.listObjectsV2("bucket");
List<S3ObjectSummary> objects = result.getObjectSummaries();

List objects stored in a bucket.

404 Not Found is returned if the bucket doesn't exist.

Request Syntax

GET /<bucket>?list-type=2&prefix=<prefix>&delimiter=<delimiter> HTTP/1.1
Host: storage.arc.io
Date: <date>
Authorization: <authentication string>

Request Query Parameters

Parameter Description Required
list-type Specify version 2 of the List Objects API. The value is always "2". Yes
continuation-token When the response to this API call is truncated (that is, the IsTruncated response element value is true), the response also includes the NextContinuationToken element. To list the next set of objects, you can use the NextContinuationToken element in the next request as the continuation-token. No
delimiter A character or multiple characters that can be used to simplify a list of objects that use a directory-like naming scheme. Can be used in conjunction with a prefix. No
max-keys The maximum number of objects to return in a list object request. No
prefix A string that can be used to limit the number of objects returned in a GET Bucket request. Can be used in conjunction with a delimiter. No
start-after The object name after which listed objects should start. No

Response Elements

Name Description
Contents Metadata about each object returned.
CommonPrefixes All of the keys rolled up into a common prefix count as a single return when calculating the number of returns. See MaxKeys.
  • A response can contain CommonPrefixes only if you specify a delimiter.
  • CommonPrefixes contains all (if there are any) keys between Prefix and the next occurrence of the string specified by a delimiter.
  • CommonPrefixes lists keys that act like subdirectories in the directory specified by Prefix.
For example, if the prefix is projects/, the delimiter is /, and the key projects/main/topsecret is returned, then a common prefix is projects/main/.
Delimiter Causes keys that contain the same string between the prefix and the first occurrence of the delimiter to be rolled up into a single result element in the CommonPrefixes collection. These rolled-up keys are not returned elsewhere in the response. Each rolled-up result counts as only one return against the MaxKeys value.
ETag The entity tag is an MD5 hash of the object. ETag reflects only changes to the contents of an object, not its metadata.
IsTruncated Set to false if all of the results were returned. Set to true if more keys are available to return. If the number of results exceeds that specified by MaxKeys, all of the results might not be returned.
Key The object's key.
LastModified The date time of when the object was last modified.
MaxKeys The max number of keys returned in the response.
Name The bucket name.
Prefix Keys that begin with the specified prefix.
Size The object's size in bytes.
ContinuationToken Included in the response if sent in the request.
KeyCount The number of keys included in the response.
NextContinuationToken If the response is truncated, Arc returns this parameter with a continuation token. You can specify the token as the continuation-token in your next request to retrieve the next set of keys.
StartAfter Included in the response if sent in the request.

Response Example

HTTP/1.1 200 OK
Content-Length: 4061
Content-Type: application/xml
Date: Wed, 17 Feb 2010 23:31:57 GMT
Expires: Wed, 17 Feb 2010 23:31:57 GMT

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Name>bucket</Name>
    <Prefix/>
    <KeyCount>205</KeyCount>
    <MaxKeys>1000</MaxKeys>
    <IsTruncated>false</IsTruncated>
    <Contents>
        <Key>my-image.jpg</Key>
        <LastModified>2009-10-12T17:50:30.000Z</LastModified>
        <ETag>fba9dede5f27731c9771645a39863328</ETag>
        <Size>434234</Size>
    </Contents>
</ListBucketResult>

HEAD Bucket

curl \
  --head \
  -H "Date: <date>" \
  -H "Authorization: <authentication string>" \
  "https://storage.arc.io/<bucket>"
const AWS = require('aws-sdk')

const s3 = new AWS.S3()
const params = {
    Bucket: 'bucket',
}
s3.headBucket(params, (err, data) => {
    if (err) console.log(err, err.stack)
    else     console.log(data)
})
import boto3

client = boto3.client('s3')
response = client.head_bucket(Bucket='bucket')
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.HeadBucketRequest;

final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
s3.headBucket(new HeadBucketRequest("bucket"));

Check if the bucket exists and if the requestor has read access to it.

404 Not Found is returned if the bucket doesn't exist.

403 Forbidden is returned if the bucket exists but you don't have read access.

Request Syntax

HEAD / HTTP/1.1
Host: storage.arc.io
Date: <date>
Authorization: <authentication string>

Response Example

HTTP/1.1 200 OK

PUT Bucket

curl \
  -X PUT \
  -H "Date: <date>" \
  -H "Authorization: <authentication string>" \
  "https://storage.arc.io/<bucket>"
const AWS = require('aws-sdk')

const s3 = new AWS.S3()
const params = {
    Bucket: 'bucket',
}
s3.createBucket(params, (err, data) => {
    if (err) console.log(err, err.stack)
    else     console.log(data)
})
import boto3

s3 = boto3.resource('s3')
bucket = s3.Bucket('bucket')
bucket.create()
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.CreateBucketRequest;

final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
s3.createBucket(new CreateBucketRequest("bucket"));

Create a bucket.

400 Bad Request is returned if an invalid bucket name is provided.

Valid bucket names must:

See S3's documentation for more information on bucket names.

Request Syntax

PUT /<bucket> HTTP/1.1
Host: storage.arc.io
Date: <date>
Content-Length: <request body length>
Authorization: <authentication string>

Response Example

HTTP/1.1 200 OK
Date: Mon, 15 Feb 2010 12:30:40 GMT
Content-Length: 0

DELETE Object

curl \
  -X DELETE \
  -H "Date: <date>" \
  -H "Authorization: <authentication string>" \
  "https://storage.arc.io/<bucket>/<key>"
const AWS = require('aws-sdk')

const s3 = new AWS.S3()
const params = {
    Bucket: 'bucket',
    Key: 'key',
}
s3.deleteObject(params, (err, data) => {
    if (err) console.log(err, err.stack)
    else     console.log(data)
})
import boto3

s3 = boto3.resource('s3')
obj = s3.Object('bucket','key')
obj.delete()
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
s3.deleteObject("bucket", "key");

Delete an object.

404 Not Found is returned if the object doesn't exist.

Request Syntax

DELETE /<bucket>/<key> HTTP/1.1
Host: storage.arc.io
Date: <date>
Content-Length: <request body length>
Authorization: <authentication string>

Response Example

HTTP/1.1 204 No Content
Date: Fri, 19 Feb  2014 10:00:00 GMT

DELETE Object - Multiple

curl \
  -X POST \
  -H "Date: <date>" \
  -H "Authorization: <authentication string>" \
  -d @deleteObjects.xml \
  "https://storage.arc.io/<bucket>?delete"

# deleteObjects.xml

<?xml version="1.0" encoding="UTF-8"?>
<Delete>
    <Quiet>true</Quiet>
    <Object>
         <Key>key1</Key>
    </Object>
    <Object>
         <Key>key2</Key>
    </Object>
</Delete>
const AWS = require('aws-sdk')

const s3 = new AWS.S3()
const params = {
    Bucket: 'bucket',
    Delete: {
        Objects: [
            { Key: "key1" },
            { Key: "key2" },
        ],
        Quiet: true,
    },
}
s3.deleteObjects(params, (err, data) => {
    if (err) console.log(err, err.stack)
    else console.log(data)
})
import boto3

client = boto3.client('s3')
response = client.delete_objects(
    Bucket='bucket',
    Delete={
        'Objects': [
            { 'Key': 'key1' },
            { 'Key': 'key2' },
        ],
        'Quiet': True,
    },
)
import java.util.ArrayList;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.DeleteObjectsRequest;
import com.amazonaws.services.s3.model.DeleteObjectsRequest.KeyVersion;
import com.amazonaws.services.s3.model.DeleteObjectsResult;

final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();

ArrayList<KeyVersion> keys = new ArrayList<KeyVersion>();
keys.add(new KeyVersion("key1"));
keys.add(new KeyVersion("key2"));
DeleteObjectsRequest request = (
    new DeleteObjectsRequest("bucket").withKeys(keys).withQuiet(true));
DeleteObjectsResult result = s3.deleteObjects(request);

Delete multiple objects with a single request.

Request Syntax

POST /<bucket>?delete HTTP/1.1
Host: storage.arc.io
Authorization: <authentication string>
Content-Length: <request body length>
Content-MD5: <MD5 digest>

<?xml version="1.0" encoding="UTF-8"?>
<Delete>
    <Quiet>true</Quiet>
    <Object>
         <Key>key1</Key>
    </Object>
    <Object>
         <Key>key2</Key>
    </Object>
</Delete>

Request Query Parameters

Parameter Description Required
delete Indicates a multi-object delete operation. Yes

Request Headers

Name Description Required
Content-Length Length of the body. Yes
Content-MD5 The base64-encoded 128-bit MD5 digest of the data. This header must be used as a message integrity check to verify that the request body was not corrupted or tampered with in transit. Yes

Request Elements

Name Description Required
Delete Container for the request.

Ancestor: None.

Type: Container.

Children: One or more Object elements and an optional Quiet element.
Yes
Object Container element that describes the delete request for an object.

Ancestor: Delete.

Type: Container.

Children: Key.
Yes
Key Key name of the object to delete.

Ancestor: Object.

Type: String.
Yes
Quiet Element to enable quiet mode for the request. If you add this element, its value must be true.

Ancestor: Delete.

Type: Boolean.

Default: false.
No

Response Elements

Name Description
DeleteResult Container for the response.

Type: Container.
Deleted Container element for a successful delete. It identifies the object that was successfully deleted.

Type: Container.
Key Key name for the object that was requested to be deleted.

Type: String.

Response Example

HTTP/1.1 200 OK
Date: Fri, 10 Aug 2018 22:57:13 GMT
Content-Type: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
   <Deleted>
      <Key>flags.min 2.css</Key>
   </Deleted>
   <Deleted>
      <Key>hosting.svg</Key>
   </Deleted>
</DeleteResult>

GET Object

curl "https://storage.arc.io/<bucket>/<key>"
const AWS = require('aws-sdk')

const s3 = new AWS.S3()
const params = {
    Bucket: 'bucket',
    Key: 'key',
}
s3.getObject(params, (err, data) => {
    if (err) console.log(err, err.stack)
    else     console.log(data)
})
import boto3

s3 = boto3.resource('s3')
obj = s3.Object('bucket', 'key')
obj.get()
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.S3Object;

final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
S3Object object = s3.getObject("bucket", "key");

Retrieve an object.

404 Not Found is returned if the object doesn't exist.

Request Syntax

GET /<bucket>/<key> HTTP/1.1
Host: storage.arc.io
Content-Length: <request body length>
Range: <bytes=byte range>
If-Match: <entity tag>
If-Modified-Since: <date>
If-None-Match: <entity tag>
If-Unmodified-Since: <date>

Request Parameters

Request headers can optionally be overwritten by appropriate query parameters.

Name Description Required
response-content-type Sets the Content-Type header of the response.

Type: String.
No
response-content-language Sets the Content-Language header of the response.

Type: String.
No
response-expires Sets the Expires header of the response.

Type: String.
No
response-cache-control Sets the Cache-Control header of the response.

Type: String.
No
response-content-disposition Sets the Content-Disposition header of the response.

Type: String.
No
response-content-encoding Sets the Content-Encoding header of the response.

Type: String.
No

Request Headers

Name Description Required
Range Downloads the specified byte range of an object.

Type: String.
No
If-Modified-Since Return the object only if it has been modified since the specified time. Otherwise 304 Not Modified is returned. For more information, see Note #2 below.

Type: String.
No
If-Unmodified-Since Return the object only if it has not been modified since the specified time. Otherwise, 412 Precondition Failed is returned. For more information, see Note #1 below.

Type: String.
No
If-Match Return the object only if its entity tag (ETag) is the same as the one specified. Otherwise, 412 Precondition Failed is returned. For more information, see Note #1 below.

Type: String.
No
If-None-Match Return the object only if its entity tag (ETag) is different from the one specified. Otherwise, 304 Not Modified is returned. For more information, see Note #2 below.

Type: String.
No

Response Example

HTTP/1.1 200 OK
Content-Type: image/jpg
Last-Modified: Fri, 19 Feb 2010 22:13:49 GMT
ETag: "2281880ef78388266ecd7d4c1b472a0e"
Content-Length: 328
Date: Fri, 19 Feb 2010 22:13:49 GMT

[328 bytes of data]

HEAD Object

curl --head "https://storage.arc.io/<bucket>/<key>"
const AWS = require('aws-sdk')

const s3 = new AWS.S3()
const params = {
    Bucket: 'bucket',
    Key: 'key',
}
s3.headObject(params, (err, data) => {
    if (err) console.log(err, err.stack)
    else     console.log(data)
})
import boto3

s3 = boto3.resource('s3')
obj = s3.Object('bucket', 'key')
obj.load()
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectMetadata;

final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
ObjectMetadata metadata = s3.getObjectMetadata("bucket", "key");

Retrieve object metadata.

This operation has the same options and response as GET Object except without a response body.

404 Not Found is returned if the object doesn't exist.

Request Syntax

HEAD /<bucket>/<key> HTTP/1.1
Host: storage.arc.io
Date: <date>
Content-Length: <request body length>
Range: <bytes=byte range>
If-Match: <entity tag>
If-Modified-Since: <date>
If-None-Match: <entity tag>
If-Unmodified-Since: <date>

Response Example

HTTP/1.1 200 OK
Date: Wed, 28 Oct 2009 22:32:00 GMT
Last-Modified: Sun, 1 Jan 2006 12:00:00 GMT
ETag: "fba9dede5f27731c9771645a39863328"
Content-Length: 434234
Content-Type: text/plain
Connection: close

POST Object

const AWS = require('aws-sdk')

const s3 = new AWS.S3()
const params = {
    Bucket: 'bucket',
    Fields: {
        key: 'key',
        success_action_redirect: 'https://example.com/post_object_success',
    },
    Conditions: [
        { success_action_redirect: 'https://example.com/post_object_success' }
    ]
}
s3.createPresignedPost(params, (err, data) => {
    if (err) console.error(err, err.stack)
    else     console.log(data)
})
import boto3

client = boto3.client('s3')
post = client.generate_presigned_post(
    'bucket',
    'key',
    Fields={
        'success_action_redirect': 'https://example.com/post_object_success',
    },
    Conditions=[
        { 'success_action_redirect': 'https://example.com/post_object_success' },
    ]
)
# Use the values in post to populate the HTML form
// The AWS Java SDK doesn't support pre-signed post.

Add an object to a bucket via a multipart-form.

Form fields

Field Description Required
ArcAccessKeyId The Arc access key ID of the owner of the bucket who grants an Anonymous user access for a request that satisfies the set of constraints in the policy.

This is required if a policy document is included with the request.
Conditional
key The name of the uploaded key.

If helpful, the filename provided by the user can be accessed with the ${filename} variable. For example, if the user slark uploads the file dota.jpg and you specify /user/slark/${filename}, the key name is /user/slark/dota.jpg.
Yes
policy The base64-encoded security policy that describes what's permitted in the request. Yes
x-amz-algorithm The signing algorithm used to authenticate the request. For AWS Signature Version 4, the value is AWS4-HMAC-SHA256. Yes
x-amz-credential In addition to your access key ID, this field provides scope information identifying the region and service for which the signature is valid. This should be the same scope used to calculate the signing key.

The string should be in the format: <your-access-key-id>/<date>/us-east-2/s3/aws4_request
x-amz-date The date of the request in ISO 8601 format (e.g. 20130728T000000Z). This date must match the date of your credential scope, or the request will be rejected. Yes
x-amz-signature The HMAC-SHA256 hash of the security policy. (AWS Signature Version 4) Yes
x-amz-meta-* Headers that start with this prefix are user-defined metadata. Each one is stored and returned as a set of key-value pairs. Arc doesn't validate nor interpret this metadata.
file The file content. This file content must be the last form field.

Only one file can be uploaded at a time.
Yes
Cache-Control, Content-Type, Content-Disposition, Content-Encoding, Expires REST specific headers. No
success_action_redirect The URL to which the client is redirected upon successful upload.

If success_action_redirect isn't specified, Arc returns the empty document type specified in the success_action_status field.

If an invalid URL is provided, this field is ignored.

If the upload fails, an error code is returned and the user isn't redirected.
No
success_action_status If success_action_redirect isn't specified, the specified status code is returned to the client when the upload succeeds. Valid values are 200, 201, and 204 (the default).

If the provided status code is 200 or 204, an empty document is returned with that status code.

If the provided status code is 201, an XML document is returned with 201 Created.

If no value is provided, or an invalid value provided, an empty document is returned with 204 No Content.
No

PUT Object

curl \
  -X PUT \
  -H "Date: <date>" \
  -H "Authorization: <authentication string>" \
  -d @file.txt \
  "https://storage.arc.io/<bucket>/<key>"

const AWS = require('aws-sdk')

const s3 = new AWS.S3()
const params = {
    Body: <Binary String>,
    Bucket: 'string',
    Key: 'string',
 }
 s3.putObject(params, (err, data) => {
    if (err) console.log(err, err.stack)
    else     console.log(data)
 })
import boto3

s3 = boto3.resource('s3')
obj = s3.Object('bucket', 'key')
obj.put(Body=b'bytes' | <file object>)
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import java.io.File;

final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
s3.putObject("bucket", "key", new File("file.txt"));

Add an object to a bucket.

Request Syntax

PUT /<bucket>/<key> HTTP/1.1
Host: storage.arc.io
Date: <date>
Content-Length: <request body length>
Content-Type: <MIME type>
Content-MD5: <MD5 digest>
Authorization: <authentication string>

Request Headers

Name Description Required
Content-Length The size of the object in bytes. Yes
Cache-Control Specify caching behavior along the request/reply chain. No
Content-Disposition Specify presentational information for the object. No
Content-Encoding Specify what content encodings have been applied to the object and thus what decoding mechanisms must be applied to obtain the media-type referenced by the Content-Type header field. No
Content-MD5 The base64-encoded 128-bit MD5 digest of the message (without the headers) according to RFC 1864. This header can be used as a message integrity check to verify that the data is the same data that was originally sent. Although optional, the Content-MD5 header is recommended. No
Content-Type The MIME type that describes the object's contents. No
Expect When your application uses 100 Continue, it doesn't send the request body until it receives an acknowledgment. If the first request is rejected, the message body isn't sent. No
Expires The date and time at which the object is no longer able to be cached. No
x-amz-meta-* Headers starting with this prefix are user-defined metadata. Within the PUT request header, this user-defined metadata is limited to 2KB in size. User-defined metadata is a set of key-value pairs. The size of user-defined metadata is the sum of the number of bytes in the UTF-8 encoding of each key and value. Arc doesn't validate nor interpret this metadata. No

Response Example

HTTP/1.1 200 OK
ETag: "881f7881ac1bc144a2672e45babb8839"
Date: Sat, 20 Feb 2010 16:31:09 GMT
Content-Length: 0
Content-Type: text/html

PUT Object - Copy

curl \
  -X PUT \
  -H "Date: <date>" \
  -H "Authorization: <authentication string>" \
  -H "X-Amz-Copy-Source: <sourceBucket>/<sourceKey>" \
  "https://storage.arc.io/<destinationBucket>/<destinationKey>"
const AWS = require('aws-sdk')

const s3 = new AWS.S3()
const params = {
    Bucket: 'destinationBucket',
    CopySource: '/sourceBucket/sourceKey',
    Key: 'destinationKey',
}
s3.copyObject(params, (err, data) => {
    if (err) console.log(err, err.stack)
    else     console.log(data)
})
import boto3

s3 = boto3.resource('s3')
copy_source = {
    'Bucket': 'sourceBucket',
    'Key': 'sourceKey',
}
bucket = s3.Bucket('destinationBucket')
bucket.copy(copy_source, 'destinationKey')
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.CopyObjectRequest;

final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
CopyObjectRequest copyObjRequest = new CopyObjectRequest(
    "sourceBucket", "sourceKey", "destinationBucket", "destinationKey");
s3.copyObject(copyObjRequest);

Create a copy of a pre-existing object. This operation is identical to a GET Object request followed by a subsequent PUT Object request.

Request Syntax

PUT /<destinationBucket>/<destinationKey> HTTP/1.1
Host: storage.arc.io
Date: <date>
Authorization: <authentication string>
X-Amz-Copy-Source: <sourceBucket>/<sourceKey>

Request Headers

Name Description Required
x-amz-copy-source The name of the source bucket and key name of the source object, separated by a slash (/).

Type: String
Yes
x-amz-metadata-directive Specify whether the metadata is copied from the source object or is replaced with metadata provided in the request.

Type: String.

Default: COPY.

Valid values: COPY, REPLACE.
No
x-amz-copy-source-if-match Copies the object if its entity tag (ETag) matches the specified tag. Otherwise, 412 Precondition Failed is returned.

For more information, see Note #1 below.

Type: String.

Constraints: This header can be used with x-amz-copy-source-if-unmodified-since, but it cannot be used with other conditional copy headers.
No
x-amz-copy-source-if-none-match Copies the object if its entity tag (ETag) is different than the specified ETag. Otherwise, 412 Precondition Failed is returned.

For more information, see Note #1 below.

Type: String.

Constraints: This header can be used with x-amz-copy-source-if-modified-since, but it cannot be used with other conditional copy headers.
No
x-amz-copy-source-if-unmodified-since Copies the object if it hasn't been modified since the specified time. Otherwise, the request returns a 412 HTTP status code error (failed precondition).

For more information, see Note #1 below.

Type: String.

Constraints: This must be a valid HTTP date. This header can be used with x-amz-copy-source-if-match, but cannot be used with other conditional copy headers.
No
x-amz-copy-source-if-modified-since Copies the object if it has been modified since the specified time; otherwise, the request returns a 412 HTTP status code error (failed condition).

For more information, see Note #2 below.

Type: String.

Constraints: This must be a valid HTTP date. This header can be used with x-amz-copy-source-if-none-match, but cannot be used with other conditional copy headers.
No

Response Example

HTTP/1.1 200 OK
ETag: "881f7881ac1bc144a2672e45babb8839"
Date: Sat, 20 Feb 2010 16:31:09 GMT
Content-Length: 0
Content-Type: text/html

S3 Compatibility

API

Arc's API is compatible with Amazon S3's API except for the differences enumerated below.

Amazon S3 Bucket APIs not yet supported by Arc:

Amazon S3 Object APIs not yet supported by Arc:

Limitations

Signature Versions

While Arc accepts both v2 and v4 signature versions, you should always use v4.

Regions

Arc doesn't support multiple regions yet. For any S3 operations that require a region, use us-east-2.