Signing Algorithm
Every Open Platform API request must be authenticated with a signature. The scheme is intentionally minimal:
sign = MD5(timestamp + body + appSecret)All credentials go into HTTP headers; the request body stays as pristine business JSON.
Three Required Headers
| Header | Type | Description |
|---|---|---|
X-Loxily-AppKey | string | Project App Key |
X-Loxily-Timestamp | number (as string) | Unix seconds (or milliseconds), valid within a 5-minute window |
X-Loxily-Sign | string (32-char lowercase hex) | MD5 signature (see below) |
Signing Formula
sign = MD5(<timestamp> + <body> + <appSecret>)<timestamp>: The value of theX-Loxily-Timestampheader, used as-is (string concatenation)<body>: The raw HTTP request body bytes (UTF-8). For GET or empty-body requests, use""<appSecret>: The project App Secret (matched againstX-Loxily-AppKey)- Take the lowercase 16-character hex digest (32 chars total)
No URL encoding, no parameter sorting, no canonical JSON, no intermediate hash — just three strings concatenated and MD5-ed.
Example
Given:
| timestamp | 1713780317 |
| body (request payload verbatim) | {"name":"Demo","target_languages":["en"],"strings":[{"string_id":"a","content":"hi"}]} |
| appSecret | my_secret_key |
Concatenate:
1713780317{"name":"Demo","target_languages":["en"],"strings":[{"string_id":"a","content":"hi"}]}my_secret_keyMD5 the result (lowercase hex) → that's your X-Loxily-Sign.
Code Examples
Java
java
import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;
public class LoxilySign {
public static String sign(String timestamp, String body, String appSecret) throws Exception {
String source = timestamp + body + appSecret;
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(source.getBytes(StandardCharsets.UTF_8));
StringBuilder hex = new StringBuilder();
for (byte b : digest) {
hex.append(String.format("%02x", b));
}
return hex.toString();
}
}Python
python
import hashlib
def sign(timestamp: str, body: str, app_secret: str) -> str:
source = f"{timestamp}{body}{app_secret}"
return hashlib.md5(source.encode("utf-8")).hexdigest()JavaScript / Node.js
javascript
const crypto = require('crypto');
function sign(timestamp, body, appSecret) {
return crypto.createHash('md5')
.update(`${timestamp}${body}${appSecret}`, 'utf8')
.digest('hex');
}Go
go
package main
import (
"crypto/md5"
"fmt"
)
func Sign(timestamp, body, appSecret string) string {
data := timestamp + body + appSecret
return fmt.Sprintf("%x", md5.Sum([]byte(data)))
}Full Request Example
bash
TIMESTAMP=$(date +%s)
BODY='{"client_task_id":"uuid-1","name":"Demo","target_languages":["en"],"strings":[{"string_id":"a","content":"hi"}]}'
SIGN=$(printf '%s' "${TIMESTAMP}${BODY}my_secret_key" | md5)
curl -X POST "https://api.loxily.com/api/open/v1/tasks/create" \
-H "Content-Type: application/json" \
-H "X-Loxily-AppKey: 5685414646a54423c891d87194d87f3f" \
-H "X-Loxily-Timestamp: ${TIMESTAMP}" \
-H "X-Loxily-Sign: ${SIGN}" \
-d "${BODY}"Integration checklist
- The
bodyused to compute the signature must be byte-identical to what is sent over the wire (same JSON string, don't pretty-print or re-serialize just before sending) - Pass
timestampas a string to preserve precision - UTF-8 encoding throughout — most languages' MD5 functions default to UTF-8 already