Story
| Method | Return | Description |
|---|---|---|
| user_stories(user_id: str, amount: int = None) | List[Story] | Get list of stories by user_id |
| story_info(story_pk: int, use_cache: bool = True) | Story | Return story info |
| story_delete(story_pk: int) | bool | Delete story |
| story_seen(story_pks: List[int], skipped_story_pks: List[int]) | bool | Mark a story as seen |
| story_pk_from_url(url: str) | int | Get Story (media) PK from URL |
| story_download(story_pk: int, filename: str = "", folder: Path = "") | Path | Download story media by media_type |
| story_download_by_url(url: str, filename: str = "", folder: Path = "") | Path | Download story media using URL to file (mp4 or jpg) |
| story_viewers(story_pk: int, amount: int = 20) | List[UserShort] | List of story viewers (via Private API) |
| story_like(story_id: str, revert: bool = False) | bool | Like a story |
| story_unlike(story_id: str) | bool | Unlike a story |
| archive_story_days(amount: int = 0, include_memories: bool = True) | List[StoryArchiveDay] | Get story archive day shells |
| archive_stories(amount: int = 0) | List[Story] | Get archived stories |
Example:
>>> await cl.story_download(await cl.story_pk_from_url('https://www.instagram.com/stories/example/2581281926631793076/'))
PosixPath('/app/189361307_229642088942817_9180243596650100310_n.mp4')
>>> s = await cl.story_info(2581281926631793076)
>>> await cl.story_download_by_url(s.video_url) # url to mp4 file
PosixPath('/app/189361307_229642088942817_9180243596650100310_n.mp4')
>>> await cl.story_download_by_url(s.thumbnail_url) # URL to jpg file
PosixPath('/app/191260083_2908005872746895_8988438451809588865_n.jpg')
>>> days = await cl.archive_story_days(amount=5)
>>> stories = await cl.archive_stories(amount=10)
Upload Stories
Upload medias to your stories.
The story file should be at 9:16 resolution (e.g. 720x1280). If you have a different resolution, then you need to prepare a file or use the StoryBuilder, which is written about below.
Common arguments:
path- Path to media filecaption- Caption for story (now use to fetch mentions)thumbnail- Thumbnail instead capture from source filementions- Tag profiles in storylocations- Add locations to storylinks- "Swipe Up" links (now use first)hashtags- Add hashtags to storystickers- Add stickers to story
| Method | Return | Description |
|---|---|---|
| photo_upload_to_story(path: Path, caption: str, upload_id: str, mentions: List[Usertag], locations: List[StoryLocation], links: List[StoryLink], hashtags: List[StoryHashtag], stickers: List[StorySticker], extra_data: Dict[str, str] = {}) | Story | Upload photo (Support JPG files) |
| video_upload_to_story(path: Path, caption: str, thumbnail: Path, mentions: List[Usertag], locations: List[StoryLocation], links: List[StoryLink], hashtags: List[StoryHashtag], stickers: List[StorySticker], extra_data: Dict[str, str] = {}) | Story | Upload video (Support MP4 files) |
In extra_data, you can pass additional story settings, for example:
| Method | Type | Description |
|---|---|---|
| audience | String | Publish story for close friends {"audience": "besties"} |
Examples:
from aiograpi import Client
from aiograpi.types import StoryMention, StoryMedia, StoryLink, StoryHashtag
cl = Client()
await cl.login(USERNAME, PASSWORD)
media_pk = await cl.media_pk_from_url('https://www.instagram.com/p/CGgDsi7JQdS/')
media_path = await cl.video_download(media_pk)
example = await cl.user_info_by_username('example')
hashtag = await cl.hashtag_info('dhbastards')
await cl.video_upload_to_story(
media_path,
"Credits @example",
mentions=[StoryMention(user=example, x=0.49892962, y=0.703125, width=0.8333333333333334, height=0.125)],
links=[StoryLink(webUri='https://github.com/subzeroid/aiograpi')],
hashtags=[StoryHashtag(hashtag=hashtag, x=0.23, y=0.32, width=0.5, height=0.22)],
medias=[StoryMedia(media_pk=media_pk, x=0.5, y=0.5, width=0.6, height=0.8)],
)
Build Story to Upload
If you want to format your story correctly (correct resolution, user mentions, etc) use StoryBuilder. StoryBuilder renders media with MoviePy and ffmpeg, so install the optional video dependencies first:
pip install "aiograpi[video]"
pip install --no-deps "moviepy==2.2.1"
MoviePy 2.2.1 currently declares Pillow<12, but aiograpi keeps Pillow>=12.2.0 for security fixes; the --no-deps install keeps the safe Pillow version. Older MoviePy 1.x imports such as moviepy.editor and clip methods such as set_duration, set_position, resize, and subclip are not supported by aiograpi's video helpers.
| Method | Return | Description |
|---|---|---|
| StoryBuilder.build_clip(clip: moviepy.Clip, max_duration: int = 0) | StoryBuild | Build CompositeVideoClip with background and mentioned users. Return MP4 file and mentions with coordinates |
| StoryBuilder.video(max_duration: int = 0) | StoryBuild | Call build_clip(VideoClip, max_duration) |
| StoryBuilder.photo(max_duration: int = 0) | StoryBuild | Call build_clip(ImageClip, max_duration) |
Example:
from aiograpi.types import StoryMention, StoryMedia, StoryLink
from aiograpi.story import StoryBuilder
media_pk = await cl.media_pk_from_url('https://www.instagram.com/p/CGgDsi7JQdS/')
media_path = await cl.video_download(media_pk)
example = await cl.user_info_by_username('example')
buildout = StoryBuilder(
media_path,
'Credits @example',
[StoryMention(user=example)],
Path('/path/to/background_720x1280.jpg')
).video(15) # seconds
await cl.video_upload_to_story(
buildout.path,
"Credits @example",
mentions=buildout.mentions,
links=[StoryLink(webUri='https://github.com/subzeroid/aiograpi')],
medias=[StoryMedia(media_pk=media_pk)]
)
Result:

Photo upload:
await cl.photo_upload_to_story('/app/image.jpg')
Upload photo as video:
buildout = StoryBuilder('/app/image.jpg').photo()
await cl.video_upload_to_story(buildout.path)
Like & unlike story:
pk = await cl.story_pk_from_url("https://instagram.com/stories/purely.anand/2884886531427631361/")
info = (await cl.story_info(pk)).dict()
await cl.story_like(info['id']) # To like story
await cl.story_unlike(info['id']) # To unlike story
# another way to unlike story
await cl.story_like(info['id'], revert=True)
More stories here https://www.instagram.com/wrclive/