1// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
3package webhooks
4
5import (
6 "crypto/hmac"
7 "crypto/sha256"
8 "crypto/subtle"
9 "encoding/base64"
10 "encoding/json"
11 "errors"
12 "fmt"
13 "net/http"
14 "strconv"
15 "strings"
16 "time"
17
18 "github.com/openai/openai-go/internal/apijson"
19 "github.com/openai/openai-go/internal/requestconfig"
20 "github.com/openai/openai-go/option"
21 "github.com/openai/openai-go/packages/respjson"
22 "github.com/openai/openai-go/shared/constant"
23)
24
25// WebhookService contains methods and other services that help with interacting
26// with the openai API.
27//
28// Note, unlike clients, this service does not read variables from the environment
29// automatically. You should not instantiate this service directly, and instead use
30// the [NewWebhookService] method instead.
31type WebhookService struct {
32 Options []option.RequestOption
33}
34
35// NewWebhookService generates a new service that applies the given options to each
36// request. These options are applied after the parent client's options (if there
37// is one), and before any request-specific options.
38func NewWebhookService(opts ...option.RequestOption) (r WebhookService) {
39 r = WebhookService{}
40 r.Options = opts
41 return
42}
43
44// Validates that the given payload was sent by OpenAI and parses the payload.
45func (r *WebhookService) Unwrap(body []byte, headers http.Header, opts ...option.RequestOption) (*UnwrapWebhookEventUnion, error) {
46 // Always perform signature verification
47 err := r.VerifySignature(body, headers, opts...)
48 if err != nil {
49 return nil, err
50 }
51
52 res := &UnwrapWebhookEventUnion{}
53 err = res.UnmarshalJSON(body)
54 if err != nil {
55 return res, err
56 }
57 return res, nil
58}
59
60// UnwrapWithTolerance validates that the given payload was sent by OpenAI using custom tolerance, then parses the payload.
61// tolerance specifies the maximum age of the webhook.
62func (r *WebhookService) UnwrapWithTolerance(body []byte, headers http.Header, tolerance time.Duration, opts ...option.RequestOption) (*UnwrapWebhookEventUnion, error) {
63 err := r.VerifySignatureWithTolerance(body, headers, tolerance, opts...)
64 if err != nil {
65 return nil, err
66 }
67
68 res := &UnwrapWebhookEventUnion{}
69 err = res.UnmarshalJSON(body)
70 if err != nil {
71 return res, err
72 }
73 return res, nil
74}
75
76// UnwrapWithToleranceAndTime validates that the given payload was sent by OpenAI using custom tolerance and time, then parses the payload.
77// tolerance specifies the maximum age of the webhook.
78// now allows specifying the current time for testing purposes.
79func (r *WebhookService) UnwrapWithToleranceAndTime(body []byte, headers http.Header, tolerance time.Duration, now time.Time, opts ...option.RequestOption) (*UnwrapWebhookEventUnion, error) {
80 err := r.VerifySignatureWithToleranceAndTime(body, headers, tolerance, now, opts...)
81 if err != nil {
82 return nil, err
83 }
84
85 res := &UnwrapWebhookEventUnion{}
86 err = res.UnmarshalJSON(body)
87 if err != nil {
88 return res, err
89 }
90 return res, nil
91}
92
93// VerifySignature validates whether or not the webhook payload was sent by OpenAI.
94// An error will be raised if the webhook signature is invalid.
95// tolerance specifies the maximum age of the webhook (default: 5 minutes).
96func (r *WebhookService) VerifySignature(body []byte, headers http.Header, opts ...option.RequestOption) error {
97 return r.VerifySignatureWithTolerance(body, headers, 5*time.Minute, opts...)
98}
99
100// VerifySignatureWithTolerance validates whether or not the webhook payload was sent by OpenAI.
101// An error will be raised if the webhook signature is invalid.
102// tolerance specifies the maximum age of the webhook.
103func (r *WebhookService) VerifySignatureWithTolerance(body []byte, headers http.Header, tolerance time.Duration, opts ...option.RequestOption) error {
104 return r.VerifySignatureWithToleranceAndTime(body, headers, tolerance, time.Now(), opts...)
105}
106
107// VerifySignatureWithToleranceAndTime validates whether or not the webhook payload was sent by OpenAI.
108// An error will be raised if the webhook signature is invalid.
109// tolerance specifies the maximum age of the webhook.
110// now allows specifying the current time for testing purposes.
111func (r *WebhookService) VerifySignatureWithToleranceAndTime(body []byte, headers http.Header, tolerance time.Duration, now time.Time, opts ...option.RequestOption) error {
112 cfg, err := requestconfig.PreRequestOptions(r.Options...)
113 if err != nil {
114 return err
115 }
116 webhookSecret := cfg.WebhookSecret
117
118 if webhookSecret == "" {
119 return errors.New("webhook secret must be provided either in the method call or configured on the client")
120 }
121
122 if headers == nil {
123 return errors.New("headers are required for webhook verification")
124 }
125
126 // Extract required headers
127 signatureHeader := headers.Get("webhook-signature")
128 if signatureHeader == "" {
129 return errors.New("missing required webhook-signature header")
130 }
131
132 timestampHeader := headers.Get("webhook-timestamp")
133 if timestampHeader == "" {
134 return errors.New("missing required webhook-timestamp header")
135 }
136
137 webhookID := headers.Get("webhook-id")
138 if webhookID == "" {
139 return errors.New("missing required webhook-id header")
140 }
141
142 // Validate timestamp to prevent replay attacks
143 timestampSeconds, err := strconv.ParseInt(timestampHeader, 10, 64)
144 if err != nil {
145 return errors.New("invalid webhook timestamp format")
146 }
147
148 nowUnix := now.Unix()
149 toleranceSeconds := int64(tolerance.Seconds())
150
151 if nowUnix-timestampSeconds > toleranceSeconds {
152 return errors.New("webhook timestamp is too old")
153 }
154
155 if timestampSeconds > nowUnix+toleranceSeconds {
156 return errors.New("webhook timestamp is too new")
157 }
158
159 // Extract signatures from v1,<base64> format
160 // The signature header can have multiple values, separated by spaces.
161 // Each value is in the format v1,<base64>. We should accept if any match.
162 var signatures []string
163 for _, part := range strings.Fields(signatureHeader) {
164 if strings.HasPrefix(part, "v1,") {
165 signatures = append(signatures, part[3:])
166 } else {
167 signatures = append(signatures, part)
168 }
169 }
170
171 // Decode the secret if it starts with whsec_
172 var decodedSecret []byte
173 if strings.HasPrefix(webhookSecret, "whsec_") {
174 decodedSecret, err = base64.StdEncoding.DecodeString(webhookSecret[6:])
175 if err != nil {
176 return fmt.Errorf("invalid webhook secret format: %v", err)
177 }
178 } else {
179 decodedSecret = []byte(webhookSecret)
180 }
181
182 // Create the signed payload: {webhook_id}.{timestamp}.{payload}
183 signedPayload := fmt.Sprintf("%s.%s.%s", webhookID, timestampHeader, string(body))
184
185 // Compute HMAC-SHA256 signature
186 h := hmac.New(sha256.New, decodedSecret)
187 h.Write([]byte(signedPayload))
188 expectedSignature := base64.StdEncoding.EncodeToString(h.Sum(nil))
189
190 // Accept if any signature matches using timing-safe comparison
191 for _, signature := range signatures {
192 if subtle.ConstantTimeCompare([]byte(expectedSignature), []byte(signature)) == 1 {
193 return nil
194 }
195 }
196
197 return errors.New("webhook signature verification failed")
198}
199
200// Sent when a batch API request has been cancelled.
201type BatchCancelledWebhookEvent struct {
202 // The unique ID of the event.
203 ID string `json:"id,required"`
204 // The Unix timestamp (in seconds) of when the batch API request was cancelled.
205 CreatedAt int64 `json:"created_at,required"`
206 // Event data payload.
207 Data BatchCancelledWebhookEventData `json:"data,required"`
208 // The type of the event. Always `batch.cancelled`.
209 Type constant.BatchCancelled `json:"type,required"`
210 // The object of the event. Always `event`.
211 //
212 // Any of "event".
213 Object BatchCancelledWebhookEventObject `json:"object"`
214 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
215 JSON struct {
216 ID respjson.Field
217 CreatedAt respjson.Field
218 Data respjson.Field
219 Type respjson.Field
220 Object respjson.Field
221 ExtraFields map[string]respjson.Field
222 raw string
223 } `json:"-"`
224}
225
226// Returns the unmodified JSON received from the API
227func (r BatchCancelledWebhookEvent) RawJSON() string { return r.JSON.raw }
228func (r *BatchCancelledWebhookEvent) UnmarshalJSON(data []byte) error {
229 return apijson.UnmarshalRoot(data, r)
230}
231
232// Event data payload.
233type BatchCancelledWebhookEventData struct {
234 // The unique ID of the batch API request.
235 ID string `json:"id,required"`
236 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
237 JSON struct {
238 ID respjson.Field
239 ExtraFields map[string]respjson.Field
240 raw string
241 } `json:"-"`
242}
243
244// Returns the unmodified JSON received from the API
245func (r BatchCancelledWebhookEventData) RawJSON() string { return r.JSON.raw }
246func (r *BatchCancelledWebhookEventData) UnmarshalJSON(data []byte) error {
247 return apijson.UnmarshalRoot(data, r)
248}
249
250// The object of the event. Always `event`.
251type BatchCancelledWebhookEventObject string
252
253const (
254 BatchCancelledWebhookEventObjectEvent BatchCancelledWebhookEventObject = "event"
255)
256
257// Sent when a batch API request has been completed.
258type BatchCompletedWebhookEvent struct {
259 // The unique ID of the event.
260 ID string `json:"id,required"`
261 // The Unix timestamp (in seconds) of when the batch API request was completed.
262 CreatedAt int64 `json:"created_at,required"`
263 // Event data payload.
264 Data BatchCompletedWebhookEventData `json:"data,required"`
265 // The type of the event. Always `batch.completed`.
266 Type constant.BatchCompleted `json:"type,required"`
267 // The object of the event. Always `event`.
268 //
269 // Any of "event".
270 Object BatchCompletedWebhookEventObject `json:"object"`
271 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
272 JSON struct {
273 ID respjson.Field
274 CreatedAt respjson.Field
275 Data respjson.Field
276 Type respjson.Field
277 Object respjson.Field
278 ExtraFields map[string]respjson.Field
279 raw string
280 } `json:"-"`
281}
282
283// Returns the unmodified JSON received from the API
284func (r BatchCompletedWebhookEvent) RawJSON() string { return r.JSON.raw }
285func (r *BatchCompletedWebhookEvent) UnmarshalJSON(data []byte) error {
286 return apijson.UnmarshalRoot(data, r)
287}
288
289// Event data payload.
290type BatchCompletedWebhookEventData struct {
291 // The unique ID of the batch API request.
292 ID string `json:"id,required"`
293 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
294 JSON struct {
295 ID respjson.Field
296 ExtraFields map[string]respjson.Field
297 raw string
298 } `json:"-"`
299}
300
301// Returns the unmodified JSON received from the API
302func (r BatchCompletedWebhookEventData) RawJSON() string { return r.JSON.raw }
303func (r *BatchCompletedWebhookEventData) UnmarshalJSON(data []byte) error {
304 return apijson.UnmarshalRoot(data, r)
305}
306
307// The object of the event. Always `event`.
308type BatchCompletedWebhookEventObject string
309
310const (
311 BatchCompletedWebhookEventObjectEvent BatchCompletedWebhookEventObject = "event"
312)
313
314// Sent when a batch API request has expired.
315type BatchExpiredWebhookEvent struct {
316 // The unique ID of the event.
317 ID string `json:"id,required"`
318 // The Unix timestamp (in seconds) of when the batch API request expired.
319 CreatedAt int64 `json:"created_at,required"`
320 // Event data payload.
321 Data BatchExpiredWebhookEventData `json:"data,required"`
322 // The type of the event. Always `batch.expired`.
323 Type constant.BatchExpired `json:"type,required"`
324 // The object of the event. Always `event`.
325 //
326 // Any of "event".
327 Object BatchExpiredWebhookEventObject `json:"object"`
328 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
329 JSON struct {
330 ID respjson.Field
331 CreatedAt respjson.Field
332 Data respjson.Field
333 Type respjson.Field
334 Object respjson.Field
335 ExtraFields map[string]respjson.Field
336 raw string
337 } `json:"-"`
338}
339
340// Returns the unmodified JSON received from the API
341func (r BatchExpiredWebhookEvent) RawJSON() string { return r.JSON.raw }
342func (r *BatchExpiredWebhookEvent) UnmarshalJSON(data []byte) error {
343 return apijson.UnmarshalRoot(data, r)
344}
345
346// Event data payload.
347type BatchExpiredWebhookEventData struct {
348 // The unique ID of the batch API request.
349 ID string `json:"id,required"`
350 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
351 JSON struct {
352 ID respjson.Field
353 ExtraFields map[string]respjson.Field
354 raw string
355 } `json:"-"`
356}
357
358// Returns the unmodified JSON received from the API
359func (r BatchExpiredWebhookEventData) RawJSON() string { return r.JSON.raw }
360func (r *BatchExpiredWebhookEventData) UnmarshalJSON(data []byte) error {
361 return apijson.UnmarshalRoot(data, r)
362}
363
364// The object of the event. Always `event`.
365type BatchExpiredWebhookEventObject string
366
367const (
368 BatchExpiredWebhookEventObjectEvent BatchExpiredWebhookEventObject = "event"
369)
370
371// Sent when a batch API request has failed.
372type BatchFailedWebhookEvent struct {
373 // The unique ID of the event.
374 ID string `json:"id,required"`
375 // The Unix timestamp (in seconds) of when the batch API request failed.
376 CreatedAt int64 `json:"created_at,required"`
377 // Event data payload.
378 Data BatchFailedWebhookEventData `json:"data,required"`
379 // The type of the event. Always `batch.failed`.
380 Type constant.BatchFailed `json:"type,required"`
381 // The object of the event. Always `event`.
382 //
383 // Any of "event".
384 Object BatchFailedWebhookEventObject `json:"object"`
385 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
386 JSON struct {
387 ID respjson.Field
388 CreatedAt respjson.Field
389 Data respjson.Field
390 Type respjson.Field
391 Object respjson.Field
392 ExtraFields map[string]respjson.Field
393 raw string
394 } `json:"-"`
395}
396
397// Returns the unmodified JSON received from the API
398func (r BatchFailedWebhookEvent) RawJSON() string { return r.JSON.raw }
399func (r *BatchFailedWebhookEvent) UnmarshalJSON(data []byte) error {
400 return apijson.UnmarshalRoot(data, r)
401}
402
403// Event data payload.
404type BatchFailedWebhookEventData struct {
405 // The unique ID of the batch API request.
406 ID string `json:"id,required"`
407 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
408 JSON struct {
409 ID respjson.Field
410 ExtraFields map[string]respjson.Field
411 raw string
412 } `json:"-"`
413}
414
415// Returns the unmodified JSON received from the API
416func (r BatchFailedWebhookEventData) RawJSON() string { return r.JSON.raw }
417func (r *BatchFailedWebhookEventData) UnmarshalJSON(data []byte) error {
418 return apijson.UnmarshalRoot(data, r)
419}
420
421// The object of the event. Always `event`.
422type BatchFailedWebhookEventObject string
423
424const (
425 BatchFailedWebhookEventObjectEvent BatchFailedWebhookEventObject = "event"
426)
427
428// Sent when an eval run has been canceled.
429type EvalRunCanceledWebhookEvent struct {
430 // The unique ID of the event.
431 ID string `json:"id,required"`
432 // The Unix timestamp (in seconds) of when the eval run was canceled.
433 CreatedAt int64 `json:"created_at,required"`
434 // Event data payload.
435 Data EvalRunCanceledWebhookEventData `json:"data,required"`
436 // The type of the event. Always `eval.run.canceled`.
437 Type constant.EvalRunCanceled `json:"type,required"`
438 // The object of the event. Always `event`.
439 //
440 // Any of "event".
441 Object EvalRunCanceledWebhookEventObject `json:"object"`
442 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
443 JSON struct {
444 ID respjson.Field
445 CreatedAt respjson.Field
446 Data respjson.Field
447 Type respjson.Field
448 Object respjson.Field
449 ExtraFields map[string]respjson.Field
450 raw string
451 } `json:"-"`
452}
453
454// Returns the unmodified JSON received from the API
455func (r EvalRunCanceledWebhookEvent) RawJSON() string { return r.JSON.raw }
456func (r *EvalRunCanceledWebhookEvent) UnmarshalJSON(data []byte) error {
457 return apijson.UnmarshalRoot(data, r)
458}
459
460// Event data payload.
461type EvalRunCanceledWebhookEventData struct {
462 // The unique ID of the eval run.
463 ID string `json:"id,required"`
464 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
465 JSON struct {
466 ID respjson.Field
467 ExtraFields map[string]respjson.Field
468 raw string
469 } `json:"-"`
470}
471
472// Returns the unmodified JSON received from the API
473func (r EvalRunCanceledWebhookEventData) RawJSON() string { return r.JSON.raw }
474func (r *EvalRunCanceledWebhookEventData) UnmarshalJSON(data []byte) error {
475 return apijson.UnmarshalRoot(data, r)
476}
477
478// The object of the event. Always `event`.
479type EvalRunCanceledWebhookEventObject string
480
481const (
482 EvalRunCanceledWebhookEventObjectEvent EvalRunCanceledWebhookEventObject = "event"
483)
484
485// Sent when an eval run has failed.
486type EvalRunFailedWebhookEvent struct {
487 // The unique ID of the event.
488 ID string `json:"id,required"`
489 // The Unix timestamp (in seconds) of when the eval run failed.
490 CreatedAt int64 `json:"created_at,required"`
491 // Event data payload.
492 Data EvalRunFailedWebhookEventData `json:"data,required"`
493 // The type of the event. Always `eval.run.failed`.
494 Type constant.EvalRunFailed `json:"type,required"`
495 // The object of the event. Always `event`.
496 //
497 // Any of "event".
498 Object EvalRunFailedWebhookEventObject `json:"object"`
499 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
500 JSON struct {
501 ID respjson.Field
502 CreatedAt respjson.Field
503 Data respjson.Field
504 Type respjson.Field
505 Object respjson.Field
506 ExtraFields map[string]respjson.Field
507 raw string
508 } `json:"-"`
509}
510
511// Returns the unmodified JSON received from the API
512func (r EvalRunFailedWebhookEvent) RawJSON() string { return r.JSON.raw }
513func (r *EvalRunFailedWebhookEvent) UnmarshalJSON(data []byte) error {
514 return apijson.UnmarshalRoot(data, r)
515}
516
517// Event data payload.
518type EvalRunFailedWebhookEventData struct {
519 // The unique ID of the eval run.
520 ID string `json:"id,required"`
521 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
522 JSON struct {
523 ID respjson.Field
524 ExtraFields map[string]respjson.Field
525 raw string
526 } `json:"-"`
527}
528
529// Returns the unmodified JSON received from the API
530func (r EvalRunFailedWebhookEventData) RawJSON() string { return r.JSON.raw }
531func (r *EvalRunFailedWebhookEventData) UnmarshalJSON(data []byte) error {
532 return apijson.UnmarshalRoot(data, r)
533}
534
535// The object of the event. Always `event`.
536type EvalRunFailedWebhookEventObject string
537
538const (
539 EvalRunFailedWebhookEventObjectEvent EvalRunFailedWebhookEventObject = "event"
540)
541
542// Sent when an eval run has succeeded.
543type EvalRunSucceededWebhookEvent struct {
544 // The unique ID of the event.
545 ID string `json:"id,required"`
546 // The Unix timestamp (in seconds) of when the eval run succeeded.
547 CreatedAt int64 `json:"created_at,required"`
548 // Event data payload.
549 Data EvalRunSucceededWebhookEventData `json:"data,required"`
550 // The type of the event. Always `eval.run.succeeded`.
551 Type constant.EvalRunSucceeded `json:"type,required"`
552 // The object of the event. Always `event`.
553 //
554 // Any of "event".
555 Object EvalRunSucceededWebhookEventObject `json:"object"`
556 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
557 JSON struct {
558 ID respjson.Field
559 CreatedAt respjson.Field
560 Data respjson.Field
561 Type respjson.Field
562 Object respjson.Field
563 ExtraFields map[string]respjson.Field
564 raw string
565 } `json:"-"`
566}
567
568// Returns the unmodified JSON received from the API
569func (r EvalRunSucceededWebhookEvent) RawJSON() string { return r.JSON.raw }
570func (r *EvalRunSucceededWebhookEvent) UnmarshalJSON(data []byte) error {
571 return apijson.UnmarshalRoot(data, r)
572}
573
574// Event data payload.
575type EvalRunSucceededWebhookEventData struct {
576 // The unique ID of the eval run.
577 ID string `json:"id,required"`
578 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
579 JSON struct {
580 ID respjson.Field
581 ExtraFields map[string]respjson.Field
582 raw string
583 } `json:"-"`
584}
585
586// Returns the unmodified JSON received from the API
587func (r EvalRunSucceededWebhookEventData) RawJSON() string { return r.JSON.raw }
588func (r *EvalRunSucceededWebhookEventData) UnmarshalJSON(data []byte) error {
589 return apijson.UnmarshalRoot(data, r)
590}
591
592// The object of the event. Always `event`.
593type EvalRunSucceededWebhookEventObject string
594
595const (
596 EvalRunSucceededWebhookEventObjectEvent EvalRunSucceededWebhookEventObject = "event"
597)
598
599// Sent when a fine-tuning job has been cancelled.
600type FineTuningJobCancelledWebhookEvent struct {
601 // The unique ID of the event.
602 ID string `json:"id,required"`
603 // The Unix timestamp (in seconds) of when the fine-tuning job was cancelled.
604 CreatedAt int64 `json:"created_at,required"`
605 // Event data payload.
606 Data FineTuningJobCancelledWebhookEventData `json:"data,required"`
607 // The type of the event. Always `fine_tuning.job.cancelled`.
608 Type constant.FineTuningJobCancelled `json:"type,required"`
609 // The object of the event. Always `event`.
610 //
611 // Any of "event".
612 Object FineTuningJobCancelledWebhookEventObject `json:"object"`
613 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
614 JSON struct {
615 ID respjson.Field
616 CreatedAt respjson.Field
617 Data respjson.Field
618 Type respjson.Field
619 Object respjson.Field
620 ExtraFields map[string]respjson.Field
621 raw string
622 } `json:"-"`
623}
624
625// Returns the unmodified JSON received from the API
626func (r FineTuningJobCancelledWebhookEvent) RawJSON() string { return r.JSON.raw }
627func (r *FineTuningJobCancelledWebhookEvent) UnmarshalJSON(data []byte) error {
628 return apijson.UnmarshalRoot(data, r)
629}
630
631// Event data payload.
632type FineTuningJobCancelledWebhookEventData struct {
633 // The unique ID of the fine-tuning job.
634 ID string `json:"id,required"`
635 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
636 JSON struct {
637 ID respjson.Field
638 ExtraFields map[string]respjson.Field
639 raw string
640 } `json:"-"`
641}
642
643// Returns the unmodified JSON received from the API
644func (r FineTuningJobCancelledWebhookEventData) RawJSON() string { return r.JSON.raw }
645func (r *FineTuningJobCancelledWebhookEventData) UnmarshalJSON(data []byte) error {
646 return apijson.UnmarshalRoot(data, r)
647}
648
649// The object of the event. Always `event`.
650type FineTuningJobCancelledWebhookEventObject string
651
652const (
653 FineTuningJobCancelledWebhookEventObjectEvent FineTuningJobCancelledWebhookEventObject = "event"
654)
655
656// Sent when a fine-tuning job has failed.
657type FineTuningJobFailedWebhookEvent struct {
658 // The unique ID of the event.
659 ID string `json:"id,required"`
660 // The Unix timestamp (in seconds) of when the fine-tuning job failed.
661 CreatedAt int64 `json:"created_at,required"`
662 // Event data payload.
663 Data FineTuningJobFailedWebhookEventData `json:"data,required"`
664 // The type of the event. Always `fine_tuning.job.failed`.
665 Type constant.FineTuningJobFailed `json:"type,required"`
666 // The object of the event. Always `event`.
667 //
668 // Any of "event".
669 Object FineTuningJobFailedWebhookEventObject `json:"object"`
670 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
671 JSON struct {
672 ID respjson.Field
673 CreatedAt respjson.Field
674 Data respjson.Field
675 Type respjson.Field
676 Object respjson.Field
677 ExtraFields map[string]respjson.Field
678 raw string
679 } `json:"-"`
680}
681
682// Returns the unmodified JSON received from the API
683func (r FineTuningJobFailedWebhookEvent) RawJSON() string { return r.JSON.raw }
684func (r *FineTuningJobFailedWebhookEvent) UnmarshalJSON(data []byte) error {
685 return apijson.UnmarshalRoot(data, r)
686}
687
688// Event data payload.
689type FineTuningJobFailedWebhookEventData struct {
690 // The unique ID of the fine-tuning job.
691 ID string `json:"id,required"`
692 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
693 JSON struct {
694 ID respjson.Field
695 ExtraFields map[string]respjson.Field
696 raw string
697 } `json:"-"`
698}
699
700// Returns the unmodified JSON received from the API
701func (r FineTuningJobFailedWebhookEventData) RawJSON() string { return r.JSON.raw }
702func (r *FineTuningJobFailedWebhookEventData) UnmarshalJSON(data []byte) error {
703 return apijson.UnmarshalRoot(data, r)
704}
705
706// The object of the event. Always `event`.
707type FineTuningJobFailedWebhookEventObject string
708
709const (
710 FineTuningJobFailedWebhookEventObjectEvent FineTuningJobFailedWebhookEventObject = "event"
711)
712
713// Sent when a fine-tuning job has succeeded.
714type FineTuningJobSucceededWebhookEvent struct {
715 // The unique ID of the event.
716 ID string `json:"id,required"`
717 // The Unix timestamp (in seconds) of when the fine-tuning job succeeded.
718 CreatedAt int64 `json:"created_at,required"`
719 // Event data payload.
720 Data FineTuningJobSucceededWebhookEventData `json:"data,required"`
721 // The type of the event. Always `fine_tuning.job.succeeded`.
722 Type constant.FineTuningJobSucceeded `json:"type,required"`
723 // The object of the event. Always `event`.
724 //
725 // Any of "event".
726 Object FineTuningJobSucceededWebhookEventObject `json:"object"`
727 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
728 JSON struct {
729 ID respjson.Field
730 CreatedAt respjson.Field
731 Data respjson.Field
732 Type respjson.Field
733 Object respjson.Field
734 ExtraFields map[string]respjson.Field
735 raw string
736 } `json:"-"`
737}
738
739// Returns the unmodified JSON received from the API
740func (r FineTuningJobSucceededWebhookEvent) RawJSON() string { return r.JSON.raw }
741func (r *FineTuningJobSucceededWebhookEvent) UnmarshalJSON(data []byte) error {
742 return apijson.UnmarshalRoot(data, r)
743}
744
745// Event data payload.
746type FineTuningJobSucceededWebhookEventData struct {
747 // The unique ID of the fine-tuning job.
748 ID string `json:"id,required"`
749 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
750 JSON struct {
751 ID respjson.Field
752 ExtraFields map[string]respjson.Field
753 raw string
754 } `json:"-"`
755}
756
757// Returns the unmodified JSON received from the API
758func (r FineTuningJobSucceededWebhookEventData) RawJSON() string { return r.JSON.raw }
759func (r *FineTuningJobSucceededWebhookEventData) UnmarshalJSON(data []byte) error {
760 return apijson.UnmarshalRoot(data, r)
761}
762
763// The object of the event. Always `event`.
764type FineTuningJobSucceededWebhookEventObject string
765
766const (
767 FineTuningJobSucceededWebhookEventObjectEvent FineTuningJobSucceededWebhookEventObject = "event"
768)
769
770// Sent when a background response has been cancelled.
771type ResponseCancelledWebhookEvent struct {
772 // The unique ID of the event.
773 ID string `json:"id,required"`
774 // The Unix timestamp (in seconds) of when the model response was cancelled.
775 CreatedAt int64 `json:"created_at,required"`
776 // Event data payload.
777 Data ResponseCancelledWebhookEventData `json:"data,required"`
778 // The type of the event. Always `response.cancelled`.
779 Type constant.ResponseCancelled `json:"type,required"`
780 // The object of the event. Always `event`.
781 //
782 // Any of "event".
783 Object ResponseCancelledWebhookEventObject `json:"object"`
784 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
785 JSON struct {
786 ID respjson.Field
787 CreatedAt respjson.Field
788 Data respjson.Field
789 Type respjson.Field
790 Object respjson.Field
791 ExtraFields map[string]respjson.Field
792 raw string
793 } `json:"-"`
794}
795
796// Returns the unmodified JSON received from the API
797func (r ResponseCancelledWebhookEvent) RawJSON() string { return r.JSON.raw }
798func (r *ResponseCancelledWebhookEvent) UnmarshalJSON(data []byte) error {
799 return apijson.UnmarshalRoot(data, r)
800}
801
802// Event data payload.
803type ResponseCancelledWebhookEventData struct {
804 // The unique ID of the model response.
805 ID string `json:"id,required"`
806 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
807 JSON struct {
808 ID respjson.Field
809 ExtraFields map[string]respjson.Field
810 raw string
811 } `json:"-"`
812}
813
814// Returns the unmodified JSON received from the API
815func (r ResponseCancelledWebhookEventData) RawJSON() string { return r.JSON.raw }
816func (r *ResponseCancelledWebhookEventData) UnmarshalJSON(data []byte) error {
817 return apijson.UnmarshalRoot(data, r)
818}
819
820// The object of the event. Always `event`.
821type ResponseCancelledWebhookEventObject string
822
823const (
824 ResponseCancelledWebhookEventObjectEvent ResponseCancelledWebhookEventObject = "event"
825)
826
827// Sent when a background response has been completed.
828type ResponseCompletedWebhookEvent struct {
829 // The unique ID of the event.
830 ID string `json:"id,required"`
831 // The Unix timestamp (in seconds) of when the model response was completed.
832 CreatedAt int64 `json:"created_at,required"`
833 // Event data payload.
834 Data ResponseCompletedWebhookEventData `json:"data,required"`
835 // The type of the event. Always `response.completed`.
836 Type constant.ResponseCompleted `json:"type,required"`
837 // The object of the event. Always `event`.
838 //
839 // Any of "event".
840 Object ResponseCompletedWebhookEventObject `json:"object"`
841 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
842 JSON struct {
843 ID respjson.Field
844 CreatedAt respjson.Field
845 Data respjson.Field
846 Type respjson.Field
847 Object respjson.Field
848 ExtraFields map[string]respjson.Field
849 raw string
850 } `json:"-"`
851}
852
853// Returns the unmodified JSON received from the API
854func (r ResponseCompletedWebhookEvent) RawJSON() string { return r.JSON.raw }
855func (r *ResponseCompletedWebhookEvent) UnmarshalJSON(data []byte) error {
856 return apijson.UnmarshalRoot(data, r)
857}
858
859// Event data payload.
860type ResponseCompletedWebhookEventData struct {
861 // The unique ID of the model response.
862 ID string `json:"id,required"`
863 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
864 JSON struct {
865 ID respjson.Field
866 ExtraFields map[string]respjson.Field
867 raw string
868 } `json:"-"`
869}
870
871// Returns the unmodified JSON received from the API
872func (r ResponseCompletedWebhookEventData) RawJSON() string { return r.JSON.raw }
873func (r *ResponseCompletedWebhookEventData) UnmarshalJSON(data []byte) error {
874 return apijson.UnmarshalRoot(data, r)
875}
876
877// The object of the event. Always `event`.
878type ResponseCompletedWebhookEventObject string
879
880const (
881 ResponseCompletedWebhookEventObjectEvent ResponseCompletedWebhookEventObject = "event"
882)
883
884// Sent when a background response has failed.
885type ResponseFailedWebhookEvent struct {
886 // The unique ID of the event.
887 ID string `json:"id,required"`
888 // The Unix timestamp (in seconds) of when the model response failed.
889 CreatedAt int64 `json:"created_at,required"`
890 // Event data payload.
891 Data ResponseFailedWebhookEventData `json:"data,required"`
892 // The type of the event. Always `response.failed`.
893 Type constant.ResponseFailed `json:"type,required"`
894 // The object of the event. Always `event`.
895 //
896 // Any of "event".
897 Object ResponseFailedWebhookEventObject `json:"object"`
898 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
899 JSON struct {
900 ID respjson.Field
901 CreatedAt respjson.Field
902 Data respjson.Field
903 Type respjson.Field
904 Object respjson.Field
905 ExtraFields map[string]respjson.Field
906 raw string
907 } `json:"-"`
908}
909
910// Returns the unmodified JSON received from the API
911func (r ResponseFailedWebhookEvent) RawJSON() string { return r.JSON.raw }
912func (r *ResponseFailedWebhookEvent) UnmarshalJSON(data []byte) error {
913 return apijson.UnmarshalRoot(data, r)
914}
915
916// Event data payload.
917type ResponseFailedWebhookEventData struct {
918 // The unique ID of the model response.
919 ID string `json:"id,required"`
920 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
921 JSON struct {
922 ID respjson.Field
923 ExtraFields map[string]respjson.Field
924 raw string
925 } `json:"-"`
926}
927
928// Returns the unmodified JSON received from the API
929func (r ResponseFailedWebhookEventData) RawJSON() string { return r.JSON.raw }
930func (r *ResponseFailedWebhookEventData) UnmarshalJSON(data []byte) error {
931 return apijson.UnmarshalRoot(data, r)
932}
933
934// The object of the event. Always `event`.
935type ResponseFailedWebhookEventObject string
936
937const (
938 ResponseFailedWebhookEventObjectEvent ResponseFailedWebhookEventObject = "event"
939)
940
941// Sent when a background response has been interrupted.
942type ResponseIncompleteWebhookEvent struct {
943 // The unique ID of the event.
944 ID string `json:"id,required"`
945 // The Unix timestamp (in seconds) of when the model response was interrupted.
946 CreatedAt int64 `json:"created_at,required"`
947 // Event data payload.
948 Data ResponseIncompleteWebhookEventData `json:"data,required"`
949 // The type of the event. Always `response.incomplete`.
950 Type constant.ResponseIncomplete `json:"type,required"`
951 // The object of the event. Always `event`.
952 //
953 // Any of "event".
954 Object ResponseIncompleteWebhookEventObject `json:"object"`
955 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
956 JSON struct {
957 ID respjson.Field
958 CreatedAt respjson.Field
959 Data respjson.Field
960 Type respjson.Field
961 Object respjson.Field
962 ExtraFields map[string]respjson.Field
963 raw string
964 } `json:"-"`
965}
966
967// Returns the unmodified JSON received from the API
968func (r ResponseIncompleteWebhookEvent) RawJSON() string { return r.JSON.raw }
969func (r *ResponseIncompleteWebhookEvent) UnmarshalJSON(data []byte) error {
970 return apijson.UnmarshalRoot(data, r)
971}
972
973// Event data payload.
974type ResponseIncompleteWebhookEventData struct {
975 // The unique ID of the model response.
976 ID string `json:"id,required"`
977 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
978 JSON struct {
979 ID respjson.Field
980 ExtraFields map[string]respjson.Field
981 raw string
982 } `json:"-"`
983}
984
985// Returns the unmodified JSON received from the API
986func (r ResponseIncompleteWebhookEventData) RawJSON() string { return r.JSON.raw }
987func (r *ResponseIncompleteWebhookEventData) UnmarshalJSON(data []byte) error {
988 return apijson.UnmarshalRoot(data, r)
989}
990
991// The object of the event. Always `event`.
992type ResponseIncompleteWebhookEventObject string
993
994const (
995 ResponseIncompleteWebhookEventObjectEvent ResponseIncompleteWebhookEventObject = "event"
996)
997
998// UnwrapWebhookEventUnion contains all possible properties and values from
999// [BatchCancelledWebhookEvent], [BatchCompletedWebhookEvent],
1000// [BatchExpiredWebhookEvent], [BatchFailedWebhookEvent],
1001// [EvalRunCanceledWebhookEvent], [EvalRunFailedWebhookEvent],
1002// [EvalRunSucceededWebhookEvent], [FineTuningJobCancelledWebhookEvent],
1003// [FineTuningJobFailedWebhookEvent], [FineTuningJobSucceededWebhookEvent],
1004// [ResponseCancelledWebhookEvent], [ResponseCompletedWebhookEvent],
1005// [ResponseFailedWebhookEvent], [ResponseIncompleteWebhookEvent].
1006//
1007// Use the [UnwrapWebhookEventUnion.AsAny] method to switch on the variant.
1008//
1009// Use the methods beginning with 'As' to cast the union to one of its variants.
1010type UnwrapWebhookEventUnion struct {
1011 ID string `json:"id"`
1012 CreatedAt int64 `json:"created_at"`
1013 // This field is a union of [BatchCancelledWebhookEventData],
1014 // [BatchCompletedWebhookEventData], [BatchExpiredWebhookEventData],
1015 // [BatchFailedWebhookEventData], [EvalRunCanceledWebhookEventData],
1016 // [EvalRunFailedWebhookEventData], [EvalRunSucceededWebhookEventData],
1017 // [FineTuningJobCancelledWebhookEventData], [FineTuningJobFailedWebhookEventData],
1018 // [FineTuningJobSucceededWebhookEventData], [ResponseCancelledWebhookEventData],
1019 // [ResponseCompletedWebhookEventData], [ResponseFailedWebhookEventData],
1020 // [ResponseIncompleteWebhookEventData]
1021 Data UnwrapWebhookEventUnionData `json:"data"`
1022 // Any of "batch.cancelled", "batch.completed", "batch.expired", "batch.failed",
1023 // "eval.run.canceled", "eval.run.failed", "eval.run.succeeded",
1024 // "fine_tuning.job.cancelled", "fine_tuning.job.failed",
1025 // "fine_tuning.job.succeeded", "response.cancelled", "response.completed",
1026 // "response.failed", "response.incomplete".
1027 Type string `json:"type"`
1028 Object string `json:"object"`
1029 JSON struct {
1030 ID respjson.Field
1031 CreatedAt respjson.Field
1032 Data respjson.Field
1033 Type respjson.Field
1034 Object respjson.Field
1035 raw string
1036 } `json:"-"`
1037}
1038
1039// anyUnwrapWebhookEvent is implemented by each variant of
1040// [UnwrapWebhookEventUnion] to add type safety for the return type of
1041// [UnwrapWebhookEventUnion.AsAny]
1042type anyUnwrapWebhookEvent interface {
1043 implUnwrapWebhookEventUnion()
1044}
1045
1046func (BatchCancelledWebhookEvent) implUnwrapWebhookEventUnion() {}
1047func (BatchCompletedWebhookEvent) implUnwrapWebhookEventUnion() {}
1048func (BatchExpiredWebhookEvent) implUnwrapWebhookEventUnion() {}
1049func (BatchFailedWebhookEvent) implUnwrapWebhookEventUnion() {}
1050func (EvalRunCanceledWebhookEvent) implUnwrapWebhookEventUnion() {}
1051func (EvalRunFailedWebhookEvent) implUnwrapWebhookEventUnion() {}
1052func (EvalRunSucceededWebhookEvent) implUnwrapWebhookEventUnion() {}
1053func (FineTuningJobCancelledWebhookEvent) implUnwrapWebhookEventUnion() {}
1054func (FineTuningJobFailedWebhookEvent) implUnwrapWebhookEventUnion() {}
1055func (FineTuningJobSucceededWebhookEvent) implUnwrapWebhookEventUnion() {}
1056func (ResponseCancelledWebhookEvent) implUnwrapWebhookEventUnion() {}
1057func (ResponseCompletedWebhookEvent) implUnwrapWebhookEventUnion() {}
1058func (ResponseFailedWebhookEvent) implUnwrapWebhookEventUnion() {}
1059func (ResponseIncompleteWebhookEvent) implUnwrapWebhookEventUnion() {}
1060
1061// Use the following switch statement to find the correct variant
1062//
1063// switch variant := UnwrapWebhookEventUnion.AsAny().(type) {
1064// case webhooks.BatchCancelledWebhookEvent:
1065// case webhooks.BatchCompletedWebhookEvent:
1066// case webhooks.BatchExpiredWebhookEvent:
1067// case webhooks.BatchFailedWebhookEvent:
1068// case webhooks.EvalRunCanceledWebhookEvent:
1069// case webhooks.EvalRunFailedWebhookEvent:
1070// case webhooks.EvalRunSucceededWebhookEvent:
1071// case webhooks.FineTuningJobCancelledWebhookEvent:
1072// case webhooks.FineTuningJobFailedWebhookEvent:
1073// case webhooks.FineTuningJobSucceededWebhookEvent:
1074// case webhooks.ResponseCancelledWebhookEvent:
1075// case webhooks.ResponseCompletedWebhookEvent:
1076// case webhooks.ResponseFailedWebhookEvent:
1077// case webhooks.ResponseIncompleteWebhookEvent:
1078// default:
1079// fmt.Errorf("no variant present")
1080// }
1081func (u UnwrapWebhookEventUnion) AsAny() anyUnwrapWebhookEvent {
1082 switch u.Type {
1083 case "batch.cancelled":
1084 return u.AsBatchCancelled()
1085 case "batch.completed":
1086 return u.AsBatchCompleted()
1087 case "batch.expired":
1088 return u.AsBatchExpired()
1089 case "batch.failed":
1090 return u.AsBatchFailed()
1091 case "eval.run.canceled":
1092 return u.AsEvalRunCanceled()
1093 case "eval.run.failed":
1094 return u.AsEvalRunFailed()
1095 case "eval.run.succeeded":
1096 return u.AsEvalRunSucceeded()
1097 case "fine_tuning.job.cancelled":
1098 return u.AsFineTuningJobCancelled()
1099 case "fine_tuning.job.failed":
1100 return u.AsFineTuningJobFailed()
1101 case "fine_tuning.job.succeeded":
1102 return u.AsFineTuningJobSucceeded()
1103 case "response.cancelled":
1104 return u.AsResponseCancelled()
1105 case "response.completed":
1106 return u.AsResponseCompleted()
1107 case "response.failed":
1108 return u.AsResponseFailed()
1109 case "response.incomplete":
1110 return u.AsResponseIncomplete()
1111 }
1112 return nil
1113}
1114
1115func (u UnwrapWebhookEventUnion) AsBatchCancelled() (v BatchCancelledWebhookEvent) {
1116 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1117 return
1118}
1119
1120func (u UnwrapWebhookEventUnion) AsBatchCompleted() (v BatchCompletedWebhookEvent) {
1121 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1122 return
1123}
1124
1125func (u UnwrapWebhookEventUnion) AsBatchExpired() (v BatchExpiredWebhookEvent) {
1126 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1127 return
1128}
1129
1130func (u UnwrapWebhookEventUnion) AsBatchFailed() (v BatchFailedWebhookEvent) {
1131 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1132 return
1133}
1134
1135func (u UnwrapWebhookEventUnion) AsEvalRunCanceled() (v EvalRunCanceledWebhookEvent) {
1136 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1137 return
1138}
1139
1140func (u UnwrapWebhookEventUnion) AsEvalRunFailed() (v EvalRunFailedWebhookEvent) {
1141 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1142 return
1143}
1144
1145func (u UnwrapWebhookEventUnion) AsEvalRunSucceeded() (v EvalRunSucceededWebhookEvent) {
1146 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1147 return
1148}
1149
1150func (u UnwrapWebhookEventUnion) AsFineTuningJobCancelled() (v FineTuningJobCancelledWebhookEvent) {
1151 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1152 return
1153}
1154
1155func (u UnwrapWebhookEventUnion) AsFineTuningJobFailed() (v FineTuningJobFailedWebhookEvent) {
1156 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1157 return
1158}
1159
1160func (u UnwrapWebhookEventUnion) AsFineTuningJobSucceeded() (v FineTuningJobSucceededWebhookEvent) {
1161 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1162 return
1163}
1164
1165func (u UnwrapWebhookEventUnion) AsResponseCancelled() (v ResponseCancelledWebhookEvent) {
1166 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1167 return
1168}
1169
1170func (u UnwrapWebhookEventUnion) AsResponseCompleted() (v ResponseCompletedWebhookEvent) {
1171 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1172 return
1173}
1174
1175func (u UnwrapWebhookEventUnion) AsResponseFailed() (v ResponseFailedWebhookEvent) {
1176 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1177 return
1178}
1179
1180func (u UnwrapWebhookEventUnion) AsResponseIncomplete() (v ResponseIncompleteWebhookEvent) {
1181 apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1182 return
1183}
1184
1185// Returns the unmodified JSON received from the API
1186func (u UnwrapWebhookEventUnion) RawJSON() string { return u.JSON.raw }
1187
1188func (r *UnwrapWebhookEventUnion) UnmarshalJSON(data []byte) error {
1189 return apijson.UnmarshalRoot(data, r)
1190}
1191
1192// UnwrapWebhookEventUnionData is an implicit subunion of
1193// [UnwrapWebhookEventUnion]. UnwrapWebhookEventUnionData provides convenient
1194// access to the sub-properties of the union.
1195//
1196// For type safety it is recommended to directly use a variant of the
1197// [UnwrapWebhookEventUnion].
1198type UnwrapWebhookEventUnionData struct {
1199 ID string `json:"id"`
1200 JSON struct {
1201 ID respjson.Field
1202 raw string
1203 } `json:"-"`
1204}
1205
1206func (r *UnwrapWebhookEventUnionData) UnmarshalJSON(data []byte) error {
1207 return apijson.UnmarshalRoot(data, r)
1208}