Bash/Shell Signature SDK Integration Guide
Overview
The Bash/Shell Signature SDK generates signed request headers such as Authorization and X-Sdk-Date for Meitu Open Platform API requests. The SDK signs the request, and the caller sends it with curl.
Current version: AIGCP-API-shell-sdk-1.0.1.
Requirements
- Run scripts with Bash. Do not use
shas a substitute. - Install cURL
7.76.0or later. - Install
openssl,base64,cut,sed,sort,od,tr, anddate. - Keep the server clock accurate.
Run the following command to check the environment:
for command_name in bash curl openssl base64 cut sed sort od tr date; do
command -v "$command_name" >/dev/null || printf 'Missing command: %s\n' "$command_name" >&2
doneDownload and import
Download AIGCP-API-shell-sdk-1.0.1.zip
unzip AIGCP-API-shell-sdk-1.0.1.zip
cd bashUse these two files from the extracted archive:
signer.sh: signing implementation;demo.sh: basic calling example.
Import signer.sh in the application script:
source ./signer.shAPI reference
The SDK provides the global Sign function:
auth_value=$(Sign "$access_key" "$secret_key" "$url" "$method" "$headers" "$body")| Parameter | Description |
|---|---|
access_key | The application's AK. |
secret_key | The SK paired with the AK. |
url | The final request URL, including its path and complete query. |
method | The uppercase HTTP method, such as GET or POST. |
headers | A newline-delimited string of Name:Value headers. |
body | The actual request body; use an empty string when there is no body. |
Sign returns a newline-delimited header string. The first line is Authorization; the remaining lines are signed request headers. Convert every line into a separate curl -H argument before sending the request.
Complete POST example
The following example calls the production synchronous task endpoint, https://openapi.meitu.com/api/v1/sdk/sync/push. Its body has five top-level fields: task, task_type, init_images, params, and sync_timeout. The params value must be a JSON string.
Set the task, image, business parameters, and sync_timeout: 30 according to the target capability's API reference. The script uses the same body variable for signing and sending, ensuring that the signed bytes exactly match the transmitted bytes.
#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
source "$script_dir/signer.sh"
: "${AIGCP_ACCESS_KEY:?AIGCP_ACCESS_KEY is required}"
: "${AIGCP_SECRET_KEY:?AIGCP_SECRET_KEY is required}"
send_signed_request() {
local method=$1
local url=$2
local body=$3
shift 3
local raw_headers=("$@")
local headers
local auth_value
local header
local curl_args
headers=$(printf '%s\n' "${raw_headers[@]}")
if ! auth_value=$(Sign "$AIGCP_ACCESS_KEY" "$AIGCP_SECRET_KEY" "$url" "$method" "$headers" "$body"); then
printf 'Signing failed\n' >&2
return 1
fi
curl_args=(
--silent
--show-error
--fail-with-body
--connect-timeout 5
--max-time 60
--request "$method"
)
while IFS= read -r header; do
[[ -n $header ]] && curl_args+=(-H "$header")
done <<< "$auth_value"
[[ -z $body ]] || curl_args+=(--data-binary "$body")
curl "${curl_args[@]}" "$url"
}
post_endpoint='https://openapi.meitu.com/api/v1/sdk/sync/push'
post_url="${post_endpoint}?"
post_body='{"task":"/v1/replace-with-product-task","task_type":"formula","init_images":[{"url":"https://example.com/input.jpg","profile":{"media_profiles":{"media_data_type":"url"},"version":"v1"}}],"params":"{\"parameter\":{\"rsp_media_type\":\"url\"}}","sync_timeout":30}'
post_headers=(
"Content-Type:application/json"
"Host:openapi.meitu.com"
)
send_signed_request 'POST' "$post_url" "$post_body" "${post_headers[@]}"Save the script as request.sh next to signer.sh, set the AK/SK, and run it:
export AIGCP_ACCESS_KEY='<your-access-key>'
export AIGCP_SECRET_KEY='<your-secret-key>'
bash request.shGET example
/api/v1/sdk/sync/push supports POST only. To call another GET API, replace the final POST section of the complete script above with the following code, using the real URL and query parameters from the target API reference:
get_url='https://openapi.meitu.com/api/v1/replace-with-get-path?task_id=replace-with-task-id'
get_body=''
get_headers=(
"Host:openapi.meitu.com"
)
send_signed_request 'GET' "$get_url" "$get_body" "${get_headers[@]}"Notes
- Shell SDK
1.0.1requires?to be present in the URL. Retain an empty trailing?when there is no query; when a query exists, pass it in full. Signing and sending must use the same URL. - Finalize the HTTP method, URL, headers, and body before signing. Do not modify them afterward.
- Generate a JSON body once and pass the same string to both
Signandcurl --data-binary. - Use
Name:Valueheader format without incidental whitespace before the value. Sort multiple headers by lowercase name. - Do not set
X-Sdk-Datemanually; let the SDK generate it. - By default, the SDK calculates SHA-256 over the body. Add
X-Sdk-Content-Sha256:UNSIGNED-PAYLOADonly when the target API explicitly supports it. - Store the SK only on the server; never include it in frontend or client code.
Common errors
| Symptom | Resolution |
|---|---|
| Signature verification fails or the API returns 401 | Check the AK/SK, HTTP method, complete URL, trailing ?, header order, and whether the body exactly matches the signed value. |
| Time-related error | Synchronize the server clock and remove any manually supplied X-Sdk-Date. |
| Query signature failure | Build the final query before signing. Do not append, remove, or re-encode parameters afterward. |
cURL does not support --fail-with-body | Upgrade to cURL 7.76.0 or later, or use --fail. |
| A required command is missing | Install the command listed under Requirements. |
| The API rejects business parameters | Replace the sample task, image, params, task_type, and sync_timeout according to the target capability's API reference. |