crowdin-api-client — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited crowdin-api-client (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Use this skill when touching Crowdin API integration code in any project that depends on @crowdin/crowdin-api-client. Core principle: verify local client typings first, then implement with strict model types and correct response envelope handling.
@crowdin/crowdin-api-client.ResponseList vs ResponseObject.Do not use this skill for unrelated infra-only changes.
node_modules/@crowdin/crowdin-api-client/out/<module>/index.d.ts.ResponseList<T> or ResponseObject<T>.Do not code from memory when typings and docs disagree.
| Scenario | Preferred Pattern |
|---|---|
| Multi-module flow | new Client(credentials, options) and destructure needed APIs |
| Single narrow flow | Direct module API class is acceptable |
| Full collection reads | .withFetchAll() |
| Transient failures | retryConfig |
| Bounded request duration | { httpRequestTimeout: 60_000 } |
| Uploads | uploadStorageApi.addStorage -> sourceFilesApi.createFile |
| Error branching | CrowdinValidationError before CrowdinError |
import { Client, Credentials } from '@crowdin/crowdin-api-client';
const credentials: Credentials = {
token: process.env.CROWDIN_TOKEN!,
organization: process.env.CROWDIN_ORG,
};
const client = new Client(credentials);const listResponse = await client.tasksApi.withFetchAll().listTasks(projectId, options);
const tasks = listResponse.data.map((entry) => entry.data); // ResponseList<T>
const createResponse = await client.tasksApi.addTask(projectId, request);
const task = createResponse.data; // ResponseObject<T>const request: TasksModel.CreateTaskRequest = {
title: 'My Task',
languageId: 'de',
type: 0,
fileIds: [12],
};import { CrowdinError, CrowdinValidationError } from '@crowdin/crowdin-api-client';
try {
// API call
} catch (error) {
if (error instanceof CrowdinValidationError) throw error;
if (error instanceof CrowdinError) throw error;
throw error;
}| Mistake | Fix |
|---|---|
| Guessing endpoint methods from memory | Validate in local index.d.ts first |
| Treating list response as object response | Check ResponseList<T> vs ResponseObject<T> and map accordingly |
| Weakening or bypassing model typing | Use client *Model types in service signatures and fixtures |
| Manual pagination loops by default | Prefer .withFetchAll() unless custom batching is required |
Uploading file directly to createFile | Create storage first, then pass storageId |
| Catching all errors as generic | Branch CrowdinValidationError and CrowdinError explicitly |
After changing API-client usage:
Reference docs: Crowdin API Client modules
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.