@idelio/contracts 0.1.0-beta.0 → 0.1.0-beta.1

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.
@@ -0,0 +1,618 @@
1
+ export const errorCatalog = {
2
+ required_assets_missing: {
3
+ type: "invalid_request_error",
4
+ status: [422],
5
+ title: "Required asset kinds are missing",
6
+ description: "Every new brand includes five asset kinds - logo, logo_alternative, logo_wordmark, color_palette and font_pairing - and the assets list in this request leaves out at least one of them. The message names the missing kinds.",
7
+ resolution: "Add the missing kinds to assets, or leave assets out entirely to get exactly the five. Other kinds can be added on top.",
8
+ },
9
+ unsupported_size: {
10
+ type: "invalid_request_error",
11
+ status: [415],
12
+ title: "The asset was not rendered at that size",
13
+ description: "Favicons and app icons come pre-rendered at a fixed set of sizes, and nothing is resized on request. The size you asked for is not one of them; the message lists the sizes this asset has.",
14
+ resolution: "Request one of the sizes the message lists, or omit size to get the asset's default file.",
15
+ },
16
+ session_required: {
17
+ type: "permission_error",
18
+ status: [403],
19
+ title: "This action needs a signed-in user",
20
+ description: "The operation acts on behalf of a person - billing, members, API keys, workspace settings - and an API key acts for the workspace, not a person, so it can never call it.",
21
+ resolution: "Do this in the Idelio app while signed in. The SDK exposes no method for these operations.",
22
+ },
23
+ already_a_member: {
24
+ type: "conflict_error",
25
+ status: [409],
26
+ title: "That person is already a member",
27
+ description: "The invite or add-member request named a person who already belongs to this workspace.",
28
+ resolution: "No action is needed - the person already has access. Check the workspace's member list.",
29
+ },
30
+ already_generating: {
31
+ type: "conflict_error",
32
+ status: [409],
33
+ title: "That suggestion is already generating",
34
+ description: "The asset a suggestion card points at is already being produced by a job that has not finished yet, so generating it again was refused.",
35
+ resolution: "Wait for the running job to finish, then check the brand's assets or suggestions again.",
36
+ },
37
+ already_on_this_plan: {
38
+ type: "invalid_request_error",
39
+ status: [422],
40
+ title: "The workspace is already on that plan",
41
+ description: "The checkout or subscription-change request named the price the workspace is subscribed to already.",
42
+ resolution: "Pick a different plan's price id, or skip the change if the current plan is the intended one.",
43
+ },
44
+ already_refunded: {
45
+ type: "conflict_error",
46
+ status: [409],
47
+ title: "This reservation was already refunded",
48
+ description: "A credit reservation can be settled or refunded exactly once. This one was already refunded, so it cannot be acted on again.",
49
+ resolution: "This indicates the request replayed an operation that already completed. If the underlying job or asset still looks stuck, report it with the request_id.",
50
+ },
51
+ already_settled: {
52
+ type: "conflict_error",
53
+ status: [409],
54
+ title: "This reservation was already settled",
55
+ description: "A credit reservation can be settled or refunded exactly once. This one was already settled, so it cannot be acted on again.",
56
+ resolution: "This indicates the request replayed an operation that already completed. If the underlying job or asset still looks stuck, report it with the request_id.",
57
+ },
58
+ api_key_not_found: {
59
+ type: "not_found_error",
60
+ status: [404],
61
+ title: "No active API key with that id",
62
+ description: "The API key id in the request does not match an active key on this workspace - it may be revoked or never existed.",
63
+ resolution: "Check the key id, or list the workspace's keys to find the right one.",
64
+ },
65
+ asset_already_exists: {
66
+ type: "conflict_error",
67
+ status: [409],
68
+ title: "The brand already has this asset kind",
69
+ description: "An expand request asked for one or more asset kinds the brand already owns. The message names which ones.",
70
+ resolution: "Use refine or regenerate on the existing asset instead of expanding for a kind the brand already has.",
71
+ },
72
+ asset_kind_does_not_support_instructions: {
73
+ type: "invalid_request_error",
74
+ status: [422],
75
+ title: "This asset kind takes no refine/variation instructions",
76
+ description: "Free-text refine or variation instructions are not supported for this asset's kind yet.",
77
+ resolution: "Omit the instructions field for this kind, or regenerate the asset without it.",
78
+ },
79
+ asset_kind_not_expandable: {
80
+ type: "invalid_request_error",
81
+ status: [422],
82
+ title: "This asset kind cannot be expanded",
83
+ description: "The expand endpoint only produces certain asset kinds - notably not logo, which has its own dedicated generation and approval flow. The message names the kinds it refused.",
84
+ resolution: "Remove the named kinds from the request, or use the kind's own dedicated endpoint if it has one.",
85
+ },
86
+ asset_kind_not_priceable: {
87
+ type: "invalid_request_error",
88
+ status: [422],
89
+ title: "This build cannot price that asset kind",
90
+ description: "The asset kind named in the request has no credit price in the currently deployed catalogue.",
91
+ resolution: "This indicates a kind that predates or postdates this deployment's catalogue. Report it with the request_id.",
92
+ },
93
+ asset_kind_not_regenerable: {
94
+ type: "api_error",
95
+ status: [501],
96
+ title: "Regeneration is not yet available for this asset kind",
97
+ description: "Regenerate is only implemented for a subset of asset kinds so far; this one is not one of them.",
98
+ resolution: "There is no workaround yet for this kind - check back as the catalogue of regenerable kinds grows.",
99
+ },
100
+ asset_kinds_require_studio_or_elite: {
101
+ type: "invalid_request_error",
102
+ status: [422],
103
+ title: "These asset kinds need a higher AI team tier",
104
+ description: "One or more requested asset kinds are not available on the flash tier. The message names which ones.",
105
+ resolution: "Request those kinds on a brand generated (or expanded) with a higher team tier, or drop them from the request.",
106
+ },
107
+ asset_not_found: {
108
+ type: "not_found_error",
109
+ status: [404],
110
+ title: "No asset with that id",
111
+ description: "The asset id in the request does not match an asset in this workspace.",
112
+ resolution: "Check the asset id, or list the brand's assets to find the right one.",
113
+ },
114
+ asset_not_ready: {
115
+ type: "not_found_error",
116
+ status: [404],
117
+ title: "This asset has no downloadable files yet",
118
+ description: "The asset exists but its generation has not produced any files yet - it may still be in progress.",
119
+ resolution: "Wait for the asset's job to finish, then request the download again.",
120
+ },
121
+ asset_not_yet_approved: {
122
+ type: "invalid_request_error",
123
+ status: [422],
124
+ title: "Approve a logo concept first",
125
+ description: "A variation was requested of a logo concept before any concept on this brand was approved.",
126
+ resolution: "Approve a logo concept for this brand, then request the variation.",
127
+ },
128
+ asset_recipe_incomplete: {
129
+ type: "invalid_request_error",
130
+ status: [422],
131
+ title: "This asset predates regeneration support",
132
+ description: "The asset was generated before its kind recorded the recipe regeneration needs, so it cannot be regenerated in place.",
133
+ resolution: "Regenerate the full brand (or, for a logo-derived kind, the logo) to get an asset that can be regenerated on its own.",
134
+ },
135
+ asset_version_not_found: {
136
+ type: "not_found_error",
137
+ status: [404],
138
+ title: "No matching asset version for that job",
139
+ description: "The asset_version_id in the request does not match a logo concept (or other version) recorded against this job.",
140
+ resolution: "Re-read the job's logo concepts and use one of the asset_version_id values it lists.",
141
+ },
142
+ bad_request: {
143
+ type: "invalid_request_error",
144
+ status: [400],
145
+ title: "The request could not be processed",
146
+ description: "A generic 400 raised without a more specific code - the request was malformed in a way none of the catalogue's other 4xx codes describe.",
147
+ resolution: "Check the request body and query parameters against the OpenAPI document for this operation.",
148
+ },
149
+ brand_asset_not_found: {
150
+ type: "not_found_error",
151
+ status: [404],
152
+ title: "The brand has no such asset yet",
153
+ description: "The brand export or download you requested needs an asset the brand does not have yet - for example a logo, a rendered PNG, a guidelines PDF or a wordmark.",
154
+ resolution: "Generate or expand the brand to produce the missing asset first, then request the export again.",
155
+ },
156
+ brand_not_found: {
157
+ type: "not_found_error",
158
+ status: [404],
159
+ title: "No brand with that id",
160
+ description: "The brand id in the request does not match a brand in this workspace.",
161
+ resolution: "Check the brand id, or list the workspace's brands to find the right one.",
162
+ },
163
+ brand_not_ready: {
164
+ type: "conflict_error",
165
+ status: [409],
166
+ title: "The brand has not finished generating",
167
+ description: "The brand's DNA (or its current version) has not been frozen yet - its generation job must complete first.",
168
+ resolution: "Wait for the brand's generation job to finish, then request this operation again.",
169
+ },
170
+ checkout_session_not_found: {
171
+ type: "not_found_error",
172
+ status: [404],
173
+ title: "No checkout session with that id",
174
+ description: "The checkout session id in the request does not match a session created for this workspace.",
175
+ resolution: "Check the session id, or start a new checkout session.",
176
+ },
177
+ clerk_error: {
178
+ type: "api_error",
179
+ status: [502],
180
+ title: "The identity provider could not complete this request",
181
+ description: "A call to the identity provider behind sign-in and organizations failed or timed out.",
182
+ resolution: "Try again. If it keeps happening, report it with the request_id.",
183
+ },
184
+ colors_locked: {
185
+ type: "conflict_error",
186
+ status: [409],
187
+ title: "This brand's color palette is locked",
188
+ description: "A generation lock is pinning the brand's color palette, so it cannot be regenerated while the lock is on.",
189
+ resolution: "Unlock the color palette in the brand's DNA, then regenerate it.",
190
+ },
191
+ conflict: {
192
+ type: "conflict_error",
193
+ status: [409],
194
+ title: "The request conflicts with the resource's current state",
195
+ description: "A generic 409 raised without a more specific code - the operation cannot be completed given the resource's current state.",
196
+ resolution: "Re-read the resource's current state and retry the operation if it still applies.",
197
+ },
198
+ creative_directions_failed: {
199
+ type: "api_error",
200
+ status: [503],
201
+ title: "Couldn't rank the creative directions",
202
+ description: "The model call that ranks candidate creative directions for a brand failed or timed out.",
203
+ resolution: "Try again. If it keeps happening, report it with the request_id.",
204
+ },
205
+ custom_image_must_be_alone: {
206
+ type: "invalid_request_error",
207
+ status: [422],
208
+ title: "custom_image cannot be combined with other kinds",
209
+ description: "A request's assets list included custom_image alongside one or more other asset kinds, which is not allowed.",
210
+ resolution: 'Send a request with assets set to exactly ["custom_image"], and request the other kinds separately.',
211
+ },
212
+ custom_image_name_not_allowed: {
213
+ type: "invalid_request_error",
214
+ status: [422],
215
+ title: "custom_image_name is only valid for a custom_image request",
216
+ description: 'The custom_image_name field was set on a request whose assets is not exactly ["custom_image"].',
217
+ resolution: 'Only send custom_image_name when assets is exactly ["custom_image"]; otherwise omit it.',
218
+ },
219
+ custom_image_prompt_required: {
220
+ type: "invalid_request_error",
221
+ status: [422],
222
+ title: "A prompt is required for a custom image",
223
+ description: "The request asked for a custom_image asset without supplying custom_image_prompt.",
224
+ resolution: "Include custom_image_prompt describing the image to generate.",
225
+ },
226
+ dna_token_kinds_must_be_alone: {
227
+ type: "invalid_request_error",
228
+ status: [422],
229
+ title: "color_palette/font_pairing cannot be combined with other kinds",
230
+ description: "Expanding color_palette or font_pairing regenerates a DNA token in a new brand version, and cannot be requested alongside any other asset kind in the same request.",
231
+ resolution: "Send color_palette or font_pairing alone, and request other kinds in a separate call.",
232
+ },
233
+ icon_locked: {
234
+ type: "conflict_error",
235
+ status: [409],
236
+ title: "This brand's icon is locked",
237
+ description: "A generation lock is pinning the brand's logo icon, so it cannot be regenerated while the lock is on.",
238
+ resolution: "Unlock the icon in the brand's DNA, then regenerate the logo.",
239
+ },
240
+ idempotency_key_required: {
241
+ type: "invalid_request_error",
242
+ status: [400],
243
+ title: "An Idempotency-Key header is required",
244
+ description: "Paid generation routes require an Idempotency-Key header so a retried request cannot be charged twice.",
245
+ resolution: "Send an Idempotency-Key header - any unique string you generate per attempt is fine; a retried attempt should reuse the same key.",
246
+ },
247
+ insufficient_credits: {
248
+ type: "payment_error",
249
+ status: [402],
250
+ title: "Not enough credits for this operation",
251
+ description: "The workspace does not have enough credits to reserve for the requested generation.",
252
+ resolution: "Buy more credits or wait for the plan's next refill, then retry the request.",
253
+ },
254
+ insufficient_role: {
255
+ type: "permission_error",
256
+ status: [403],
257
+ title: "Your role does not allow this action",
258
+ description: "The signed-in user's role in this workspace is below the role this action requires. The message names the required role.",
259
+ resolution: "Ask a workspace owner or admin to perform this action, or to raise your role.",
260
+ },
261
+ insufficient_scope: {
262
+ type: "permission_error",
263
+ status: [403],
264
+ title: "This API key is missing a required scope",
265
+ description: "The API key used for this request does not carry the scope this action requires. The message names the required scope.",
266
+ resolution: "Create or use an API key that includes the required scope.",
267
+ },
268
+ internal_error: {
269
+ type: "api_error",
270
+ status: [500],
271
+ title: "Something went wrong on our side",
272
+ description: "An unexpected error occurred while handling the request, and it was not one this catalogue names more specifically.",
273
+ resolution: "Try again. If it keeps happening, report it with the request_id.",
274
+ },
275
+ invalid_amount: {
276
+ type: "invalid_request_error",
277
+ status: [400],
278
+ title: "The amount is not valid",
279
+ description: "A credits amount in the request must be a non-negative integer (or, for a top-up, a positive integer), and it was not.",
280
+ resolution: "Send a whole, non-negative number for the amount field (positive for a top-up).",
281
+ },
282
+ invalid_api_key: {
283
+ type: "authentication_error",
284
+ status: [401],
285
+ title: "The API key is not valid",
286
+ description: "The API key on the request is unknown, has been revoked, or its workspace no longer exists.",
287
+ resolution: "Use a current, active API key for an existing workspace. Create a new one in the Idelio app if needed.",
288
+ },
289
+ invalid_cursor: {
290
+ type: "invalid_request_error",
291
+ status: [400],
292
+ title: "The pagination cursor is malformed",
293
+ description: "The cursor query parameter on a list request could not be decoded.",
294
+ resolution: "Only pass a cursor value exactly as returned by a previous page of the same list - never construct one by hand.",
295
+ },
296
+ invalid_settlement: {
297
+ type: "conflict_error",
298
+ status: [409],
299
+ title: "This settlement does not match its reservation",
300
+ description: "The amount being settled against a credit reservation is more than the reservation actually holds.",
301
+ resolution: "This indicates an internal inconsistency between a job's reservation and its settlement. Report it with the request_id.",
302
+ },
303
+ invalid_signature: {
304
+ type: "authentication_error",
305
+ status: [401],
306
+ title: "The webhook signature could not be verified",
307
+ description: "An inbound webhook (from the billing provider or the identity provider) arrived with a signature that does not match its payload.",
308
+ resolution: "This is not something an integrator can resolve on our webhooks. If you operate your own webhook endpoint and see this from us, verify the signing secret you configured matches ours.",
309
+ },
310
+ invalid_target: {
311
+ type: "invalid_request_error",
312
+ status: [422],
313
+ title: "That export target is not supported",
314
+ description: "The target query parameter on a brand export request did not name one of the supported export targets.",
315
+ resolution: "Use one of the supported target values documented for this endpoint.",
316
+ },
317
+ invalid_token: {
318
+ type: "authentication_error",
319
+ status: [401],
320
+ title: "The session token could not be verified",
321
+ description: "The bearer token on the request is not a valid, current identity provider session token.",
322
+ resolution: "Sign in again to get a fresh session token.",
323
+ },
324
+ job_already_finalized: {
325
+ type: "conflict_error",
326
+ status: [409],
327
+ title: "This job has already finalized",
328
+ description: "The job has already reached a terminal state and can no longer accept an asset retry.",
329
+ resolution: "Start a new job (generate or expand again) instead of retrying an asset on this one.",
330
+ },
331
+ job_asset_not_found: {
332
+ type: "not_found_error",
333
+ status: [404],
334
+ title: "No asset of that kind on this job",
335
+ description: "The kind named in the request does not match any asset this job produced or is producing.",
336
+ resolution: "Check the job's steps to find the asset kinds it actually covers.",
337
+ },
338
+ job_asset_not_retryable: {
339
+ type: "conflict_error",
340
+ status: [409],
341
+ title: "This asset is not in a retryable state",
342
+ description: "A retry was requested for a job asset that is not currently in a failed, retryable state. The message names its current state.",
343
+ resolution: "Only retry an asset while the job reports it as failed and retryable.",
344
+ },
345
+ job_not_awaiting_logo_selection: {
346
+ type: "conflict_error",
347
+ status: [409],
348
+ title: "This job is not awaiting a logo selection",
349
+ description: "A logo concept selection was submitted for a job that is not currently paused waiting for one.",
350
+ resolution: "Only select a logo concept while the job's status shows it is awaiting a logo selection.",
351
+ },
352
+ job_not_cancelable: {
353
+ type: "conflict_error",
354
+ status: [409],
355
+ title: "This job has already finished",
356
+ description: "A cancel was requested for a job that already reached a terminal status. The message names that status.",
357
+ resolution: "There is nothing to cancel - the job is no longer running.",
358
+ },
359
+ job_not_found: {
360
+ type: "not_found_error",
361
+ status: [404],
362
+ title: "No job with that id",
363
+ description: "The job id in the request does not match a job in this workspace.",
364
+ resolution: "Check the job id, or read the brand's current job to find the right one.",
365
+ },
366
+ last_owner: {
367
+ type: "conflict_error",
368
+ status: [409],
369
+ title: "The workspace must keep at least one owner",
370
+ description: "The requested change (removing a member or changing a role) would leave the workspace with no owner.",
371
+ resolution: "Promote another member to owner first, then repeat this change.",
372
+ },
373
+ lockup_not_available: {
374
+ type: "invalid_request_error",
375
+ status: [422],
376
+ title: "This brand has no lockup yet",
377
+ description: "The brand's logo predates the pipeline producing a lockup file, so variant=lockup has nothing to return.",
378
+ resolution: "Regenerate the logo to get a lockup, or request variant=mark instead.",
379
+ },
380
+ logo_concept_preview_failed: {
381
+ type: "api_error",
382
+ status: [503],
383
+ title: "Couldn't render that logo concept preview",
384
+ description: "The render that produces a logo concept's preview image failed or timed out.",
385
+ resolution: "Try again. If it keeps happening, report it with the request_id.",
386
+ },
387
+ logo_not_approved: {
388
+ type: "conflict_error",
389
+ status: [409],
390
+ title: "This brand has no approved logo yet",
391
+ description: "The requested asset kind renders from the brand's approved logo mark, and this brand has not approved a logo concept yet.",
392
+ resolution: "Approve a logo concept for this brand, then request the asset kind again.",
393
+ },
394
+ logo_not_found: {
395
+ type: "not_found_error",
396
+ status: [404],
397
+ title: "This brand has no approved logo yet",
398
+ description: "The endpoint reads the brand's approved logo treatment, and this brand has not approved a logo concept yet.",
399
+ resolution: "Approve a logo concept for this brand, then call this endpoint again.",
400
+ },
401
+ logo_not_raster: {
402
+ type: "conflict_error",
403
+ status: [409],
404
+ title: "This brand's logo predates raster generation",
405
+ description: "The brand's approved logo is a vector-only mark from before the raster-only logo pipeline, and cannot render the requested kind.",
406
+ resolution: "Regenerate the logo to get a raster mark, then request the asset kind again.",
407
+ },
408
+ member_not_found: {
409
+ type: "not_found_error",
410
+ status: [404],
411
+ title: "No member with that user id",
412
+ description: "The user id in the request does not match a member of this workspace.",
413
+ resolution: "Check the user id, or list the workspace's members to find the right one.",
414
+ },
415
+ missing_authorization: {
416
+ type: "authentication_error",
417
+ status: [401],
418
+ title: "No Authorization header was sent",
419
+ description: "The request carried no Authorization header at all.",
420
+ resolution: "Send an Authorization: Bearer header with either a session token or an API key.",
421
+ },
422
+ name_ideas_failed: {
423
+ type: "api_error",
424
+ status: [503],
425
+ title: "Couldn't come up with names",
426
+ description: "The model call that generates brand name ideas failed or timed out.",
427
+ resolution: "Try again. If it keeps happening, report it with the request_id.",
428
+ },
429
+ no_active_subscription: {
430
+ type: "conflict_error",
431
+ status: [409],
432
+ title: "This workspace has no active subscription",
433
+ description: "The requested billing operation needs an active subscription, and this workspace does not have one yet.",
434
+ resolution: "Start a subscription with POST /v1/billing/checkout, then retry this operation.",
435
+ },
436
+ no_billing_customer: {
437
+ type: "conflict_error",
438
+ status: [409],
439
+ title: "This workspace has never made a purchase",
440
+ description: "The requested billing operation needs an existing billing customer record, and this workspace has none yet.",
441
+ resolution: "Make a purchase or start a subscription first, then retry this operation.",
442
+ },
443
+ not_a_membership: {
444
+ type: "invalid_request_error",
445
+ status: [422],
446
+ title: "This action belongs to a signed-in user",
447
+ description: "Onboarding-style operations act on a person's own membership and cannot be performed by an API key.",
448
+ resolution: "Perform this action in the Idelio app while signed in. The SDK exposes no method for it.",
449
+ },
450
+ organization_required: {
451
+ type: "authentication_error",
452
+ status: [401],
453
+ title: "An active organization is required",
454
+ description: "The signed-in session has no active organization selected, and this action needs one.",
455
+ resolution: "Select or create an organization in the Idelio app, then retry.",
456
+ },
457
+ package_failed: {
458
+ type: "api_error",
459
+ status: [503],
460
+ title: "Couldn't package the files for download",
461
+ description: "Building the requested download archive failed or timed out.",
462
+ resolution: "Try again. If it keeps happening, report it with the request_id.",
463
+ },
464
+ preview_failed: {
465
+ type: "api_error",
466
+ status: [503],
467
+ title: "Couldn't render that preview",
468
+ description: "The render behind this preview request failed or timed out.",
469
+ resolution: "Try again. If it keeps happening, report it with the request_id.",
470
+ },
471
+ rate_limited: {
472
+ type: "rate_limit_error",
473
+ status: [429],
474
+ title: "Too many requests in a short time",
475
+ description: "The caller exceeded a rate limit - on the general API, on the free AI-assist routes, or on a public form like consent or the waitlist.",
476
+ resolution: "Honor the Retry-After header (when present) and slow down before retrying.",
477
+ },
478
+ reservation_not_found: {
479
+ type: "not_found_error",
480
+ status: [404],
481
+ title: "No credit reservation for that job",
482
+ description: "The job id (and idempotency key, where relevant) does not match a credit reservation on record.",
483
+ resolution: "This indicates the job never reserved credits, or the reservation was already resolved. Report it with the request_id if the job still appears to be paid work in progress.",
484
+ },
485
+ resource_missing: {
486
+ type: "not_found_error",
487
+ status: [404],
488
+ title: "The requested resource does not exist",
489
+ description: "A generic 404 raised without a more specific code - nothing matches the id or path in the request.",
490
+ resolution: "Check the id or path against the resource's list endpoint.",
491
+ },
492
+ slug_taken: {
493
+ type: "conflict_error",
494
+ status: [409],
495
+ title: "That slug is already in use",
496
+ description: "The slug named in a brand update request already belongs to another brand in this workspace.",
497
+ resolution: "Choose a different slug.",
498
+ },
499
+ stripe_error: {
500
+ type: "api_error",
501
+ status: [502],
502
+ title: "The billing provider could not complete this request",
503
+ description: "A call to the billing provider failed or timed out.",
504
+ resolution: "Try again. If it keeps happening, report it with the request_id.",
505
+ },
506
+ suggestion_needs_review: {
507
+ type: "conflict_error",
508
+ status: [409],
509
+ title: "This custom asset idea needs review first",
510
+ description: "A custom asset idea's prompt is generated from the brand page after review, and cannot be generated directly by kind.",
511
+ resolution: "Open the brand page's suggestions and generate the custom asset idea from there.",
512
+ },
513
+ suggestion_not_found: {
514
+ type: "not_found_error",
515
+ status: [404],
516
+ title: "No current suggestion for that kind",
517
+ description: "The brand has no live suggestion card for the requested asset kind right now.",
518
+ resolution: "Re-read the brand's current suggestions and act on one that is actually listed.",
519
+ },
520
+ surprise_brief_failed: {
521
+ type: "api_error",
522
+ status: [503],
523
+ title: "Couldn't come up with an idea",
524
+ description: "The model call that generates a surprise-me brand brief failed or timed out.",
525
+ resolution: "Try again. If it keeps happening, report it with the request_id.",
526
+ },
527
+ template_not_found: {
528
+ type: "not_found_error",
529
+ status: [404],
530
+ title: "No template with that id",
531
+ description: "The template id in the request does not match a template in the catalog.",
532
+ resolution: "Check the template id, or list the catalog's templates to find the right one.",
533
+ },
534
+ too_many_running_jobs: {
535
+ type: "conflict_error",
536
+ status: [409],
537
+ title: "Too many generations running at once",
538
+ description: "The workspace already has as many generation jobs running as its plan allows.",
539
+ resolution: "Wait for a running job to finish, or cancel one, then start the new one.",
540
+ },
541
+ typography_locked: {
542
+ type: "conflict_error",
543
+ status: [409],
544
+ title: "This brand's typography is locked",
545
+ description: "A generation lock is pinning the brand's typography, so it cannot be regenerated - or the logo's font changed - while the lock is on.",
546
+ resolution: "Unlock typography in the brand's DNA, then retry.",
547
+ },
548
+ unauthenticated: {
549
+ type: "authentication_error",
550
+ status: [401],
551
+ title: "Sign in is required",
552
+ description: "The requested action (recording consent, for example) requires a signed-in user and none is present.",
553
+ resolution: "Sign in, then retry the request.",
554
+ },
555
+ unknown_price_id: {
556
+ type: "invalid_request_error",
557
+ status: [422],
558
+ title: "That price id is not recognized",
559
+ description: "The price_id in the checkout or plan-change request does not match a price this deployment knows about.",
560
+ resolution: "Use one of the price ids the plans/pricing endpoint returns.",
561
+ },
562
+ unsupported_format: {
563
+ type: "invalid_request_error",
564
+ status: [415, 422],
565
+ title: "That file format is not available for this asset",
566
+ description: "The requested file format (for a download, an export, or a logo/wordmark variant) does not exist for this asset - for example, no svg file was ever produced for it.",
567
+ resolution: "Request one of the formats the asset actually has, or regenerate the asset in a way that produces the format you need.",
568
+ },
569
+ validation_failed: {
570
+ type: "invalid_request_error",
571
+ status: [400, 422],
572
+ title: "The request body failed validation",
573
+ description: "The request body does not match the schema this operation expects - a field is missing, of the wrong type, or otherwise invalid.",
574
+ resolution: "Check the errors array on the envelope, if present, and fix each named field against the OpenAPI document for this operation.",
575
+ },
576
+ version_not_found: {
577
+ type: "not_found_error",
578
+ status: [404],
579
+ title: "No such version",
580
+ description: "The version named in a restore request does not exist for this brand or asset.",
581
+ resolution: "List the resource's version history to find a version id that actually exists.",
582
+ },
583
+ version_pinning_not_supported: {
584
+ type: "invalid_request_error",
585
+ status: [422],
586
+ title: "Pinning a version is not supported here yet",
587
+ description: "This export always reflects the brand's current head version, and a version query parameter was supplied to pin an older one.",
588
+ resolution: "Omit the version parameter - the export always uses the brand's current version.",
589
+ },
590
+ webhook_endpoint_not_found: {
591
+ type: "not_found_error",
592
+ status: [404],
593
+ title: "No webhook endpoint with that id",
594
+ description: "The webhook endpoint id in the request does not match one registered on this workspace.",
595
+ resolution: "Check the endpoint id, or list the workspace's webhook endpoints to find the right one.",
596
+ },
597
+ workflow_start_failed: {
598
+ type: "api_error",
599
+ status: [503],
600
+ title: "Couldn't start the job",
601
+ description: "Starting the durable workflow behind this generation failed - any reserved credits were refunded.",
602
+ resolution: "Try again. If it keeps happening, report it with the request_id.",
603
+ },
604
+ workspace_deleted: {
605
+ type: "authentication_error",
606
+ status: [401],
607
+ title: "This workspace has been deleted",
608
+ description: "The session's workspace has been deleted and can no longer be used.",
609
+ resolution: "Sign in to (or create) a different workspace.",
610
+ },
611
+ workspace_not_found: {
612
+ type: "not_found_error",
613
+ status: [404],
614
+ title: "No workspace with that id",
615
+ description: "The workspace id in the request does not match a workspace this credential can access.",
616
+ resolution: "Check the workspace id, or use GET /v1/me to find the workspace your credential is scoped to.",
617
+ },
618
+ };
package/dist/events.d.ts CHANGED
@@ -1,16 +1,13 @@
1
1
  import { z } from "zod";
2
- export declare const webhookEventTypes: readonly ["brand.completed", "brand.updated", "asset.ready", "asset.regenerated", "job.failed", "credits.low", "credits.settled", "subscription.changed"];
2
+ export declare const webhookEventTypes: readonly ["brand.completed", "asset.ready", "asset.regenerated", "job.failed", "credits.low"];
3
3
  export declare const webhookEnvelopeSchema: z.ZodObject<{
4
4
  id: z.ZodString;
5
5
  type: z.ZodEnum<{
6
6
  "brand.completed": "brand.completed";
7
- "brand.updated": "brand.updated";
8
7
  "asset.ready": "asset.ready";
9
8
  "asset.regenerated": "asset.regenerated";
10
9
  "job.failed": "job.failed";
11
10
  "credits.low": "credits.low";
12
- "credits.settled": "credits.settled";
13
- "subscription.changed": "subscription.changed";
14
11
  }>;
15
12
  created_at: z.ZodString;
16
13
  data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
package/dist/events.js CHANGED
@@ -1,13 +1,10 @@
1
1
  import { z } from "zod";
2
2
  export const webhookEventTypes = [
3
3
  "brand.completed",
4
- "brand.updated",
5
4
  "asset.ready",
6
5
  "asset.regenerated",
7
6
  "job.failed",
8
7
  "credits.low",
9
- "credits.settled",
10
- "subscription.changed",
11
8
  ];
12
9
  export const webhookEnvelopeSchema = z.object({
13
10
  id: z.string(),
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export * from "./catalog.js";
6
6
  export * from "./consent.js";
7
7
  export * from "./creative-direction.js";
8
8
  export * from "./credits.js";
9
+ export * from "./error-catalog.js";
9
10
  export * from "./errors.js";
10
11
  export * from "./events.js";
11
12
  export * from "./ids.js";
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ export * from "./catalog.js";
6
6
  export * from "./consent.js";
7
7
  export * from "./creative-direction.js";
8
8
  export * from "./credits.js";
9
+ export * from "./error-catalog.js";
9
10
  export * from "./errors.js";
10
11
  export * from "./events.js";
11
12
  export * from "./ids.js";