@spicyapi/sdk 0.4.0 → 0.5.0

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.
@@ -13,6 +13,17 @@ info:
13
13
  The `/v1` operations tagged `OpenAI Compatible` are the one documented
14
14
  exception: they return OpenAI / Anthropic response and error objects so
15
15
  the official SDKs work by changing only `base_url`.
16
+
17
+ Error text language: `msg`, task `errorMessage` and the compatible
18
+ layers' `error.message` are English by default. Send `Accept-Language`
19
+ (`en`, `zh-Hant`, `ja`, `ko`, `de`, `fr`, `es`, `pt-BR`, `ru`; regional
20
+ variants such as `de-DE` or `zh-TW` match their language, `zh-CN` and `*`
21
+ do not) to choose another language for one request, or set the account's
22
+ API error language in the console; a recognized header takes precedence.
23
+ Webhooks follow the account setting. Error responses carry
24
+ `Content-Language`. Codes (`code`, `errorCode`, OpenAI `type` / `code`,
25
+ Gemini `code` / `status`) never change with the language, so branch on
26
+ codes, not on text.
16
27
  servers:
17
28
  - url: https://api.spicyapi.ai
18
29
  description: Production
@@ -22,7 +33,13 @@ tags:
22
33
  - name: Account
23
34
  - name: Media
24
35
  - name: OpenAI Compatible
25
- description: OpenAI / Anthropic protocol shells under `/v1`. They share authentication, limits, validation and billing with `/api/v1` but use the external protocol's own response and error shapes.
36
+ description: >-
37
+ OpenAI / Anthropic protocol shells under `/v1` and the Google Gemini shell under `/v1beta`.
38
+ They share API keys, limits, validation and billing with `/api/v1` but use the external
39
+ protocol's own request, response and error shapes. On these paths the API key may be sent as
40
+ `Authorization: Bearer <key>`, `x-api-key: <key>` (Anthropic SDKs) or
41
+ `x-goog-api-key: <key>` (Google GenAI SDKs); `/api/v1` accepts only `Authorization: Bearer`.
42
+ Keys in the URL query string are never accepted.
26
43
  security:
27
44
  - bearerAuth: []
28
45
  paths:
@@ -81,6 +98,7 @@ paths:
81
98
  private/loopback destinations before acceptance.
82
99
  parameters:
83
100
  - $ref: '#/components/parameters/IdempotencyKey'
101
+ - $ref: '#/components/parameters/SpicyRetention'
84
102
  requestBody:
85
103
  required: true
86
104
  content:
@@ -202,7 +220,7 @@ paths:
202
220
  as a Server-Sent Events stream. Each event is a `data:` line carrying one
203
221
  JSON chunk; the stream ends with `data: [DONE]`.
204
222
 
205
- The hold is settled when the stream completes. If the upstream call fails
223
+ The hold is settled when the stream completes. If generation fails
206
224
  before the first event, the response is a normal JSON error and the hold is
207
225
  released. If it fails mid-stream the connection is terminated with an
208
226
  `error` event and the hold is still released — a truncated answer is never
@@ -213,6 +231,7 @@ paths:
213
231
  returns `503`.
214
232
  parameters:
215
233
  - $ref: '#/components/parameters/IdempotencyKey'
234
+ - $ref: '#/components/parameters/SpicyRetention'
216
235
  requestBody:
217
236
  required: true
218
237
  content:
@@ -242,7 +261,7 @@ paths:
242
261
  summary: Create a new task from a failed or expired task
243
262
  description: |
244
263
  The source terminal task is never modified. Current model schema,
245
- pricing, permissions, balance, and routing are evaluated again. An
264
+ pricing, permissions, balance, and availability are evaluated again. An
246
265
  optional Idempotency-Key is scoped to the source task and retry action.
247
266
  The source task must have been created by the same API key; unknown,
248
267
  cross-account, and same-account cross-key task IDs all return 404.
@@ -269,6 +288,57 @@ paths:
269
288
  '429': { $ref: '#/components/responses/RateLimited' }
270
289
  '500': { $ref: '#/components/responses/ServerError' }
271
290
  '503': { $ref: '#/components/responses/Unavailable' }
291
+ /api/v1/jobs/purge:
292
+ post:
293
+ tags: [Tasks]
294
+ operationId: purgeTask
295
+ summary: Destroy the stored content of a finished task
296
+ description: |
297
+ Removes the task's generated media objects, its result payload, and the
298
+ stored request text including the prompt.
299
+
300
+ **Billing evidence is never touched.** The ledger, the charged amount,
301
+ the model identifier, the state, the timestamps and the request_id all
302
+ remain, so the task stays fully auditable in billing. What is destroyed
303
+ is the content, not the spend record; the response repeats this as
304
+ `billingRetained`.
305
+
306
+ Only a finished task can be destroyed; a task that is still queued or
307
+ running returns 400. Its outputs have not landed yet, and removing half
308
+ of them is worse than removing none. An accepted generation task cannot
309
+ be stopped, so the only thing to do is wait for it to reach a terminal
310
+ state and call this endpoint then.
311
+
312
+ The call is idempotent by `taskId`: destroying an already destroyed task
313
+ returns 200 with the original `purgedAt`, so a client may safely retry
314
+ after a timeout. No `Idempotency-Key` is needed.
315
+
316
+ Media objects are removed by a background sweep within about a minute,
317
+ so `mediaDeletionPending` can be true while `contentState` is already
318
+ `purged`. Deleting them inline would let one undeletable object block the
319
+ whole request.
320
+ parameters:
321
+ - $ref: '#/components/parameters/IdempotencyKey'
322
+ requestBody:
323
+ required: true
324
+ content:
325
+ application/json:
326
+ schema: { $ref: '#/components/schemas/TaskActionRequest' }
327
+ responses:
328
+ '200':
329
+ description: Content destroyed, or already destroyed by an earlier call.
330
+ headers:
331
+ Cache-Control:
332
+ schema: { type: string, const: no-store }
333
+ content:
334
+ application/json:
335
+ schema: { $ref: '#/components/schemas/TaskPurgeEnvelope' }
336
+ '400': { $ref: '#/components/responses/BadRequest' }
337
+ '401': { $ref: '#/components/responses/Unauthorized' }
338
+ '403': { $ref: '#/components/responses/Forbidden' }
339
+ '404': { $ref: '#/components/responses/NotFound' }
340
+ '429': { $ref: '#/components/responses/RateLimited' }
341
+ '500': { $ref: '#/components/responses/ServerError' }
272
342
  /api/v1/models:
273
343
  get:
274
344
  tags: [Models]
@@ -285,7 +355,7 @@ paths:
285
355
  - name: provider
286
356
  in: query
287
357
  schema: { type: string }
288
- description: Exact model creator/author identifier. This never identifies an execution channel.
358
+ description: Exact model creator/author identifier, such as the research lab that built the model.
289
359
  - name: task
290
360
  in: query
291
361
  schema: { type: string }
@@ -362,7 +432,7 @@ paths:
362
432
  Returns only visible tasks created by this API key and its account,
363
433
  newest first by createdAt and taskId. The list contains metadata only;
364
434
  use recordInfo for a selected task's result. No input, output, signed
365
- media URL, or execution-channel information is included.
435
+ media URL, or internal processing detail is included.
366
436
  Dates form a UTC half-open interval [from,to), up to 92 days.
367
437
  Default to is tomorrow in UTC; omitted from is seven days before to.
368
438
  Keep all filters, including explicit from/to dates, unchanged while
@@ -478,7 +548,7 @@ paths:
478
548
  The server generates the object key. Upload the exact declared number of
479
549
  bytes with PUT and copy every returned header. Supported media types are
480
550
  JPEG, PNG, WebP and GIF images (10 MiB), or MP4/WebM video and
481
- MP3/WAV audio (100 MiB, at most 600 seconds). Audio/video commit verifies
551
+ MP3/WAV audio (90 MiB, at most 600 seconds). Audio/video commit verifies
482
552
  format and measurable duration; it does not inspect adult content. After PUT,
483
553
  call the file commit endpoint and use its spicy:// URI in task input.
484
554
  requestBody:
@@ -572,8 +642,8 @@ paths:
572
642
  description: |
573
643
  Returns every model that can be called right now. `id` is the SpicyAPI
574
644
  model identifier accepted by every `/v1` and `/api/v1` operation;
575
- `owned_by` is the model publisher (for example a research lab), never
576
- an execution supplier. Pricing is not included; use `/api/v1/models`.
645
+ `owned_by` is the model publisher (for example a research lab).
646
+ Pricing is not included; use `/api/v1/models`.
577
647
  responses:
578
648
  '200':
579
649
  description: OpenAI-style model list.
@@ -723,6 +793,102 @@ paths:
723
793
  '500': { $ref: '#/components/responses/AnthropicError' }
724
794
  '503': { $ref: '#/components/responses/AnthropicError' }
725
795
 
796
+ /v1beta/models/{model}:generateContent:
797
+ post:
798
+ tags: [OpenAI Compatible]
799
+ operationId: geminiGenerateContent
800
+ summary: Google Gemini generateContent on a SpicyAPI text model
801
+ description: |
802
+ Accepts a Google Gemini `generateContent` request (`contents` with
803
+ text / inlineData / functionCall / functionResponse parts,
804
+ `systemInstruction`, `tools.functionDeclarations`, `toolConfig`,
805
+ `generationConfig` such as `temperature`, `topP`, `maxOutputTokens`,
806
+ `stopSequences`, `responseMimeType`, `responseSchema`,
807
+ `thinkingConfig`). `{model}` is a SpicyAPI text model identifier from
808
+ `/v1/models` and may contain a slash (for example
809
+ `google/gemini-3-flash-preview`). Validation, pricing and availability are
810
+ identical to `/v1/chat/completions`. The response is one
811
+ `GenerateContentResponse`. Errors use the Google
812
+ `{error:{code,message,status}}` shape.
813
+ parameters:
814
+ - name: model
815
+ in: path
816
+ required: true
817
+ schema: { type: string }
818
+ - $ref: '#/components/parameters/IdempotencyKey'
819
+ requestBody:
820
+ required: true
821
+ content:
822
+ application/json:
823
+ schema:
824
+ $ref: '#/components/schemas/GeminiGenerateContentRequest'
825
+ responses:
826
+ '200':
827
+ description: One `GenerateContentResponse`.
828
+ content:
829
+ application/json:
830
+ schema:
831
+ $ref: '#/components/schemas/GeminiGenerateContentResponse'
832
+ '400': { $ref: '#/components/responses/GeminiError' }
833
+ '401': { $ref: '#/components/responses/GeminiError' }
834
+ '402': { $ref: '#/components/responses/GeminiError' }
835
+ '403': { $ref: '#/components/responses/GeminiError' }
836
+ '404': { $ref: '#/components/responses/GeminiError' }
837
+ '409': { $ref: '#/components/responses/GeminiError' }
838
+ '413': { $ref: '#/components/responses/GeminiError' }
839
+ '429': { $ref: '#/components/responses/GeminiError' }
840
+ '500': { $ref: '#/components/responses/GeminiError' }
841
+ '503': { $ref: '#/components/responses/GeminiError' }
842
+
843
+ /v1beta/models/{model}:streamGenerateContent:
844
+ post:
845
+ tags: [OpenAI Compatible]
846
+ operationId: geminiStreamGenerateContent
847
+ summary: Google Gemini streamGenerateContent on a SpicyAPI text model
848
+ description: |
849
+ Same request as `generateContent`. With `?alt=sse` (what the Google
850
+ GenAI SDKs send) the response is a server-sent event stream where each
851
+ `data:` line is one `GenerateContentResponse`; the final one carries
852
+ `finishReason` and `usageMetadata`. There is no `[DONE]` sentinel.
853
+ Without `alt=sse` the response is a JSON array of
854
+ `GenerateContentResponse` objects written progressively.
855
+ parameters:
856
+ - name: model
857
+ in: path
858
+ required: true
859
+ schema: { type: string }
860
+ - name: alt
861
+ in: query
862
+ required: false
863
+ schema: { type: string, enum: [sse] }
864
+ - $ref: '#/components/parameters/IdempotencyKey'
865
+ requestBody:
866
+ required: true
867
+ content:
868
+ application/json:
869
+ schema:
870
+ $ref: '#/components/schemas/GeminiGenerateContentRequest'
871
+ responses:
872
+ '200':
873
+ description: An SSE stream (`alt=sse`) or a JSON array of `GenerateContentResponse`.
874
+ content:
875
+ text/event-stream:
876
+ schema: { type: string }
877
+ application/json:
878
+ schema:
879
+ type: array
880
+ items: { $ref: '#/components/schemas/GeminiGenerateContentResponse' }
881
+ '400': { $ref: '#/components/responses/GeminiError' }
882
+ '401': { $ref: '#/components/responses/GeminiError' }
883
+ '402': { $ref: '#/components/responses/GeminiError' }
884
+ '403': { $ref: '#/components/responses/GeminiError' }
885
+ '404': { $ref: '#/components/responses/GeminiError' }
886
+ '409': { $ref: '#/components/responses/GeminiError' }
887
+ '413': { $ref: '#/components/responses/GeminiError' }
888
+ '429': { $ref: '#/components/responses/GeminiError' }
889
+ '500': { $ref: '#/components/responses/GeminiError' }
890
+ '503': { $ref: '#/components/responses/GeminiError' }
891
+
726
892
  /v1/videos:
727
893
  post:
728
894
  tags: [OpenAI Compatible]
@@ -839,6 +1005,28 @@ components:
839
1005
  required: false
840
1006
  description: Stable key for one logical task submission; retained for 24 hours per account and bound to both the submitting API key and normalized request fingerprint. A sibling key receives 409 without the original task ID.
841
1007
  schema: { type: string, minLength: 1, maxLength: 128 }
1008
+ SpicyRetention:
1009
+ name: X-Spicy-Retention
1010
+ in: header
1011
+ required: false
1012
+ description: >-
1013
+ Retention for this one task, in whole seconds. It applies to both the
1014
+ generated outputs and the stored request text. The effective value is
1015
+ always `min(header, account setting, platform maximum)`: a request can
1016
+ only shorten retention, never extend it.
1017
+
1018
+ `0` is valid and means the outputs are removed as soon as the task
1019
+ reaches a terminal state. Values that cannot be applied never fail the
1020
+ request: a negative number is clamped to `0`, a value above the ceiling
1021
+ is clamped to the ceiling, and a value that is not a decimal integer is
1022
+ ignored so the account setting applies. The effective result is always
1023
+ reported back in `retention` on the task record.
1024
+
1025
+ Accepted by `createTask` and `stream`. `retry` inherits the source
1026
+ task's effective value and ignores this header, so one task family never
1027
+ ends up with two different expiry times. `quote` does not accept it
1028
+ because it does not create a task.
1029
+ schema: { type: string, pattern: '^-?[0-9]+$' }
842
1030
  headers:
843
1031
  RateLimitLimit:
844
1032
  description: Capacity of the active account-level rate-limit window.
@@ -893,6 +1081,9 @@ components:
893
1081
  AnthropicError:
894
1082
  description: Error in the Anthropic `{type:"error",error:{type,message}}` shape.
895
1083
  content: { application/json: { schema: { $ref: '#/components/schemas/AnthropicErrorBody' } } }
1084
+ GeminiError:
1085
+ description: Error in the Google `{error:{code,message,status}}` shape. `status` is the google.rpc code name (for example `INVALID_ARGUMENT`, `UNAUTHENTICATED`, `RESOURCE_EXHAUSTED`).
1086
+ content: { application/json: { schema: { $ref: '#/components/schemas/GeminiErrorBody' } } }
896
1087
  schemas:
897
1088
  FundingGrantItem:
898
1089
  type: object
@@ -952,7 +1143,9 @@ components:
952
1143
  code:
953
1144
  type: integer
954
1145
  enum: [400, 401, 40201, 40202, 403, 40301, 40302, 40303, 404, 409, 40901, 413, 429, 500, 50301]
955
- msg: { type: string }
1146
+ msg:
1147
+ type: string
1148
+ description: Human-readable explanation, English unless `Accept-Language` or the account's API error language selects another supported language. Never parse it; branch on `code`.
956
1149
  CreateTaskRequest:
957
1150
  type: object
958
1151
  required: [model, input]
@@ -1047,6 +1240,46 @@ components:
1047
1240
  code: { type: integer, const: 200 }
1048
1241
  msg: { type: string, const: success }
1049
1242
  data: { $ref: '#/components/schemas/RetryTaskResponse' }
1243
+ TaskPurgeResponse:
1244
+ type: object
1245
+ required: [taskId, contentState, billingRetained, mediaDeletionPending]
1246
+ properties:
1247
+ taskId: { type: string }
1248
+ contentState:
1249
+ type: string
1250
+ enum: [present, expired, purged]
1251
+ description: >-
1252
+ `purged` after a successful destroy, and on any idempotent repeat.
1253
+ Still `present` means this call removed nothing and may be retried
1254
+ later; the reason is deliberately not disclosed.
1255
+ purgedAt:
1256
+ type: string
1257
+ format: date-time
1258
+ description: Time of the **first** destroy, not of this call.
1259
+ contentRemovedBy:
1260
+ type: string
1261
+ enum: [user, system]
1262
+ description: Omitted while `contentState` is `present`.
1263
+ billingRetained:
1264
+ type: boolean
1265
+ const: true
1266
+ description: >-
1267
+ Always true. Destroying content never changes the ledger, the
1268
+ charged amount, or any other billing fact. It is stated explicitly
1269
+ because it is the one thing a caller is likely to get wrong about
1270
+ an endpoint named "purge".
1271
+ mediaDeletionPending:
1272
+ type: boolean
1273
+ description: True while the background sweep has not finished removing the stored media objects.
1274
+ TaskPurgeEnvelope:
1275
+ allOf:
1276
+ - $ref: '#/components/schemas/EnvelopeBase'
1277
+ - type: object
1278
+ required: [data]
1279
+ properties:
1280
+ code: { type: integer, const: 200 }
1281
+ msg: { type: string, const: success }
1282
+ data: { $ref: '#/components/schemas/TaskPurgeResponse' }
1050
1283
  CreateTaskEnvelope:
1051
1284
  allOf:
1052
1285
  - $ref: '#/components/schemas/EnvelopeBase'
@@ -1096,8 +1329,23 @@ components:
1096
1329
  type: object
1097
1330
  additionalProperties: true
1098
1331
  output: { $ref: '#/components/schemas/TaskOutput' }
1099
- errorCode: { type: string, description: Stable SpicyAPI failure identifier; never a raw execution-channel code. }
1100
- errorMessage: { type: string, description: Safe normalized explanation without internal service names, hosts, task IDs, or raw errors. }
1332
+ errorCode:
1333
+ type: string
1334
+ description: >-
1335
+ Stable SpicyAPI failure identifier from a closed set; never an internal diagnostic code.
1336
+ The set is closed: any other value a client sees should be handled as
1337
+ `upstream_failed`.
1338
+ enum:
1339
+ - invalid_request
1340
+ - unsupported_combination
1341
+ - content_rejected
1342
+ - rate_limited
1343
+ - upstream_unavailable
1344
+ - generation_failed
1345
+ - timeout
1346
+ - invalid_asset
1347
+ - upstream_failed
1348
+ errorMessage: { type: string, description: 'Safe normalized explanation without internal service names, hosts, task IDs, or raw errors. Follows the same language selection as `msg`; `errorCode` never changes.' }
1101
1349
  cost: { $ref: '#/components/schemas/USDString' }
1102
1350
  settled:
1103
1351
  type: boolean
@@ -1105,6 +1353,52 @@ components:
1105
1353
  createdAt: { type: string, format: date-time }
1106
1354
  deadlineAt: { type: string, format: date-time, description: Server execution deadline. Present in current responses; historical stored webhook events may omit it. Not the result retention or URL expiry time. }
1107
1355
  completedAt: { type: string, format: date-time }
1356
+ contentState:
1357
+ type: string
1358
+ enum: [present, expired, purged]
1359
+ description: >-
1360
+ Whether the task content is still stored, and why it is not.
1361
+ `expired` means the retention policy removed it; `purged` means the
1362
+ account owner destroyed it with `purgeTask`. The two are deliberately
1363
+ distinct: telling a customer their own deletion was an expiry reads
1364
+ as the platform losing their data.
1365
+ contentRemovedBy:
1366
+ type: string
1367
+ enum: [user, system]
1368
+ description: Present only once content has been removed. Omitted while `contentState` is `present`.
1369
+ purgedAt:
1370
+ type: string
1371
+ format: date-time
1372
+ description: Present only for a task destroyed with `purgeTask`. Expiry does not set it.
1373
+ retention: { $ref: '#/components/schemas/TaskRetention' }
1374
+ TaskRetention:
1375
+ type: object
1376
+ description: >-
1377
+ When this task's content is scheduled to be removed, and which layer
1378
+ decided it. Omitted for tasks created before per-task retention existed;
1379
+ those follow the platform maximum.
1380
+ required: [outputsExpireAt, promptsExpireAt, source]
1381
+ properties:
1382
+ outputsExpireAt:
1383
+ type: string
1384
+ format: date-time
1385
+ description: >-
1386
+ When the generated media objects and the result payload are removed.
1387
+ Before the task finishes this is measured from acceptance; when the
1388
+ task reaches a terminal state it is re-based on the completion time
1389
+ using the same window, so it only ever moves later, never earlier.
1390
+ promptsExpireAt:
1391
+ type: string
1392
+ format: date-time
1393
+ description: When the stored request text is erased. The task row, its state, amounts and request_id remain.
1394
+ source:
1395
+ type: string
1396
+ enum: [header, account, platform]
1397
+ description: >-
1398
+ Which layer actually constrained the value: the per-request
1399
+ `X-Spicy-Retention` header, the account setting, or the platform
1400
+ maximum. A request that sends the header and still sees `account`
1401
+ has an account setting that is already shorter than it asked for.
1108
1402
  TaskRecordEnvelope:
1109
1403
  allOf:
1110
1404
  - $ref: '#/components/schemas/EnvelopeBase'
@@ -1251,17 +1545,17 @@ components:
1251
1545
  displayName: { type: string }
1252
1546
  provider:
1253
1547
  type: string
1254
- description: Model creator/author identifier. It never identifies an execution channel.
1548
+ description: Model creator/author identifier, such as the research lab that built the model.
1255
1549
  modality: { type: string, enum: [image, video, audio, text] }
1256
1550
  tasks: { type: array, items: { type: string } }
1257
1551
  async: { type: boolean }
1258
1552
  mature:
1259
1553
  type: boolean
1260
- description: Informational model-creator capability metadata only. It does not participate in routing, authorization, or request rejection.
1554
+ description: Informational model-creator capability metadata only. It does not participate in authorization, availability decisions, or request rejection.
1261
1555
  policyTier:
1262
1556
  type: string
1263
1557
  enum: [unrestricted, borderline, unspecified]
1264
- description: Informational model-creator policy metadata only. It does not participate in routing, authorization, or request rejection.
1558
+ description: Informational model-creator policy metadata only. It does not participate in authorization, availability decisions, or request rejection.
1265
1559
  taskTimeoutSeconds:
1266
1560
  type: integer
1267
1561
  minimum: 1
@@ -1351,7 +1645,7 @@ components:
1351
1645
  additionalProperties: false
1352
1646
  properties:
1353
1647
  contentType: { type: string, enum: [image/jpeg, image/png, image/webp, image/gif, video/mp4, video/webm, audio/mpeg, audio/wav] }
1354
- bytes: { type: integer, minimum: 1, maximum: 104857600, description: Images are limited to 10 MiB; supported audio/video to 100 MiB. }
1648
+ bytes: { type: integer, minimum: 1, maximum: 94371840, description: Images are limited to 10 MiB; supported audio/video to 90 MiB. }
1355
1649
  UploadURLResponse:
1356
1650
  type: object
1357
1651
  required: [fileId, key, uploadUrl, method, headers, expiresAt, maxBytes]
@@ -1605,6 +1899,71 @@ components:
1605
1899
  input_tokens: { type: integer }
1606
1900
  output_tokens: { type: integer }
1607
1901
  total_tokens: { type: integer }
1902
+ GeminiGenerateContentRequest:
1903
+ type: object
1904
+ required: [contents]
1905
+ description: Google Gemini `generateContent` request. Which generation parameters a model accepts comes from that model's `inputSchema` in `/v1/models` and the catalog; unsupported parameters return 400.
1906
+ properties:
1907
+ contents:
1908
+ type: array
1909
+ items:
1910
+ type: object
1911
+ properties:
1912
+ role: { type: string, enum: [user, model] }
1913
+ parts:
1914
+ type: array
1915
+ items:
1916
+ type: object
1917
+ description: One of `text`, `inlineData {mimeType,data}`, `fileData {mimeType,fileUri}`, `functionCall {name,args}`, `functionResponse {name,response}`.
1918
+ systemInstruction: { type: object }
1919
+ tools: { type: array, items: { type: object } }
1920
+ toolConfig: { type: object }
1921
+ generationConfig:
1922
+ type: object
1923
+ properties:
1924
+ temperature: { type: number }
1925
+ topP: { type: number }
1926
+ maxOutputTokens: { type: integer }
1927
+ stopSequences: { type: array, items: { type: string } }
1928
+ responseMimeType: { type: string }
1929
+ responseSchema: { type: object }
1930
+ thinkingConfig: { type: object }
1931
+ GeminiGenerateContentResponse:
1932
+ type: object
1933
+ properties:
1934
+ candidates:
1935
+ type: array
1936
+ items:
1937
+ type: object
1938
+ properties:
1939
+ index: { type: integer }
1940
+ content:
1941
+ type: object
1942
+ properties:
1943
+ role: { type: string }
1944
+ parts: { type: array, items: { type: object } }
1945
+ finishReason: { type: string }
1946
+ usageMetadata:
1947
+ type: object
1948
+ properties:
1949
+ promptTokenCount: { type: integer }
1950
+ candidatesTokenCount: { type: integer }
1951
+ totalTokenCount: { type: integer }
1952
+ cachedContentTokenCount: { type: integer }
1953
+ thoughtsTokenCount: { type: integer }
1954
+ modelVersion: { type: string, description: The SpicyAPI model identifier. }
1955
+ responseId: { type: string }
1956
+ GeminiErrorBody:
1957
+ type: object
1958
+ required: [error]
1959
+ properties:
1960
+ error:
1961
+ type: object
1962
+ required: [code, message, status]
1963
+ properties:
1964
+ code: { type: integer }
1965
+ message: { type: string }
1966
+ status: { type: string }
1608
1967
  AnthropicMessageRequest:
1609
1968
  type: object
1610
1969
  required: [model, messages, max_tokens]
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/docs/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAiID,eAAO,MAAM,aAAa,EAAE,kBAAkB,EAG3C,CAAC;AA6CJ,wBAAgB,mBAAmB,CAAC,KAAK,SAAK,EAAE,KAAK,SAAK,GAAG,kBAAkB,EAAE,CAoChF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/docs/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA4HD,eAAO,MAAM,aAAa,EAAE,kBAAkB,EAG3C,CAAC;AA6CJ,wBAAgB,mBAAmB,CAAC,KAAK,SAAK,EAAE,KAAK,SAAK,GAAG,kBAAkB,EAAE,CAoChF"}
@@ -4,55 +4,55 @@ const definitions = [
4
4
  slug: "",
5
5
  title: "Quickstart",
6
6
  summary: "Create a task, follow its state, and retrieve generated media.",
7
- keywords: ["start", "guide", "quickstart", "入门", "开始"],
7
+ keywords: ["start", "guide", "quickstart", "introduction", "tutorial"],
8
8
  },
9
9
  {
10
10
  slug: "authentication",
11
11
  title: "Authentication",
12
12
  summary: "API keys, per-key controls, rotation, and incident response.",
13
- keywords: ["api key", "bearer", "security", "认证", "密钥"],
13
+ keywords: ["api key", "bearer", "security"],
14
14
  },
15
15
  {
16
16
  slug: "models",
17
17
  title: "Models and parameters",
18
18
  summary: "Live model IDs, account-specific pricing, input schemas, and examples.",
19
- keywords: ["catalog", "schema", "price", "model", "模型", "价格", "参数"],
19
+ keywords: ["catalog", "schema", "price", "model"],
20
20
  },
21
21
  {
22
22
  slug: "tasks",
23
23
  title: "Asynchronous tasks",
24
24
  summary: "Create tasks, inspect task records, states, costs, and outputs.",
25
- keywords: ["createTask", "recordInfo", "poll", "state", "任务", "轮询"],
25
+ keywords: ["createTask", "recordInfo", "poll", "polling", "state"],
26
26
  },
27
27
  {
28
28
  slug: "task-actions",
29
29
  title: "Task actions",
30
30
  summary: "Retry failed or expired tasks safely and understand unsupported actions.",
31
- keywords: ["retry", "cancel", "重试", "取消"],
31
+ keywords: ["retry", "cancel"],
32
32
  },
33
33
  {
34
34
  slug: "media",
35
35
  title: "Media transfer",
36
36
  summary: "Public HTTPS media inputs, optional local uploads, and direct signed result URLs.",
37
- keywords: ["upload", "download", "file", "image", "上传", "下载", "文件"],
37
+ keywords: ["upload", "download", "file", "image"],
38
38
  },
39
39
  {
40
40
  slug: "billing",
41
41
  title: "Billing",
42
42
  summary: "Prices, holds, settlement, failures, refunds, and balance fields.",
43
- keywords: ["cost", "credit", "balance", "payment", "billing", "余额", "付费", "计费"],
43
+ keywords: ["cost", "credit", "balance", "payment", "billing"],
44
44
  },
45
45
  {
46
46
  slug: "idempotency",
47
47
  title: "Idempotency",
48
48
  summary: "Retry one logical generation without duplicate work or duplicate holds.",
49
- keywords: ["idempotency-key", "retry", "duplicate", "幂等", "重复"],
49
+ keywords: ["idempotency-key", "retry", "duplicate"],
50
50
  },
51
51
  {
52
52
  slug: "webhooks",
53
53
  title: "Webhooks",
54
54
  summary: "Payload versions, raw-body signatures, delivery IDs, and retries.",
55
- keywords: ["callback", "hmac", "signature", "webhook", "回调", "签名"],
55
+ keywords: ["callback", "hmac", "signature", "webhook"],
56
56
  },
57
57
  {
58
58
  slug: "errors",
@@ -67,34 +67,31 @@ const definitions = [
67
67
  "service unavailable",
68
68
  "no route",
69
69
  "customer price",
70
- "错误",
71
- "不可用",
72
- "重试",
73
70
  ],
74
71
  },
75
72
  {
76
73
  slug: "limits",
77
74
  title: "Rate limits",
78
75
  summary: "Shared account rate limits and recommended backoff behavior.",
79
- keywords: ["rate", "quota", "retry-after", "限流", "配额"],
76
+ keywords: ["rate", "quota", "retry-after", "throttling"],
80
77
  },
81
78
  {
82
79
  slug: "retention",
83
80
  title: "Data retention",
84
- summary: "Task input, output, media, and operational-record retention boundaries.",
85
- keywords: ["privacy", "delete", "storage", "retention", "隐私", "删除", "保留"],
81
+ summary: "Retention boundaries, per-request retention, and destroying one task's stored content.",
82
+ keywords: ["privacy", "delete", "storage", "retention", "purge", "destroy"],
86
83
  },
87
84
  {
88
85
  slug: "policy",
89
86
  title: "Content policy",
90
87
  summary: "Model capabilities, no per-request platform content review, and caller responsibility.",
91
- keywords: ["model capabilities", "content review", "content", "policy", "透明传递", "内容"],
88
+ keywords: ["model capabilities", "content review", "content", "policy"],
92
89
  },
93
90
  {
94
91
  slug: "agents",
95
92
  title: "Agent integrations",
96
93
  summary: "Safe patterns for AI agents using the public API contract.",
97
- keywords: ["agent", "mcp", "tool", "智能体", "代理"],
94
+ keywords: ["agent", "mcp", "tool"],
98
95
  },
99
96
  {
100
97
  slug: "quotes-and-compatibility",
@@ -109,16 +106,13 @@ const definitions = [
109
106
  "openai",
110
107
  "responses",
111
108
  "chat completions",
112
- "报价",
113
- "价格变化",
114
- "文本",
115
109
  ],
116
110
  },
117
111
  {
118
112
  slug: "api-reference",
119
113
  title: "API reference",
120
114
  summary: "The complete public endpoint and envelope reference.",
121
- keywords: ["openapi", "endpoint", "reference", "接口", "参考"],
115
+ keywords: ["openapi", "endpoint", "reference"],
122
116
  },
123
117
  ];
124
118
  export const DOCUMENTATION = definitions.map((entry) => ({