babysea 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +473 -0
- package/badges/license.svg +1 -0
- package/badges/node.svg +1 -0
- package/badges/types.svg +1 -0
- package/badges/version.svg +1 -0
- package/dist/index.cjs +287 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +202 -0
- package/dist/index.d.ts +202 -0
- package/dist/index.js +282 -0
- package/dist/index.js.map +1 -0
- package/dist/types-9mmJNI_Q.d.cts +378 -0
- package/dist/types-9mmJNI_Q.d.ts +378 -0
- package/dist/webhooks.cjs +70 -0
- package/dist/webhooks.cjs.map +1 -0
- package/dist/webhooks.d.cts +15 -0
- package/dist/webhooks.d.ts +15 -0
- package/dist/webhooks.js +68 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +81 -0
- package/socket.json +9 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) BabySea, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
# BabySea
|
|
2
|
+
|
|
3
|
+
Official TypeScript SDK for the [BabySea API](https://babysea.ai). BabySea offers one API for image and video generation across multiple AI inference providers, with automatic failover and a unified schema.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/babysea) [](./LICENSE) [](https://www.typescriptlang.org/) [](https://nodejs.org/en/about/previous-releases)
|
|
6
|
+
|
|
7
|
+
- **Zero dependencies** - pure `fetch` and `crypto.subtle`, works everywhere
|
|
8
|
+
- **Isomorphic** - Node 18+, Edge runtimes (Vercel, Cloudflare Workers), browsers
|
|
9
|
+
- **ESM + CJS** dual build with full TypeScript types
|
|
10
|
+
- **Auto-retry** with exponential backoff and `Retry-After` support
|
|
11
|
+
- **Typed errors** - structured BSE error codes, retry flags, rate limit info
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install babysea
|
|
19
|
+
# or
|
|
20
|
+
pnpm add babysea
|
|
21
|
+
# or
|
|
22
|
+
yarn add babysea
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { BabySea } from 'babysea';
|
|
31
|
+
|
|
32
|
+
const client = new BabySea({
|
|
33
|
+
apiKey: 'bye_...',
|
|
34
|
+
region: 'us', // 'us' | 'eu'
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Preview cost before generating
|
|
38
|
+
const est = await client.estimate('{model_identifier}', 2);
|
|
39
|
+
console.log(est.data.credit_balance_can_afford); // true
|
|
40
|
+
console.log(est.data.cost_total_consumed); // 0.102
|
|
41
|
+
|
|
42
|
+
// Generate an image
|
|
43
|
+
const result = await client.generate('{model_identifier}', {
|
|
44
|
+
generation_prompt: 'A cute baby seal on the beach at golden hour',
|
|
45
|
+
generation_ratio: '16:9',
|
|
46
|
+
generation_output_format: 'png',
|
|
47
|
+
generation_output_number: 1,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
console.log(result.data.generation_id);
|
|
51
|
+
// → "gen_01jh..."
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
> Generations are async - you get a `generation_id` immediately. Use **webhooks** to receive the completed output.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Configuration
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const client = new BabySea({
|
|
62
|
+
/** API key (required). Create one in your BabySea dashboard. */
|
|
63
|
+
apiKey: 'bye_...',
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Region endpoint.
|
|
67
|
+
* - 'us' → https://api.us.babysea.ai (default)
|
|
68
|
+
* - 'eu' → https://api.eu.babysea.ai
|
|
69
|
+
*/
|
|
70
|
+
region: 'us',
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Override the base URL entirely - for custom domains or self-hosted.
|
|
74
|
+
* Takes precedence over `region`.
|
|
75
|
+
*/
|
|
76
|
+
baseUrl: 'https://acme.api.us.babysea.ai',
|
|
77
|
+
|
|
78
|
+
/** Request timeout in milliseconds. Default: 30 000 (30s). */
|
|
79
|
+
timeout: 30_000,
|
|
80
|
+
|
|
81
|
+
/** Max automatic retries on retryable errors (429, 5xx). Default: 2. */
|
|
82
|
+
maxRetries: 2,
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Methods
|
|
89
|
+
|
|
90
|
+
### `generate(model, params)` - Create an image generation
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
const result = await client.generate('{model_identifier}', {
|
|
94
|
+
// Required
|
|
95
|
+
generation_prompt: 'A serene Japanese garden in spring',
|
|
96
|
+
|
|
97
|
+
// Optional
|
|
98
|
+
generation_ratio: '16:9', // '1:1' | '16:9' | '9:16' | '4:3' | '3:4'
|
|
99
|
+
generation_output_format: 'png', // 'png' | 'jpeg' | 'webp'
|
|
100
|
+
generation_output_number: 1, // number of output images
|
|
101
|
+
generation_input_file: [ // input image URLs (for img2img models)
|
|
102
|
+
'https://example.com/reference.jpg',
|
|
103
|
+
],
|
|
104
|
+
generation_provider_order: 'replicate, fal', // optional, model-dependent default
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const { generation_id, generation_provider_order } = result.data;
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
### `generateVideo(model, params)` - Create a video generation
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
// Duration-only video model
|
|
116
|
+
const result = await client.generateVideo('{model_identifier}', {
|
|
117
|
+
// Required
|
|
118
|
+
generation_prompt: 'A baby seal swimming in the ocean',
|
|
119
|
+
generation_duration: 5, // seconds (range varies per model)
|
|
120
|
+
|
|
121
|
+
// Optional
|
|
122
|
+
generation_ratio: '16:9',
|
|
123
|
+
generation_output_format: 'mp4',
|
|
124
|
+
generation_input_file: [
|
|
125
|
+
'https://example.com/reference.jpg',
|
|
126
|
+
],
|
|
127
|
+
generation_provider_order: 'replicate, fal',
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Duration + resolution video model
|
|
131
|
+
const hd = await client.generateVideo('{model_identifier}', {
|
|
132
|
+
generation_prompt: 'Cinematic drone shot over a coral reef',
|
|
133
|
+
generation_duration: 8,
|
|
134
|
+
generation_resolution: '1080p', // required for resolution-priced models
|
|
135
|
+
generation_ratio: '16:9',
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const { generation_id, generation_provider_order } = result.data;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
### `estimate(model, count?)` - Preview cost before generating
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
const est = await client.estimate('{model_identifier}', 5);
|
|
147
|
+
|
|
148
|
+
est.data.cost_per_generation; // 0.051 credits
|
|
149
|
+
est.data.cost_total_consumed; // 0.255 credits
|
|
150
|
+
est.data.credit_balance; // 10.000
|
|
151
|
+
est.data.credit_balance_can_afford; // true
|
|
152
|
+
est.data.credit_balance_max_affordable; // 196
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
### `getGeneration(id)` - Fetch a single generation
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
const gen = await client.getGeneration('gen_01jh...');
|
|
161
|
+
|
|
162
|
+
gen.data.generation_status; // 'processing' | 'succeeded' | 'failed' | 'canceled'
|
|
163
|
+
gen.data.generation_output_file; // string[] of output URLs (when succeeded)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
### `listGenerations(options?)` - List with pagination
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
const page = await client.listGenerations({ limit: 20, offset: 0 });
|
|
172
|
+
|
|
173
|
+
page.total; // total count across all pages
|
|
174
|
+
page.data.generations; // Generation[]
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### `cancelGeneration(id)` - Cancel an in-progress generation
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
const cancel = await client.cancelGeneration('gen_01jh...');
|
|
183
|
+
|
|
184
|
+
cancel.data.generation_status; // 'canceled'
|
|
185
|
+
cancel.data.credits_refunded; // true
|
|
186
|
+
cancel.data.provider_cancel_sent; // true (best-effort signal to provider)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
> Only available while status is `pending` or `processing`. Sends a cancel signal to the upstream provider (best-effort) and refunds credits.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### `deleteGeneration(id)` - Delete a generation and its files
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
const del = await client.deleteGeneration('gen_01jh...');
|
|
197
|
+
|
|
198
|
+
del.data.files_deleted; // number of storage files removed
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
### `status()` - Verify API key and connectivity
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
const s = await client.status();
|
|
207
|
+
|
|
208
|
+
s.data.account_id;
|
|
209
|
+
s.data.apikey_prefix; // 'bye_abc...'
|
|
210
|
+
s.data.apikey_last_used_at;
|
|
211
|
+
s.data.apikey_expires_at;
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
### `account()` - Account details
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
const acct = await client.account();
|
|
220
|
+
|
|
221
|
+
acct.data.account_name;
|
|
222
|
+
acct.data.account_email;
|
|
223
|
+
acct.data.account_is_personal;
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
### `billing()` - Credit balance and subscription
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
const bill = await client.billing();
|
|
232
|
+
|
|
233
|
+
bill.data.billing_credit_balance; // 42.500
|
|
234
|
+
bill.data.billing_plan; // 'Scale'
|
|
235
|
+
bill.data.billing_period_ends_at;
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
### `usage(days?)` - Usage analytics
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
const u = await client.usage(30); // last 30 days (1–90)
|
|
244
|
+
|
|
245
|
+
u.data.usage_total_generations;
|
|
246
|
+
u.data.usage_total_estimated_cost;
|
|
247
|
+
u.data.usage_providers; // per-provider submission breakdown
|
|
248
|
+
u.data.usage_endpoints; // per-endpoint request breakdown
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
### `health.*` - Infrastructure health
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
// Provider circuit breaker state
|
|
257
|
+
const prov = await client.health.providers();
|
|
258
|
+
prov.data.providers;
|
|
259
|
+
// [{ provider: 'replicate', status: 'healthy', failure_rate: 0.01, window: {...} }, ...]
|
|
260
|
+
|
|
261
|
+
// Model availability across inference providers
|
|
262
|
+
const healthModels = await client.health.models();
|
|
263
|
+
healthModels.data.models.forEach((m) => {
|
|
264
|
+
console.log(m.model_identifier, m.model_pricing);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// Redis cache latency
|
|
268
|
+
const cache = await client.health.cache();
|
|
269
|
+
cache.data.latency_ms;
|
|
270
|
+
|
|
271
|
+
// Supabase storage latency
|
|
272
|
+
const storage = await client.health.storage();
|
|
273
|
+
storage.data.latency_ms;
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
### `library.*` - Model and provider catalog
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
// All available models (image + video) with pricing and input schemas
|
|
282
|
+
const models = await client.library.models();
|
|
283
|
+
models.data.models.forEach((m) => {
|
|
284
|
+
// Flat pricing (image + some video models)
|
|
285
|
+
// m.model_pricing → number
|
|
286
|
+
|
|
287
|
+
// Resolution-based pricing (some video models)
|
|
288
|
+
// m.model_pricing → { "480p": 0.030, "720p": 0.062, "1080p": 0.166 }
|
|
289
|
+
|
|
290
|
+
if (typeof m.model_pricing === 'number') {
|
|
291
|
+
console.log(m.model_identifier, m.model_pricing);
|
|
292
|
+
} else {
|
|
293
|
+
console.log(m.model_identifier, m.model_pricing); // per-resolution map
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// All provider integration details
|
|
298
|
+
const providers = await client.library.providers();
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Error Handling
|
|
304
|
+
|
|
305
|
+
```ts
|
|
306
|
+
import { BabySea, BabySeaError, BabySeaTimeoutError, BabySeaRetryError } from 'babysea';
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
await client.generate('{model_identifier}', {
|
|
310
|
+
generation_prompt: 'A rainy city street',
|
|
311
|
+
});
|
|
312
|
+
} catch (err) {
|
|
313
|
+
if (err instanceof BabySeaError) {
|
|
314
|
+
console.error(err.code); // 'BSE1004' - structured error code
|
|
315
|
+
console.error(err.type); // 'insufficient_credits'
|
|
316
|
+
console.error(err.message); // human-readable
|
|
317
|
+
console.error(err.status); // HTTP status (402, 429, 5xx...)
|
|
318
|
+
console.error(err.retryable); // boolean - safe to retry?
|
|
319
|
+
console.error(err.requestId); // unique ID for support
|
|
320
|
+
|
|
321
|
+
// Present on 429 responses
|
|
322
|
+
if (err.rateLimit) {
|
|
323
|
+
console.error(err.rateLimit.remaining); // requests left in window
|
|
324
|
+
console.error(err.rateLimit.retryAfter); // seconds until reset
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (err instanceof BabySeaTimeoutError) {
|
|
329
|
+
// Request exceeded the configured `timeout`
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (err instanceof BabySeaRetryError) {
|
|
333
|
+
// All retry attempts exhausted
|
|
334
|
+
console.error(err.attempts); // number of attempts made
|
|
335
|
+
console.error(err.lastError); // the final BabySeaError
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## Webhooks
|
|
343
|
+
|
|
344
|
+
Receive real-time generation events on your server. BabySea signs every delivery with HMAC-SHA256 (Stripe-style `t=<ts>,v1=<hex>`).
|
|
345
|
+
|
|
346
|
+
```ts
|
|
347
|
+
import { verifyWebhook } from 'babysea/webhooks';
|
|
348
|
+
|
|
349
|
+
// Next.js App Router
|
|
350
|
+
export async function POST(req: Request) {
|
|
351
|
+
const rawBody = await req.text();
|
|
352
|
+
const signature = req.headers.get('X-BabySea-Signature') ?? '';
|
|
353
|
+
|
|
354
|
+
let payload;
|
|
355
|
+
try {
|
|
356
|
+
payload = await verifyWebhook(
|
|
357
|
+
rawBody,
|
|
358
|
+
signature,
|
|
359
|
+
process.env.BABYSEA_WEBHOOK_SECRET!,
|
|
360
|
+
);
|
|
361
|
+
} catch {
|
|
362
|
+
return new Response('Invalid signature', { status: 400 });
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
switch (payload.webhook_event) {
|
|
366
|
+
case 'generation.completed':
|
|
367
|
+
const urls = payload.webhook_data.generation_output_file;
|
|
368
|
+
// urls → string[] of output image URLs
|
|
369
|
+
await saveToDatabase(payload.webhook_data.generation_id, urls);
|
|
370
|
+
break;
|
|
371
|
+
|
|
372
|
+
case 'generation.failed':
|
|
373
|
+
console.error(payload.webhook_data.generation_error);
|
|
374
|
+
break;
|
|
375
|
+
|
|
376
|
+
case 'generation.canceled':
|
|
377
|
+
// credits were automatically refunded
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return new Response('OK');
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Webhook Events
|
|
386
|
+
|
|
387
|
+
| Event | When |
|
|
388
|
+
|---|---|
|
|
389
|
+
| `generation.started` | Generation accepted, provider called |
|
|
390
|
+
| `generation.completed` | Provider succeeded, output files available |
|
|
391
|
+
| `generation.failed` | All providers failed or infrastructure error |
|
|
392
|
+
| `generation.canceled` | Canceled by user, credits refunded |
|
|
393
|
+
| `webhook.test` | Test ping from the dashboard |
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## API Key Scopes
|
|
398
|
+
|
|
399
|
+
BabySea supports scoped API keys - issue a read-only key for your analytics dashboard, a generate-only key for your backend, and a full-access key for internal tools.
|
|
400
|
+
|
|
401
|
+
| Scope | Routes |
|
|
402
|
+
|---|---|
|
|
403
|
+
| `generation:write` | POST `/v1/generate/image/:model`, POST `/v1/generate/video/:model` |
|
|
404
|
+
| `generation:read` | GET `/v1/content/:generationId`, GET `/v1/content/list` |
|
|
405
|
+
| `generation:delete` | DELETE `/v1/content/:generationId`, POST `/v1/content/generation/cancel/:generationId` |
|
|
406
|
+
| `account:read` | GET `/v1/user/account`, `/v1/user/billing`, `/v1/usage`, `/v1/status` |
|
|
407
|
+
| `health:read` | GET `/v1/health/*` |
|
|
408
|
+
| `library:read` | GET `/v1/library/*`, `/v1/estimate/*` |
|
|
409
|
+
|
|
410
|
+
**Preset bundles:**
|
|
411
|
+
|
|
412
|
+
| Preset | Included scopes |
|
|
413
|
+
|---|---|
|
|
414
|
+
| `full_access` | All scopes |
|
|
415
|
+
| `generate_only` | `generation:write`, `generation:read`, `library:read` |
|
|
416
|
+
| `read_only` | `generation:read`, `account:read`, `health:read`, `library:read` |
|
|
417
|
+
| `monitor_only` | `health:read`, `library:read` |
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Response Envelope
|
|
422
|
+
|
|
423
|
+
All successful responses share this shape:
|
|
424
|
+
|
|
425
|
+
```ts
|
|
426
|
+
interface ApiResponse<T> {
|
|
427
|
+
status: 'success';
|
|
428
|
+
request_id: string; // unique ID - include this when contacting support
|
|
429
|
+
message: string;
|
|
430
|
+
timestamp: string;
|
|
431
|
+
data: T;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Paginated responses add:
|
|
435
|
+
interface PaginatedResponse<T> extends ApiResponse<T> {
|
|
436
|
+
total: number;
|
|
437
|
+
limit: number;
|
|
438
|
+
offset: number;
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Rate Limits
|
|
445
|
+
|
|
446
|
+
| Plan | General (req/min) | Generation (req/min) |
|
|
447
|
+
|---|---|---|
|
|
448
|
+
| Free | 30 | 10 |
|
|
449
|
+
| Starter ($9/mo) | 60 | 20 |
|
|
450
|
+
| Pro ($29/mo) | 150 | 50 |
|
|
451
|
+
| Scale ($99/mo) | 300 | 100 |
|
|
452
|
+
| Enterprise ($199/mo) | 600 | 200 |
|
|
453
|
+
|
|
454
|
+
All limits are per-account (shared across all API keys under the same account). The SDK automatically retries 429 responses using `Retry-After`, up to `maxRetries` (default: 2).
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## Regions
|
|
459
|
+
|
|
460
|
+
| Region | Endpoint |
|
|
461
|
+
|---|---|
|
|
462
|
+
| `us` | `https://api.us.babysea.ai` |
|
|
463
|
+
| `eu` | `https://api.eu.babysea.ai` |
|
|
464
|
+
|
|
465
|
+
Custom API domains (Scale and Enterprise plans) are supported via the `baseUrl` option.
|
|
466
|
+
|
|
467
|
+
BabySea routes requests across all configured inference providers (Replicate, Fal, BytePlus) automatically with failover.
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
## License
|
|
472
|
+
|
|
473
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="78" height="20" role="img" aria-label="license: MIT"><title>license: MIT</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="78" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="47" height="20" fill="#555"/><rect x="47" width="31" height="20" fill="#4c1"/><rect width="78" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="245" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370">license</text><text x="245" y="140" transform="scale(.1)" fill="#fff" textLength="370">license</text><text aria-hidden="true" x="615" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="210">MIT</text><text x="615" y="140" transform="scale(.1)" fill="#fff" textLength="210">MIT</text></g></svg>
|
package/badges/node.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="78" height="20" role="img" aria-label="node: >=18"><title>node: >=18</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="78" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="37" height="20" fill="#555"/><rect x="37" width="41" height="20" fill="#339933"/><rect width="78" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">node</text><text x="195" y="140" transform="scale(.1)" fill="#fff" textLength="270">node</text><text aria-hidden="true" x="565" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="310">>=18</text><text x="565" y="140" transform="scale(.1)" fill="#fff" textLength="310">>=18</text></g></svg>
|
package/badges/types.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="192" height="20" role="img" aria-label="npm type definitions: TypeScript"><title>npm type definitions: TypeScript</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="192" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="123" height="20" fill="#555"/><rect x="123" width="69" height="20" fill="#3178c6"/><rect width="192" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="625" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="1130">npm type definitions</text><text x="625" y="140" transform="scale(.1)" fill="#fff" textLength="1130">npm type definitions</text><text aria-hidden="true" x="1565" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="590">TypeScript</text><text x="1565" y="140" transform="scale(.1)" fill="#fff" textLength="590">TypeScript</text></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="20" role="img" aria-label="npm: v1.0.2"><title>npm: v1.0.2</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="80" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="35" height="20" fill="#555"/><rect x="35" width="45" height="20" fill="#cb3837"/><rect width="80" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="185" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="250">npm</text><text x="185" y="140" transform="scale(.1)" fill="#fff" textLength="250">npm</text><text aria-hidden="true" x="565" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="350">v1.0.2</text><text x="565" y="140" transform="scale(.1)" fill="#fff" textLength="350">v1.0.2</text></g></svg>
|