Storage API Reference
REST endpoints for buckets (CRUD) and objects (CRUD), multipart upload, presigned URLs, versioning. Example requests and responses.
NFYio provides an S3-compatible storage API. Use the AWS SDK, AWS CLI, or direct REST calls. This reference covers the main REST endpoints and patterns.
Base URL: https://storage.yourdomain.com (or your configured endpoint)
Buckets
Create Bucket
PUT /{bucket-name} HTTP/1.1
Host: storage.yourdomain.com
Authorization: AWS4-HMAC-SHA256 Credential=...
cURL (using AWS CLI profile):
aws --endpoint-url https://storage.yourdomain.com s3 mb s3://my-bucket
Response: 200 OK (bucket created)
List Buckets
GET / HTTP/1.1
Host: storage.yourdomain.com
Authorization: AWS4-HMAC-SHA256 Credential=...
Response:
<?xml version="1.0" encoding="UTF-8"?>
<ListAllMyBucketsResult>
<Buckets>
<Bucket>
<Name>my-bucket</Name>
<CreationDate>2026-03-01T12:00:00.000Z</CreationDate>
</Bucket>
</Buckets>
</ListAllMyBucketsResult>
Delete Bucket
DELETE /{bucket-name} HTTP/1.1
Host: storage.yourdomain.com
Authorization: AWS4-HMAC-SHA256 Credential=...
Note: Bucket must be empty. Delete all objects first.
Get Bucket Versioning
GET /{bucket-name}?versioning HTTP/1.1
Host: storage.yourdomain.com
Authorization: AWS4-HMAC-SHA256 Credential=...
Response:
<VersioningConfiguration>
<Status>Enabled</Status>
</VersioningConfiguration>
Put Bucket Versioning
PUT /{bucket-name}?versioning HTTP/1.1
Host: storage.yourdomain.com
Content-Type: application/xml
Authorization: AWS4-HMAC-SHA256 Credential=...
<VersioningConfiguration>
<Status>Enabled</Status>
</VersioningConfiguration>
Objects
Put Object
PUT /{bucket-name}/{object-key} HTTP/1.1
Host: storage.yourdomain.com
Content-Type: application/octet-stream
Content-Length: 1234
Authorization: AWS4-HMAC-SHA256 Credential=...
[binary body]
cURL:
curl -X PUT "https://storage.yourdomain.com/my-bucket/path/to/file.txt" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: text/plain" \
--data-binary @file.txt
Response: 200 OK with optional headers:
ETag: "d41d8cd98f00b204e9800998ecf8427e"
x-amz-version-id: 3/L4kqtJl40Nr8X8gdRQBOFU
Get Object
GET /{bucket-name}/{object-key} HTTP/1.1
Host: storage.yourdomain.com
Authorization: AWS4-HMAC-SHA256 Credential=...
Response: 200 OK with object body and headers:
Content-Type: application/octet-stream
Content-Length: 1234
ETag: "d41d8cd98f00b204e9800998ecf8427e"
Last-Modified: Mon, 01 Mar 2026 12:00:00 GMT
List Objects
GET /{bucket-name}?list-type=2&prefix=path/&max-keys=1000 HTTP/1.1
Host: storage.yourdomain.com
Authorization: AWS4-HMAC-SHA256 Credential=...
Response:
<ListBucketResult>
<Name>my-bucket</Name>
<Prefix>path/</Prefix>
<KeyCount>2</KeyCount>
<Contents>
<Key>path/file1.txt</Key>
<LastModified>2026-03-01T12:00:00.000Z</LastModified>
<Size>1024</Size>
<ETag>"abc123"</ETag>
</Contents>
<Contents>
<Key>path/file2.txt</Key>
<LastModified>2026-03-01T12:05:00.000Z</LastModified>
<Size>2048</Size>
<ETag>"def456"</ETag>
</Contents>
</ListBucketResult>
Delete Object
DELETE /{bucket-name}/{object-key} HTTP/1.1
Host: storage.yourdomain.com
Authorization: AWS4-HMAC-SHA256 Credential=...
Response: 204 No Content
Copy Object
PUT /{bucket-name}/{dest-key} HTTP/1.1
Host: storage.yourdomain.com
x-amz-copy-source: /source-bucket/source-key
Authorization: AWS4-HMAC-SHA256 Credential=...
Response: 200 OK with copy metadata in XML body.
Multipart Upload
For large files (>100MB), use multipart upload for better throughput and resumability.
Initiate Multipart Upload
POST /{bucket-name}/{object-key}?uploads HTTP/1.1
Host: storage.yourdomain.com
Authorization: AWS4-HMAC-SHA256 Credential=...
Response:
<InitiateMultipartUploadResult>
<Bucket>my-bucket</Bucket>
<Key>large-file.zip</Key>
<UploadId>upload-id-abc123</UploadId>
</InitiateMultipartUploadResult>
Upload Part
PUT /{bucket-name}/{object-key}?partNumber=1&uploadId=upload-id-abc123 HTTP/1.1
Host: storage.yourdomain.com
Content-Length: 5242880
Authorization: AWS4-HMAC-SHA256 Credential=...
[binary part data]
Response: 200 OK with ETag header. Store the ETag for the complete step.
Complete Multipart Upload
POST /{bucket-name}/{object-key}?uploadId=upload-id-abc123 HTTP/1.1
Host: storage.yourdomain.com
Content-Type: application/xml
Authorization: AWS4-HMAC-SHA256 Credential=...
<CompleteMultipartUpload>
<Part>
<PartNumber>1</PartNumber>
<ETag>"etag1"</ETag>
</Part>
<Part>
<PartNumber>2</PartNumber>
<ETag>"etag2"</ETag>
</Part>
</CompleteMultipartUpload>
Abort Multipart Upload
DELETE /{bucket-name}/{object-key}?uploadId=upload-id-abc123 HTTP/1.1
Host: storage.yourdomain.com
Authorization: AWS4-HMAC-SHA256 Credential=...
Response: 204 No Content
Presigned URLs
Generate time-limited URLs for upload or download without exposing credentials.
Request (via API):
curl -X POST https://api.yourdomain.com/v1/presigned-url \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"bucket": "my-bucket",
"key": "documents/report.pdf",
"method": "GET",
"expires_in": 3600
}'
Response:
{
"url": "https://storage.yourdomain.com/my-bucket/documents/report.pdf?X-Amz-Algorithm=...&X-Amz-Credential=...&X-Amz-Date=...&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=...",
"expires_at": "2026-03-01T13:00:00Z"
}
JavaScript (AWS SDK):
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
const { GetObjectCommand } = require('@aws-sdk/client-s3');
const url = await getSignedUrl(client, new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'documents/report.pdf',
}), { expiresIn: 3600 });
Versioning Endpoints
| Operation | Method | Endpoint |
|---|---|---|
| Get object version | GET | /{bucket}/{key}?versionId={id} |
| List object versions | GET | /{bucket}?versions&prefix={prefix} |
| Delete object version | DELETE | /{bucket}/{key}?versionId={id} |
Next Steps
- Agents API Reference — RAG and chat endpoints
- Error Handling — Handling storage errors
- SDKs & Libraries — AWS SDK and language clients