Skip to content

[Feature] Add support for uploading Instants (Quick Snaps) #2709

Description

@SkyPlay-Code

Problem to solve

Users cannot interact with Instagram's new "QuickSnaps" feature. There is currently no way to retrieve a user's QuickSnap history, upload a QuickSnap, or configure it for the default "Mutual Followers" audience.

Proposed API

# To retrieve the paginated history of QuickSnaps
cl.quicksnap_history(amount: int = 20) -> dict

# To upload and send a new QuickSnap
cl.quicksnap_send(photo_path: Path, audience: str = "mutual_followers") -> dict

Example usage

from instagrapi import Client

cl = Client()
cl.login("username", "password")

# 1. Retrieve the last 20 QuickSnaps
history = cl.quicksnap_history(amount=20)
print(history)

# 2. Send a new QuickSnap to Mutual Followers
response = cl.quicksnap_send("path/to/snap.jpg", audience="mutual_followers")
print(f"QuickSnap sent successfully. Media ID: {response['media_ids'][0]}")

Why current methods are insufficient

Existing methods like cl.photo_upload_to_direct() or cl.photo_upload_to_story() use different configuration endpoints (such as configure_to_direct or configure_to_story). These endpoints do not route to the QuickSnap pipeline, do not support the "mutual_followers" audience parameter, and do not trigger the 24-hour ephemeral behavior required for QuickSnaps.

Does this require new Instagram endpoint knowledge?

yes

References, logs, HAR, or similar implementations

GLOBAL SESSION & DEVICE IDENTIFIERS

  • Instagram App ID: 567067343352427
  • Target User ID (UID / PK): 123456789
  • Account Username: your_username
  • Session UUID: 3a66a40d-b663-4ab8-8d7c-14d1291f7406
  • Media Upload ID: 102893695060748
  • Device Context: vivo 1819 (Android 11, API Level 30)

PART 1: QUICKSNAP HISTORY PAGINATED QUERY (GRAPHQL)


PART 2: RAW MEDIA INGESTION (RUPLOAD IGPHOTO)

{
  "upload_id": "102893695060748",
  "status": "ok"
}

PART 3: MEDIA CONFIGURATION AND PUBLICATION API

  • Method: POST
  • URL: https://i.instagram.com/api/v1/media/configure_to_quick_snap/
  • Headers:
    • x-ig-client-endpoint: InsightsHostImpl:quick_snap_audience_picker
    • x-ig-nav-chain: DirectInboxFragment:direct_inbox:2:main_direct:1782916129.748:::1782916129.748,QuickSnapUnifiedFragment:quicksnap_unified_fragment:3:button:1782916165.844:::1782916165.844,ConstAnalyticsModule:quick_snap_camera:4:button:1782916165.990:::1782916166.398,InsightsHostImpl:quick_snap_audience_picker:6:button:1782916180.717:::1782916180.717
  • Signed Request Payload (Decoded):
{
  "original_height": "0",
  "original_width": "0",
  "include_e2ee_mentioned_user_list": "1",
  "hide_from_profile_grid": "false",
  "timezone_offset": "19800",
  "source_type": "3",
  "_uid": "123456789",
  "async_publish": "1",
  "device_id": "android-mock_device_id",
  "_uuid": "3a66a40d-b663-4ab8-8d7c-14d1291f7406",
  "audience": "mutual_followers",
  "upload_id": "102893695060748",
  "bottom_camera_dial_selected": "11",
  "publish_id": "1",
  "device": {
    "manufacturer": "vivo",
    "model": "vivo 1819",
    "android_version": 30,
    "android_release": "11"
  }
}
  • Response JSON snippet (Confirming QuickSnap expiration):
{
  "posts": [
    {
      "id": 3931708346854699261,
      "post_client_id": "102893695060748",
      "status": "COMPLETED"
    }
  ],
  "medias": [
    {
      "media_dict": {
        "subtype_name_for_REST__": "XDTQuickSnapMedia",
        "product_type": "quick_snap",
        "audience": "mutual_followers",
        "taken_at": 1782916183,
        "expiring_at": 1783002583
      }
    }
  ]
}

PART 4: MEDIA INTEGRITY / PDQ HASH INFO UPDATE

{
  "_uid": "123456789",
  "_uuid": "3a66a40d-b663-4ab8-8d7c-14d1291f7406",
  "upload_id": "102893695060748",
  "pdq_hash_info": "[{\"pdq_hash\":\"905b28d5556aa54a15ed8c4d14ea60ad2aed749aaaad5ce9bee9704ab75189d3:100\",\"frame_time\":0}]"
}

Technical Update: Part 5 - The Deletion Pipeline (soft_delete)

To complete the full lifecycle mapping for this feature, I also captured the deletion flow. When a user deletes an active QuickSnap, the client does not hit the standard deletion endpoint. Instead, it routes the request through a specific soft_delete endpoint triggered from the quick_snap_archive module.

Endpoint: POST https://i.instagram.com/api/v1/media/{media_id}/soft_delete/

Key Headers:

  • x-ig-client-endpoint: ConstAnalyticsModule:quick_snap_archive

Request Payload:

media_id=<MEDIA_ID>&_uuid=<CLIENT_UUID>

(Sent as standard signed body/form-data)

Server Response:

{
  "did_delete": true,
  "cxp_deep_deletion_global_response": {},
  "cxp_deep_deletion_waterfall_id": "77401009-9e2e-4053-8277-1105586bf225",
  "status": "ok"
}

Proposed API Addition:

def quicksnap_delete(self, media_id: str) -> bool:
    """Soft-deletes an active QuickSnap."""
    media_id = self.media_id(media_id)
    data = {
        "media_id": media_id,
        "_uuid": self.uuid
    }
    result = self.private_request(
        f"media/{media_id}/soft_delete/",
        data=self.with_default_data(data)
    )
    return result.get("did_delete") is True

This should provide everything needed to build out the complete QuickSnap (Instants) module.

QuickSnaps_Docs.md

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions