{"_id":"@higgsfield/client","_rev":"10-23a8ff5bc9790e34094335349a49d7ad","name":"@higgsfield/client","dist-tags":{"latest":"0.2.1"},"versions":{"0.1.2":{"name":"@higgsfield/client","version":"0.1.2","keywords":["higgsfield","ai","api","client","sdk","typescript","image-generation","video-generation"],"author":{"name":"Higgsfield"},"license":"MIT","_id":"@higgsfield/client@0.1.2","maintainers":[{"name":"rakhmedy","email":"rustem.akhmedyarov@gmail.com"}],"homepage":"https://higgsfield.ai","bugs":{"url":"https://github.com/higgsfield/nodejs-client/issues"},"dist":{"shasum":"538bc7dfbab229211812e927f36e9845061ace5d","tarball":"https://registry.npmjs.org/@higgsfield/client/-/client-0.1.2.tgz","fileCount":66,"integrity":"sha512-pywkc7RyPt+yfUWNPX9Zjln846HRknt3KWH9nZxm1hy8qanPWMEp98RLG3TrA7VC79DYhLD5gi+Vwj2QwoPVAw==","signatures":[{"sig":"MEUCIDfeouIrLA17K0BjStQ8GGcop0hvdrY1TY4V7ODHvM7QAiEA6y8EEuehiapvaTslPWHxWcORC6OjR8JWhffB1+1+4Qo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":165048},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"gitHead":"addbf439d05357bf8b141c00032eb260359d60d6","scripts":{"lint":"eslint src/**/*.ts","test":"jest","build":"tsc","format":"prettier --write \"src/**/*.ts\"","version":"git add -A src","test:watch":"jest --watch","build:watch":"tsc --watch","postversion":"git push && git push --tags","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"rakhmedy","email":"rustem.akhmedyarov@gmail.com"},"repository":{"url":"git+https://github.com/higgsfield/nodejs-client.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Higgsfield SDK for Node.js and TypeScript","directories":{},"_nodeVersion":"18.20.8","dependencies":{"axios":"^1.6.5","form-data":"^4.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.56.0","ts-jest":"^29.1.1","prettier":"^3.1.1","typescript":"^5.3.3","@types/jest":"^30.0.0","@types/node":"^20.10.6","@typescript-eslint/parser":"^6.18.1","@typescript-eslint/eslint-plugin":"^6.18.1"},"_npmOperationalInternal":{"tmp":"tmp/client_0.1.2_1763458787657_0.7974069310102898","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@higgsfield/client","version":"0.2.1","keywords":["higgsfield","ai","api","client","sdk","typescript","image-generation","video-generation"],"author":{"name":"Higgsfield"},"license":"MIT","_id":"@higgsfield/client@0.2.1","maintainers":[{"name":"rakhmedy","email":"rustem.akhmedyarov@gmail.com"}],"homepage":"https://higgsfield.ai","bugs":{"url":"https://github.com/higgsfield-ai/higgsfield-js.git/issues"},"dist":{"shasum":"a9ec01afa0438e7e2170392a42e003df0bbe8394","tarball":"https://registry.npmjs.org/@higgsfield/client/-/client-0.2.1.tgz","fileCount":62,"integrity":"sha512-xRIlOF0jQwRQ1jIj93okju1PnG/ngx7yeJsmpPq2SSattWUMsL1TjkEZJlVfrrkUeDfP5g8TY/wJ/+TLRNwqFw==","signatures":[{"sig":"MEYCIQDmB5NKwsi1nmxb03SBv1DM626I7vDfGc0NYK/cSFp3cQIhAM+lARCgjePhtOqO5TUhnIwTKYGTOm+Qkf+o0spyYTzn","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":125299},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./v2":{"types":"./dist/v2/index.d.ts","default":"./dist/v2/index.js"}},"gitHead":"09721af14c3e37047f02dc1b350e55ccb0181553","scripts":{"lint":"eslint src/**/*.ts","test":"jest --passWithNoTests","build":"tsc","format":"prettier --write \"src/**/*.ts\"","test:v2":"npx ts-node test-v2.ts","version":"git add -A src","test:nano":"npx ts-node test-nano-banana-pro.ts","build:prod":"tsc -p tsconfig.prod.json","test:watch":"jest --watch --passWithNoTests","build:watch":"tsc --watch","postversion":"git push && git push --tags","prepublishOnly":"npm run build:prod && npm run test"},"_npmUser":{"name":"rakhmedy","email":"rustem.akhmedyarov@gmail.com"},"repository":{"url":"git+https://github.com/higgsfield-ai/higgsfield-js.git","type":"git"},"_npmVersion":"10.8.2","description":"Official Higgsfield SDK for Node.js and TypeScript","directories":{},"_nodeVersion":"20.19.5","dependencies":{"axios":"^1.6.5","form-data":"^4.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.56.0","ts-jest":"^29.1.1","prettier":"^3.1.1","typescript":"^5.3.3","@types/jest":"^30.0.0","@types/node":"^20.10.6","@typescript-eslint/parser":"^6.18.1","@typescript-eslint/eslint-plugin":"^6.18.1"},"_npmOperationalInternal":{"tmp":"tmp/client_0.2.1_1764002826741_0.5524196514174056","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-11-18T09:39:47.580Z","modified":"2026-05-12T12:56:10.029Z","1.0.0":"2025-10-01T18:43:19.548Z","0.1.0":"2025-10-01T19:00:45.704Z","0.1.1":"2025-10-04T21:09:36.342Z","0.1.2":"2025-11-18T09:39:47.840Z","0.2.1":"2025-11-24T16:47:06.920Z"},"bugs":{"url":"https://github.com/higgsfield-ai/higgsfield-js.git/issues"},"author":{"name":"Higgsfield"},"license":"MIT","homepage":"https://higgsfield.ai","keywords":["higgsfield","ai","api","client","sdk","typescript","image-generation","video-generation"],"repository":{"url":"git+https://github.com/higgsfield-ai/higgsfield-js.git","type":"git"},"description":"Official Higgsfield SDK for Node.js and TypeScript","maintainers":[{"email":"alen.a@higgsfield.ai","name":"justtrustme"},{"email":"kuanysh@higgsfield.ai","name":"kuanysh-higgsfield"},{"email":"zhakhanger@higgsfield.ai","name":"zhakhanger-higgsfield"},{"email":"rustem.akhmedyarov@gmail.com","name":"rakhmedy"}],"readme":"# Higgsfield SDK for Node.js and TypeScript\n\nOfficial SDK for interacting with Higgsfield AI's video and image generation APIs.\n\n## Installation\n\n```bash\nnpm install @higgsfield/client\n```\n\n---\n\n## V2 Client (Recommended)\n\nThe v2 client is the modern, recommended way to use the Higgsfield SDK. It features:\n- Single `credentials` field (`KEY_ID:KEY_SECRET` format)\n- `Authorization: Key KEY_ID:KEY_SECRET` authentication header\n- Automatic obfuscated `User-Agent: higgsfield-server-js/2.0` header\n- Server-side only (browser usage blocked for security)\n- Simplified API with `subscribe()` method\n- Automatic polling via `/requests/{request_id}/status` endpoint\n\n### Quick Start\n\n```typescript\nimport { higgsfield, config } from '@higgsfield/client/v2';\n\n// Configure credentials\nconfig({\n  credentials: 'YOUR_KEY_ID:YOUR_KEY_SECRET'\n});\n\n// Generate content\nconst jobSet = await higgsfield.subscribe('flux-pro/kontext/max/text-to-image', {\n  input: {\n    aspect_ratio: '9:16',\n    prompt: 'A beautiful sunset',\n    safety_tolerance: 2,\n    seed: 1234\n  },\n  withPolling: true\n});\n\nif (jobSet.isCompleted) {\n  console.log('Image URL:', jobSet.jobs[0].results?.raw.url);\n}\n```\n\n### Authentication\n\nThe v2 client supports multiple authentication methods:\n\n**Option 1: Single credentials field (recommended)**\n```typescript\nimport { config } from '@higgsfield/client/v2';\n\nconfig({\n  credentials: 'YOUR_KEY_ID:YOUR_KEY_SECRET'\n});\n```\n\n**Option 2: Separate fields (backward compatibility)**\n```typescript\nconfig({\n  apiKey: 'YOUR_KEY_ID',\n  apiSecret: 'YOUR_KEY_SECRET'\n});\n```\n\n**Option 3: Environment variables**\n```bash\n# Preferred: Single variable\nexport HF_CREDENTIALS=\"YOUR_KEY_ID:YOUR_KEY_SECRET\"\n\n# Or separate variables\nexport HF_API_KEY=\"YOUR_KEY_ID\"\nexport HF_API_SECRET=\"YOUR_KEY_SECRET\"\n```\n\n```typescript\n// No config needed - automatically reads from environment\nimport { higgsfield } from '@higgsfield/client/v2';\n```\n\n### Creating a Client Instance\n\n```typescript\nimport { createHiggsfieldClient } from '@higgsfield/client/v2';\n\nconst client = createHiggsfieldClient({\n  credentials: 'YOUR_KEY_ID:YOUR_KEY_SECRET'\n});\n```\n\n### API Methods\n\n#### `subscribe(endpoint, options)`\n\nSubscribe to an endpoint for content generation:\n\n```typescript\nconst jobSet = await higgsfield.subscribe('flux-pro/kontext/max/text-to-image', {\n  input: {\n    aspect_ratio: '9:16',\n    prompt: 'A beautiful sunset',\n    safety_tolerance: 2,\n    seed: 1234\n  },\n  withPolling: true,  // Automatically poll for completion (default: true)\n  webhook: {           // Optional webhook\n    url: 'https://your-webhook-url.com/callback',\n    secret: 'your-webhook-secret'\n  }\n});\n```\n\n**Parameters:**\n- `endpoint` (string): The API endpoint (e.g., `'flux-pro/kontext/max/text-to-image'`)\n- `options.input` (object): Input parameters for the endpoint\n- `options.withPolling` (boolean, default: `true`): Automatically poll for job completion\n- `options.webhook` (object, optional): Webhook configuration\n  - `url` (string): Webhook URL\n  - `secret` (string): Webhook secret\n\n**Note:** When a webhook is provided, the SDK automatically appends `?hf_webhook=<url>` to the endpoint URL.\n\n### Examples\n\n#### Text-to-Image Generation\n\n```typescript\nimport { higgsfield, config } from '@higgsfield/client/v2';\n\nconfig({\n  credentials: 'YOUR_KEY_ID:YOUR_KEY_SECRET'\n});\n\nconst jobSet = await higgsfield.subscribe('flux-pro/kontext/max/text-to-image', {\n  input: {\n    aspect_ratio: '9:16',\n    prompt: 'A majestic mountain landscape at sunset',\n    safety_tolerance: 2,\n    seed: 1234\n  },\n  withPolling: true\n});\n\nif (jobSet.isCompleted) {\n  console.log('Image URL:', jobSet.jobs[0].results?.raw.url);\n}\n```\n\n#### Image-to-Video Generation\n\n```typescript\nconst jobSet = await higgsfield.subscribe('/v1/image2video/dop', {\n  input: {\n    model: 'dop-turbo',\n    prompt: 'Cinematic camera movement',\n    input_images: [{ \n      type: 'image_url', \n      image_url: 'https://example.com/image.jpg' \n    }]\n  },\n  withPolling: true\n});\n\nif (jobSet.isCompleted) {\n  console.log('Video URL:', jobSet.jobs[0].results?.raw.url);\n}\n```\n\n### Polling & Status Lifecycle\n\nThe v2 client automatically polls `/requests/{request_id}/status` when `withPolling` is `true`. The API returns responses with the following structure:\n\n**Status Values:**\n- `queued` – Request accepted and waiting for execution\n- `in_progress` – Generation currently running (cannot cancel)\n- `nsfw` – Content rejected by moderation, credits refunded\n- `failed` – Generation errored, credits refunded\n- `completed` – Generation finished and media URLs are returned\n\n**API Response Format:**\n```json\n{\n  \"status\": \"completed\",\n  \"request_id\": \"d7e6c0f3-6699-4f6c-bb45-2ad7fd9158ff\",\n  \"status_url\": \"https://platform.higgsfield.ai/requests/d7e6c0f3-6699-4f6c-bb45-2ad7fd9158ff/status\",\n  \"cancel_url\": \"https://platform.higgsfield.ai/requests/d7e6c0f3-6699-4f6c-bb45-2ad7fd9158ff/cancel\",\n  \"images\": [{ \"url\": \"https://image.url/example.jpg\" }],\n  \"video\": { \"url\": \"https://video.url/example.mp4\" }\n}\n```\n\nThe SDK automatically converts this response into a `JobSet` with a single job, mapping `images`/`video` to `results.raw` and `results.min` for compatibility with existing code.\n\n### Working with JobSet\n\n```typescript\nconst jobSet = await higgsfield.subscribe('flux-pro/kontext/max/text-to-image', {\n  input: { prompt: 'Test' },\n  withPolling: true\n});\n\n// Check status\nconsole.log('JobSet ID:', jobSet.id);\nconsole.log('Is completed:', jobSet.isCompleted);\nconsole.log('Is queued:', jobSet.isQueued);\nconsole.log('Is in progress:', jobSet.isInProgress);\nconsole.log('Is failed:', jobSet.isFailed);\nconsole.log('Is NSFW:', jobSet.isNsfw);\n\n// Access results\nfor (const job of jobSet.jobs) {\n  if (job.results) {\n    console.log('Result URL:', job.results.raw.url);\n    console.log('Thumbnail URL:', job.results.min.url);\n  }\n}\n```\n\n### Configuration\n\n```typescript\nimport { createHiggsfieldClient } from '@higgsfield/client/v2';\n\nconst client = createHiggsfieldClient({\n  credentials: 'YOUR_KEY_ID:YOUR_KEY_SECRET',\n  \n  // Optional configuration\n  baseURL: 'https://platform.higgsfield.ai', // Default\n  timeout: 120000, // 2 minutes default\n  maxRetries: 3,\n  retryBackoff: 1000,\n  retryMaxBackoff: 60000,\n  pollInterval: 2000, // Check every 2 seconds\n  maxPollTime: 300000, // Timeout after 5 minutes\n  headers: {\n    'X-Custom-Header': 'value'\n  }\n});\n```\n\n### TypeScript Support\n\n```typescript\nimport { \n  createHiggsfieldClient,\n  HiggsfieldClient,\n  JobSet\n} from '@higgsfield/client/v2';\n\nconst client: HiggsfieldClient = createHiggsfieldClient({\n  credentials: 'YOUR_KEY_ID:YOUR_KEY_SECRET'\n});\n\nconst jobSet: JobSet = await client.subscribe('flux-pro/kontext/max/text-to-image', {\n  input: {\n    prompt: 'Test',\n    aspect_ratio: '1:1'\n  }\n});\n```\n\n---\n\n## V1 Client (Deprecated)\n\n> **⚠️ Deprecated:** The v1 client is deprecated. Please use the [V2 Client](#v2-client-recommended) for new projects. The v1 client will continue to work but will not receive new features or updates.\n\nThe v1 client uses the traditional `generate()` method and supports both browser and Node.js environments.\n\n### Quick Start\n\n```typescript\nimport { HiggsfieldClient } from '@higgsfield/client';\nimport { InputImage, SoulQuality, SoulSize, BatchSize, DoPModel } from '@higgsfield/client/helpers';\n\n// Initialize the client\nconst client = new HiggsfieldClient({\n  apiKey: 'YOUR_API_KEY',\n  apiSecret: 'YOUR_API_SECRET'\n});\n```\n\n### Authentication\n\n**Option 1: Pass credentials directly**\n```typescript\nconst client = new HiggsfieldClient({\n  apiKey: 'YOUR_API_KEY',\n  apiSecret: 'YOUR_API_SECRET'\n});\n```\n\n**Option 2: Use environment variables**\n```bash\nexport HF_API_KEY=\"YOUR_API_KEY\"\nexport HF_SECRET=\"YOUR_API_SECRET\"\n```\n\n```typescript\nconst client = new HiggsfieldClient();\n```\n\n### API Methods\n\n#### `generate(endpoint, params, options?)`\n\nGenerate content using any Higgsfield API endpoint:\n\n```typescript\nconst jobSet = await client.generate('/v1/text2image/soul', {\n  prompt: 'A beautiful landscape',\n  width_and_height: SoulSize.SQUARE_1536x1536,\n  quality: SoulQuality.HD,\n  batch_size: BatchSize.SINGLE\n}, {\n  withPolling: true, // Default: true\n  webhook: {\n    url: 'https://your-webhook-url.com/callback',\n    secret: 'your-webhook-secret'\n  }\n});\n```\n\n#### Other Methods\n\n- `getMotions(): Promise<Motion[]>` - Get available motions for image-to-video generation\n- `getSoulStyles(): Promise<SoulStyle[]>` - Get available Soul styles for text-to-image generation\n- `uploadImage(imageBuffer: Buffer, format?: 'jpeg' | 'png' | 'webp'): Promise<string>` - Upload an image\n- `upload(data: Buffer | Uint8Array, contentType: string): Promise<string>` - Upload any data\n- `createSoulId(data: SoulIdCreateData, withPolling?: boolean): Promise<SoulId>` - Create a custom character reference\n- `listSoulIds(page?: number, pageSize?: number): Promise<SoulIdListResponse>` - List all your SoulIds\n\n### Examples\n\n#### Image-to-Video Generation (DoP Model)\n\n```typescript\nimport { InputImage, DoPModel, inputMotion } from '@higgsfield/client/helpers';\n\n// Basic usage\nconst jobSet = await client.generate('/v1/image2video/dop', {\n  model: DoPModel.TURBO,\n  prompt: 'Cinematic camera movement around the subject',\n  input_images: [InputImage.fromUrl('https://example.com/image.jpg')]\n});\n\n// With motions\nconst motions = await client.getMotions();\nconst zoomMotion = motions.find(m => m.name === 'Zoom In');\n\nconst jobSet = await client.generate('/v1/image2video/dop', {\n  model: DoPModel.TURBO,\n  prompt: 'Apply zoom motion to the subject',\n  input_images: [InputImage.fromUrl('https://example.com/image.jpg')],\n  motions: [inputMotion(zoomMotion.id, 0.8)]\n});\n```\n\n#### Text-to-Image Generation (Soul)\n\n```typescript\nimport { SoulQuality, SoulSize, BatchSize, strength, seed } from '@higgsfield/client/helpers';\n\n// Basic usage\nconst jobSet = await client.generate('/v1/text2image/soul', {\n  prompt: 'A majestic mountain landscape at sunset',\n  width_and_height: SoulSize.SQUARE_1536x1536,\n  quality: SoulQuality.HD,\n  batch_size: BatchSize.SINGLE\n});\n\n// With style presets\nconst styles = await client.getSoulStyles();\nconst oilPaintingStyle = styles.find(s => s.name === 'Oil Painting');\n\nconst jobSet = await client.generate('/v1/text2image/soul', {\n  prompt: 'Portrait of a wise elderly person',\n  style_id: oilPaintingStyle.id,\n  style_strength: strength(0.8),\n  width_and_height: SoulSize.PORTRAIT_1536x2048,\n  quality: SoulQuality.HD,\n  batch_size: BatchSize.QUAD,\n  seed: seed(12345)\n});\n```\n\n#### Speech-to-Video Generation (Speak v2)\n\n```typescript\nimport { InputImage, InputAudio, SpeakVideoQuality, SpeakDuration } from '@higgsfield/client/helpers';\n\nconst jobSet = await client.generate('/v1/speak/higgsfield', {\n  input_image: InputImage.fromUrl('https://example.com/avatar.jpg'),\n  input_audio: InputAudio.fromUrl('https://example.com/speech.wav'), // Only WAV files\n  prompt: 'Professional presentation style',\n  quality: SpeakVideoQuality.MID,\n  duration: SpeakDuration.SHORT\n});\n```\n\n#### Custom Character References (SoulIds)\n\n```typescript\nimport { InputImageType } from '@higgsfield/client';\n\n// List existing SoulIds\nconst soulIdList = await client.listSoulIds(1, 10);\n\n// Create a new SoulId\nconst newSoulId = await client.createSoulId({\n  name: 'My Character',\n  input_images: [\n    { type: InputImageType.IMAGE_URL, image_url: 'https://example.com/ref1.jpg' },\n    { type: InputImageType.IMAGE_URL, image_url: 'https://example.com/ref2.jpg' }\n  ]\n}, true); // with polling\n\n// Use in generation\nif (newSoulId.isCompleted) {\n  const jobSet = await client.generate('/v1/text2image/soul', {\n    prompt: 'Portrait in professional attire',\n    custom_reference_id: newSoulId.id,\n    custom_reference_strength: strength(1),\n    width_and_height: SoulSize.PORTRAIT_1536x2048,\n    quality: SoulQuality.HD\n  });\n}\n```\n\n### Configuration\n\n```typescript\nconst client = new HiggsfieldClient({\n  // Authentication\n  apiKey: 'YOUR_API_KEY',\n  apiSecret: 'YOUR_API_SECRET',\n  \n  // API Configuration\n  baseURL: 'https://platform.higgsfield.ai', // Default\n  timeout: 120000, // 2 minutes default\n  \n  // Retry Configuration\n  maxRetries: 3,\n  retryBackoff: 1000,\n  retryMaxBackoff: 60000,\n  \n  // Polling Configuration\n  pollInterval: 2000, // Check every 2 seconds\n  maxPollTime: 300000, // Timeout after 5 minutes\n  \n  // Custom Headers\n  headers: {\n    'X-Custom-Header': 'value'\n  }\n});\n```\n\n---\n\n## Error Handling\n\nThe SDK provides comprehensive error handling with specific error types:\n\n```typescript\nimport { \n  AuthenticationError, \n  BadInputError, \n  ValidationError, \n  NotEnoughCreditsError, \n  APIError,\n  BrowserNotSupportedError // V2 only\n} from '@higgsfield/client';\n\ntry {\n  const jobSet = await higgsfield.subscribe('flux-pro/kontext/max/text-to-image', {\n    input: { prompt: 'Test' }\n  });\n} catch (error) {\n  if (error instanceof AuthenticationError) {\n    console.error('❌ Authentication failed - check your API credentials');\n  } else if (error instanceof NotEnoughCreditsError) {\n    console.error('💳 Insufficient credits - please top up your account');\n  } else if (error instanceof BadInputError) {\n    console.error('📋 Invalid input parameters:', error.message);\n  } else if (error instanceof ValidationError) {\n    console.error('⚠️  Validation error:', error.message);\n  } else if (error instanceof APIError) {\n    console.error('🌐 API Error:', error.statusCode, error.message);\n  } else if (error instanceof BrowserNotSupportedError) {\n    console.error('🚫 Browser usage not supported - use Node.js environment');\n  } else {\n    console.error('💥 Unexpected error:', error);\n  }\n}\n```\n\n### Job Status Handling\n\n```typescript\nfor (const job of jobSet.jobs) {\n  switch (job.status) {\n    case 'completed':\n      console.log('Success:', job.results?.raw.url);\n      break;\n    case 'failed':\n      console.error('Generation failed');\n      break;\n    case 'nsfw':\n      console.warn('Content flagged as NSFW');\n      break;\n    case 'canceled':\n      console.warn('Job was canceled');\n      break;\n  }\n}\n```\n\n---\n\n## Best Practices\n\n1. **Use V2 Client**: For new projects, always use the V2 client as it's actively maintained and includes security improvements.\n\n2. **Upload large files**: For better performance, upload large image/audio files to the CDN first:\n   ```typescript\n   const imageUrl = await client.uploadImage(localImageBuffer, 'jpeg');\n   ```\n\n3. **Handle rate limits**: Configure exponential backoff for retries:\n   ```typescript\n   const client = createHiggsfieldClient({\n     credentials: 'YOUR_KEY_ID:YOUR_KEY_SECRET',\n     maxRetries: 5,\n     retryBackoff: 2000,\n     retryMaxBackoff: 30000\n   });\n   ```\n\n4. **Use webhooks for long operations**: For production, consider implementing webhooks instead of polling to reduce server load.\n\n5. **Cache motion and style IDs**: Fetch and cache available motions/styles at startup:\n   ```typescript\n   const motions = await client.getMotions();\n   const styles = await client.getSoulStyles();\n   const motionMap = new Map(motions.map(m => [m.id, m]));\n   const styleMap = new Map(styles.map(s => [s.id, s]));\n   ```\n\n6. **Environment variables**: Store credentials in environment variables for security:\n   ```bash\n   export HF_CREDENTIALS=\"YOUR_KEY_ID:YOUR_KEY_SECRET\"\n   ```\n\n---\n\n## Support\n\n- Documentation: https://docs.higgsfield.ai\n- API Status: https://status.higgsfield.ai\n\n## License\n\nMIT\n","readmeFilename":"README.md"}