← All posts
2 min read

S3 CLI vs S3 API commands

#aws#cli#s3#storage
📑 On this page

Part 13 of AWS from Zero. S3 has two command families in AWS CLI:

aws s3 ...
aws s3api ...

This can feel strange at first. The shortcut version is: use aws s3 for file movement and aws s3api for exact API control.

What we are learning

The high-level aws s3 commands are convenient:

aws s3 ls
aws s3 cp
aws s3 sync
aws s3 rm

The lower-level aws s3api commands map more directly to S3 APIs:

aws s3api list-buckets
aws s3api create-bucket
aws s3api put-bucket-versioning
aws s3api head-object

You will use both throughout this series.

Before you run it

aws sts get-caller-identity
REGION="ap-south-1"
BUCKET="aws-zero-command-families-12345"

Create a bucket:

aws s3api create-bucket \
  --bucket "$BUCKET" \
  --region "$REGION" \
  --create-bucket-configuration LocationConstraint="$REGION"

Create a file:

echo "hello command families" > hello.txt

Use aws s3 for file movement

Upload:

aws s3 cp hello.txt "s3://$BUCKET/hello.txt"

List:

aws s3 ls "s3://$BUCKET/"

Download:

aws s3 cp "s3://$BUCKET/hello.txt" downloaded.txt

Use aws s3api for exact inspection

Inspect the object without downloading it:

aws s3api head-object \
  --bucket "$BUCKET" \
  --key hello.txt

Shape the output:

aws s3api head-object \
  --bucket "$BUCKET" \
  --key hello.txt \
  --query "{Size:ContentLength,Type:ContentType,Modified:LastModified}" \
  --output table

One tiny variation

Use high-level recursive listing:

aws s3 ls "s3://$BUCKET/" --recursive

Then use lower-level object listing:

aws s3api list-objects-v2 \
  --bucket "$BUCKET" \
  --query "Contents[].{Key:Key,Size:Size}" \
  --output table

Both show objects. The second gives you a more API-shaped response.

Common mistake

Do not expect every aws s3api operation to behave like a file command.

This works:

aws s3 cp hello.txt "s3://$BUCKET/hello.txt"

This is a different style:

aws s3api put-object \
  --bucket "$BUCKET" \
  --key hello.txt \
  --body hello.txt

Same destination, different command family.

Cleanup

Remove the object and bucket:

aws s3 rm "s3://$BUCKET/" --recursive
aws s3api delete-bucket --bucket "$BUCKET" --region "$REGION"
rm hello.txt downloaded.txt

Next, we will upload an object with custom metadata and inspect it with head-object.