Upload callbacks let OSS notify your application server when an object upload completes. Include callback parameters in the upload request to enable this — no separate configuration step is required.
How it works
Your client sends an upload request to OSS with callback parameters attached.
OSS stores the object.
OSS sends an HTTP POST request to your callback server URL with the fields you specified in
callbackBody.Your callback server processes the request and returns a JSON response.
OSS forwards that response to your client.
Upload callbacks work with both simple upload (putObject) and multipart upload (completeMultipartUpload). For multipart upload, attach the callback parameters in Step 3 (complete), not in Step 1 (initiate).
Prerequisites
Before you begin, make sure that you have:
An OSS bucket
The
OSS_ACCESS_KEY_IDandOSS_ACCESS_KEY_SECRETenvironment variables set with valid access credentialsA publicly accessible callback server URL that can handle HTTP POST requests
Usage notes
The examples in this topic use the public endpoint for the China (Hangzhou) region. To access OSS from other Alibaba Cloud services in the same region, use an internal endpoint instead. For supported regions and endpoints, see Regions and endpoints.
The examples create an OSSClient instance using an OSS endpoint. To create an OSSClient instance using a custom domain name or Security Token Service (STS), see Create an OSSClient instance.
Callback parameters
All callback parameters are passed as a JSON string to OssClient::OSS_CALLBACK. Custom variables are passed separately to OssClient::OSS_CALLBACK_VAR.
| Parameter | Required | Description |
|---|---|---|
callbackUrl | Yes | The URL of your callback server. OSS sends an HTTP POST request to this address after the upload completes. Example: https://oss-demo.aliyuncs.com:23450 |
callbackHost | No | The value of the Host header in the callback request. If omitted, OSS uses the host parsed from callbackUrl. |
callbackBody | Yes | The body of the callback request. Use system variables (e.g., ${bucket}, ${object}, ${size}) and custom variables (e.g., ${x:var1}) to include upload metadata. |
callbackBodyType | Yes | The Content-Type of the callback request body. Use application/x-www-form-urlencoded for simple upload or application/json for multipart upload. |
Custom variables are key-value pairs passed to OssClient::OSS_CALLBACK_VAR. Each key must start with x:. These values are available in callbackBody as ${x:key_name}.
System variables available in `callbackBody`:
| Variable | Description |
|---|---|
${bucket} | Bucket name |
${object} | Object path |
${etag} | ETag of the uploaded object |
${size} | Object size in bytes |
${mimeType} | MIME type of the object |
${imageInfo.height} | Image height (for image objects) |
${imageInfo.width} | Image width (for image objects) |
${imageInfo.format} | Image format (for image objects) |
Callback server requirements
OSS sends an HTTP POST request to your callback server URL after the upload completes. Your callback server must meet the following requirements:
Publicly accessible: The callback URL must be reachable from the internet.
Return valid JSON: The response body must be valid JSON. OSS forwards this JSON response to the client as-is.
Return HTTP 200: Return an HTTP 200 status code to indicate success. OSS treats other status codes as callback failures.
Respond promptly: If your callback server does not respond in time, OSS treats the callback as failed. Design your callback handler to respond quickly — offload any time-consuming processing to an asynchronous queue.
Configure a callback for simple upload
Attach callback parameters to a putObject call using OssClient::OSS_CALLBACK and OssClient::OSS_CALLBACK_VAR.
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
// Load access credentials from environment variables.
// Set OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET before running this code.
$provider = new EnvironmentVariableCredentialsProvider();
// Replace with the endpoint of the region where your bucket is located.
// Example: https://oss-cn-hangzhou.aliyuncs.com
$endpoint = "yourEndpoint";
// Replace with your bucket name and object path.
$bucket = "examplebucket";
$object = "exampledir/exampleobject.txt";
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region" => "cn-hangzhou"
);
$ossClient = new OssClient($config);
// Define the callback. callbackBody uses form-urlencoded format for simple upload.
$callback =
'{
"callbackUrl":"yourCallbackServerUrl",
"callbackHost":"yourCallbackServerHost",
"callbackBody":"bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&imageInfo.height=${imageInfo.height}&imageInfo.width=${imageInfo.width}&imageInfo.format=${imageInfo.format}&my_var1=${x:var1}&my_var2=${x:var2}",
"callbackBodyType":"application/x-www-form-urlencoded"
}';
// Define custom variables. Keys must start with x:.
$var =
'{
"x:var1":"value1",
"x:var2":"value2"
}';
$options = array(
OssClient::OSS_CALLBACK => $callback,
OssClient::OSS_CALLBACK_VAR => $var,
);
$result = $ossClient->putObject($bucket, $object, file_get_contents(__FILE__), $options);
// Print the callback server response body and the HTTP status code.
print_r($result['body']);
print_r($result['info']['http_code']);Replace the following placeholders before running the code:
| Placeholder | Description | Example |
|---|---|---|
yourEndpoint | Endpoint of the region where your bucket is located | https://oss-cn-hangzhou.aliyuncs.com |
examplebucket | Bucket name | my-bucket |
exampledir/exampleobject.txt | Full object path, excluding the bucket name | uploads/photo.jpg |
yourCallbackServerUrl | Publicly accessible URL of your callback server | https://example.com/callback |
yourCallbackServerHost | (Optional) Host header value for the callback request | example.com |
What your callback server receives:
For simple upload with application/x-www-form-urlencoded, your server receives an HTTP POST request with a body similar to:
bucket=examplebucket&object=exampledir%2Fexampleobject.txt&etag=5B3C1A2E883EC0D921E4571E9B4F2C38&size=1024&mimeType=text%2Fplain&imageInfo.height=&imageInfo.width=&imageInfo.format=&my_var1=value1&my_var2=value2Configure a callback for multipart upload
For multipart upload, add callback parameters to the completeMultipartUpload call — not to initiateMultipartUpload or uploadPart.
The example below uses application/json for callbackBodyType.
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Core\OssUtil;
// Load access credentials from environment variables.
// Set OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET before running this code.
$provider = new EnvironmentVariableCredentialsProvider();
// Replace with the endpoint of the region where your bucket is located.
$endpoint = "yourEndpoint";
// Replace with your bucket name, object path, and local file path.
$bucket = "examplebucket";
$object = "exampledir/exampleobject.txt";
$uploadFile = "D:\\localpath\\examplefile.txt";
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region" => "cn-hangzhou"
);
$ossClient = new OssClient($config);
/**
* Step 1: Initiate a multipart upload and get the upload ID.
* Use the upload ID to upload parts, and to cancel or query the upload task.
*/
$uploadId = $ossClient->initiateMultipartUpload($bucket, $object);
print(__FUNCTION__ . ": initiateMultipartUpload OK\n");
/**
* Step 2: Upload parts.
*/
$partSize = 10 * 1024 * 1024; // 10 MB per part
$uploadFileSize = sprintf('%u', filesize($uploadFile));
$pieces = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize);
$responseUploadPart = array();
$uploadPosition = 0;
$isCheckMd5 = true;
foreach ($pieces as $i => $piece) {
$fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO];
$toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1;
$upOptions = array(
$ossClient::OSS_FILE_UPLOAD => $uploadFile,
$ossClient::OSS_PART_NUM => ($i + 1),
$ossClient::OSS_SEEK_TO => $fromPos,
$ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
$ossClient::OSS_CHECK_MD5 => $isCheckMd5,
);
// Compute and attach the Content-MD5 header for integrity verification.
if ($isCheckMd5) {
$contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos);
$upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
}
try {
$responseUploadPart[] = $ossClient->uploadPart($bucket, $object, $uploadId, $upOptions);
} catch (OssException $e) {
printf(__FUNCTION__ . ": uploadPart - part#%d FAILED\n", $i);
printf($e->getMessage() . "\n");
return;
}
printf(__FUNCTION__ . ": uploadPart - part#%d OK\n", $i);
}
// Build the parts list. Each entry contains the ETag and part number returned by uploadPart.
$uploadParts = array();
foreach ($responseUploadPart as $i => $eTag) {
$uploadParts[] = array(
'PartNumber' => ($i + 1),
'ETag' => $eTag,
);
}
/**
* Step 3: Complete the multipart upload and trigger the callback.
* OSS verifies all parts, assembles the object, then sends the callback.
*/
$callback =
'{
"callbackUrl":"yourCallbackServerUrl",
"callbackHost":"yourCallbackServerHost",
"callbackBody":"{\"mimeType\":${mimeType},\"size\":${size},\"x:var1\":${x:var1},\"x:var2\":${x:var2}}",
"callbackBodyType":"application/json"
}';
// Custom variables. Keys must start with x:.
$var =
'{
"x:var1":"value1",
"x:var2":"value2"
}';
$options = array(
OssClient::OSS_CALLBACK => $callback,
OssClient::OSS_CALLBACK_VAR => $var,
);
// Pass all uploaded parts. OSS verifies each part, then assembles the final object.
$ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts, $options);
printf(__FUNCTION__ . ": completeMultipartUpload OK\n");Replace the following placeholders before running the code:
| Placeholder | Description | Example |
|---|---|---|
yourEndpoint | Endpoint of the region where your bucket is located | https://oss-cn-hangzhou.aliyuncs.com |
examplebucket | Bucket name | my-bucket |
exampledir/exampleobject.txt | Full object path, excluding the bucket name | uploads/video.mp4 |
D:\\localpath\\examplefile.txt | Full path of the local file to upload | D:\\videos\\sample.mp4 |
yourCallbackServerUrl | Publicly accessible URL of your callback server | https://example.com/callback |
yourCallbackServerHost | (Optional) Host header value for the callback request | example.com |
What your callback server receives:
For multipart upload with application/json, your server receives an HTTP POST request with a body similar to:
{"mimeType":"video/mp4","size":104857600,"x:var1":"value1","x:var2":"value2"}What's next
For the complete sample code, see Callback.php on GitHub.
For the underlying API that powers upload callbacks, see Callback.