JavaScript Signature SDK Integration Guide

Function

The javaScript signature SDK generates the X-Sdk-Date and Authorization headers for Meitu Open Platform API requests. It calculates an SDK-HMAC-SHA256 signature from the HTTP method, URL, headers, and request body, then returns request options accepted by https.request().

The SDK only signs requests and does not send them. Follow the target capability API reference for the endpoint, HTTP method, and business parameters.

Environment Requirements

  • Node.js 18 or later
  • A CommonJS module environment
  • HTTPS network access to the target API
  • An Access Key (AK) and Secret Key (SK)

Download and Import

SDK version: 1.0.3 Download: AIGCP-API-javaScript-sdk-1.0.3.zip

Extract the archive, place sign.js in the project directory, and install the dependencies:

npm install moment@2.29.4 moment-timezone@0.5.43

Import the SDK in application code:

const {
  Signer,
  HeaderXDate,
  HeaderHost,
  HeaderAuthorization,
  HeaderContentSha256,
} = require('./sign');

API Reference

Create a signer

const signer = new Signer(accessKey, secretKey);
ParameterTypeDescription
accessKeystringAccess Key.
secretKeystringSecret Key.

Sign a request

const requestOptions = signer.sign(url, method, headers, body);
ParameterTypeDescription
urlstringFinal request URL, including the path and query parameters.
methodstringUppercase HTTP method, such as GET or POST.
headersobjectHeaders to sign. Must include a Host that matches the URL.
bodystring or BufferFinal request body. Pass '' for an empty body.

sign() adds X-Sdk-Date and Authorization to headers, then returns the method, hostname, path, port, and headers required by https.request().

Common headers are listed below:

ConstantHeaderDescription
HeaderHostHostRequired. Use the host from the final URL.
HeaderXDateX-Sdk-DateOptional. The SDK generates the current UTC time when omitted.
HeaderAuthorizationAuthorizationGenerated by the SDK.
HeaderContentSha256X-Sdk-Content-Sha256Optional. Set it to UNSIGNED-PAYLOAD only when permitted by the target API.

By default, the SDK calculates the SHA-256 digest of the body and includes it in the signature. If the target API explicitly permits an unsigned payload, set the following before calling sign():

headers[HeaderContentSha256] = 'UNSIGNED-PAYLOAD';

Complete POST Example

This example calls the production synchronous push endpoint at https://openapi.meitu.com/api/v1/sdk/sync/push. The body is serialized once, and the same string is used for both signing and transmission.

const https = require('https');
const { Signer, HeaderHost } = require('./sign');

const accessKey = process.env.AIGCP_ACCESS_KEY;
const secretKey = process.env.AIGCP_SECRET_KEY;

if (!accessKey || !secretKey) {
  throw new Error('AIGCP_ACCESS_KEY and AIGCP_SECRET_KEY are required');
}

const endpoint = new URL('https://openapi.meitu.com/api/v1/sdk/sync/push');
const body = JSON.stringify({
  task: 'replace-with-task',
  task_type: 'replace-with-task-type',
  init_images: ['https://example.com/input.jpg'],
  params: JSON.stringify({
    example: 'replace with parameters from the target API reference',
  }),
  sync_timeout: 30,
});
const headers = {
  'Content-Type': 'application/json',
  [HeaderHost]: endpoint.host,
};

const signer = new Signer(accessKey, secretKey);
const requestOptions = signer.sign(endpoint.href, 'POST', headers, body);

const request = https.request(requestOptions, (response) => {
  response.setEncoding('utf8');
  let responseBody = '';

  response.on('data', (chunk) => {
    responseBody += chunk;
  });
  response.on('end', () => {
    console.log(`status=${response.statusCode}`);
    console.log(responseBody);

    if (response.statusCode < 200 || response.statusCode >= 300) {
      process.exitCode = 1;
    }
  });
});

request.setTimeout(60_000, () => {
  request.destroy(new Error('request timed out'));
});
request.on('error', (error) => {
  console.error(error.message);
  process.exitCode = 1;
});
request.write(body);
request.end();

Set the credentials before running the example:

export AIGCP_ACCESS_KEY='<your-access-key>'
export AIGCP_SECRET_KEY='<your-secret-key>'
node demo.js

The example task, task_type, image URL, contents of params, and sync_timeout only demonstrate the request structure. Replace them according to the target capability API reference. params must be a JSON string.

GET Example

For a GET request, construct the final query parameters before signing. Set AIGCP_GET_API_URL to the complete HTTPS endpoint from the target capability reference.

const https = require('https');
const { Signer, HeaderHost } = require('./sign');

const accessKey = process.env.AIGCP_ACCESS_KEY;
const secretKey = process.env.AIGCP_SECRET_KEY;
const apiUrl = process.env.AIGCP_GET_API_URL;

if (!accessKey || !secretKey || !apiUrl) {
  throw new Error('AIGCP_ACCESS_KEY, AIGCP_SECRET_KEY, and AIGCP_GET_API_URL are required');
}

const endpoint = new URL(apiUrl);
if (endpoint.protocol !== 'https:') {
  throw new Error('AIGCP_GET_API_URL must be an HTTPS URL');
}
endpoint.searchParams.set('task_id', 'replace-with-task-id');

const headers = {
  [HeaderHost]: endpoint.host,
};
const signer = new Signer(accessKey, secretKey);
const requestOptions = signer.sign(endpoint.href, 'GET', headers, '');

const request = https.request(requestOptions, (response) => {
  response.setEncoding('utf8');
  response.on('data', (chunk) => process.stdout.write(chunk));
});
request.on('error', (error) => console.error(error.message));
request.end();

Notes

  • Sign the final URL, HTTP method, headers, and body. Do not change them after signing.
  • Set Host from endpoint.host for the final URL, including a non-default port.
  • Call JSON.stringify() once for a JSON body. The content passed to sign() and request.write() must be identical.
  • Create new headers for every request. Do not reuse an object containing an old Authorization or X-Sdk-Date.
  • Pass '' for GET or another empty-body request, and finish setting all query parameters before signing.
  • Keep the server clock synchronized. Normally, let the SDK generate X-Sdk-Date.
  • Use HTTPS for production requests.
  • Store the SK only on a trusted server, and do not use this SDK in a browser.

Common Errors

Error or symptomResolution
Cannot find module 'moment'Run the dependency installation command in the project directory.
401 or signature verification failureConfirm that the AK/SK, HTTP method, final URL, query, Host, headers, and body exactly match the signed request.
The second request fails signature verificationDo not reuse signed headers; create a new object for every request.
value.trim is not a functionSet every signed header value to a string.
Payload hashing errorSerialize JSON to a string first. Pass '', not null or undefined, for an empty body.
Time verification failureSynchronize the server clock, remove a manually supplied X-Sdk-Date, and sign again.
Request timeoutCheck the network, proxy, and endpoint, then adjust the request timeout for the use case.
4xx or 5xx responseRead the error code and message in the response body and follow the target capability API reference.