Skip to main content

gproxy_protocol/wire/openai/
video.rs

1//! OpenRouter-shaped video generation extension in the OpenAI wire family.
2//! Sources: design/protocol-spec.md section 7 and local OpenRouter Submit/Poll/
3//! Download video documents. Native* retains original OpenAI resource shapes;
4//! normalization/alias conversion is explicitly not performed by these DTOs.
5//! Native Video resource detail checked against openai-python commit
6//! e12b81d3bbf644ec7045e152d69bc4b68d69cd48, types/video.py (2026-09-13).
7use crate::connection::{HttpBody, MultipartPart};
8use crate::{Rest, WireRequest, WireResponse};
9use serde::{Deserialize, Serialize};
10use std::collections::BTreeMap;
11fn optional<'de, D, T>(d: D) -> Result<Option<T>, D::Error>
12where
13    D: serde::Deserializer<'de>,
14    T: Deserialize<'de>,
15{
16    T::deserialize(d).map(Some)
17}
18fn nullable<'de, D, T>(d: D) -> Result<Option<Option<T>>, D::Error>
19where
20    D: serde::Deserializer<'de>,
21    T: Deserialize<'de>,
22{
23    Option::<T>::deserialize(d).map(Some)
24}
25
26#[derive(
27    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
28)]
29#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
30#[derive(gproxy_protocol_macros::DeclaredFields)]
31#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
32pub struct CreateVideoRequestBody {
33    pub model: String,
34    #[serde(
35        default,
36        deserialize_with = "optional",
37        skip_serializing_if = "Option::is_none"
38    )]
39    pub prompt: Option<String>,
40    #[serde(
41        default,
42        deserialize_with = "optional",
43        skip_serializing_if = "Option::is_none"
44    )]
45    pub duration: Option<i64>,
46    #[serde(
47        default,
48        deserialize_with = "optional",
49        skip_serializing_if = "Option::is_none"
50    )]
51    pub aspect_ratio: Option<VideoAspectRatio>,
52    #[serde(
53        default,
54        deserialize_with = "optional",
55        skip_serializing_if = "Option::is_none"
56    )]
57    pub resolution: Option<VideoResolution>,
58    #[serde(
59        default,
60        deserialize_with = "optional",
61        skip_serializing_if = "Option::is_none"
62    )]
63    pub size: Option<String>,
64    #[serde(
65        default,
66        deserialize_with = "optional",
67        skip_serializing_if = "Option::is_none"
68    )]
69    pub seed: Option<i64>,
70    #[serde(
71        default,
72        deserialize_with = "optional",
73        skip_serializing_if = "Option::is_none"
74    )]
75    pub frame_images: Option<Vec<FrameImage>>,
76    #[serde(
77        default,
78        deserialize_with = "optional",
79        skip_serializing_if = "Option::is_none"
80    )]
81    pub input_references: Option<Vec<InputReference>>,
82    #[serde(
83        default,
84        deserialize_with = "optional",
85        skip_serializing_if = "Option::is_none"
86    )]
87    pub generate_audio: Option<bool>,
88    #[serde(
89        default,
90        deserialize_with = "optional",
91        skip_serializing_if = "Option::is_none"
92    )]
93    pub callback_url: Option<String>,
94    #[serde(
95        default,
96        deserialize_with = "optional",
97        skip_serializing_if = "Option::is_none"
98    )]
99    pub provider: Option<VideoProvider>,
100    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
101    pub rest: Rest,
102}
103
104#[derive(
105    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
106)]
107#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
108#[derive(gproxy_protocol_macros::DeclaredFields)]
109#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
110pub struct VideoGenerationResponseBody {
111    pub id: String,
112    pub polling_url: String,
113    pub status: VideoStatus,
114    #[serde(
115        default,
116        deserialize_with = "optional",
117        skip_serializing_if = "Option::is_none"
118    )]
119    pub error: Option<String>,
120    #[serde(
121        default,
122        deserialize_with = "optional",
123        skip_serializing_if = "Option::is_none"
124    )]
125    pub generation_id: Option<String>,
126    #[serde(
127        default,
128        deserialize_with = "optional",
129        skip_serializing_if = "Option::is_none"
130    )]
131    pub unsigned_urls: Option<Vec<String>>,
132    #[serde(
133        default,
134        deserialize_with = "optional",
135        skip_serializing_if = "Option::is_none"
136    )]
137    pub usage: Option<VideoUsage>,
138    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
139    pub rest: Rest,
140}
141
142#[derive(
143    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
144)]
145#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
146#[derive(gproxy_protocol_macros::DeclaredFields)]
147#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
148pub struct VideoUsage {
149    #[serde(
150        default,
151        deserialize_with = "nullable",
152        skip_serializing_if = "Option::is_none"
153    )]
154    pub cost: Option<Option<serde_json::Number>>,
155    #[serde(
156        default,
157        deserialize_with = "optional",
158        skip_serializing_if = "Option::is_none"
159    )]
160    pub is_byok: Option<bool>,
161    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
162    pub rest: Rest,
163}
164
165#[derive(
166    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
167)]
168#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
169/// provider.options is explicitly arbitrary per-provider JSON in the OpenRouter schema.
170/// Video provider configuration has no routing preferences; do not import rerank fields.
171#[derive(gproxy_protocol_macros::DeclaredFields)]
172#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
173pub struct VideoProvider {
174    #[serde(
175        default,
176        deserialize_with = "optional",
177        skip_serializing_if = "Option::is_none"
178    )]
179    pub options: Option<BTreeMap<String, Rest>>,
180    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
181    pub rest: Rest,
182}
183
184#[derive(
185    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
186)]
187#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
188#[derive(gproxy_protocol_macros::DeclaredFields)]
189#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
190pub struct ReferenceUrl {
191    pub url: String,
192    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
193    pub rest: Rest,
194}
195
196#[derive(
197    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
198)]
199#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
200#[derive(gproxy_protocol_macros::DeclaredFields)]
201#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
202pub struct FrameImage {
203    #[serde(rename = "type")]
204    pub type_: VideoImageType,
205    pub image_url: ReferenceUrl,
206    pub frame_type: FrameType,
207    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
208    pub rest: Rest,
209}
210
211#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
212#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
213#[derive(gproxy_protocol_macros::DeclaredFields)]
214#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
215pub enum VideoImageType {
216    #[serde(rename = "image_url")]
217    ImageUrl,
218}
219
220#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
221#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
222#[derive(gproxy_protocol_macros::DeclaredFields)]
223#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
224pub enum FrameType {
225    #[serde(rename = "first_frame")]
226    FirstFrame,
227    #[serde(rename = "last_frame")]
228    LastFrame,
229}
230
231#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
232#[serde(tag = "type")]
233#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
234#[derive(gproxy_protocol_macros::DeclaredFields)]
235#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
236pub enum InputReference {
237    #[serde(rename = "image_url")]
238    Image(InputImageReference),
239    #[serde(rename = "audio_url")]
240    Audio(InputAudioReference),
241    #[serde(rename = "video_url")]
242    Video(InputVideoReference),
243}
244
245#[derive(
246    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
247)]
248#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
249#[derive(gproxy_protocol_macros::DeclaredFields)]
250#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
251pub struct InputImageReference {
252    pub image_url: ReferenceUrl,
253    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
254    pub rest: Rest,
255}
256
257#[derive(
258    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
259)]
260#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
261#[derive(gproxy_protocol_macros::DeclaredFields)]
262#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
263pub struct InputAudioReference {
264    pub audio_url: ReferenceUrl,
265    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
266    pub rest: Rest,
267}
268
269#[derive(
270    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
271)]
272#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
273#[derive(gproxy_protocol_macros::DeclaredFields)]
274#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
275pub struct InputVideoReference {
276    pub video_url: ReferenceUrl,
277    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
278    pub rest: Rest,
279}
280
281#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
282#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
283#[derive(gproxy_protocol_macros::DeclaredFields)]
284#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
285pub enum VideoAspectRatio {
286    #[serde(rename = "16:9")]
287    R16x9,
288    #[serde(rename = "9:16")]
289    R9x16,
290    #[serde(rename = "1:1")]
291    R1x1,
292    #[serde(rename = "4:3")]
293    R4x3,
294    #[serde(rename = "3:4")]
295    R3x4,
296    #[serde(rename = "3:2")]
297    R3x2,
298    #[serde(rename = "2:3")]
299    R2x3,
300    #[serde(rename = "21:9")]
301    R21x9,
302    #[serde(rename = "9:21")]
303    R9x21,
304}
305
306#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
307#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
308#[derive(gproxy_protocol_macros::DeclaredFields)]
309#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
310pub enum VideoResolution {
311    #[serde(rename = "480p")]
312    P480,
313    #[serde(rename = "720p")]
314    P720,
315    #[serde(rename = "768p")]
316    P768,
317    #[serde(rename = "1080p")]
318    P1080,
319    #[serde(rename = "1K")]
320    K1,
321    #[serde(rename = "2K")]
322    K2,
323    #[serde(rename = "4K")]
324    K4,
325}
326
327#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
328#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
329#[derive(gproxy_protocol_macros::DeclaredFields)]
330#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
331pub enum VideoStatus {
332    #[serde(rename = "pending")]
333    Pending,
334    #[serde(rename = "in_progress")]
335    InProgress,
336    #[serde(rename = "completed")]
337    Completed,
338    #[serde(rename = "failed")]
339    Failed,
340    #[serde(rename = "cancelled")]
341    Cancelled,
342    #[serde(rename = "expired")]
343    Expired,
344}
345
346#[derive(
347    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
348)]
349#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
350#[derive(gproxy_protocol_macros::DeclaredFields)]
351#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
352pub struct RetrieveVideoPath {
353    #[serde(rename = "jobId")]
354    pub job_id: String,
355    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
356    pub rest: Rest,
357}
358
359#[derive(
360    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
361)]
362#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
363#[derive(gproxy_protocol_macros::DeclaredFields)]
364#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
365pub struct DownloadVideoQuery {
366    #[serde(
367        default,
368        deserialize_with = "nullable",
369        skip_serializing_if = "Option::is_none"
370    )]
371    pub index: Option<Option<i64>>,
372    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
373    pub rest: Rest,
374}
375
376pub type CreateVideoRequest = WireRequest<CreateVideoRequestBody>;
377pub type CreateVideoResponse = WireResponse<VideoGenerationResponseBody>;
378pub type RetrieveVideoRequest = WireRequest<()>;
379pub type RetrieveVideoResponse = WireResponse<VideoGenerationResponseBody>;
380pub type DownloadVideoRequest = WireRequest<()>;
381pub type DownloadVideoResponse = WireResponse<HttpBody>;
382
383#[derive(
384    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
385)]
386#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
387#[derive(gproxy_protocol_macros::DeclaredFields)]
388#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
389pub struct NativeCreateVideoRequestBody {
390    pub prompt: String,
391    #[serde(
392        default,
393        deserialize_with = "optional",
394        skip_serializing_if = "Option::is_none"
395    )]
396    pub input_reference: Option<NativeInputReference>,
397    #[serde(
398        default,
399        deserialize_with = "optional",
400        skip_serializing_if = "Option::is_none"
401    )]
402    pub model: Option<String>,
403    #[serde(
404        default,
405        deserialize_with = "optional",
406        skip_serializing_if = "Option::is_none"
407    )]
408    pub seconds: Option<NativeVideoSeconds>,
409    #[serde(
410        default,
411        deserialize_with = "optional",
412        skip_serializing_if = "Option::is_none"
413    )]
414    pub size: Option<NativeVideoSize>,
415    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
416    pub rest: Rest,
417}
418
419#[derive(Debug, gproxy_protocol_macros::WireBuilder)]
420#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
421#[derive(gproxy_protocol_macros::DeclaredFields)]
422#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
423pub struct NativeCreateVideoMultipartForm {
424    pub prompt: String,
425    pub input_reference: Option<MultipartPart>,
426    pub model: Option<String>,
427    pub seconds: Option<NativeVideoSeconds>,
428    pub size: Option<NativeVideoSize>,
429}
430
431#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
432#[serde(untagged)]
433#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
434#[derive(gproxy_protocol_macros::DeclaredFields)]
435#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
436pub enum NativeInputReference {
437    File(NativeFileReference),
438    Url(NativeUrlReference),
439}
440
441#[derive(
442    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
443)]
444#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
445#[derive(gproxy_protocol_macros::DeclaredFields)]
446#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
447pub struct NativeFileReference {
448    pub file_id: String,
449    #[serde(
450        default,
451        flatten,
452        deserialize_with = "file_extensions",
453        skip_serializing_if = "serde_json::Map::is_empty"
454    )]
455    pub rest: Rest,
456}
457
458#[derive(
459    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
460)]
461#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
462#[derive(gproxy_protocol_macros::DeclaredFields)]
463#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
464pub struct NativeUrlReference {
465    pub image_url: String,
466    #[serde(
467        default,
468        flatten,
469        deserialize_with = "url_extensions",
470        skip_serializing_if = "serde_json::Map::is_empty"
471    )]
472    pub rest: Rest,
473}
474
475fn file_extensions<'de, D: serde::Deserializer<'de>>(d: D) -> Result<Rest, D::Error> {
476    let rest = Rest::deserialize(d)?;
477    if rest.contains_key("image_url") {
478        return Err(serde::de::Error::custom(
479            "reference requires exactly one of file_id and image_url",
480        ));
481    }
482    Ok(rest)
483}
484fn url_extensions<'de, D: serde::Deserializer<'de>>(d: D) -> Result<Rest, D::Error> {
485    let rest = Rest::deserialize(d)?;
486    if rest.contains_key("file_id") {
487        return Err(serde::de::Error::custom(
488            "reference requires exactly one of file_id and image_url",
489        ));
490    }
491    Ok(rest)
492}
493
494#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
495#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
496#[derive(gproxy_protocol_macros::DeclaredFields)]
497#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
498pub enum NativeVideoSeconds {
499    #[serde(rename = "4")]
500    Four,
501    #[serde(rename = "8")]
502    Eight,
503    #[serde(rename = "12")]
504    Twelve,
505}
506
507#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
508#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
509#[derive(gproxy_protocol_macros::DeclaredFields)]
510#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
511pub enum NativeVideoSize {
512    #[serde(rename = "720x1280")]
513    Portrait720,
514    #[serde(rename = "1280x720")]
515    Landscape720,
516    #[serde(rename = "1024x1792")]
517    Portrait1024,
518    #[serde(rename = "1792x1024")]
519    Landscape1024,
520}
521
522#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
523#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
524#[derive(gproxy_protocol_macros::DeclaredFields)]
525#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
526pub enum NativeVideoStatus {
527    #[serde(rename = "queued")]
528    Queued,
529    #[serde(rename = "in_progress")]
530    InProgress,
531    #[serde(rename = "completed")]
532    Completed,
533    #[serde(rename = "failed")]
534    Failed,
535}
536
537#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
538#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
539#[derive(gproxy_protocol_macros::DeclaredFields)]
540#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
541pub enum NativeVideoObject {
542    #[serde(rename = "video")]
543    Video,
544}
545
546#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
547#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
548#[derive(gproxy_protocol_macros::DeclaredFields)]
549#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
550pub enum NativeVideoDeletedObject {
551    #[serde(rename = "video.deleted")]
552    VideoDeleted,
553}
554
555#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
556#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
557#[derive(gproxy_protocol_macros::DeclaredFields)]
558#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
559pub enum NativeVideoListOrder {
560    #[serde(rename = "asc")]
561    Asc,
562    #[serde(rename = "desc")]
563    Desc,
564}
565
566#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
567#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
568#[derive(gproxy_protocol_macros::DeclaredFields)]
569#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
570pub enum NativeVideoDownloadVariant {
571    #[serde(rename = "video")]
572    Video,
573    #[serde(rename = "thumbnail")]
574    Thumbnail,
575    #[serde(rename = "spritesheet")]
576    Spritesheet,
577}
578
579#[derive(
580    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
581)]
582#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
583#[derive(gproxy_protocol_macros::DeclaredFields)]
584#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
585pub struct NativeVideo {
586    pub id: String,
587    pub created_at: i64,
588    pub model: String,
589    pub object: NativeVideoObject,
590    pub progress: i64,
591    pub seconds: String,
592    pub size: NativeVideoSize,
593    pub status: NativeVideoStatus,
594    #[serde(
595        default,
596        deserialize_with = "nullable",
597        skip_serializing_if = "Option::is_none"
598    )]
599    pub completed_at: Option<Option<i64>>,
600    #[serde(
601        default,
602        deserialize_with = "nullable",
603        skip_serializing_if = "Option::is_none"
604    )]
605    pub error: Option<Option<NativeVideoError>>,
606    #[serde(
607        default,
608        deserialize_with = "nullable",
609        skip_serializing_if = "Option::is_none"
610    )]
611    pub expires_at: Option<Option<i64>>,
612    #[serde(
613        default,
614        deserialize_with = "nullable",
615        skip_serializing_if = "Option::is_none"
616    )]
617    pub prompt: Option<Option<String>>,
618    #[serde(
619        default,
620        deserialize_with = "nullable",
621        skip_serializing_if = "Option::is_none"
622    )]
623    pub remixed_from_video_id: Option<Option<String>>,
624    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
625    pub rest: Rest,
626}
627
628#[derive(
629    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
630)]
631#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
632#[derive(gproxy_protocol_macros::DeclaredFields)]
633#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
634pub struct NativeVideoError {
635    pub code: String,
636    pub message: String,
637    #[serde(
638        default,
639        deserialize_with = "nullable",
640        skip_serializing_if = "Option::is_none"
641    )]
642    pub misalignment: Option<Option<NativeVideoMisalignment>>,
643    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
644    pub rest: Rest,
645}
646
647#[derive(
648    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
649)]
650#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
651#[derive(gproxy_protocol_macros::DeclaredFields)]
652#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
653pub struct NativeVideoPath {
654    pub video_id: String,
655    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
656    pub rest: Rest,
657}
658
659#[derive(
660    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
661)]
662#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
663#[derive(gproxy_protocol_macros::DeclaredFields)]
664#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
665pub struct NativeListVideosQuery {
666    #[serde(
667        default,
668        deserialize_with = "optional",
669        skip_serializing_if = "Option::is_none"
670    )]
671    pub after: Option<String>,
672    #[serde(
673        default,
674        deserialize_with = "optional",
675        skip_serializing_if = "Option::is_none"
676    )]
677    pub limit: Option<i64>,
678    #[serde(
679        default,
680        deserialize_with = "optional",
681        skip_serializing_if = "Option::is_none"
682    )]
683    pub order: Option<NativeVideoListOrder>,
684    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
685    pub rest: Rest,
686}
687
688#[derive(
689    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
690)]
691#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
692#[derive(gproxy_protocol_macros::DeclaredFields)]
693#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
694pub struct NativeListVideosResponseBody {
695    pub data: Vec<NativeVideo>,
696    #[serde(
697        default,
698        deserialize_with = "nullable",
699        skip_serializing_if = "Option::is_none"
700    )]
701    pub has_more: Option<Option<bool>>,
702    #[serde(
703        default,
704        deserialize_with = "nullable",
705        skip_serializing_if = "Option::is_none"
706    )]
707    pub last_id: Option<Option<String>>,
708    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
709    pub rest: Rest,
710}
711
712#[derive(
713    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
714)]
715#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
716#[derive(gproxy_protocol_macros::DeclaredFields)]
717#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
718pub struct NativeDeleteVideoResponseBody {
719    pub id: String,
720    pub deleted: bool,
721    pub object: NativeVideoDeletedObject,
722    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
723    pub rest: Rest,
724}
725
726#[derive(
727    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
728)]
729#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
730#[derive(gproxy_protocol_macros::DeclaredFields)]
731#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
732pub struct NativeDownloadVideoQuery {
733    #[serde(
734        default,
735        deserialize_with = "optional",
736        skip_serializing_if = "Option::is_none"
737    )]
738    pub variant: Option<NativeVideoDownloadVariant>,
739    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
740    pub rest: Rest,
741}
742
743pub type NativeCreateVideoRequest = WireRequest<NativeCreateVideoRequestBody>;
744pub type NativeCreateVideoMultipartRequest = WireRequest<NativeCreateVideoMultipartForm>;
745pub type NativeRawCreateVideoRequest = WireRequest<crate::connection::Multipart>;
746pub type NativeCreateVideoResponse = WireResponse<NativeVideo>;
747pub type NativeRetrieveVideoRequest = WireRequest<()>;
748pub type NativeRetrieveVideoResponse = WireResponse<NativeVideo>;
749pub type NativeListVideosRequest = WireRequest<()>;
750pub type NativeListVideosResponse = WireResponse<NativeListVideosResponseBody>;
751pub type NativeDeleteVideoRequest = WireRequest<()>;
752pub type NativeDeleteVideoResponse = WireResponse<NativeDeleteVideoResponseBody>;
753pub type NativeDownloadVideoRequest = WireRequest<()>;
754pub type NativeDownloadVideoResponse = WireResponse<HttpBody>;
755
756/// video_create_error.py in the pinned SDK includes structured safety context.
757#[derive(
758    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
759)]
760#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
761#[derive(gproxy_protocol_macros::DeclaredFields)]
762#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
763pub struct NativeVideoMisalignment {
764    #[serde(
765        default,
766        deserialize_with = "nullable",
767        skip_serializing_if = "Option::is_none"
768    )]
769    pub detailed_explanation: Option<Option<String>>,
770    #[serde(
771        default,
772        deserialize_with = "nullable",
773        skip_serializing_if = "Option::is_none"
774    )]
775    pub error_type: Option<Option<String>>,
776    #[serde(
777        default,
778        deserialize_with = "nullable",
779        skip_serializing_if = "Option::is_none"
780    )]
781    pub steer: Option<Option<NativeVideoSteer>>,
782    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
783    pub rest: Rest,
784}
785#[derive(
786    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
787)]
788#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
789#[derive(gproxy_protocol_macros::DeclaredFields)]
790#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
791pub struct NativeVideoSteer {
792    pub message: String,
793    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
794    pub rest: Rest,
795}