Official Sinch API skills for AI coding agents — SMS, Voice, Verification, Numbers, Mailgun email, and more.
69
87%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
/*
* EXECUTION TOOL — not a schema reference.
* Run this to PERFORM a task (e.g. create a webhook, send a test message) when you do not
* need to write application code. Do NOT copy its payload literals or logic into a new
* codebase as if they were the API spec — load the authoritative developers.sinch.com doc
* instead. See "Source of Truth" in this skill's SKILL.md.
*/
/**
* Shared Sinch API client utilities.
*
* Provides OAuth2 authentication and environment variable helpers
* used by all send_*.cjs and list_messages.cjs scripts.
*/
var https = require("https");
var querystring = require("querystring");
var AUTH_URL = "https://auth.sinch.com/oauth2/token";
var API_BASE = "https://{region}.conversation.api.sinch.com";
function getEnv(name, defaultValue) {
var value = process.env[name] || defaultValue;
if (value === undefined || value === null) {
process.stderr.write("Error: " + name + " environment variable is required\n");
process.exit(1);
}
return value;
}
function getAccessToken(keyId, keySecret) {
return new Promise(function (resolve, reject) {
var credentials = Buffer.from(keyId + ":" + keySecret).toString("base64");
var postData = querystring.stringify({ grant_type: "client_credentials" });
var url = new URL(AUTH_URL);
var options = {
hostname: url.hostname,
path: url.pathname,
method: "POST",
headers: {
Authorization: "Basic " + credentials,
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": Buffer.byteLength(postData),
},
};
var req = https.request(options, function (res) {
var body = "";
res.on("data", function (chunk) {
body += chunk;
});
res.on("end", function () {
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve(JSON.parse(body).access_token);
} else {
reject(new Error("Auth failed (" + res.statusCode + "): " + body));
}
});
});
req.on("error", reject);
req.write(postData);
req.end();
});
}
function apiUrl(region, projectId, path) {
var base = API_BASE.replace("{region}", region);
return base + "/v1/projects/" + projectId + "/" + path;
}
function httpRequest(url, options, body) {
return new Promise(function (resolve, reject) {
var parsed = new URL(url);
var reqOptions = {
hostname: parsed.hostname,
path: parsed.pathname + parsed.search,
method: options.method || "GET",
headers: options.headers || {},
};
if (body) {
reqOptions.headers["Content-Length"] = Buffer.byteLength(body);
}
var req = https.request(reqOptions, function (res) {
var data = "";
res.on("data", function (chunk) {
data += chunk;
});
res.on("end", function () {
if (res.statusCode >= 200 && res.statusCode < 300) {
try {
resolve(JSON.parse(data));
} catch (e) {
resolve(data);
}
} else {
reject(new Error("API error (" + res.statusCode + "): " + data));
}
});
});
req.on("error", reject);
if (body) {
req.write(body);
}
req.end();
});
}
module.exports = {
getEnv: getEnv,
getAccessToken: getAccessToken,
apiUrl: apiUrl,
httpRequest: httpRequest,
};skills
sinch-10dlc
references
sinch-authentication
sinch-conversation-api
sinch-elastic-sip-trunking
references
sinch-fax-api
sinch-imported-numbers-hosting-orders
references
sinch-in-app-calling
sinch-mailgun
references
sinch-mailgun-inspect
references
sinch-mailgun-optimize
references
sinch-mailgun-validate
sinch-mms
sinch-number-lookup-api
sinch-number-order-api
sinch-numbers-api
sinch-porting-api
sinch-provisioning-api
sinch-rcs
sinch-sdks
sinch-sms
scripts
sinch-verification-api
sinch-voice-api
sinch-whatsapp