| copyright |
|
||
|---|---|---|---|
| lastupdated | 2026-08-27 | ||
| keywords | object storage, node, javascript, sdk | ||
| subcollection | cloud-object-storage |
{{site.data.keyword.attribute-definition-list}}
{: #node-v2}
The {{site.data.keyword.cos_full}} SDK for Node.js v2 provides features to make the most of {{site.data.keyword.cos_full_notm}}.
The {{site.data.keyword.cos_full_notm}} SDK for Node.js v2 is comprehensive, with many features and capabilities that exceed the scope and space of this guide. For detailed class and method documentation, see the Node.js API reference documentation. Source code can be found in the GitHub repository.
{: #node-v2-whatsnew}
The {{site.data.keyword.cos_full_notm}} SDK for Node.js v2 is a modernized version that is built on the AWS SDK v3 architecture, bringing significant improvements:
- Modular architecture - Import only the commands and clients you need
- Promise-first design - Native async/await support with cleaner error handling
- Smaller bundle sizes - Tree-shakeable modules reduce application size
- Modern JavaScript - Leverages ES6+ features and TypeScript support
- Middleware stack - Extensible request/response pipeline
- Better error handling - Structured error types with detailed information
For developers migrating from v1, see the Migration Guide.
{: #node-v2-get}
The preferred way to install the IBM COS SDK for Node.js is to use the npm package manager for Node.js. Simply type the following into a terminal window:
npm install ibm-cos-sdk-v2{: #node-v2-prerequisites}
- Node.js 18 or later - The SDK requires a minimum version of Node.js 18 or newer.
- An instance of {{site.data.keyword.cos_full_notm}}
- An API key from IBM Cloud Identity and Access Management with at least
Writerpermissions - The ID of the instance of COS that you are working with
- Token acquisition endpoint
- Service endpoint
These values can be found in the IBM Cloud Console by generating a 'service credential'.
{: #node-v2-import-packages}
After you have installed the SDK, you will need to import the packages that you require into your Node.js applications to use the SDK, as shown in the following example:
CommonJS:
const { S3Client } = require('ibm-cos-sdk-v2');
const {
CreateBucketCommand,
ListBucketsCommand,
PutObjectCommand,
GetObjectCommand
} = require('ibm-cos-sdk-v2');ES Modules / TypeScript:
import { S3Client } from 'ibm-cos-sdk-v2';
import {
CreateBucketCommand,
ListBucketsCommand,
PutObjectCommand,
GetObjectCommand
} from 'ibm-cos-sdk-v2';{: #node-v2-reference}
{: #node-v2-reference-core-classes}
- S3Client - Primary client for interacting with {{site.data.keyword.cos_full_notm}}
- Command classes - Each operation has a corresponding command class (e.g.,
PutObjectCommand,GetObjectCommand)
{: #node-v2-reference-configurations}
- S3Client constructor - Creates a new S3 client with configuration options
- region - Sets the region for the client
- endpoint - Sets the service endpoint URL
- credentials - Sets authentication credentials
{: #node-v2-credentials}
To connect to {{site.data.keyword.cos_full_notm}}, a client is created and configured by providing credential information (API key and service instance ID). These values can also be automatically sourced from a credentials file or from environment variables.
The credentials can be found by creating a Service Credential, or through the CLI.
{: #node-v2-authentication}
The following example shows how to create a client using IBM IAM authentication with an API key:
CommonJS:
const { S3Client } = require('ibm-cos-sdk-v2');
// Initialize client
const client = new S3Client({
endpoint: 'https://s3.us-south.cloud-object-storage.appdomain.cloud',
region: 'us-south',
credentials: {
apiKey: '<API_KEY>',
serviceInstanceId: '<SERVICE_INSTANCE_ID>'
}
});TypeScript:
import { S3Client } from 'ibm-cos-sdk-v2';
const client = new S3Client({
endpoint: 'https://s3.us-south.cloud-object-storage.appdomain.cloud',
region: 'us-south',
credentials: {
apiKey: '<API_KEY>',
serviceInstanceId: '<SERVICE_INSTANCE_ID>'
}
});The required configuration options are:
endpoint- The endpoint URL for your COS bucket's regionregion- The region where your bucket is locatedcredentials.apiKey- Your IBM Cloud API key with appropriate permissionscredentials.serviceInstanceId- The CRN (Cloud Resource Name) of your COS instance
{: #node-v2-examples}
The following examples assume you have already created a client as shown in the previous section.
{: #node-v2-examples-create-bucket}
const { CreateBucketCommand } = require('ibm-cos-sdk-v2');
const command = new CreateBucketCommand({
Bucket: 'my-new-bucket',
CreateBucketConfiguration: {
LocationConstraint: 'us-south-standard'
}
});
try {
const response = await client.send(command);
console.log('Bucket created successfully');
} catch (err) {
console.error('Error creating bucket:', err);
}{: #node-v2-available-bucket}
const { ListBucketsCommand } = require('ibm-cos-sdk-v2');
try {
const command = new ListBucketsCommand({});
const response = await client.send(command);
console.log('Buckets:');
if (response.Buckets && response.Buckets.length > 0) {
response.Buckets.forEach(bucket => {
console.log(` - ${bucket.Name} (created: ${bucket.CreationDate})`);
});
} else {
console.log(' No buckets found');
}
} catch (err) {
console.error('Failed to list buckets:', err);
}{: #node-v2-list-bucket}
{{site.data.keyword.cos_full_notm}} provides an extended listing operation that returns additional bucket information:
const { ListBucketsExtendedCommand } = require('ibm-cos-sdk-v2');
const command = new ListBucketsExtendedCommand({
IBMServiceInstanceId: '<SERVICE_INSTANCE_ID>',
Prefix: 'my-bucket-prefix',
MaxKeys: 100
});
try {
const response = await client.send(command);
console.log('Extended Bucket Information:');
if (response.Buckets && response.Buckets.length > 0) {
response.Buckets.forEach(bucket => {
console.log(` Bucket: ${bucket.Name}`);
console.log(` Location: ${bucket.LocationConstraint}`);
console.log(` Created: ${bucket.CreationDate}`);
});
} else {
console.log(' No buckets found');
}
} catch (err) {
console.error('Failed to list buckets:', err);
}{: #node-v2-location-bucket}
const { GetBucketLocationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new GetBucketLocationCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`Bucket '${bucketName}' is located in: ${response.LocationConstraint}`);
} catch (err) {
console.error('Failed to get bucket location:', err);
}{: #node-v2-delete-bucket}
const { DeleteBucketCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket-to-delete';
const command = new DeleteBucketCommand({
Bucket: bucketName
});
try {
await client.send(command);
console.log(`Bucket '${bucketName}' deleted successfully`);
} catch (err) {
console.error('Failed to delete bucket:', err);
}Note: A bucket must be empty before it can be deleted.
{: #node-v2-upload-object}
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const content = 'Hello, IBM Cloud Object Storage!';
const command = new PutObjectCommand({
Bucket: bucketName,
Key: objectKey,
Body: content
});
try {
const response = await client.send(command);
console.log(`Object '${objectKey}' uploaded successfully`);
console.log(`ETag: ${response.ETag}`);
} catch (err) {
console.error('Failed to upload object:', err);
}{: #node-v2-download-bucket}
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new GetObjectCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
// Convert stream to buffer
const chunks = [];
for await (const chunk of response.Body) {
chunks.push(chunk);
}
const buffer = Buffer.concat(chunks);
console.log(`Object '${objectKey}' downloaded successfully`);
console.log(`Content-Type: ${response.ContentType}`);
console.log(`Content-Length: ${response.ContentLength} bytes`);
console.log(`Size: ${buffer.length} bytes`);
} catch (err) {
console.error('Failed to download object:', err);
}{: #node-v2-list-object}
const { ListObjectsV2Command } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListObjectsV2Command({
Bucket: bucketName,
MaxKeys: 1000
});
try {
const response = await client.send(command);
console.log(`Objects in bucket '${bucketName}':`);
if (response.Contents && response.Contents.length > 0) {
response.Contents.forEach(object => {
console.log(` - ${object.Key} (size: ${object.Size} bytes, modified: ${object.LastModified})`);
});
console.log(`\nTotal objects: ${response.Contents.length}`);
} else {
console.log(' No objects found');
}
} catch (err) {
console.error('Failed to list objects:', err);
}{: #node-v2-copy-object}
const { CopyObjectCommand } = require('ibm-cos-sdk-v2');
const sourceBucket = 'source-bucket';
const sourceKey = 'source-object.txt';
const destinationBucket = 'destination-bucket';
const destinationKey = 'destination-object.txt';
// CopySource format: source-bucket/source-key
const copySource = `${sourceBucket}/${sourceKey}`;
const command = new CopyObjectCommand({
Bucket: destinationBucket,
Key: destinationKey,
CopySource: copySource
});
try {
const response = await client.send(command);
console.log('Object copied successfully');
if (response.CopyObjectResult) {
console.log(`ETag: ${response.CopyObjectResult.ETag}`);
}
} catch (err) {
console.error('Failed to copy object:', err);
}{: #node-v2-delete-object}
const { DeleteObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'object-to-delete.txt';
const command = new DeleteObjectCommand({
Bucket: bucketName,
Key: objectKey
});
try {
await client.send(command);
console.log(`Object '${objectKey}' deleted successfully`);
} catch (err) {
console.error('Failed to delete object:', err);
}{: #node-v2-delete-multiple-object}
const { DeleteObjectsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectsToDelete = [
'object1.txt',
'object2.txt',
'object3.txt'
];
// Build delete request
const objects = objectsToDelete.map(key => ({ Key: key }));
const command = new DeleteObjectsCommand({
Bucket: bucketName,
Delete: {
Objects: objects,
Quiet: false
}
});
try {
const response = await client.send(command);
console.log('Delete operation completed');
if (response.Deleted && response.Deleted.length > 0) {
console.log(`Successfully deleted ${response.Deleted.length} object(s):`);
response.Deleted.forEach(deleted => {
console.log(` - ${deleted.Key}`);
});
}
if (response.Errors && response.Errors.length > 0) {
console.log(`\nFailed to delete ${response.Errors.length} object(s):`);
response.Errors.forEach(error => {
console.log(` - ${error.Key}: ${error.Message}`);
});
}
} catch (err) {
console.error('Failed to delete objects:', err);
}{: #node-v2-get-object}
const { HeadObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new HeadObjectCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
console.log(`Object Metadata for '${objectKey}':`);
console.log(` Content-Type: ${response.ContentType}`);
console.log(` Content-Length: ${response.ContentLength} bytes`);
console.log(` ETag: ${response.ETag}`);
console.log(` Last-Modified: ${response.LastModified}`);
if (response.Metadata && Object.keys(response.Metadata).length > 0) {
console.log(' Custom Metadata:');
for (const [key, value] of Object.entries(response.Metadata)) {
console.log(` ${key}: ${value}`);
}
}
} catch (err) {
console.error('Failed to get object metadata:', err);
}{: #node-v2-upload-multipart-object}
For large objects, multipart upload provides improved throughput and the ability to resume uploads. Each part must be at least 5 MB (except the last part).
Manual Multipart Upload:
const {
CreateMultipartUploadCommand,
UploadPartCommand,
CompleteMultipartUploadCommand,
AbortMultipartUploadCommand
} = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'large-object.dat';
try {
// Step 1: Initiate multipart upload
const createCommand = new CreateMultipartUploadCommand({
Bucket: bucketName,
Key: objectKey
});
const createResponse = await client.send(createCommand);
const uploadId = createResponse.UploadId;
console.log(`Multipart upload initiated with ID: ${uploadId}`);
// Step 2: Upload parts (minimum 5MB per part except last)
const completedParts = [];
const minPartSize = 5 * 1024 * 1024; // 5MB
// Create sample parts
const parts = [
'A'.repeat(minPartSize),
'B'.repeat(minPartSize)
];
for (let i = 0; i < parts.length; i++) {
const partNumber = i + 1;
const uploadPartCommand = new UploadPartCommand({
Bucket: bucketName,
Key: objectKey,
PartNumber: partNumber,
UploadId: uploadId,
Body: parts[i]
});
try {
const uploadResponse = await client.send(uploadPartCommand);
completedParts.push({
ETag: uploadResponse.ETag,
PartNumber: partNumber
});
console.log(`Part ${partNumber} uploaded (ETag: ${uploadResponse.ETag})`);
} catch (err) {
// Abort multipart upload on error
const abortCommand = new AbortMultipartUploadCommand({
Bucket: bucketName,
Key: objectKey,
UploadId: uploadId
});
await client.send(abortCommand);
throw err;
}
}
// Step 3: Complete multipart upload
const completeCommand = new CompleteMultipartUploadCommand({
Bucket: bucketName,
Key: objectKey,
UploadId: uploadId,
MultipartUpload: {
Parts: completedParts
}
});
const completeResponse = await client.send(completeCommand);
console.log('Multipart upload completed successfully');
console.log(`Location: ${completeResponse.Location}`);
console.log(`ETag: ${completeResponse.ETag}`);
} catch (err) {
console.error('Failed to complete multipart upload:', err);
}Using Upload Manager (Recommended):
For easier multipart uploads, use the @ibm-cos/lib-storage package:
const { Upload } = require('@ibm-cos/lib-storage');
const { S3Client } = require('ibm-cos-sdk-v2');
const fs = require('fs');
const fileStream = fs.createReadStream('large-file.bin');
const upload = new Upload({
client: client,
params: {
Bucket: 'my-bucket',
Key: 'large-file.bin',
Body: fileStream
},
queueSize: 4, // Concurrent parts
partSize: 5 * 1024 * 1024, // 5MB parts
leavePartsOnError: false
});
// Track progress
upload.on('httpUploadProgress', (progress) => {
console.log('Upload progress:', progress);
});
try {
const result = await upload.done();
console.log('Upload completed:', result);
} catch (err) {
console.error('Upload failed:', err);
}{: #node-v2-list-multipart-upload}
const { ListMultipartUploadsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListMultipartUploadsCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`In-progress multipart uploads in bucket '${bucketName}':`);
if (response.Uploads && response.Uploads.length > 0) {
response.Uploads.forEach(upload => {
console.log(` Key: ${upload.Key}`);
console.log(` Upload ID: ${upload.UploadId}`);
console.log(` Initiated: ${upload.Initiated}`);
});
} else {
console.log(' No in-progress uploads found');
}
} catch (err) {
console.error('Failed to list multipart uploads:', err);
}{: #node-v2-list-parts}
Lists all uploaded parts for an in-progress multipart upload. Useful for inspecting progress or gathering ETags before completing the upload.
const { ListPartsCommand } = require('ibm-cos-sdk-v2');
const command = new ListPartsCommand({
Bucket: 'my-bucket',
Key: 'my-large-object',
UploadId: 'YOUR_UPLOAD_ID_HERE'
});
try {
const response = await client.send(command);
console.log('Parts listed successfully');
if (response.Parts && response.Parts.length > 0) {
response.Parts.forEach(p =>
console.log(' - Part', p.PartNumber, '| ETag:', p.ETag, '| Size:', p.Size, 'bytes')
);
} else {
console.log('No parts found.');
}
} catch (err) {
console.error('Error listing parts:', err);
}{: #node-v2-copy-part-upload}
Uploads a part by copying from an existing object. Use this instead of uploading raw bytes when the source data already exists in COS.
const { UploadPartCopyCommand } = require('ibm-cos-sdk-v2');
const command = new UploadPartCopyCommand({
Bucket: 'my-bucket',
Key: 'my-large-object',
UploadId: 'YOUR_UPLOAD_ID_HERE',
PartNumber: 1,
CopySource: 'my-bucket/source-object-key'
});
try {
const response = await client.send(command);
console.log('Part copy uploaded successfully');
console.log('ETag:', response.CopyPartResult?.ETag);
} catch (err) {
console.error('Error uploading part copy:', err);
}{: #node-v2-bucket-lifecycle}
Archive policies allow you to automatically transition objects to archive storage classes after a specified time period:
const { PutBucketLifecycleConfigurationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
// Configure lifecycle rule to expire objects after 30 days
const command = new PutBucketLifecycleConfigurationCommand({
Bucket: bucketName,
LifecycleConfiguration: {
Rules: [
{
Id: 'delete-old-logs',
Status: 'Enabled',
Filter: {
Prefix: 'logs/',
},
Expiration: {
Days: 30,
},
},
{
Id: 'cleanup-multipart-uploads',
Status: 'Enabled',
Filter: {
Prefix: '',
},
AbortIncompleteMultipartUpload: {
DaysAfterInitiation: 7,
},
},
]
}
});
try {
await client.send(command);
console.log(`Lifecycle configuration set for bucket '${bucketName}'`);
} catch (err) {
console.error('Failed to set lifecycle configuration:', err);
}{: #node-v2-get-bucket-lifecycle}
const { GetBucketLifecycleConfigurationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new GetBucketLifecycleConfigurationCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`Lifecycle rules for bucket '${bucketName}':`);
if (response.Rules && response.Rules.length > 0) {
response.Rules.forEach(rule => {
console.log(` Rule ID: ${rule.ID}`);
console.log(` Status: ${rule.Status}`);
if (rule.Transitions && rule.Transitions.length > 0) {
rule.Transitions.forEach(transition => {
console.log(` Transition to ${transition.StorageClass} after ${transition.Days} days`);
});
}
});
} else {
console.log(' No lifecycle rules found');
}
} catch (err) {
console.error('Failed to get lifecycle configuration:', err);
}{: #node-v2-enable-versioning}
const { PutBucketVersioningCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new PutBucketVersioningCommand({
Bucket: bucketName,
VersioningConfiguration: {
// Valid values: 'Enabled' | 'Suspended'
Status: 'Enabled',
},
});
try {
await client.send(command);
console.log(`Versioning enabled for bucket '${bucketName}'`);
} catch (err) {
console.error('Failed to enable versioning:', err);
}{: #node-v2-list-version}
const { ListObjectVersionsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListObjectVersionsCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`Object versions in bucket '${bucketName}':`);
if (response.Versions && response.Versions.length > 0) {
response.Versions.forEach(version => {
console.log(` Key: ${version.Key}`);
console.log(` Version ID: ${version.VersionId}`);
console.log(` Is Latest: ${version.IsLatest}`);
console.log(` Last Modified: ${version.LastModified}`);
});
} else {
console.log(' No versions found');
}
} catch (err) {
console.error('Failed to list object versions:', err);
}{: #node-v2-set-cors}
const { PutBucketCorsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
// Set CORS configuration
const command = new PutBucketCorsCommand({
Bucket: bucketName,
CORSConfiguration: {
CORSRules: [
{
AllowedHeaders: ['*'],
AllowedMethods: ['GET', 'PUT', 'POST', 'DELETE'],
AllowedOrigins: ['https://example.com'],
ExposeHeaders: ['ETag'],
MaxAgeSeconds: 3000
}
]
}
});
try {
await client.send(command);
console.log(`CORS configuration set for bucket '${bucketName}'`);
} catch (err) {
console.error('Failed to set CORS configuration:', err);
}{: #node-v2-set-tagging}
const { PutObjectTaggingCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
// Set object tags
const command = new PutObjectTaggingCommand({
Bucket: bucketName,
Key: objectKey,
Tagging: {
TagSet: [
{
Key: 'Department',
Value: 'Finance'
},
{
Key: 'Project',
Value: 'Q4-2024'
},
{
Key: 'Classification',
Value: 'Confidential'
}
]
}
});
try {
await client.send(command);
console.log(`Tags set for object '${objectKey}'`);
} catch (err) {
console.error('Failed to set object tags:', err);
}{: #node-v2-get-object-tag}
const { GetObjectTaggingCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new GetObjectTaggingCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
console.log(`Tags for object '${objectKey}':`);
if (response.TagSet && response.TagSet.length > 0) {
response.TagSet.forEach(tag => {
console.log(` ${tag.Key}: ${tag.Value}`);
});
} else {
console.log(' No tags found');
}
} catch (err) {
console.error('Failed to get object tags:', err);
}{: #node-v2-restore-object}
Objects in archive storage classes must be restored before they can be accessed:
const command = new RestoreObjectCommand({
Bucket: bucketName,
Key: objectKey,
RestoreRequest: {
Days: 7,
GlacierJobParameters: {
Tier: 'Bulk',
},
},
});
try {
await client.send(command);
console.log('Object restore initiated successfully');
console.log(
'Retrieval time depends on storage class: Vault typically 1-5 hours, Cold Vault typically 5-12 hours.'
);
} catch (err) {
console.error('Failed to restore object:', err);
}Note: {{site.data.keyword.cos_full_notm}} supports only the Bulk retrieval tier for restoring objects from Vault and Cold Vault storage classes.
{: #node-v2-set-object-retention}
Governance mode: Users with specific IAM permissions can delete object versions during the retention period. {: note}
Compliance mode: No users can delete object versions during the retention period. {: note}
const { PutObjectRetentionCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-protected-bucket';
const objectKey = 'important-document.pdf';
// Set retention until a specific date
const retainUntil = new Date();
retainUntil.setDate(retainUntil.getDate() + 30);
const command = new PutObjectRetentionCommand({
Bucket: bucketName,
Key: objectKey,
Retention: {
Mode: 'COMPLIANCE',
RetainUntilDate: retainUntil,
},
});
try {
await client.send(command);
console.log('Object retention set successfully');
console.log('RetainUntil:', retainUntil.toISOString());
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-get-object-retention}
const { GetObjectRetentionCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-protected-bucket';
const objectKey = 'important-document.pdf';
const command = new GetObjectRetentionCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
console.log('Object retention retrieved successfully');
console.log('Mode:', response.Retention?.Mode);
console.log('RetainUntilDate:', response.Retention?.RetainUntilDate);
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-create-bucket-object-lock}
S3 Object Lock prevents objects from being deleted or overwritten for a fixed retention period or indefinitely. Object Lock must be enabled at bucket creation time — it cannot be added to an existing bucket.
Governance mode: Users with specific IAM permissions can delete object versions during the retention period. {: note}
Compliance mode: No users can delete object versions during the retention period. {: note}
This section covers S3-compatible Object Lock. For IBM COS-specific WORM protection, see Setting bucket protection (WORM) and Managing legal holds. {: note}
const {
CreateBucketCommand,
PutObjectLockConfigurationCommand
} = require('ibm-cos-sdk-v2');
// Step 1: Create bucket with Object Lock enabled
const createCommand = new CreateBucketCommand({
Bucket: 'my-locked-bucket',
ObjectLockEnabledForBucket: true
});
try {
await client.send(createCommand);
console.log('Bucket created with Object Lock enabled');
} catch (err) {
console.error('Error creating bucket:', err.message);
}
// Step 2: Set default retention rule
const lockConfigCommand = new PutObjectLockConfigurationCommand({
Bucket: 'my-locked-bucket',
ObjectLockConfiguration: {
ObjectLockEnabled: 'Enabled',
Rule: {
DefaultRetention: {
Mode: 'GOVERNANCE',
Days: 30
}
}
}
});
try {
await client.send(lockConfigCommand);
console.log('Default Object Lock configuration set successfully');
} catch (err) {
console.error('Error setting lock config:', err.message);
}{: #node-v2-put-object-lock-config}
Sets or updates the default retention rule applied to every new object uploaded to a bucket.
const { PutObjectLockConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectLockConfigurationCommand({
Bucket: 'my-object-lock-bucket',
ObjectLockConfiguration: {
ObjectLockEnabled: 'Enabled',
Rule: {
DefaultRetention: {
Mode: 'COMPLIANCE',
Days: 2
}
}
}
});
try {
await client.send(command);
console.log('Object lock configuration set successfully');
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-get-object-lock-config}
const { GetObjectLockConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectLockConfigurationCommand({
Bucket: 'my-object-lock-bucket'
});
try {
const response = await client.send(command);
console.log('Object lock configuration retrieved successfully');
console.log('ObjectLockEnabled:', response.ObjectLockConfiguration?.ObjectLockEnabled);
console.log('Rule:', JSON.stringify(response.ObjectLockConfiguration?.Rule, null, 2));
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-put-object-legal-hold}
Places or removes a legal hold on an object. While a legal hold is active the object cannot be deleted, regardless of its retention period.
const { PutObjectLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectLegalHoldCommand({
Bucket: 'my-locked-bucket',
Key: 'my-file.txt',
LegalHold: {
Status: 'ON' // 'ON' or 'OFF'
}
});
try {
await client.send(command);
console.log('Legal hold set successfully');
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-get-object-legal-hold}
const { GetObjectLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectLegalHoldCommand({
Bucket: 'my-locked-bucket',
Key: 'my-file.txt'
});
try {
const response = await client.send(command);
console.log('Legal hold retrieved successfully');
console.log('Status:', response.LegalHold?.Status);
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-head-bucket}
const { HeadBucketCommand } = require('ibm-cos-sdk-v2');
const command = new HeadBucketCommand({
Bucket: 'my-bucket'
});
try {
await client.send(command);
console.log('Bucket exists');
} catch (err) {
if (err.name === 'NotFound') {
console.log('Bucket does not exist');
} else {
console.error('Error checking bucket:', err);
}
}{: #node-v2-stream-upload}
const fs = require('fs');
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const fileStream = fs.createReadStream('large-file.bin');
const command = new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'large-file.bin',
Body: fileStream
});
try {
const response = await client.send(command);
console.log('File uploaded successfully');
} catch (err) {
console.error('Error uploading file:', err);
}{: #node-v2-stream-download}
const fs = require('fs');
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'large-file.bin'
});
try {
const response = await client.send(command);
const fileStream = fs.createWriteStream('downloaded-file.bin');
response.Body.pipe(fileStream);
await new Promise((resolve, reject) => {
fileStream.on('finish', resolve);
fileStream.on('error', reject);
response.Body.on('error', reject);
});
console.log('File downloaded successfully');
} catch (err) {
console.error('Error downloading file:', err);
}{: #node-v2-paginate-objects}
The v2 SDK provides built-in paginators for operations that return truncated results.
Using a paginator (recommended):
const { paginateListObjectsV2 } = require('ibm-cos-sdk-v2');
async function listAllObjects(bucket, prefix) {
const allObjects = [];
const paginator = paginateListObjectsV2(
{ client: client, pageSize: 1000 },
{ Bucket: bucket, Prefix: prefix }
);
try {
for await (const page of paginator) {
if (page.Contents) {
allObjects.push(...page.Contents);
}
}
console.log('Total objects:', allObjects.length);
return allObjects;
} catch (err) {
console.error('Error listing objects:', err);
throw err;
}
}Manual pagination:
const { ListObjectsV2Command } = require('ibm-cos-sdk-v2');
async function listAllObjects(bucket, prefix) {
const allObjects = [];
let continuationToken = undefined;
do {
const command = new ListObjectsV2Command({
Bucket: bucket,
Prefix: prefix,
ContinuationToken: continuationToken
});
const response = await client.send(command);
if (response.Contents) {
allObjects.push(...response.Contents);
}
continuationToken = response.NextContinuationToken;
} while (continuationToken);
console.log('Total objects:', allObjects.length);
return allObjects;
}{: #node-v2-presigned-urls}
Presigned URLs allow temporary, unauthenticated access to objects. Install the presigner package first:
npm install @ibm-cos/s3-request-presignerPresigned GET URL (download):
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const { getSignedUrl } = require('@ibm-cos/s3-request-presigner');
const command = new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt'
});
try {
const url = await getSignedUrl(client, command, { expiresIn: 3600 });
console.log('Presigned URL:', url);
} catch (err) {
console.error('Error generating presigned URL:', err);
}Presigned PUT URL (upload):
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const { getSignedUrl } = require('@ibm-cos/s3-request-presigner');
const command = new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'upload-object.txt',
ContentType: 'text/plain'
});
try {
const url = await getSignedUrl(client, command, { expiresIn: 3600 });
console.log('Presigned PUT URL:', url);
} catch (err) {
console.error('Error generating presigned URL:', err);
}{: #node-v2-get-cors}
const { GetBucketCorsCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketCorsCommand({
Bucket: 'my-bucket'
});
try {
const response = await client.send(command);
console.log('CORS rules:', response.CORSRules);
} catch (err) {
console.error('Error getting CORS configuration:', err);
}{: #node-v2-delete-cors}
const { DeleteBucketCorsCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketCorsCommand({
Bucket: 'my-bucket'
});
try {
await client.send(command);
console.log('Bucket CORS configuration deleted successfully');
} catch (err) {
console.error('Error deleting CORS:', err);
}{: #node-v2-delete-object-tags}
const { DeleteObjectTaggingCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteObjectTaggingCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt'
});
try {
await client.send(command);
console.log('Object tagging deleted successfully');
} catch (err) {
console.error('Error deleting object tags:', err);
}{: #node-v2-upload-object-metadata}
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt',
Body: 'content',
Metadata: {
'author': 'John Doe',
'department': 'Engineering'
}
});
try {
await client.send(command);
console.log('Object uploaded with metadata');
} catch (err) {
console.error('Error uploading object:', err);
}{: #node-v2-set-bucket-tagging}
const { PutBucketTaggingCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketTaggingCommand({
Bucket: 'my-bucket',
Tagging: {
TagSet: [
{ Key: 'Environment', Value: 'Production' },
{ Key: 'Project', Value: 'WebApp' }
]
}
});
try {
await client.send(command);
console.log('Bucket tags updated');
} catch (err) {
console.error('Error updating bucket tags:', err);
}{: #node-v2-delete-bucket-lifecycle}
const { DeleteBucketLifecycleCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketLifecycleCommand({
Bucket: 'my-bucket'
});
try {
await client.send(command);
console.log('Lifecycle configuration deleted successfully');
} catch (err) {
console.error('Error deleting lifecycle:', err);
}{: #node-v2-set-bucket-acl}
const { PutBucketAclCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketAclCommand({
Bucket: 'my-bucket',
ACL: 'public-read'
});
try {
await client.send(command);
console.log('Bucket ACL updated');
} catch (err) {
console.error('Error updating bucket ACL:', err);
}{: #node-v2-get-bucket-acl}
const { GetBucketAclCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketAclCommand({
Bucket: 'my-bucket'
});
try {
const response = await client.send(command);
console.log('Bucket ACL retrieved successfully');
console.log('Owner:', response.Owner);
console.log('Grants:', response.Grants);
} catch (err) {
console.error('Error getting bucket ACL:', err);
}{: #node-v2-set-object-acl}
const { PutObjectAclCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectAclCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt',
ACL: 'public-read'
});
try {
await client.send(command);
console.log('Object ACL updated');
} catch (err) {
console.error('Error updating object ACL:', err);
}{: #node-v2-get-object-acl}
const { GetObjectAclCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectAclCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt'
});
try {
const response = await client.send(command);
console.log('Object ACL retrieved successfully');
console.log('Owner:', response.Owner);
console.log('Grants:', response.Grants);
} catch (err) {
console.error('Error getting object ACL:', err);
}{: #node-v2-get-versioning}
const { GetBucketVersioningCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketVersioningCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Bucket versioning configuration retrieved successfully');
console.log('Status:', response.Status);
// MFADelete is always undefined for IBM COS.
console.log('MFADelete:', response.MFADelete);
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-get-object-version}
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'my-file.txt',
VersionId: '<VERSION_ID>'
});
try {
const response = await client.send(command);
console.log('Version ID:', response.VersionId);
// Stream response.Body to a file or buffer as needed.
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-put-object-versioned}
When versioning is enabled, each PutObjectCommand call creates a new version. The response includes the new VersionId.
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectCommand({
Bucket: 'my-versioned-bucket',
Key: 'my-file.txt',
Body: 'Hello, World!'
});
try {
const response = await client.send(command);
console.log('Object uploaded successfully');
console.log('Version ID:', response.VersionId);
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-delete-object-version}
Permanently removes one specific version of an object by including its VersionId. Without a version ID on a versioned bucket, a delete marker is created instead.
const { DeleteObjectCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteObjectCommand({
Bucket: 'my-versioned-bucket',
Key: 'my-file.txt',
VersionId: 'YOUR_VERSION_ID_HERE'
});
try {
const response = await client.send(command);
console.log('Object version deleted successfully');
console.log('Deleted Version ID:', response.VersionId);
console.log('Delete Marker:', response.DeleteMarker ? 'Yes' : 'No');
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-bucket-protection}
{{site.data.keyword.cos_full_notm}} supports Write-Once-Read-Many (WORM) bucket protection for compliance and data retention.
Setting bucket protection:
const { PutBucketProtectionConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketProtectionConfigurationCommand({
Bucket: 'my-protected-bucket',
ProtectionConfiguration: {
Status: 'Retention',
MinimumRetention: { Days: 1 },
DefaultRetention: { Days: 30 },
MaximumRetention: { Days: 365 },
},
});
try {
await client.send(command);
console.log('Bucket protection configuration set successfully');
} catch (err) {
console.error('Error configuring protection:', err.message);
}Getting bucket protection:
const { GetBucketProtectionConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketProtectionConfigurationCommand({
Bucket: 'my-protected-bucket'
});
try {
const response = await client.send(command);
console.log('Bucket protection configuration retrieved successfully');
console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
console.error('Error getting protection config:', err);
}{: #node-v2-legal-hold}
Legal holds prevent object deletion regardless of retention period expiry. Each hold is identified by a unique ID and all holds must be explicitly removed before an object can be deleted.
Note: Legal holds require the bucket to have an IBM COS protection configuration set. {: note}
Adding a legal hold:
const { AddLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new AddLegalHoldCommand({
Bucket: 'my-protected-bucket',
Key: 'important-document.pdf',
RetentionLegalHoldId: 'legal-case-12345'
});
try {
await client.send(command);
console.log('Legal hold added');
} catch (err) {
console.error('Error adding legal hold:', err);
}Listing legal holds:
const { ListLegalHoldsCommand } = require('ibm-cos-sdk-v2');
const command = new ListLegalHoldsCommand({
Bucket: 'my-protected-bucket',
Key: 'important-document.pdf'
});
try {
const response = await client.send(command);
console.log('Legal holds listed successfully');
console.log('Legal holds:', JSON.stringify(response.LegalHolds, null, 2));
} catch (err) {
console.error('Error listing legal holds:', err);
}Deleting a legal hold:
const { DeleteLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteLegalHoldCommand({
Bucket: 'my-protected-bucket',
Key: 'important-document.pdf',
RetentionLegalHoldId: 'legal-case-12345'
});
try {
await client.send(command);
console.log('Legal hold removed');
} catch (err) {
console.error('Error removing legal hold:', err);
}{: #node-v2-key-protect}
IBM Key Protect provides encryption key management for bucket-level encryption:
const { CreateBucketCommand } = require('ibm-cos-sdk-v2');
const command = new CreateBucketCommand({
Bucket: 'my-encrypted-bucket',
CreateBucketConfiguration: {
LocationConstraint: 'us-south-standard'
},
IBMSSEKPEncryptionAlgorithm: 'AES256',
IBMSSEKPCustomerRootKeyCrn: 'crn:v1:bluemix:public:kms:us-south:...'
});
try {
await client.send(command);
console.log('Encrypted bucket created');
} catch (err) {
console.error('Error creating encrypted bucket:', err);
}{: #node-v2-rename-object}
RenameObject is an IBM COS-specific atomic server-side operation. No data is transferred — only the key changes:
const { RenameObjectCommand } = require('ibm-cos-sdk-v2');
const command = new RenameObjectCommand({
Bucket: 'my-bucket',
Key: 'new-object-key', // destination key
RenameSource: 'my-bucket/old-object-key' // source: bucket/key
});
try {
await client.send(command);
console.log('Object renamed successfully');
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-update-object-encryption}
UpdateObjectEncryption updates the encryption key reference on an existing object. Requires the bucket to have IBM Key Protect or HPCS configured:
const { UpdateObjectEncryptionCommand } = require('ibm-cos-sdk-v2');
const command = new UpdateObjectEncryptionCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt'
});
try {
await client.send(command);
console.log('Object encryption updated successfully');
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-bucket-replication}
Getting replication configuration:
const { GetBucketReplicationCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketReplicationCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Bucket replication configuration retrieved successfully');
console.log('Rules:', JSON.stringify(response.ReplicationConfiguration?.Rules, null, 2));
} catch (err) {
console.error('Error:', err.message);
}Deleting replication configuration:
const { DeleteBucketReplicationCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketReplicationCommand({ Bucket: 'my-bucket' });
try {
await client.send(command);
console.log('Bucket replication configuration deleted successfully');
} catch (err) {
console.error('Error:', err.message);
}Listing replication failures:
const { ListBucketReplicationFailuresCommand } = require('ibm-cos-sdk-v2');
const command = new ListBucketReplicationFailuresCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Bucket replication failures listed successfully');
console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
console.error('Error:', err.message);
}Reattempting failed replications:
const { PutBucketReplicationReattemptCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketReplicationReattemptCommand({ Bucket: 'my-bucket' });
try {
await client.send(command);
console.log('Bucket replication reattempt triggered successfully');
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-create-session}
CreateSession creates a temporary session token for an {{site.data.keyword.cos_full_notm}} bucket:
const { CreateSessionCommand } = require('ibm-cos-sdk-v2');
const command = new CreateSessionCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Session created successfully');
console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
console.error('Error:', err.message);
}{: #node-v2-waiters}
Waiters poll a resource until it reaches a desired state, removing the need for manual polling loops.
Waiting for a bucket to exist:
const { waitUntilBucketExists } = require('ibm-cos-sdk-v2');
try {
await waitUntilBucketExists(
{
client: client,
maxWaitTime: 120, // Maximum wait time in seconds
minDelay: 2, // Minimum delay between checks in seconds
maxDelay: 10 // Maximum delay between checks in seconds
},
{ Bucket: 'my-bucket' }
);
console.log('Bucket exists and is ready');
} catch (err) {
console.error('Bucket did not become available:', err);
}Waiting for an object to exist:
const { waitUntilObjectExists } = require('ibm-cos-sdk-v2');
try {
await waitUntilObjectExists(
{
client: client,
maxWaitTime: 60,
minDelay: 1,
maxDelay: 5
},
{
Bucket: 'my-bucket',
Key: 'my-object.txt'
}
);
console.log('Object exists and is ready');
} catch (err) {
console.error('Object did not become available:', err);
}{: #node-v2-next-steps}
- Review the Node.js API reference documentation for detailed information on all available methods and types
- Explore the GitHub repository for additional examples and source code
- Read the Migration Guide if you're upgrading from v1
- Check out the IBM Cloud Object Storage documentation for service-specific features and best practices
- For help and support:
- Ask questions on Stack Overflow with tags
ibmandobject-storage - Open an issue on GitHub
- Contact IBM Cloud Support
- Ask questions on Stack Overflow with tags