TypeScript SDK for Fusion API task and action endpoints.
This package is designed around the two stable shapes in Fusion API:
- async task endpoints:
submit -> state/result - action endpoints:
/action/{name}
It also includes:
- grouped service shortcuts such as
client.doubaoTts.runData(...) - generated raw OpenAPI types
- AI-oriented docs and normalized error handling
npm install oomol-fusion-sdkRequirements:
- Node.js 18+
- global
fetchavailable, or provide one in client options
import { FusionClient } from "oomol-fusion-sdk";
const client = new FusionClient({
apiKey: process.env.FUSION_API_KEY,
});Available client options:
apiKey?: stringtoken?: stringbaseUrl?: stringfetch?: typeof fetchdefaultHeaders?: Record<string, string>pollIntervalMs?: numbertimeoutMs?: number
Example with custom baseUrl:
const client = new FusionClient({
apiKey: process.env.FUSION_API_KEY,
baseUrl: "https://fusion-api.oomol.com",
pollIntervalMs: 2000,
timeoutMs: 300000,
});Default values:
baseUrl:https://fusion-api.oomol.compollIntervalMs:2000timeoutMs:300000
Use these defaults unless you have a specific reason not to:
- task endpoints: prefer
runData() - split task control: use
submit()thenwaitData() - action endpoints: prefer grouped methods like
client.jinaReader.read(...) - unmodeled future endpoints: use
client.request(...)
Task example:
const audio = await client.doubaoTts.runData({
text: "Hello from Fusion SDK",
voice: "zh_female_vv_uranus_bigtts",
});
console.log(audio);Action example:
const page = await client.jinaReader.read({
URL: "https://example.com/article",
format: "markdown",
});
console.log(page.data);Every async task service supports the same workflow methods:
submit(payload)state(sessionID)result(sessionID)wait(sessionID, options)run(payload, options)waitData(sessionID, options)runData(payload, options)
Example:
const { sessionID } = await client.pdfTransformMarkdown.submit({
pdfURL: "https://example.com/book.pdf",
});
const markdown = await client.pdfTransformMarkdown.waitData(sessionID);
console.log(markdown);run()returns the completed response shaperunData()returns the result payload directly
Fusion API completion responses are not perfectly uniform across all services. Some endpoints return:
{ success, state, data }Some return the completed object directly.
waitData() and runData() normalize both cases and are the preferred choice for most callers.
Built-in task services:
client.doubaoTtsclient.doubaoSttclient.oomolTtsclient.falRemoveBackgroundclient.falFluxProKontextclient.falAuraSrclient.falSora2ImageToVideoclient.falSora2TextToVideoclient.falNanoBanana2client.falNanoBananaclient.imageTranslateclient.mangaZipTranslateclient.qwenMtImageclient.wanxImageclient.pdfTransformEpubclient.pdfTransformMarkdownclient.falNanoBananaProclient.wanxKf2vVideoclient.cphoneNanoBanana
Built-in action groups:
client.customFinancialFundamentalReportclient.doubaoTextToImageSeedreamclient.textToEpubIllustrateclient.jinaReaderclient.tinifyPngShrinkclient.fileUploadclient.qwenImageEditPlusclient.qwenDocTurbo
You can call action endpoints either by grouped shortcut or by raw action key.
Grouped shortcut:
const response = await client.qwenDocTurbo.analyze({
text: "Product A costs 100 USD.",
instruction: "Extract the product name and price.",
});Raw action key:
const response = await client.action("jina-reader/search", {
content: "Fusion API SDK",
jsonResponse: true,
});Use request() when the backend adds a new endpoint before the SDK model is updated:
const response = await client.request({
method: "POST",
path: "/v1/new-service/submit",
body: {
prompt: "hello",
},
});If a new endpoint still matches the standard task shape:
client.registerTask("new-service");
const result = await client.task("new-service").runData({
prompt: "hello",
});If you need to register a custom action endpoint:
client.registerAction({
key: "custom-service/custom-action",
method: "POST",
path: "/v1/custom-service/action/custom-action",
});The SDK exports a normalized AI-friendly error type:
import { OomolFusionSdkError } from "oomol-fusion-sdk";
try {
const result = await client.doubaoTts.runData({
text: "hello",
voice: "zh_female_vv_uranus_bigtts",
});
} catch (error) {
const sdkError = OomolFusionSdkError.fromUnknown(error);
console.log(sdkError.code);
console.log(sdkError.message);
console.log(sdkError.status);
console.log(sdkError.retryable);
console.log(sdkError.details);
}Normalized fields:
codemessagestatusretryabledetails
Main SDK:
import { FusionClient, OomolFusionSdkError } from "oomol-fusion-sdk";Generated raw OpenAPI types:
import type { WanxImageSubmitPostRequest } from "oomol-fusion-sdk/openapi-types";Type augmentation target:
declare module "oomol-fusion-sdk/types" {
interface FusionTaskDefinitions {
"new-service": {
submit: { prompt: string };
completed: { success: true; state: "completed"; data: { output: string } };
stateCompleted: { success: true; state: "completed" };
};
}
}If you want compile-time types for new APIs before the SDK adds built-in aliases:
import type {
ActionResponse,
CompletedTaskResultResponse,
CompletedTaskStateResponse,
} from "oomol-fusion-sdk";
declare module "oomol-fusion-sdk/types" {
interface FusionTaskDefinitions {
"new-service": {
submit: {
prompt: string;
mode?: "fast" | "quality";
};
completed: CompletedTaskResultResponse<{ downloadURL: string }>;
stateCompleted: CompletedTaskStateResponse;
};
}
interface FusionActionDefinitions {
"new-service/preview": {
method: "POST";
request: {
prompt: string;
};
response: ActionResponse<{ previewURL: string }>;
};
}
}The SDK uses one canonical OpenAPI snapshot:
openapi.full.snapshot.json
Generated files:
src/services.tssrc/generated/endpoints.tssrc/generated/openapi-types.ts
Useful commands:
npm run generate
npm run checknpm run generate: regenerate service shortcuts, generated types, and build outputnpm run check: run generation, build, and compile-only type verification
Additional AI-oriented docs included in the package:
README.ai.mdCAPABILITIES.mdAGENT_GUIDE.md
- This package is currently versioned as
2.0.0 - Built-in grouped services are generated from the OpenAPI snapshot
- Generated raw OpenAPI types are intentionally exposed as a separate import path