API docs menu
Get started
Libraries
The official libraries call the same API as the rest of these docs and have no dependencies. They add types, safe retries, waiting for a result, paging through lists and webhook verification. Field names are the same as in this reference. Use them on your server: never put an API key in a web page or an app.
| Language | Package | Needs |
|---|---|---|
| JavaScript and TypeScript | @fittins/sdk on npm (npmjs.com/package/@fittins/sdk) | Node.js 20.3 or later |
| Python | fittins on PyPI (pypi.org/project/fittins) | Python 3.10 or later |
Install
npm install @fittins/sdkCreate a photo
Both read your key from the FITTINS_API_KEY environment variable, or you can pass it in. wait checks until the generation has succeeded, failed or been canceled.
import Fittins from '@fittins/sdk';
const fittins = new Fittins(); // reads FITTINS_API_KEY
const generation = await fittins.images.create({
product_images: [{ url: 'https://cdn.mystore.com/p/dress.jpg' }],
model_id: 'mdl_lib_DM5rQvl3KtlR7nqumd6I',
prompt: 'full body, soft studio light, front view',
aspect_ratio: '3:4',
quality: '4k',
metadata: { sku: 'DRESS-RED-M' },
});
const done = await fittins.generations.wait(generation.id);
if (done.status === 'succeeded') {
console.log(done.output?.url); // a download link, valid for 24 hours
} else {
console.error(done.error?.code, done.error?.message);
}What each library includes
| JavaScript | Python | |
|---|---|---|
| Photos and videos | images.create, videos.create | images.create, videos.create |
| Results | generations.get, list, listAll, wait, delete | generations.get, list, list_all, wait, delete |
| Product photos | uploads.create, with a Blob, ArrayBuffer or Uint8Array | uploads.create, with a path, bytes or an open file |
| Files | files.download | files.download |
| Models and locations | models and locations: list, get, create, delete | models and locations: list, get, create, delete |
| Webhook endpoints | webhookEndpoints: create, list, delete, rotateSecret | webhook_endpoints: create, list, delete, rotate_secret |
| Webhook checks | verifyWebhook | verify_webhook |
| Usage and account | usage.get, account.get | usage.get, account.get |
Retries and safe creates
- Failed requests are sent up to 2 more times, with a growing pause. After a 429, the library waits for the time in Retry-After.
- Each create gets an Idempotency-Key that its retries reuse, so a retry can't charge twice.
- Uploads, webhook endpoint changes and deletes are only retried after a 429, because sending them twice could do the work twice.
- Set your own limits when you create the client: maxRetries and timeoutMs in JavaScript, max_retries and timeout in Python.
To protect against your own job running twice, pass a key you can repeat:
await fittins.images.create(params, { idempotencyKey: `photo-${sku}` });Errors
import { FittinsApiError } from '@fittins/sdk';
try {
await fittins.images.create(params);
} catch (error) {
if (error instanceof FittinsApiError && error.code === 'insufficient_credits') {
// error.status, error.code, error.message, error.param, error.requestId
} else {
throw error;
}
}- A connection error (FittinsConnectionError in JavaScript, APIConnectionError in Python) means no answer arrived.
- WaitTimeoutError means wait ran out of time. The default is 20 minutes, and the generation may still finish.
- A generation that fails after being accepted isn't thrown as an error: check status and error on the result.
Verify webhooks
Pass the body exactly as received, before any JSON parsing. The check throws an error when the signature or the time is wrong, and returns the event when it passes.
import express from 'express';
import { verifyWebhook } from '@fittins/sdk';
const app = express();
app.post('/webhooks/fittins', express.raw({ type: 'application/json' }), async (req, res) => {
let event;
try {
event = await verifyWebhook(req.body, req.get('Fittins-Signature'), process.env.FITTINS_WEBHOOK_SECRET);
} catch {
return res.sendStatus(400);
}
if (event.type === 'generation.succeeded') {
console.log(event.data.object.output?.url);
}
res.sendStatus(200);
});Test without credits
A fit_test_ key works with both libraries. It runs the checks on your request and returns a sample result, without using the AI or any credits. See Test mode.