Skip to content

Types

aiograpi.types contains the public Pydantic models returned by high-level client methods and accepted by upload/story helpers.

Import models directly when you need structured input objects:

from aiograpi.types import Location, Media, StoryMention, UserShort, Usertag

How To Read Fields

Required fields have no default value. Optional[...] fields may be absent from Instagram responses or returned as null. Fields with raw dict or list types intentionally preserve Instagram data whose shape is not stable enough for a dedicated public model yet.

Common Models

Model Common source Notes
Account account_info() Private account profile for the authenticated user, including email/phone fields when Instagram returns them.
User user_info(...), user_info_by_username(...) Full public profile fields such as counts, biography, public contacts, business category, location, and messaging ids.
UserShort user lists, tags, comments, direct threads Compact user profile used inside many other models. Preserves newer v2 fields such as fbid_v2, profile_pic_id, account_badges, and friendship_status.
Media media_info(...), feeds, timelines, hashtag media Main post/Reel/album object. Includes caption/count flags, resources, usertags, coauthors, DASH info, music attribution, and inline comment previews when returned.
Resource Media.resources Album child media with thumbnail/video URLs and nested usertags.
Comment comment helpers Public comment model with author, text, like state/count, and reply target.
DirectThread direct thread helpers Direct conversation shell with participants, messages, mute/pin/group state, and activity metadata.
DirectMessage direct message helpers Individual direct item with text, media shares, visual media, links, reactions, replies, and seen state.
Story story/reel helpers Story media object with stickers, mentions, hashtags, links, locations, sponsor tags, and video metadata.
Location location helpers and upload metadata Place metadata used by media and story publishing flows.
Hashtag hashtag helpers Hashtag identity, media count, and profile picture.
Track music/Reels helpers Music track metadata and audio URLs when available.
Note notes helpers Direct Notes payload with author, audience, timestamps, and style flags.

Account And User Models

Bases: TypesBaseModel

Source code in aiograpi/types.py
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
class Account(TypesBaseModel):
    pk: str
    username: str
    full_name: str
    is_private: bool
    profile_pic_url: HttpUrl
    is_verified: bool
    biography: Optional[str] = ""
    external_url: Optional[str] = None
    is_business: bool
    birthday: Optional[str] = None
    phone_number: Optional[str] = None
    gender: Optional[int] = None
    email: Optional[str] = None

    @field_validator("external_url")
    @classmethod
    def validate_external_url(cls, v):
        if v is None or (v.startswith("http") and "://" in v) or isinstance(v, str):
            return v
        raise ValidationError("external_url must be a URL or string")

Bases: TypesBaseModel

Source code in aiograpi/types.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
class User(TypesBaseModel):
    pk: str
    username: str
    full_name: str
    is_private: bool
    profile_pic_url: HttpUrl
    profile_pic_url_hd: Optional[HttpUrl] = None
    is_verified: bool
    media_count: int
    follower_count: int
    following_count: int
    biography: Optional[str] = ""
    bio_links: List[BioLink] = []
    external_url: Optional[str] = None
    account_type: Optional[int] = None
    is_business: bool

    broadcast_channel: List[Broadcast] = []

    public_email: Optional[str] = None
    contact_phone_number: Optional[str] = None
    public_phone_country_code: Optional[str] = None
    public_phone_number: Optional[str] = None
    business_contact_method: Optional[str] = None
    business_category_name: Optional[str] = None
    category_name: Optional[str] = None
    category: Optional[str] = None

    address_street: Optional[str] = None
    city_id: Optional[str] = None
    city_name: Optional[str] = None
    latitude: Optional[float] = None
    longitude: Optional[float] = None
    zip: Optional[str] = None
    instagram_location_id: Optional[str] = None
    interop_messaging_user_fbid: Optional[str] = None

    @field_validator("external_url")
    @classmethod
    def validate_external_url(cls, v):
        if v is None or (v.startswith("http") and "://" in v) or isinstance(v, str):
            return v
        raise ValidationError("external_url must be a URL or string")

Bases: TypesBaseModel

Source code in aiograpi/types.py
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
class UserShort(TypesBaseModel):
    def __hash__(self):
        return hash(self.pk)

    def __eq__(self, other):
        if isinstance(other, UserShort):
            return self.pk == other.pk
        return NotImplemented

    pk: str
    username: Optional[str] = None
    full_name: Optional[str] = ""
    profile_pic_url: Optional[HttpUrl] = None
    profile_pic_url_hd: Optional[HttpUrl] = None
    is_private: Optional[bool] = None
    stories: List = Field(default_factory=list)
    is_verified: Optional[bool] = None
    latest_reel_media: Optional[int] = None
    has_anonymous_profile_picture: Optional[bool] = None
    profile_pic_id: Optional[str] = None
    fbid_v2: Optional[str] = None
    interop_messaging_user_fbid: Optional[str] = None
    strong_id__: Optional[str] = None
    account_badges: List[dict] = Field(default_factory=list)
    friendship_status: Optional[RelationshipShort] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
145
146
147
148
149
150
151
152
153
class RelationshipShort(TypesBaseModel):
    user_id: str
    following: bool
    incoming_request: bool
    is_bestie: bool
    is_feed_favorite: bool
    is_private: bool
    is_restricted: bool
    outgoing_request: bool

Bases: TypesBaseModel

Source code in aiograpi/types.py
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
class Relationship(TypesBaseModel):
    user_id: str
    blocking: bool
    followed_by: bool
    following: bool
    incoming_request: bool
    is_bestie: bool
    is_blocking_reel: bool
    is_muting_reel: bool
    is_private: bool
    is_restricted: bool
    muting: bool
    outgoing_request: bool

Bases: UserShort

Source code in aiograpi/types.py
183
184
185
186
class Viewer(UserShort):
    has_liked: bool = False
    reply_text: str = ""
    is_spam_viewer: bool = False

Bases: TypesBaseModel

Source code in aiograpi/types.py
189
190
191
192
class Usertag(TypesBaseModel):
    user: UserShort
    x: float
    y: float

Bases: TypesBaseModel

Source code in aiograpi/types.py
 99
100
101
102
103
104
class About(TypesBaseModel):
    username: Optional[str] = ""
    is_verified: Optional[bool] = False
    country: Optional[str] = ""
    date: Optional[str] = ""
    former_usernames: Optional[str] = ""

Bases: TypesBaseModel

Source code in aiograpi/types.py
30
31
32
33
34
35
36
37
class BioLink(TypesBaseModel):
    link_id: Optional[str] = None
    url: str
    lynx_url: Optional[str] = None
    link_type: Optional[str] = None
    title: Optional[str] = None
    is_pinned: Optional[bool] = None
    open_external_url_with_in_app_browser: Optional[bool] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
40
41
42
43
44
45
46
47
48
49
50
51
class Broadcast(TypesBaseModel):
    title: str
    thread_igid: str
    subtitle: str
    invite_link: str
    is_member: bool
    group_image_uri: str
    group_image_background_uri: str
    thread_subtype: int
    number_of_members: int
    creator_igid: Optional[str] = None
    creator_username: str

Bases: TypesBaseModel

Source code in aiograpi/types.py
107
108
class AddressBookPhone(TypesBaseModel):
    phone_number: str

Bases: TypesBaseModel

Source code in aiograpi/types.py
111
112
class AddressBookEmail(TypesBaseModel):
    email_address: str

Bases: TypesBaseModel

Source code in aiograpi/types.py
115
116
117
118
119
class AddressBookContact(TypesBaseModel):
    phone_numbers: List[AddressBookPhone] = Field(default_factory=list)
    email_addresses: List[AddressBookEmail] = Field(default_factory=list)
    first_name: str = ""
    last_name: str = ""

Media Models

Bases: TypesBaseModel

Source code in aiograpi/types.py
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
class Media(TypesBaseModel):
    pk: Union[str, int]
    id: str
    code: str
    taken_at: datetime
    media_type: int
    image_versions2: Optional[SharedMediaImageVersions] = None
    product_type: Optional[str] = ""  # igtv or feed
    thumbnail_url: Optional[HttpUrl] = None
    location: Optional[Location] = None
    user: UserShort
    comment_count: Optional[int] = 0
    comments_disabled: Optional[bool] = False
    commenting_disabled_for_viewer: Optional[bool] = False
    like_count: int
    play_count: Optional[int] = None
    has_liked: Optional[bool] = None
    caption_is_edited: Optional[bool] = False
    dimensions: Optional[MediaDimensions] = None
    has_audio: Optional[bool] = False
    like_and_view_counts_disabled: Optional[bool] = False
    viewer_can_reshare: Optional[bool] = False
    viewer_has_saved: Optional[bool] = False
    is_paid_partnership: Optional[bool] = False
    is_affiliate: Optional[bool] = False
    dash_info: Optional[MediaDashInfo] = None
    clips_music_attribution_info: Optional[ClipsMusicAttributionInfo] = None
    comments_preview: Optional[MediaCommentsPreview] = None
    hoisted_comments: List[MediaInlineComment] = []
    caption_text: str
    accessibility_caption: Optional[str] = None
    usertags: List[Usertag]
    coauthor_producers: List[UserShort] = []
    sponsor_tags: List[UserShort]
    video_url: Optional[HttpUrl] = None  # for Video and IGTV
    view_count: Optional[int] = 0  # for Video and IGTV
    video_duration: Optional[float] = 0.0  # for Video and IGTV
    title: Optional[str] = ""
    resources: List[Resource] = []
    clips_metadata: Optional[Union[ClipsMetadata, dict]] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
22
23
24
25
26
27
class Resource(TypesBaseModel):
    pk: str
    video_url: Optional[HttpUrl] = None  # for Video and IGTV
    thumbnail_url: Optional[HttpUrl] = None
    media_type: int
    usertags: List["Usertag"] = []

Bases: TypesBaseModel

Source code in aiograpi/types.py
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
class MediaOembed(TypesBaseModel):
    title: str
    author_name: str
    author_url: str
    author_id: str
    media_id: str
    provider_name: str
    provider_url: HttpUrl
    type: str
    width: Optional[int] = None
    height: Optional[int] = None
    html: str
    thumbnail_url: HttpUrl
    thumbnail_width: int
    thumbnail_height: int
    can_view: bool

Bases: TypesBaseModel

Source code in aiograpi/types.py
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
class MediaXma(TypesBaseModel):
    # media_type: int
    video_url: str  # XMA target_url; can be http(s) or an Instagram deep link (instagram://)
    title: Optional[str] = ""
    preview_url: Optional[str] = None
    preview_url_mime_type: Optional[str] = None
    header_icon_url: Optional[str] = None
    header_icon_width: Optional[int] = None
    header_icon_height: Optional[int] = None
    header_title_text: Optional[str] = None
    preview_media_fbid: Optional[str] = None

    @field_validator("preview_url", "header_icon_url")
    @classmethod
    def validate_url_fields(cls, v):
        """Validate URL fields allowing None, valid URLs, or any string"""
        if v is None or (v.startswith("http") and "://" in v) or isinstance(v, str):
            return v
        raise ValidationError("URL field must be a URL or string")

validate_url_fields(v) classmethod

Validate URL fields allowing None, valid URLs, or any string

Source code in aiograpi/types.py
561
562
563
564
565
566
567
@field_validator("preview_url", "header_icon_url")
@classmethod
def validate_url_fields(cls, v):
    """Validate URL fields allowing None, valid URLs, or any string"""
    if v is None or (v.startswith("http") and "://" in v) or isinstance(v, str):
        return v
    raise ValidationError("URL field must be a URL or string")

Bases: TypesBaseModel

Source code in aiograpi/types.py
466
467
468
class MediaDimensions(TypesBaseModel):
    height: Optional[int] = None
    width: Optional[int] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
471
472
473
474
class MediaDashInfo(TypesBaseModel):
    is_dash_eligible: Optional[bool] = False
    video_dash_manifest: Optional[str] = None
    number_of_qualities: Optional[int] = 0

Bases: TypesBaseModel

Source code in aiograpi/types.py
486
487
488
489
490
491
492
493
494
495
496
497
class MediaInlineComment(TypesBaseModel):
    pk: str
    text: str
    user: UserShort
    created_at_utc: datetime
    has_liked: Optional[bool] = None
    like_count: Optional[int] = None
    replied_to_comment_id: Optional[str] = None
    did_report_as_spam: Optional[bool] = None
    is_restricted_pending: Optional[bool] = None
    replies_count: Optional[int] = 0
    replies: List["MediaInlineComment"] = []

Bases: TypesBaseModel

Source code in aiograpi/types.py
500
501
502
503
504
class MediaCommentsPreview(TypesBaseModel):
    count: Optional[int] = 0
    has_next_page: Optional[bool] = False
    end_cursor: Optional[str] = None
    comments: List[MediaInlineComment] = []

Bases: TypesBaseModel

Image candidate for shared media clips with video features

Source code in aiograpi/types.py
214
215
216
217
218
219
220
221
222
class SharedMediaImageCandidate(TypesBaseModel):
    """Image candidate for shared media clips with video features"""

    estimated_scans_sizes: List[int] = []
    height: int
    scans_profile: Optional[str] = None
    url: str
    width: int
    is_spatial_image: Optional[bool] = None

Bases: TypesBaseModel

Complete image_versions2 structure for shared media clips

Source code in aiograpi/types.py
256
257
258
259
260
261
class SharedMediaImageVersions(TypesBaseModel):
    """Complete image_versions2 structure for shared media clips"""

    additional_candidates: Optional[AdditionalCandidates] = None
    candidates: List[SharedMediaImageCandidate] = []
    scrubber_spritesheet_info_candidates: Optional[ScrubberSpritesheetInfoCandidates] = None

Bases: TypesBaseModel

Additional candidates structure in image_versions2

Source code in aiograpi/types.py
248
249
250
251
252
253
class AdditionalCandidates(TypesBaseModel):
    """Additional candidates structure in image_versions2"""

    first_frame: Optional[SharedMediaImageCandidate] = None
    igtv_first_frame: Optional[SharedMediaImageCandidate] = None
    smart_frame: Optional[SharedMediaImageCandidate] = None

Bases: TypesBaseModel

Spritesheet information for video scrubbing

Source code in aiograpi/types.py
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
class ScrubberSpritesheetInfo(TypesBaseModel):
    """Spritesheet information for video scrubbing"""

    file_size_kb: int
    max_thumbnails_per_sprite: int
    rendered_width: int
    sprite_height: int
    sprite_urls: List[str]
    sprite_width: int
    thumbnail_duration: float
    thumbnail_height: int
    thumbnail_width: int
    thumbnails_per_row: int
    total_thumbnail_num_per_sprite: int
    video_length: float

Bases: TypesBaseModel

Container for spritesheet information candidates

Source code in aiograpi/types.py
242
243
244
245
class ScrubberSpritesheetInfoCandidates(TypesBaseModel):
    """Container for spritesheet information candidates"""

    default: ScrubberSpritesheetInfo

Bases: TypesBaseModel

Source code in aiograpi/types.py
588
589
590
591
592
class Collection(TypesBaseModel):
    id: str
    name: str
    type: str
    media_count: int

Bases: TypesBaseModel

Source code in aiograpi/types.py
595
596
597
598
599
600
601
602
603
604
class Comment(TypesBaseModel):
    pk: str
    text: str
    user: UserShort
    created_at_utc: datetime
    content_type: str
    status: str
    replied_to_comment_id: Optional[str] = None
    has_liked: Optional[bool] = None
    like_count: Optional[int] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
class Location(TypesBaseModel):
    pk: Optional[int] = None
    name: str
    phone: Optional[str] = ""
    website: Optional[str] = ""
    category: Optional[str] = ""
    hours: Optional[dict] = {}  # opening hours
    address: Optional[str] = ""
    city: Optional[str] = ""
    zip: Optional[str] = ""
    lng: Optional[float] = None
    lat: Optional[float] = None
    external_id: Optional[int] = None
    external_id_source: Optional[str] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
607
608
609
610
611
class Hashtag(TypesBaseModel):
    id: str
    name: str
    media_count: Optional[int] = None
    profile_pic_url: Optional[HttpUrl] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
749
750
751
752
753
754
class Guide(TypesBaseModel):
    id: Optional[str] = None
    title: Optional[str] = None
    description: str
    cover_media: Media
    feedback_item: Optional[dict] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
class Highlight(TypesBaseModel):
    pk: str  # 17895485401104052
    id: str  # highlight:17895485401104052
    latest_reel_media: int
    cover_media: dict
    user: UserShort
    title: str
    created_at: datetime
    is_pinned_highlight: bool
    media_count: int
    media_ids: List[int] = []
    items: List[Story] = []

Bases: TypesBaseModel

Source code in aiograpi/types.py
1077
1078
1079
class Share(TypesBaseModel):
    pk: str
    type: str

Reels And Music Models

Bases: TypesBaseModel

Complete clips metadata structure for Media objects

Source code in aiograpi/types.py
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
class ClipsMetadata(TypesBaseModel):
    """Complete clips metadata structure for Media objects"""

    clips_creation_entry_point: str = "clips"
    featured_label: Optional[str] = None
    is_public_chat_welcome_video: bool = False
    professional_clips_upsell_type: int = 0
    show_tips: Optional[str] = None
    achievements_info: ClipsAchievementsInfo
    additional_audio_info: ClipsAdditionalAudioInfo
    asset_recommendation_info: Optional[dict] = None
    audio_ranking_info: ClipsAudioRankingInfo
    audio_type: str = "original_sounds"
    branded_content_tag_info: ClipsBrandedContentTagInfo
    breaking_content_info: Optional[dict] = None
    breaking_creator_info: Optional[dict] = None
    challenge_info: Optional[dict] = None
    content_appreciation_info: ClipsContentAppreciationInfo
    contextual_highlight_info: Optional[dict] = None
    cutout_sticker_info: List[dict] = []
    disable_use_in_clips_client_cache: bool = False
    external_media_info: Optional[dict] = None
    is_fan_club_promo_video: bool = False
    is_shared_to_fb: Optional[bool] = None
    mashup_info: Optional[ClipsMashupInfo] = None
    merchandising_pill_info: Optional[dict] = None
    music_canonical_id: str
    music_info: Optional[dict] = None
    nux_info: Optional[dict] = None
    original_sound_info: Optional[ClipsOriginalSoundInfo] = None
    originality_info: Optional[dict] = None
    reels_on_the_rise_info: Optional[dict] = None
    reusable_text_attribute_string: Optional[str] = None
    reusable_text_info: Optional[List[ClipsReusableTextInfo]] = None
    shopping_info: Optional[dict] = None
    show_achievements: bool = False
    template_info: Optional[dict] = None
    may_have_template_info: Optional[dict] = None
    viewer_interaction_settings: Optional[dict] = None

Bases: TypesBaseModel

Information about achievements in clips

Source code in aiograpi/types.py
264
265
266
267
268
class ClipsAchievementsInfo(TypesBaseModel):
    """Information about achievements in clips"""

    num_earned_achievements: Optional[int] = None
    show_achievements: bool = False

Bases: TypesBaseModel

Audio reattribution settings

Source code in aiograpi/types.py
271
272
273
274
class AudioReattributionInfo(TypesBaseModel):
    """Audio reattribution settings"""

    should_allow_restore: bool = False

Bases: TypesBaseModel

Additional audio information for clips

Source code in aiograpi/types.py
277
278
279
280
281
class ClipsAdditionalAudioInfo(TypesBaseModel):
    """Additional audio information for clips"""

    additional_audio_username: Optional[str] = None
    audio_reattribution_info: AudioReattributionInfo

Bases: TypesBaseModel

Audio ranking information for clips

Source code in aiograpi/types.py
284
285
286
287
class ClipsAudioRankingInfo(TypesBaseModel):
    """Audio ranking information for clips"""

    best_audio_cluster_id: str

Bases: TypesBaseModel

Branded content tag information for clips

Source code in aiograpi/types.py
290
291
292
293
class ClipsBrandedContentTagInfo(TypesBaseModel):
    """Branded content tag information for clips"""

    can_add_tag: bool = False

Bases: TypesBaseModel

Content appreciation information for clips

Source code in aiograpi/types.py
296
297
298
299
300
class ClipsContentAppreciationInfo(TypesBaseModel):
    """Content appreciation information for clips"""

    enabled: bool = False
    entry_point_container: Optional[str] = None

Bases: TypesBaseModel

Mashup information for clips

Source code in aiograpi/types.py
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
class ClipsMashupInfo(TypesBaseModel):
    """Mashup information for clips"""

    can_toggle_mashups_allowed: bool = False
    formatted_mashups_count: Optional[str] = None
    has_been_mashed_up: bool = False
    has_nonmimicable_additional_audio: bool = False
    is_creator_requesting_mashup: bool = False
    is_light_weight_check: bool = True
    is_light_weight_reuse_allowed_check: bool = False
    is_pivot_page_available: bool = False
    is_reuse_allowed: bool = True
    mashup_type: Optional[str] = None
    mashups_allowed: bool = True
    non_privacy_filtered_mashups_media_count: int = 0
    privacy_filtered_mashups_media_count: Optional[int] = None
    original_media: Optional[dict] = None

Bases: TypesBaseModel

Consumption information for clips original sound

Source code in aiograpi/types.py
322
323
324
325
326
327
328
329
330
class ClipsConsumptionInfo(TypesBaseModel):
    """Consumption information for clips original sound"""

    display_media_id: Optional[str] = None
    is_bookmarked: bool = False
    is_trending_in_clips: bool = False
    should_mute_audio_reason: str = ""
    should_mute_audio_reason_type: Optional[str] = None
    user_notes: Optional[str] = None

Bases: TypesBaseModel

Facebook downstream use xpost metadata for clips

Source code in aiograpi/types.py
333
334
335
336
class ClipsFbDownstreamUseXpostMetadata(TypesBaseModel):
    """Facebook downstream use xpost metadata for clips"""

    downstream_use_xpost_deny_reason: str = "NONE"

Bases: TypesBaseModel

Instagram artist information for clips original sound

Source code in aiograpi/types.py
339
340
341
342
343
344
345
346
347
348
349
350
351
class ClipsIgArtist(TypesBaseModel):
    """Instagram artist information for clips original sound"""

    pk: int
    pk_id: str
    id: str
    username: str
    full_name: str
    is_private: bool = False
    is_verified: bool = False
    profile_pic_id: Optional[str] = None
    profile_pic_url: str
    strong_id__: str

Bases: TypesBaseModel

Original sound information for clips

Source code in aiograpi/types.py
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
class ClipsOriginalSoundInfo(TypesBaseModel):
    """Original sound information for clips"""

    allow_creator_to_rename: bool = True
    audio_asset_id: int
    attributed_custom_audio_asset_id: Optional[int] = None
    can_remix_be_shared_to_fb: bool = True
    can_remix_be_shared_to_fb_expansion: bool = True
    dash_manifest: str
    duration_in_ms: int
    formatted_clips_media_count: Optional[str] = None
    hide_remixing: bool = False
    is_audio_automatically_attributed: bool = False
    is_eligible_for_audio_effects: bool = True
    is_eligible_for_vinyl_sticker: bool = True
    is_explicit: bool = False
    is_original_audio_download_eligible: bool = True
    is_reuse_disabled: bool = False
    is_xpost_from_fb: bool = False
    music_canonical_id: Optional[str] = None
    oa_owner_is_music_artist: bool = False
    original_audio_subtype: str = "default"
    original_audio_title: str = "Original audio"
    original_media_id: int
    progressive_download_url: str
    should_mute_audio: bool = False
    time_created: int
    trend_rank: Optional[int] = None
    previous_trend_rank: Optional[int] = None
    overlap_duration_in_ms: Optional[int] = None
    audio_asset_start_time_in_ms: Optional[int] = None
    ig_artist: ClipsIgArtist
    audio_filter_infos: Optional[List[dict]] = None
    audio_parts: List[dict] = []
    audio_parts_by_filter: List[dict] = []
    consumption_info: ClipsConsumptionInfo
    xpost_fb_creator_info: Optional[dict] = None
    fb_downstream_use_xpost_metadata: ClipsFbDownstreamUseXpostMetadata

Bases: TypesBaseModel

Color information for reusable text in clips

Source code in aiograpi/types.py
394
395
396
397
398
class ClipsReusableTextColor(TypesBaseModel):
    """Color information for reusable text in clips"""

    count: int
    hex_rgba_color: str

Bases: TypesBaseModel

Reusable text information for clips

Source code in aiograpi/types.py
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
class ClipsReusableTextInfo(TypesBaseModel):
    """Reusable text information for clips"""

    alignment: str
    end_time_ms: float
    font_size: float
    height: float
    id: str
    is_animated: bool
    offset_x: float
    offset_y: float
    rotation_degree: float
    scale: float
    start_time_ms: float
    text: str
    text_emphasis_mode: str
    text_format_type: str
    width: float
    z_index: int
    effects: str = ""
    animation: str = ""
    colors: List[ClipsReusableTextColor] = []

Bases: TypesBaseModel

Source code in aiograpi/types.py
477
478
479
480
481
482
483
class ClipsMusicAttributionInfo(TypesBaseModel):
    artist_name: Optional[str] = None
    song_name: Optional[str] = None
    uses_original_audio: Optional[bool] = None
    should_mute_audio: Optional[bool] = None
    should_mute_audio_reason: Optional[str] = None
    audio_id: Optional[str] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
class Track(TypesBaseModel):
    id: str
    title: str
    subtitle: str
    display_artist: str
    audio_cluster_id: int
    music_canonical_id: Optional[str] = None
    artist_id: Optional[int] = None
    cover_artwork_uri: Optional[HttpUrl] = None
    cover_artwork_thumbnail_uri: Optional[HttpUrl] = None
    progressive_download_url: Optional[HttpUrl] = None
    fast_start_progressive_download_url: Optional[HttpUrl] = None
    reactive_audio_download_url: Optional[HttpUrl] = None
    highlight_start_times_in_ms: List[int]
    is_explicit: bool
    dash_manifest: str
    uri: Optional[HttpUrl] = None
    has_lyrics: bool
    audio_asset_id: int
    duration_in_ms: int
    dark_message: Optional[str] = None
    allows_saving: bool
    territory_validity_periods: dict

Story Models

Bases: TypesBaseModel

Source code in aiograpi/types.py
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
class Story(TypesBaseModel):
    pk: str
    id: str
    code: str
    taken_at: datetime
    imported_taken_at: Optional[datetime] = None
    media_type: int
    product_type: Optional[str] = ""
    thumbnail_url: Optional[HttpUrl] = None
    user: UserShort
    video_url: Optional[HttpUrl] = None  # for Video and IGTV
    video_duration: Optional[float] = 0.0  # for Video and IGTV
    sponsor_tags: List[UserShort]
    is_paid_partnership: Optional[bool] = False
    mentions: List[StoryMention]
    links: List[StoryLink]
    hashtags: List[StoryHashtag]
    locations: List[StoryLocation]
    stickers: List[StorySticker]
    medias: List[StoryMedia] = []
    polls: List[StoryPoll] = []

Bases: TypesBaseModel

Source code in aiograpi/types.py
614
615
616
617
618
619
620
class StoryMention(TypesBaseModel):
    user: UserShort
    x: Optional[float] = None
    y: Optional[float] = None
    width: Optional[float] = None
    height: Optional[float] = None
    rotation: Optional[float] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
class StoryMedia(TypesBaseModel):
    # Instagram does not return the feed_media object when requesting story,
    # so you will have to make an additional request to get media and this is overhead:
    # media: Media
    x: float = 0.5
    y: float = 0.4997396
    z: float = 0
    width: float = 0.8
    height: float = 0.60572916
    rotation: float = 0.0
    is_pinned: Optional[bool] = None
    is_hidden: Optional[bool] = None
    is_sticker: Optional[bool] = None
    is_fb_sticker: Optional[bool] = None
    media_pk: int
    user_id: Optional[int] = None
    product_type: Optional[str] = None
    media_code: Optional[str] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
643
644
645
646
647
648
649
class StoryHashtag(TypesBaseModel):
    hashtag: Hashtag
    x: Optional[float] = None
    y: Optional[float] = None
    width: Optional[float] = None
    height: Optional[float] = None
    rotation: Optional[float] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
652
653
654
655
656
657
658
class StoryLocation(TypesBaseModel):
    location: Location
    x: Optional[float] = None
    y: Optional[float] = None
    width: Optional[float] = None
    height: Optional[float] = None
    rotation: Optional[float] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
661
662
663
664
665
class StoryStickerLink(TypesBaseModel):
    url: HttpUrl
    link_title: Optional[str] = None
    link_type: Optional[str] = None
    display_url: Optional[str] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
668
669
670
671
672
673
674
675
676
677
678
class StorySticker(TypesBaseModel):
    id: Optional[str] = None
    type: Optional[str] = "gif"
    x: float
    y: float
    z: Optional[int] = 1000005
    width: float
    height: float
    rotation: Optional[float] = 0.0
    story_link: Optional[StoryStickerLink] = None
    extra: Optional[dict] = {}

Bases: TypesBaseModel

Source code in aiograpi/types.py
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
class StoryPoll(TypesBaseModel):
    id: Optional[str] = None
    type: Optional[str] = "poll"
    x: float
    y: float
    z: Optional[int] = 0
    width: float
    height: float
    rotation: Optional[float] = 0.0
    is_multi_option: Optional[bool] = True
    is_shared_result: Optional[bool] = False
    viewer_can_vote: Optional[bool] = True
    finished: Optional[bool] = False
    color: Optional[str] = "black"
    poll_type: Optional[str] = ""
    question: str
    options: list
    extra: Optional[dict] = {}

Bases: TypesBaseModel

Source code in aiograpi/types.py
701
702
703
704
705
class StoryBuild(TypesBaseModel):
    mentions: List[StoryMention]
    path: FilePath
    paths: List[FilePath] = []
    stickers: List[StorySticker] = []

Bases: TypesBaseModel

Source code in aiograpi/types.py
708
709
710
711
712
713
714
715
class StoryLink(TypesBaseModel):
    webUri: HttpUrl
    x: float = 0.5126011
    y: float = 0.5168225
    z: float = 0.0
    width: float = 0.50998676
    height: float = 0.25875
    rotation: float = 0.0

Bases: TypesBaseModel

Source code in aiograpi/types.py
741
742
743
744
745
746
class StoryArchiveDay(TypesBaseModel):
    id: str
    timestamp: datetime
    media_count: int
    reel_type: str
    latest_reel_media: Optional[int] = None

Direct Models

Bases: TypesBaseModel

Source code in aiograpi/types.py
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
class DirectThread(TypesBaseModel):
    pk: str  # thread_v2_id, e.g. 17898572618026348
    id: str  # thread_id, e.g. 340282366841510300949128268610842297468
    messages: List[DirectMessage]
    users: List[UserShort]
    inviter: Optional[UserShort] = None
    left_users: List[UserShort] = []
    admin_user_ids: list
    last_activity_at: datetime
    muted: bool
    is_pin: Optional[bool] = None
    named: bool
    canonical: bool
    pending: bool
    archived: bool
    thread_type: str
    thread_title: str
    folder: int
    vc_muted: bool
    is_group: bool
    mentions_muted: bool
    approval_required_for_new_members: bool
    input_mode: int
    business_thread_folder: Optional[int] = None
    read_state: Optional[int] = None
    is_close_friend_thread: bool = False
    assigned_admin_id: Optional[int] = None
    shh_mode_enabled: Optional[bool] = None
    last_seen_at: Dict[str, LastSeenInfo] = {}

    def is_seen(self, user_id: str):
        """Have I seen this thread?
        :param user_id: You account user_id
        """
        user_id = str(user_id)
        if user_id not in self.last_seen_at:
            return False
        own_timestamp = self.last_seen_at[user_id].timestamp.timestamp()
        timestamps = [
            (v.timestamp.timestamp() - own_timestamp) > 0 for k, v in self.last_seen_at.items() if k != user_id
        ]
        return not any(timestamps)

is_seen(user_id)

Have I seen this thread? :param user_id: You account user_id

Source code in aiograpi/types.py
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
def is_seen(self, user_id: str):
    """Have I seen this thread?
    :param user_id: You account user_id
    """
    user_id = str(user_id)
    if user_id not in self.last_seen_at:
        return False
    own_timestamp = self.last_seen_at[user_id].timestamp.timestamp()
    timestamps = [
        (v.timestamp.timestamp() - own_timestamp) > 0 for k, v in self.last_seen_at.items() if k != user_id
    ]
    return not any(timestamps)

Bases: TypesBaseModel

Source code in aiograpi/types.py
 993
 994
 995
 996
 997
 998
 999
1000
1001
class DirectShortThread(TypesBaseModel):
    id: str
    users: List[UserShort]
    named: bool
    thread_title: str
    pending: bool
    thread_type: str
    viewer_id: str
    is_group: bool

Bases: TypesBaseModel

Source code in aiograpi/types.py
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
class DirectMessage(TypesBaseModel):
    id: str  # e.g. 28597946203914980615241927545176064
    user_id: Optional[str] = None
    thread_id: Optional[int] = None  # e.g. 340282366841710300949128531777654287254
    timestamp: datetime
    item_type: Optional[str] = None
    is_sent_by_viewer: Optional[bool] = None
    is_shh_mode: Optional[bool] = None
    reactions: Optional[MessageReactions] = None
    text: Optional[str] = None
    reply: Optional[ReplyMessage] = None
    link: Optional[MessageLink] = None
    animated_media: Optional[dict] = None
    media: Optional[DirectMedia] = None
    visual_media: Optional[VisualMedia] = None
    media_share: Optional[Media] = None
    reel_share: Optional[dict] = None
    story_share: Optional[dict] = None
    felix_share: Optional[dict] = None
    xma_share: Optional[MediaXma] = None
    generic_xma: Optional[List[MediaXma]] = None
    raw_xma: Optional[dict] = None
    clip: Optional[Media] = None
    placeholder: Optional[dict] = None
    client_context: Optional[str] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
987
988
989
990
class DirectResponse(TypesBaseModel):
    unseen_count: Optional[int] = None
    unseen_count_ts: Optional[int] = None
    status: Optional[str] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
757
758
759
760
761
762
763
class DirectMedia(TypesBaseModel):
    id: str
    media_type: int
    user: Optional[UserShort] = None
    thumbnail_url: Optional[HttpUrl] = None
    video_url: Optional[HttpUrl] = None
    audio_url: Optional[HttpUrl] = None

Bases: TypesBaseModel

Source code in aiograpi/types.py
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
class ReplyMessage(TypesBaseModel):
    id: str
    user_id: Optional[str] = None
    timestamp: datetime
    item_type: Optional[str] = None
    is_sent_by_viewer: Optional[bool] = None
    is_shh_mode: Optional[bool] = None
    text: Optional[str] = None
    link: Optional[dict] = None
    animated_media: Optional[dict] = None
    media: Optional[DirectMedia] = None
    visual_media: Optional[VisualMedia] = None
    media_share: Optional[Media] = None
    reel_share: Optional[dict] = None
    story_share: Optional[dict] = None
    felix_share: Optional[dict] = None
    xma_share: Optional[MediaXma] = None
    generic_xma: Optional[List[MediaXma]] = None
    raw_xma: Optional[dict] = None
    clip: Optional[Media] = None
    placeholder: Optional[dict] = None

Bases: TypesBaseModel

Individual emoji reaction on a direct message

Source code in aiograpi/types.py
766
767
768
769
770
771
772
773
class MessageReaction(TypesBaseModel):
    """Individual emoji reaction on a direct message"""

    timestamp: datetime
    client_context: Optional[str] = None
    sender_id: int
    emoji: str
    super_react_type: str = "none"

Bases: TypesBaseModel

Reactions structure for direct messages

Source code in aiograpi/types.py
776
777
778
779
780
781
class MessageReactions(TypesBaseModel):
    """Reactions structure for direct messages"""

    likes: List[dict] = []  # Structure unknown from current examples
    likes_count: Optional[int] = 0
    emojis: List[MessageReaction] = []

Bases: TypesBaseModel

Link structure for direct messages

Source code in aiograpi/types.py
793
794
795
796
797
798
799
class MessageLink(TypesBaseModel):
    """Link structure for direct messages"""

    text: str
    link_context: LinkContext
    client_context: Optional[str] = None
    mutation_token: Optional[str] = None

Bases: TypesBaseModel

Link context metadata for direct message links

Source code in aiograpi/types.py
784
785
786
787
788
789
790
class LinkContext(TypesBaseModel):
    """Link context metadata for direct message links"""

    link_url: str
    link_title: Optional[str] = ""
    link_summary: Optional[str] = ""
    link_image_url: Optional[str] = ""

Bases: TypesBaseModel

Last seen information for a user in a direct thread

Source code in aiograpi/types.py
810
811
812
813
814
815
816
817
class LastSeenInfo(TypesBaseModel):
    """Last seen information for a user in a direct thread"""

    item_id: str
    timestamp: datetime
    created_at: datetime
    shh_seen_state: dict = {}
    disappearing_messages_seen_state: Optional[DisappearingMessagesSeenState] = None

Bases: TypesBaseModel

Disappearing messages seen state information

Source code in aiograpi/types.py
802
803
804
805
806
807
class DisappearingMessagesSeenState(TypesBaseModel):
    """Disappearing messages seen state information"""

    item_id: str
    timestamp: datetime
    created_at: datetime

Bases: TypesBaseModel

Fallback URL structure for media candidates

Source code in aiograpi/types.py
820
821
822
823
class FallbackUrl(TypesBaseModel):
    """Fallback URL structure for media candidates"""

    url: str

Bases: TypesBaseModel

Image candidate for ephemeral visual media in direct messages

Source code in aiograpi/types.py
826
827
828
829
830
831
832
833
834
class DirectMessageImageCandidate(TypesBaseModel):
    """Image candidate for ephemeral visual media in direct messages"""

    width: int
    height: int
    url: str
    scans_profile: Optional[str] = None
    fallback: Optional[FallbackUrl] = None
    url_expiration_timestamp_us: Optional[datetime] = None

Bases: TypesBaseModel

Image versions for ephemeral visual media in direct messages

Source code in aiograpi/types.py
837
838
839
840
class DirectMessageImageVersions(TypesBaseModel):
    """Image versions for ephemeral visual media in direct messages"""

    candidates: List[DirectMessageImageCandidate] = []

Bases: TypesBaseModel

Individual video version with specific resolution and quality

Source code in aiograpi/types.py
843
844
845
846
847
848
849
850
851
852
853
class VideoVersion(TypesBaseModel):
    """Individual video version with specific resolution and quality"""

    id: Optional[str] = ""
    type: Optional[int] = None
    width: int
    height: int
    url: str
    fallback: Optional[FallbackUrl] = None
    url_expiration_timestamp_us: Optional[datetime] = None
    bandwidth: Optional[int] = 0

Bases: TypesBaseModel

Friendship status information for visual media user

Source code in aiograpi/types.py
856
857
858
859
860
861
862
class FriendshipStatus(TypesBaseModel):
    """Friendship status information for visual media user"""

    blocking: bool = False
    is_messaging_only_blocking: bool = False
    is_messaging_pseudo_blocking: bool = False
    is_unavailable: bool = False

Bases: TypesBaseModel

Complete visual media structure for direct messages

Source code in aiograpi/types.py
921
922
923
924
925
926
927
928
929
930
931
932
933
934
class VisualMedia(TypesBaseModel):
    """Complete visual media structure for direct messages"""

    media: VisualMediaContent
    seen_user_ids: List[str] = []
    seen_count: int = 0
    view_mode: str  # 'replayable', 'permanent', etc.
    replay_expiring_at_us: Optional[int] = None
    reply_type: Optional[str] = None
    url_expire_at_secs: Optional[int] = None
    story_app_attribution: Optional[dict] = None
    playback_duration_secs: Optional[int] = None
    tap_models: List[dict] = []
    expiring_media_action_summary: Optional[ExpiringMediaActionSummary] = None

Bases: TypesBaseModel

Content structure for visual media (can be rich or minimal)

Source code in aiograpi/types.py
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
class VisualMediaContent(TypesBaseModel):
    """Content structure for visual media (can be rich or minimal)"""

    media_type: int  # Always present: 1=image, 2=video
    id: Optional[str] = None
    media_id: Optional[int] = None
    image_versions2: Optional[DirectMessageImageVersions] = None
    video_versions: Optional[List[VideoVersion]] = None
    original_width: Optional[int] = None
    original_height: Optional[int] = None
    user: Optional[VisualMediaUser] = None
    organic_tracking_token: Optional[str] = None
    video_duration: Optional[int] = None
    video_dash_manifest: Optional[str] = None
    is_dash_eligible: Optional[int] = None
    create_mode_attribution: Optional[dict] = None
    creative_config: Optional[dict] = None
    expiring_media_action_summary: Optional[ExpiringMediaActionSummary] = None

Bases: TypesBaseModel

User information in visual media (enhanced UserShort)

Source code in aiograpi/types.py
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
class VisualMediaUser(TypesBaseModel):
    """User information in visual media (enhanced UserShort)"""

    id: str
    strong_id__: Optional[str] = None
    pk: int
    pk_id: str
    full_name: str
    username: str
    account_type: Optional[int] = None
    short_name: Optional[str] = None
    profile_pic_url: str
    is_verified: bool = False
    interop_messaging_user_fbid: Optional[int] = None
    fbid_v2: Optional[int] = None
    has_ig_profile: bool = True
    interop_user_type: Optional[int] = 0
    is_using_unified_inbox_for_direct: bool = False
    is_private: bool = False
    is_creator_agent_enabled: bool = False
    is_creator_automated_response_enabled: bool = False
    friendship_status: Optional[FriendshipStatus] = None
    is_shared_account: bool = False
    is_shared_account_with_messaging_access: bool = False
    ai_agent_banner_type: Optional[str] = None
    is_eligible_for_ai_bot_group_chats: bool = False

Bases: TypesBaseModel

Summary of expiring media actions

Source code in aiograpi/types.py
893
894
895
896
897
898
class ExpiringMediaActionSummary(TypesBaseModel):
    """Summary of expiring media actions"""

    type: str
    timestamp: datetime
    count: int

Notes

Bases: TypesBaseModel

Source code in aiograpi/types.py
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
class Note(TypesBaseModel):
    id: str
    text: str
    user_id: str
    user: UserShort
    audience: int
    created_at: datetime
    expires_at: datetime
    is_emoji_only: bool
    has_translation: bool
    note_style: int