goinsta

package module
v0.7.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 55 Imported by: 0

README

go-insta

Private Instagram Android API client (app 453.0.0.55.79), rebuilt from device captures on top of Davincible/goinsta. Requests replay the app's TLS fingerprint, headers and attestation.

go get github.com/TheForgotten69/go-insta

Session

A session file holds the device ids, token, password key and the attestation keys (attestation.zca_key_pem, usdid_key_pem, last_uploaded_key_time_ms, usdid_uuid). It is written mode 0600; treat it as a credential.

go run ./cmd/httplog session log_http.txt > login.session.json   # from a capture
IG_PASSWORD=... go run ./cmd/login -user NAME                     # password login (prompts for 2FA)
IG_PASSWORD=... IG_TOTP_SECRET=... go run ./cmd/login -user NAME  # non-interactive 2FA
IG_PASSWORD=... go run ./cmd/login -user NAME -log login.log       # also log every response (holds the token)
go run ./cmd/smoke [-writes] [-highlight] [-reel file.mp4]       # live check

Use

Every call takes a context.Context. Paged endpoints return a *Pager[T]: Next(ctx) loads one page into Items (ErrNoMore at the end), All(ctx) ranges over every item, Collect(ctx, n) gathers up to n.

insta, err := goinsta.ImportSession("login.session.json")
defer insta.ExportSession("login.session.json") // keeps rotated headers

for post, err := range user.Posts().All(ctx) { ... }
followers, err := user.Followers().Collect(ctx, 200)

tray, err := insta.StoryTray(ctx, goinsta.TrayColdStart)
err = insta.LoadReels(ctx, tray.Reels...) // fills unloaded reels, batched

item, err := insta.UploadAlbum(ctx, photos, goinsta.PostOptions{Caption: "hi"})
// Cross-post to Threads, hide counts, and share to the story as a post card.
item, err = insta.UploadPhoto(ctx, img, goinsta.PostOptions{
	ShareToThreads: true, HideLikeCounts: true, HideShareCounts: true, ShareToStory: true,
})
paths, err := item.DownloadTo(ctx, "out/")
err = item.Edit(ctx, goinsta.MediaEdit{Caption: "fixed typo"}) // also DisableComments, SetCountsHidden, Unarchive…

reel, err := insta.UploadReel(ctx, mp4, goinsta.ReelOptions{ // H.264/AAC MP4
	PostOptions: goinsta.PostOptions{Caption: "hi", ShareToStory: true},
	Captions:    true,
	VoiceTranslation: &goinsta.VoiceTranslation{InputLanguage: "fra", Languages: []string{"eng", "spa"}},
}) // every field: docs/reel-fields.md

story, err := insta.UploadStory(ctx, img, goinsta.StoryOptions{LinkPost: item}) // img as is; tapping it opens item
hl, err := insta.CreateHighlight(ctx, "Trips", story) // first item is the cover
err = hl.AddItems(ctx, otherStory)
err = hl.Edit(ctx, goinsta.HighlightEdit{Title: "Trips 2026", Cover: otherStory, Remove: []*goinsta.Item{story}})
err = hl.Archive(ctx) // hidden from the profile; Unarchive shows it again
err = hl.Delete(ctx)

// Analytics (professional accounts).
over, err := insta.Account.InsightsOverview(ctx, goinsta.PeriodLast90Days) // views, reach, interactions
aud, err := insta.Account.InsightsAudience(ctx, goinsta.PeriodThisMonth)   // followers, active times, demographics
in, err := reel.ReelInsights(ctx)                                          // views, watch time, skip rate

Pagers: Timeline(), Reels(), Collections(), Activity(), SearchUsers(), User.Posts/Followers/Following(), Item.Comments(), Collection.Posts(), Account.InsightsContent(), Account.MediaInsightsGrid(), Item.StoryViewers().

One *Instagram can be shared across goroutines; each pager belongs to one. Login must not overlap other requests. Rate-limit waits and, at debug level, every response body go to insta.Logger (an *slog.Logger, default slog.Default()). Set insta.OnSessionChange to persist the session when the server rotates a header.

PLAN.md tracks the remaining work.

Documentation

Index

Constants

View Source
const DefaultRateLimitWait = 8 * time.Minute

Variables

View Source
var (
	PeriodThisWeek      = InsightsPeriod{/* contains filtered or unexported fields */}
	PeriodLast14Days    = InsightsPeriod{/* contains filtered or unexported fields */}
	PeriodThisMonth     = InsightsPeriod{/* contains filtered or unexported fields */}
	PeriodLast60Days    = InsightsPeriod{/* contains filtered or unexported fields */}
	PeriodPreviousMonth = InsightsPeriod{/* contains filtered or unexported fields */}
	PeriodLast90Days    = InsightsPeriod{/* contains filtered or unexported fields */}
	PeriodLast180Days   = InsightsPeriod{/* contains filtered or unexported fields */}
	PeriodLast365Days   = InsightsPeriod{/* contains filtered or unexported fields */}
	PeriodLast2Years    = InsightsPeriod{/* contains filtered or unexported fields */}
	PeriodLifetime      = InsightsPeriod{/* contains filtered or unexported fields */}
)

The periods in the app's picker order, plus LIFETIME, which only an insights deep-link parser accepts.

View Source
var (
	ErrTooManyRequests   = errors.New("too many requests, please wait a few minutes before you try again")
	ErrLoggedOut         = errors.New("you have been logged out, capture a new session")
	ErrLoginRequired     = errors.New("session is not valid, capture a new session")
	ErrChallengeRequired = errors.New("challenge required, resolve it in the app and capture a new session")
	// ErrTwoFactorRequired means the password was accepted but the account has
	// two-factor on; finish with LoginTwoFactor.
	ErrTwoFactorRequired  = errors.New("two-factor required, finish with LoginTwoFactor")
	ErrCheckpointRequired = errors.New("checkpoint required, resolve it in the app and capture a new session")
	ErrBadPassword        = errors.New("the password you entered is incorrect")
	ErrSessionInvalid     = errors.New("session is missing authorization or user id")

	ErrInvalidImage       = errors.New("invalid file type, please use a jpeg or webp image")
	ErrInvalidVideo       = errors.New("invalid video, please use an mp4 with a video track")
	ErrNoHighlightItems   = errors.New("a highlight needs at least one story item")
	ErrNotHighlight       = errors.New("reel is not a highlight")
	ErrCarouselMediaLimit = errors.New("an album takes 2 to 20 photos")

	ErrPrivateAccount = errors.New("account is private and not followed")
	ErrNoMore         = errors.New("no more posts available, page end has been reached")
	ErrMediaDeleted   = errors.New("sorry, this media has been deleted")
	ErrNoMedia        = errors.New("failed to download, no media found")
	ErrEmptyResponse  = errors.New("empty response body")
)
View Source
var ErrPasswordKeyUnknown = fmt.Errorf("password encryption key unknown; fetch it from a response first")

ErrPasswordKeyUnknown means no ig-set-password-encryption-* headers have been seen yet; make one request first (or import a session that carries them).

View Source
var (
	Waydroid = Device{
		Manufacturer:     "Waydroid/waydroid",
		Model:            "WayDroid x86_64 Device",
		CodeName:         "waydroid_x86_64",
		AndroidVersion:   33,
		AndroidRelease:   13,
		ScreenDpi:        "243dpi",
		ScreenResolution: "3839x2160",
		Chipset:          "unknown",
	}
)

Functions

func MediaIDFromShortID

func MediaIDFromShortID(code string) (string, error)

MediaIDFromShortID decodes a post shortcode (the /p/<code>/ part of a URL).

func TOTP

func TOTP(secret string, t time.Time) (string, error)

TOTP returns the current 6-digit RFC 6238 code for a base32 secret, as shown when enabling an authenticator app (spaces and lowercase are accepted). This is the code the 2FA login step submits; verification_method 3 is TOTP.

Types

type APIError

type APIError struct {
	StatusCode int    `json:"-"`
	Endpoint   string `json:"-"`
	Status     string `json:"status"`
	Message    string `json:"message"`
	ErrorType  string `json:"error_type"`
	ErrorTitle string `json:"error_title"`
	ErrorBody  string `json:"error_body"`
	Payload    struct {
		Message string `json:"message"`
	} `json:"payload"`
	DebugInfo struct {
		Message   string `json:"string"`
		Retriable bool   `json:"retriable"`
		Type      string `json:"type"`
	} `json:"debug_info"`
}

APIError is a non-2xx response that maps to none of the sentinel errors.

func (*APIError) Error

func (e *APIError) Error() string

type Account

type Account struct {
	ID                         Int64        `json:"pk"`
	Username                   string       `json:"username"`
	FullName                   string       `json:"full_name"`
	Biography                  string       `json:"biography"`
	ProfilePicURL              string       `json:"profile_pic_url"`
	Email                      string       `json:"email"`
	PhoneNumber                string       `json:"phone_number"`
	IsBusiness                 bool         `json:"is_business"`
	Gender                     int          `json:"gender"`
	ProfilePicID               string       `json:"profile_pic_id"`
	CanSeeOrganicInsights      bool         `json:"can_see_organic_insights"`
	ShowInsightsTerms          bool         `json:"show_insights_terms"`
	HasAnonymousProfilePicture bool         `json:"has_anonymous_profile_picture"`
	IsPrivate                  bool         `json:"is_private"`
	IsUnpublished              bool         `json:"is_unpublished"`
	AllowedCommenterType       string       `json:"allowed_commenter_type"`
	IsVerified                 bool         `json:"is_verified"`
	MediaCount                 int          `json:"media_count"`
	FollowerCount              int          `json:"follower_count"`
	FollowingCount             int          `json:"following_count"`
	GeoMediaCount              int          `json:"geo_media_count"`
	ExternalURL                string       `json:"external_url"`
	HasBiographyTranslation    bool         `json:"has_biography_translation"`
	ExternalLynxURL            string       `json:"external_lynx_url"`
	HdProfilePicURLInfo        PicURLInfo   `json:"hd_profile_pic_url_info"`
	HdProfilePicVersions       []PicURLInfo `json:"hd_profile_pic_versions"`
	UsertagsCount              int          `json:"usertags_count"`
	HasChaining                bool         `json:"has_chaining"`
	ReelAutoArchive            string       `json:"reel_auto_archive"`
	PublicEmail                string       `json:"public_email"`
	PublicPhoneNumber          string       `json:"public_phone_number"`
	PublicPhoneCountryCode     string       `json:"public_phone_country_code"`
	ContactPhoneNumber         string       `json:"contact_phone_number"`
	Byline                     string       `json:"byline"`
	SocialContext              string       `json:"social_context,omitempty"`
	SearchSocialContext        string       `json:"search_social_context,omitempty"`
	MutualFollowersCount       float64      `json:"mutual_followers_count"`
	LatestReelMedia            Int64        `json:"latest_reel_media,omitempty"`
	CityID                     Int64        `json:"city_id"`
	CityName                   string       `json:"city_name"`
	AddressStreet              string       `json:"address_street"`
	DirectMessaging            string       `json:"direct_messaging"`
	Latitude                   float64      `json:"latitude"`
	Longitude                  float64      `json:"longitude"`
	Category                   string       `json:"category"`
	BusinessContactMethod      string       `json:"business_contact_method"`
	IsCallToActionEnabled      bool         `json:"is_call_to_action_enabled"`
	FbPageCallToActionID       string       `json:"fb_page_call_to_action_id"`
	Zip                        string       `json:"zip"`
	AllowContactsSync          bool         `json:"allow_contacts_sync"`
	CanBoostPost               bool         `json:"can_boost_post"`
	// contains filtered or unexported fields
}

func (*Account) AcceptInsightsTerms added in v0.7.0

func (account *Account) AcceptInsightsTerms(ctx context.Context) error

AcceptInsightsTerms accepts the insights terms (Account.ShowInsightsTerms).

func (*Account) BlockedUsers added in v0.7.0

func (account *Account) BlockedUsers(ctx context.Context) ([]BlockedUser, error)

BlockedUsers returns every account the account has blocked.

func (*Account) CommentInsightsOptIn added in v0.7.0

func (account *Account) CommentInsightsOptIn(ctx context.Context) (bool, error)

CommentInsightsOptIn reports whether the account opted in to comment summaries.

func (*Account) FanClubInsights added in v0.7.0

func (account *Account) FanClubInsights(ctx context.Context, fanClubID string, day time.Time) (json.RawMessage, error)

FanClubInsights loads the subscriptions (fan club) dashboard for day; a zero day means today, as the app asks.

func (*Account) InsightsAudience added in v0.7.0

func (account *Account) InsightsAudience(ctx context.Context, period InsightsPeriod) (*AccountInsightsAudience, error)

InsightsAudience loads the audience (followers) tab. A custom period reads the follower snapshot, as the redesigned app does.

func (account *Account) InsightsBioLinks(ctx context.Context, period InsightsPeriod) (*AccountInsightsBioLinks, error)

InsightsBioLinks loads the bio link taps for the period.

func (*Account) InsightsContent added in v0.7.0

func (account *Account) InsightsContent(opts ContentInsightsOptions) *Pager[ContentInsightsItem]

InsightsContent pages through the content tab.

func (*Account) InsightsHome added in v0.7.0

func (account *Account) InsightsHome(ctx context.Context, opts InsightsHomeOptions) (*AccountInsightsHome, error)

InsightsHome loads the dashboard's home tab.

func (*Account) InsightsMediaComponent added in v0.7.0

func (account *Account) InsightsMediaComponent(ctx context.Context, mediaID string) (string, error)

InsightsMediaComponent returns the Bloks UI bundle of one post's insights carousel card. mediaID is the post's pk.

func (*Account) InsightsOverview added in v0.7.0

func (account *Account) InsightsOverview(ctx context.Context, period InsightsPeriod) (*AccountInsightsOverview, error)

InsightsOverview loads the overview tab.

func (account *Account) InsightsPreviousBioLinks(period InsightsPeriod) *Pager[BioLinkInsights]

InsightsPreviousBioLinks pages through the links removed from the bio.

func (*Account) InsightsViewerState added in v0.7.0

func (account *Account) InsightsViewerState(ctx context.Context, period InsightsPeriod, includePremium bool) (*AccountInsightsViewerState, error)

InsightsViewerState loads the dashboard's eligibility state, with the premium (Meta Verified) insights when includePremium is set.

func (*Account) MediaInsightsGrid added in v0.7.0

func (account *Account) MediaInsightsGrid(product MediaProduct) *Pager[json.RawMessage]

MediaInsightsGrid pages through the account's media of one kind with their reach; each item is the raw media node. Stories cover the last day, other kinds their lifetime.

func (*Account) OptInStoriesInsightsMonthBack added in v0.7.0

func (account *Account) OptInStoriesInsightsMonthBack(ctx context.Context) error

OptInStoriesInsightsMonthBack turns on story insights for the past month. The app sends it as a GET.

func (*Account) PendingFollowRequests added in v0.7.0

func (account *Account) PendingFollowRequests(ctx context.Context) ([]*User, error)

PendingFollowRequests returns the users waiting for the (private) account to accept their follow request; first page only, as the app's request screen.

func (*Account) ReelSettings

func (account *Account) ReelSettings(ctx context.Context) (*ReelSettings, error)

func (*Account) ResetStoriesInsightsOptIn added in v0.7.0

func (account *Account) ResetStoriesInsightsOptIn(ctx context.Context) error

ResetStoriesInsightsOptIn resets the story insights opt-in; a GET too.

func (*Account) RestrictedUsers

func (account *Account) RestrictedUsers(ctx context.Context) ([]*User, error)

func (*Account) SetCommentInsightsOptIn added in v0.7.0

func (account *Account) SetCommentInsightsOptIn(ctx context.Context, optedIn bool) error

func (*Account) SetStoryAutoArchive

func (account *Account) SetStoryAutoArchive(ctx context.Context, on bool) error

func (*Account) SetTranslationSettings added in v0.7.0

func (account *Account) SetTranslationSettings(ctx context.Context, u TranslationCreationUpdate) error

SetTranslationSettings saves u, as the app's AI voice translation screen does.

func (*Account) Stories

func (account *Account) Stories(ctx context.Context) (*Reel, error)

func (*Account) SubscriptionInsights added in v0.7.0

func (account *Account) SubscriptionInsights(ctx context.Context) (*SubscriptionInsights, error)

func (*Account) SuggestedUsers

func (account *Account) SuggestedUsers(ctx context.Context) ([]*User, error)

SuggestedUsers is the "Suggested for you" list (discover/ayml) on the own profile.

func (*Account) Sync

func (account *Account) Sync(ctx context.Context) error

func (*Account) TranslationSettings added in v0.7.0

func (account *Account) TranslationSettings(ctx context.Context) (*TranslationSettings, error)

TranslationSettings reads the account's translation preferences.

func (*Account) UpdateCloseFriends added in v0.7.0

func (account *Account) UpdateCloseFriends(ctx context.Context, add, remove []*User) error

UpdateCloseFriends adds and removes users on the account's close-friends list.

func (*Account) User

func (account *Account) User() *User

type AccountInsightsAudience added in v0.7.0

type AccountInsightsAudience struct {
	Followers               Metric          `json:"follower_count"`
	FollowersDelta          InsightsDelta   `json:"follower_growth_delta"`
	ActiveFollowersOverTime TimeSeries      `json:"active_followers_over_time"`
	ActiveTimes             ActiveTimes     `json:"active_times"`
	Age                     AgeDemographics `json:"age_demographics"`
	TopCities               []AudienceShare `json:"top_cities"`
	TopCountries            []AudienceShare `json:"top_countries"`
	// Empty or null on every account tried, so the shapes are unknown.
	Genders              json.RawMessage `json:"gender_demographics"`
	TopLanguages         json.RawMessage `json:"top_languages"`
	NetFollowersOverTime json.RawMessage `json:"net_followers_over_time"` // {follows, unfollows, overall}
	FollowerGrowth       json.RawMessage `json:"follower_growth"`
	Tip                  json.RawMessage `json:"audience_tip"`
	ActiveTimesTip       json.RawMessage `json:"active_times_tip"`
}

AccountInsightsAudience is the audience tab: followers, their activity and demographics.

type AccountInsightsBioLinks struct {
	Taps             Metric
	PageViews        Metric
	Links            []BioLinkInsights
	HasPreviousLinks bool
}

AccountInsightsBioLinks are the link taps on the profile's bio links.

type AccountInsightsHome added in v0.7.0

type AccountInsightsHome struct {
	Layout                   string // HERO_PLUS_TWO, …
	Tiles                    []InsightsTile
	Tools                    []InsightsTool
	HasAccountStatusWarnings bool
	NextStepsBloks           string // the next-steps cards' Bloks UI bundle
	MetaOneEligibility       string // Meta Verified upsell: INELIGIBLE, …
}

AccountInsightsHome is the home tab.

type AccountInsightsOverview added in v0.7.0

type AccountInsightsOverview struct {
	Views                     ViewsCount            `json:"account_views_count"`
	ViewsByContentType        ContentTypeBreakdown  `json:"account_views_by_content_type"`
	Viewers                   Metric                `json:"viewers_or_reach"`
	FollowerViews             Metric                `json:"follower_views"`
	NonFollowerViews          Metric                `json:"non_follower_views"`
	ViewsOverTime             TimeSeries            `json:"views_over_time"`
	ViewersOverTime           TimeSeries            `json:"viewers_over_time"`
	FollowerViewsOverTime     TimeSeries            `json:"follower_views_over_time"`
	NonFollowerViewsOverTime  TimeSeries            `json:"non_follower_views_over_time"`
	Interactions              InteractionsCount     `json:"interactions_count"`
	InteractionsByContentType InteractionsBreakdown `json:"interactions_by_content_type"`
	ProfileVisits             Metric                `json:"profile_visits"`
	BioLinkTaps               Metric                `json:"bio_link_taps"`
	BusinessAddressTaps       Metric                `json:"business_address_taps"`
	LinkPageViews             Metric                `json:"link_page_views"`
	// Null on every account tried, so the shapes are unknown.
	FollowerGrowth json.RawMessage `json:"follower_growth"`
	Tip            json.RawMessage `json:"overview_tip"`
}

AccountInsightsOverview is the overview tab: views, reach and interactions, split by follower and content type.

type AccountInsightsViewerState added in v0.7.0

type AccountInsightsViewerState struct {
	IsCXUser          bool            `json:"is_cx_user"`
	CXInsightsEnabled bool            `json:"cx_insights_enabled"`
	PremiumInsights   json.RawMessage `json:"premium_insights"` // null without Meta Verified
}

AccountInsightsViewerState is the dashboard's eligibility state.

type ActiveSlot added in v0.7.0

type ActiveSlot struct {
	Day   int     `json:"day"`
	Hour  int     `json:"hour"`
	Value float64 `json:"value"`
}

type ActiveTimes added in v0.7.0

type ActiveTimes struct {
	Slots    []ActiveSlot    `json:"slots"`
	TopSlots json.RawMessage `json:"top_slots"`
}

ActiveTimes is when followers are on Instagram, in 3-hour slots per weekday.

type Activity

type Activity struct {
	*Pager[RecentItems]
	Badges ActivityBadges
}

Activity pages the notifications inbox; Items holds the page's priority, new and old stories, Badges the badge counts of the last page. The first page marks the inbox as seen, as the app does.

type ActivityBadges added in v0.1.1

type ActivityBadges struct {
	Total           int
	ActivityFeedDot int
	BrandedContent  int
	Campaign        int
	CommentLikes    int
	Comments        int
	Fundraiser      int
	Likes           int
	MediaToApprove  int
	NewPosts        int
	Promotional     int
	Relationships   int
	Shopping        int
	StoryMentions   int
	UserTags        int
}

ActivityBadges decodes badging_info.badge_count_breakdown, a list of {badge_use_case_id, count}.

func (*ActivityBadges) UnmarshalJSON added in v0.1.1

func (b *ActivityBadges) UnmarshalJSON(data []byte) error

type AgeDemographics added in v0.7.0

type AgeDemographics struct {
	Entries []AgeShare `json:"entries"`
}

type AgeShare added in v0.7.0

type AgeShare struct {
	AgeRange        string  `json:"age_range"` // 13-17 … 65+
	Percentage      float64 `json:"percentage"`
	MenPercentage   float64 `json:"men_percentage"`
	WomenPercentage float64 `json:"women_percentage"`
	OtherPercentage float64 `json:"other_percentage"`
}

type Attestation

type Attestation struct {

	// payload.plugins.bat; defaults match the capture.
	BatteryLevel int
	BatteryState string
	// contains filtered or unexported fields
}

Attestation reproduces the x-meta-zca and x-meta-usdid headers the app signs at launch, using the device keys already registered for this session. It does not register anything new: keyHash and lastUploadedKeyTimeMs stay the values the device uploaded, carried over from the capture.

func NewAttestation

func NewAttestation(c AttestationConfig) (*Attestation, error)

func (*Attestation) USDID

func (a *Attestation) USDID(now time.Time) (string, error)

USDID builds the x-meta-usdid value "uuid.expiry.spki.sig", signed over the first three fields. The app re-signs with a fresh one-hour expiry each launch.

func (*Attestation) ZCA

func (a *Attestation) ZCA(now time.Time) (string, error)

ZCA builds the x-meta-zca value. hash is base64url(sha256(time)); dataToSign is signed by the zca key (verified against two captures).

type AttestationConfig

type AttestationConfig = httplog.AttestationKeys

type Audience added in v0.6.0

type Audience string

Audience is who sees the Reel.

const (
	AudienceDefault         Audience = "default"
	AudienceCloseFriends    Audience = "besties"
	AudienceFollowersOnly   Audience = "followers_only"
	AudienceMutualFollowers Audience = "mutual_followers"
	AudienceOnlyMe          Audience = "only_me"
)

type AudienceShare added in v0.7.0

type AudienceShare struct {
	ID           string          `json:"id"`
	Name         string          `json:"name"`
	DisplayValue string          `json:"display_value"`
	Percentage   float64         `json:"percentage"`
	Segments     json.RawMessage `json:"segments"`
}

AudienceShare is a city or country; "--" names a slot without data.

type BioLinkInsights added in v0.7.0

type BioLinkInsights struct {
	ID         string `json:"id"`
	Title      string `json:"title"`
	DisplayURL string `json:"display_url"`
	ImageURL   string `json:"image_url"`
	Taps       Metric `json:"taps"`
}

BioLinkInsights is one bio link and its taps.

type BlockedUser added in v0.7.0

type BlockedUser struct {
	UserID        Int64  `json:"user_id"`
	Username      string `json:"username"`
	FullName      string `json:"full_name"`
	ProfilePicURL string `json:"profile_pic_url"`
	BlockedAt     Int64  `json:"block_at"`
}

BlockedUser is one entry of the account's blocked list.

type Candidate

type Candidate struct {
	Width        int    `json:"width"`
	Height       int    `json:"height"`
	URL          string `json:"url"`
	ScansProfile string `json:"scans_profile"`
}

type Caption

type Caption struct {
	// can be both string or int
	ID              any    `json:"pk"`
	UserID          Int64  `json:"user_id"`
	Text            string `json:"text"`
	Type            int    `json:"type"`
	CreatedAt       Int64  `json:"created_at"`
	CreatedAtUtc    Int64  `json:"created_at_utc"`
	ContentType     string `json:"content_type"`
	Status          string `json:"status"`
	BitFlags        int    `json:"bit_flags"`
	User            User   `json:"user"`
	DidReportAsSpam bool   `json:"did_report_as_spam"`
	MediaID         Int64  `json:"media_id"`
	HasTranslation  bool   `json:"has_translation"`
}

type Collection

type Collection struct {
	ID         string `json:"collection_id"`
	MediaCount int    `json:"collection_media_count"`
	Name       string `json:"collection_name"`
	Type       string `json:"collection_type"`
	Cover      struct {
		ID             string    `json:"id"`
		Images         Images    `json:"image_versions2"`
		OriginalWidth  int       `json:"original_width"`
		OriginalHeight int       `json:"original_height"`
		MediaType      MediaType `json:"media_type"`
	} `json:"cover_media"`
	// contains filtered or unexported fields
}

func (*Collection) IsAuto

func (c *Collection) IsAuto() bool

IsAuto reports whether this is one of Instagram's automatic collections (such as the all-media collection), which are read from a different endpoint than a user-created one.

func (*Collection) Posts

func (c *Collection) Posts() *Pager[*Item]

Posts pages the saved media in the collection.

type Comment

type Comment struct {
	ID                             json.Number `json:"pk"`
	Text                           string      `json:"text"`
	Type                           any         `json:"type"`
	User                           User        `json:"user"`
	UserID                         Int64       `json:"user_id"`
	BitFlags                       int         `json:"bit_flags"`
	ChildCommentCount              int         `json:"child_comment_count"`
	CommentIndex                   int         `json:"comment_index"`
	CommentLikeCount               int         `json:"comment_like_count"`
	ContentType                    string      `json:"content_type"`
	CreatedAt                      Int64       `json:"created_at"`
	CreatedAtUtc                   Int64       `json:"created_at_utc"`
	DidReportAsSpam                bool        `json:"did_report_as_spam"`
	HasLikedComment                bool        `json:"has_liked_comment"`
	InlineComposerDisplayCondition string      `json:"inline_composer_display_condition"`
	OtherPreviewUsers              []*User     `json:"other_preview_users"`
	PreviewChildComments           []*Comment  `json:"preview_child_comments"`
	NextMaxChildCursor             string      `json:"next_max_child_cursor,omitempty"`
	HasMoreTailChildComments       bool        `json:"has_more_tail_child_comments,omitempty"`
	NextMinChildCursor             string      `json:"next_min_child_cursor,omitempty"`
	HasMoreHeadChildComments       bool        `json:"has_more_head_child_comments,omitempty"`
	NumTailChildComments           int         `json:"num_tail_child_comments,omitempty"`
	NumHeadChildComments           int         `json:"num_head_child_comments,omitempty"`
	ShareEnabled                   bool        `json:"share_enabled"`
	IsCovered                      bool        `json:"is_covered"`
	PrivateReplyStatus             Int64       `json:"private_reply_status"`
	SupporterInfo                  struct {
		SupportTier string `json:"support_tier"`
		BadgesCount int    `json:"badges_count"`
	} `json:"supporter_info"`
	Status string `json:"status"`
	// contains filtered or unexported fields
}

func (*Comment) Delete

func (c *Comment) Delete(ctx context.Context) error

func (*Comment) Like

func (c *Comment) Like(ctx context.Context) error

func (*Comment) Pin added in v0.7.0

func (c *Comment) Pin(ctx context.Context) error

Pin pins the comment to the top of its post; Unpin undoes it.

func (*Comment) Replies

func (c *Comment) Replies(ctx context.Context) ([]*Comment, error)

Replies loads the comment's thread (inline_child_comments).

func (*Comment) Unlike

func (c *Comment) Unlike(ctx context.Context) error

func (*Comment) Unpin added in v0.7.0

func (c *Comment) Unpin(ctx context.Context) error

type Comments

type Comments struct {
	*Pager[*Comment]

	Count   Int64
	Caption Caption
	// contains filtered or unexported fields
}

type ContentInsightsItem added in v0.7.0

type ContentInsightsItem struct {
	Thumbnail ContentInsightsThumbnail `json:"thumbnail"`
	Metrics   []InsightsMetricValue    `json:"metrics"`
}

ContentInsightsItem is one post, Reel or story with its metrics.

type ContentInsightsOptions added in v0.7.0

type ContentInsightsOptions struct {
	Period             InsightsPeriod
	Metric             InsightsMetric
	Type               InsightsContentType
	SortByCreationTime bool
	Ascending          bool
}

ContentInsightsOptions are the content tab's filters.

type ContentInsightsThumbnail added in v0.7.0

type ContentInsightsThumbnail struct {
	MediaID      string `json:"media_id"`
	MediaURL     string `json:"media_url"`
	MediaType    string `json:"media_type"`
	CaptionText  string `json:"caption_text"`
	CreationTime Int64  `json:"creation_time"`
	IsPromoted   bool   `json:"is_promoted"`
	IsTrialReel  bool   `json:"is_trial_reel"`
	IsCollab     bool   `json:"is_collab"`
}

type ContentTypeBreakdown added in v0.7.0

type ContentTypeBreakdown struct {
	Total   int                `json:"total"`
	Entries []ContentTypeCount `json:"entries"`
}

ContentTypeBreakdown counts per content type: post, story, reel, live.

type ContentTypeCount added in v0.7.0

type ContentTypeCount struct {
	ContentType      string `json:"content_type"`
	Total            int    `json:"total"`
	FollowerCount    int    `json:"follower_count"`
	NonFollowerCount int    `json:"non_follower_count"`
	FacebookCount    *int   `json:"facebook_count"`
}

type ContentTypeValue added in v0.7.0

type ContentTypeValue struct {
	ContentType string `json:"content_type"`
	Value       int    `json:"value"`
}

type DataPoint added in v0.7.0

type DataPoint struct {
	Timestamp int64   `json:"timestamp"` // epoch seconds
	Value     float64 `json:"value"`
}

type Device

type Device struct {
	Manufacturer     string `json:"manufacturer"`
	Model            string `json:"model"`
	CodeName         string `json:"code_name"`
	AndroidVersion   int    `json:"android_version"`
	AndroidRelease   int    `json:"android_release"`
	ScreenDpi        string `json:"screen_dpi"`
	ScreenResolution string `json:"screen_resolution"`
	Chipset          string `json:"chipset"`
}

type DirectItem added in v0.7.0

type DirectItem struct {
	ItemID        string `json:"item_id"`
	UserID        Int64  `json:"user_id"`
	Timestamp     Int64  `json:"timestamp"` // microseconds
	ItemType      string `json:"item_type"` // text, media_share, clip, link, like, reel_share, story_share, …
	Text          string `json:"text"`
	ClientContext string `json:"client_context"`
	MediaShare    *Item  `json:"media_share"`
	Clip          *struct {
		Clip *Item `json:"clip"`
	} `json:"clip"`
	Link *struct {
		Text        string `json:"text"`
		LinkContext struct {
			URL   string `json:"link_url"`
			Title string `json:"link_title"`
		} `json:"link_context"`
	} `json:"link"`
	Raw json.RawMessage `json:"-"`
}

DirectItem is one message. Raw holds the whole item, for kinds the typed fields do not cover.

func (*DirectItem) UnmarshalJSON added in v0.7.0

func (d *DirectItem) UnmarshalJSON(b []byte) error

type DirectSent added in v0.7.0

type DirectSent struct {
	ItemID        string `json:"item_id"`
	ThreadID      string `json:"thread_id"`
	ClientContext string `json:"client_context"`
	Timestamp     string `json:"timestamp"`
}

DirectSent is the server's acknowledgement of a sent message.

type FollowerShare added in v0.7.0

type FollowerShare struct {
	Follower    Metric `json:"follower"`
	NonFollower Metric `json:"non_follower"`
}

FollowerShare splits a total between followers and everyone else, as fractions (0.152 is 15.2%).

type Friendship

type Friendship struct {
	Following       bool `json:"following"`
	FollowedBy      bool `json:"followed_by"`
	IncomingRequest bool `json:"incoming_request"`
	OutgoingRequest bool `json:"outgoing_request"`
	Muting          bool `json:"muting"`
	Blocking        bool `json:"blocking"`
	IsBestie        bool `json:"is_bestie"`
	IsBlockingReel  bool `json:"is_blocking_reel"`
	IsMutingReel    bool `json:"is_muting_reel"`
	IsPrivate       bool `json:"is_private"`
	IsRestricted    bool `json:"is_restricted"`
}

type GraphQLError added in v0.3.2

type GraphQLError struct {
	Code    int    `json:"code"`
	Summary string `json:"summary"`
	Message string `json:"message"`
}

GraphQLError is the first error of a response part that came back without data. Instagram answers 1357005 for a private account the viewer does not follow.

func (*GraphQLError) Error added in v0.3.2

func (e *GraphQLError) Error() string

type HighlightEdit added in v0.4.0

type HighlightEdit struct {
	Title       string
	Cover       *Item
	Add, Remove []*Item
}

HighlightEdit is one save of the profile's "Edit highlight" screen. An empty Title or a nil Cover keeps the current one.

type Images

type Images struct {
	Versions []Candidate `json:"candidates"`
}

func (Images) Best

func (img Images) Best() string

Best returns the URL of the largest candidate.

type Inbox added in v0.7.0

type Inbox struct {
	*Pager[*Thread]
	UnseenCount  int
	PendingTotal int
}

Inbox is the direct inbox; UnseenCount and PendingTotal come from the first page.

type Insights added in v0.7.0

type Insights struct {
	MediaFBID              string               `json:"media_id"`
	Likes                  int                  `json:"likes"`
	Comments               int                  `json:"comments"`
	Saves                  int                  `json:"saves"`
	Shares                 *int                 `json:"shares"`
	Reposts                int                  `json:"reposts"`
	TotalViews             int                  `json:"total_views"`
	FollowersViews         int                  `json:"followers_views"`
	NonFollowersViews      int                  `json:"non_followers_views"`
	Demographics           InsightsDemographics `json:"demographics"`
	IsMediaRecentlyCreated bool                 `json:"is_media_recently_created"`
	IsCollab               bool                 `json:"is_collab"`
	CollaboratorUsernames  []string             `json:"collaborator_usernames"`
	ShowBoostCTA           bool                 `json:"show_boost_cta"`
	ThumbnailURL           string               `json:"thumbnail_url"`
}

Insights are a post's metrics, as the app's post insights screen shows them; captured on a personal account. Shares is nil when Instagram has no count.

type InsightsBenchmark added in v0.7.0

type InsightsBenchmark struct {
	Value         float64 `json:"value"`
	Comparison    string  `json:"comparison"` // HIGHER, TYPICAL, …
	Sentiment     string  `json:"sentiment"`
	DisplayString string  `json:"display_string"`
}

InsightsBenchmark compares a value with the previous period or similar accounts.

type InsightsContentType added in v0.7.0

type InsightsContentType string

InsightsContentType filters the content tab; the empty value is all content.

const (
	ContentPosts      InsightsContentType = "posts"
	ContentReels      InsightsContentType = "reels"
	ContentStories    InsightsContentType = "stories"
	ContentLiveVideos InsightsContentType = "live_videos"
)

type InsightsDelta added in v0.7.0

type InsightsDelta struct {
	Value     string `json:"value"`
	Sentiment string `json:"sentiment"`
}

InsightsDelta is the change over the previous period, as display text.

type InsightsDemographics added in v0.7.0

type InsightsDemographics struct {
	Status string `json:"status"`
}

InsightsDemographics.Status is "INSUFFICIENT_DATA" until the post has enough views for the age, gender and country breakdowns.

type InsightsHomeOptions added in v0.7.0

type InsightsHomeOptions struct {
	Period InsightsPeriod
	// Creator picks the creator dashboard's Meta One upsell key; the app decides
	// it from the account type (creator vs business).
	Creator bool
}

InsightsHomeOptions are the home tab's inputs. The app sets the include flags from mobile config; InsightsHome turns them all on.

type InsightsMetric added in v0.7.0

type InsightsMetric string

InsightsMetric ranks the content tab. The empty value sends "views", as the app does for its "latest" sort.

const (
	MetricViews               InsightsMetric = "views"
	MetricViewers             InsightsMetric = "viewers"
	MetricFollows             InsightsMetric = "follows"
	MetricLikes               InsightsMetric = "likes"
	MetricComments            InsightsMetric = "comments"
	MetricReposts             InsightsMetric = "reposts"
	MetricShares              InsightsMetric = "shares"
	MetricSaves               InsightsMetric = "saves"
	MetricSkipRate            InsightsMetric = "skip_rate" // Reels only
	MetricProfileVisits       InsightsMetric = "profile_visits"
	MetricBioLinkTaps         InsightsMetric = "bio_link_taps"
	MetricBusinessAddressTaps InsightsMetric = "business_address_taps"
	MetricLinkClicks          InsightsMetric = "link_clicks"
)

type InsightsMetricValue added in v0.7.0

type InsightsMetricValue struct {
	Metric string   `json:"metric"`
	Value  *float64 `json:"value"`
}

type InsightsPeriod added in v0.7.0

type InsightsPeriod struct {
	// contains filtered or unexported fields
}

InsightsPeriod is the dashboard's time range. The zero value is PeriodThisMonth, the app's default.

func CustomPeriod added in v0.7.0

func CustomPeriod(start, end time.Time) InsightsPeriod

CustomPeriod is the date picker's range; Instagram takes it in whole seconds.

func (InsightsPeriod) String added in v0.7.0

func (p InsightsPeriod) String() string

type InsightsTile added in v0.7.0

type InsightsTile struct {
	ID         string        `json:"id"`
	Title      string        `json:"title"`
	Metric     Metric        `json:"metric"`
	Delta      InsightsDelta `json:"delta"`
	TimeSeries TimeSeries    `json:"time_series"`
}

InsightsTile is a summary metric (views, interactions, followers, …).

type InsightsTool added in v0.7.0

type InsightsTool struct {
	ID                 string `json:"id"`
	Title              string `json:"title"`
	Destination        string `json:"destination"`
	DestinationType    string `json:"destination_type"`
	ImpressionDeeplink string `json:"impression_deeplink"`
}

InsightsTool is a home-tab shortcut (an id enum and an in-app destination).

type Instagram

type Instagram struct {
	Account *Account

	// Logger receives rate-limit warnings and, at debug level, every response
	// body. It defaults to slog.Default().
	Logger *slog.Logger
	// OnSessionChange, if set, is called when the server rotates a stored header
	// (token, mid, www-claim, rur, password key), so a caller can persist the
	// session without polling. It runs on the request goroutine; keep it quick
	// and do not call back into the same client from it.
	OnSessionChange func(Session)
	// RateLimitWait is how long a 429 is waited out before retrying (up to 3
	// times); 0 returns ErrTooManyRequests at once.
	RateLimitWait time.Duration
	// contains filtered or unexported fields
}

Instagram is safe for concurrent use once configured: call the Set* methods (except SetProxy/UnsetProxy/SetHTTPClient, which may run at any time) before sharing it. Login swaps the client's attestation headers for a throwaway logged-out key until it (or LoginTwoFactor) returns, so do not run other requests in between. Pagers (Timeline, Posts, ...) and the Account struct belong to one goroutine each.

func ImportSession

func ImportSession(path string) (*Instagram, error)

func New

func New(s Session) (*Instagram, error)

func (*Instagram) AccountFamily

func (insta *Instagram) AccountFamily(ctx context.Context) ([]byte, error)

func (*Instagram) Activity

func (insta *Instagram) Activity() *Activity

func (*Instagram) Collections

func (insta *Instagram) Collections() *Pager[*Collection]

func (*Instagram) CreateHighlight added in v0.3.0

func (insta *Instagram) CreateHighlight(ctx context.Context, title string, items ...*Item) (*Reel, error)

CreateHighlight makes a highlight from story items; the first is the cover. Instagram silently cuts the title to 16 characters; the returned Title shows it.

func (*Instagram) ExportSession

func (insta *Instagram) ExportSession(path string) error

ExportSession writes the session (with the attestation private keys) mode 0600.

func (*Instagram) FetchReels

func (insta *Instagram) FetchReels(ctx context.Context, reelIDs ...string) (map[string]*Reel, error)

FetchReels loads the items of the given reels (user ids or "highlight:<id>").

func (*Instagram) Friendships

func (insta *Instagram) Friendships(ctx context.Context, ids ...int64) (map[string]Friendship, error)

Friendships returns the friendship status for each user id (friendships/show_many).

func (*Instagram) Inbox added in v0.7.0

func (insta *Instagram) Inbox() *Inbox

Inbox pages through the direct inbox, newest threads first.

func (*Instagram) LoadReels

func (insta *Instagram) LoadReels(ctx context.Context, reels ...*Reel) error

LoadReels fills the items of every reel that is not Loaded, one request per batch of reels, in place.

func (*Instagram) LocationFeed added in v0.7.0

func (insta *Instagram) LocationFeed(id int64, tab LocationTab) *Pager[*Item]

LocationFeed pages the posts at a location, ranked or most recent first.

func (*Instagram) LocationInfo added in v0.7.0

func (insta *Instagram) LocationInfo(ctx context.Context, id int64) (*Location, error)

func (*Instagram) Login

func (insta *Instagram) Login(ctx context.Context, username, password string) (err error)

Login replays the app's logged-out password login: register a fresh zca key (challenge nonce), render the login context (aac), then send the credentials. The attestation headers in use before the call are restored afterwards.

When the account has two-factor on, Login returns ErrTwoFactorRequired; call LoginTwoFactor with a TOTP code to finish. The logged-out attestation stays applied until then, so do not make other requests in between.

func (*Instagram) LoginTwoFactor

func (insta *Instagram) LoginTwoFactor(ctx context.Context, code string) (err error)

LoginTwoFactor finishes a login that returned ErrTwoFactorRequired with a TOTP code (see TOTP): it selects the TOTP method, then submits the code, whose response carries the bearer. The pending login is consumed either way, so a rejected code needs a fresh Login. The attestation Login swapped out is restored on return.

func (*Instagram) Logout

func (insta *Instagram) Logout(ctx context.Context) (*LogoutResult, error)

Logout ends the session server-side. The session's token is invalid afterward; the returned nonce allows a later one-tap re-login from the same device.

func (*Instagram) MarkActivitySeen

func (insta *Instagram) MarkActivitySeen(ctx context.Context) error

func (*Instagram) MarkReelsSeen

func (insta *Instagram) MarkReelsSeen(ctx context.Context, items ...*Item) error

func (*Instagram) MediaInfo added in v0.7.0

func (insta *Instagram) MediaInfo(ctx context.Context, id string) (*Item, error)

MediaInfo loads one post, Reel or story item by id ("<pk>_<owner id>" or pk).

func (*Instagram) NewUser

func (insta *Instagram) NewUser(id int64) *User

func (*Instagram) PendingInbox added in v0.7.0

func (insta *Instagram) PendingInbox() *Inbox

PendingInbox pages through message requests.

func (*Instagram) Reels

func (insta *Instagram) Reels() *Pager[*Item]

func (*Instagram) SearchLocations added in v0.7.0

func (insta *Instagram) SearchLocations(ctx context.Context, query string, lat, lng float64) ([]Location, error)

SearchLocations finds places by name around lat/lng; 0, 0 searches without a position, as the app does without location access.

func (*Instagram) SearchUsers

func (insta *Instagram) SearchUsers(query string) *Pager[*User]

SearchUsers pages the "Accounts" tab of search. The session ids stay fixed across pages, as the app keeps them; later pages carry the server's page_token.

func (*Instagram) SendDirectText added in v0.7.0

func (insta *Instagram) SendDirectText(ctx context.Context, text string, userIDs ...int64) (*DirectSent, error)

SendDirectText sends a text message to these users, in their existing thread or a new one.

func (*Instagram) SeriesInsightsAudience added in v0.7.0

func (insta *Instagram) SeriesInsightsAudience(ctx context.Context, seriesID string) (json.RawMessage, error)

func (*Instagram) SeriesInsightsEngagement added in v0.7.0

func (insta *Instagram) SeriesInsightsEngagement(ctx context.Context, seriesID string) (json.RawMessage, error)

func (*Instagram) SeriesInsightsOverview added in v0.7.0

func (insta *Instagram) SeriesInsightsOverview(ctx context.Context, seriesID string, viewsOverTime bool) (json.RawMessage, error)

SeriesInsightsOverview loads the overview tab of a Reels series (a linked media playlist, the linked_media_playlist_id of its Reels).

func (*Instagram) Session

func (insta *Instagram) Session() Session

func (*Instagram) SetAttestation

func (insta *Instagram) SetAttestation(a *Attestation) error

SetAttestation signs both headers and uses them for every request, replacing the values carried in the session. They are re-signed before they expire.

func (*Instagram) SetHTTPClient

func (insta *Instagram) SetHTTPClient(client *http.Client)

SetHTTPClient replaces the client wholesale. Its transport does not present the app's TLS fingerprint unless it came from SetProxy; logins from other fingerprints get 429. Meant for tests and custom round trippers.

func (*Instagram) SetProxy

func (insta *Instagram) SetProxy(rawURL string, insecure bool) error

SetProxy routes requests through an http:// (CONNECT) or socks5:// proxy while keeping the app's TLS fingerprint. insecure skips certificate verification, which an intercepting proxy such as mitmproxy needs.

func (*Instagram) SetTimeout

func (insta *Instagram) SetTimeout(t time.Duration)

SetTimeout is configure-time only: a concurrent SetProxy can undo it.

func (*Instagram) StoryTray

func (insta *Instagram) StoryTray(ctx context.Context, reason TrayReason) (*Tray, error)

StoryTray loads the stories tray. Reels further down arrive without items; LoadReels fills them in batches.

func (*Instagram) Thread added in v0.7.0

func (insta *Instagram) Thread(ctx context.Context, threadID string) (*Thread, error)

Thread loads one conversation with its latest messages.

func (*Instagram) Timeline

func (insta *Instagram) Timeline() *Timeline

func (*Instagram) UnsetProxy

func (insta *Instagram) UnsetProxy()

func (*Instagram) UploadAlbum

func (insta *Instagram) UploadAlbum(ctx context.Context, photos []io.Reader, opts PostOptions) (*Item, error)

UploadAlbum posts 2 to 20 JPEG or WebP images as one carousel. All images are checked before any upload starts; the uploads then run in parallel. Instagram stores each image as uploaded and takes the album's shape from the first one (1080x1350 gives a 4:5 album), so crop them all to one ratio first.

func (*Instagram) UploadPhoto

func (insta *Instagram) UploadPhoto(ctx context.Context, r io.Reader, opts PostOptions) (*Item, error)

UploadPhoto posts a single JPEG or WebP image to the feed. Instagram stores the pixels as uploaded, so crop to the wanted aspect ratio first.

func (*Instagram) UploadReel added in v0.5.0

func (insta *Instagram) UploadReel(ctx context.Context, r io.Reader, opts ReelOptions) (*Item, error)

UploadReel posts an MP4 (H.264 video, AAC audio) as a Reel; Instagram picks the cover frame unless CoverFrameMs is set.

func (*Instagram) UploadStory

func (insta *Instagram) UploadStory(ctx context.Context, r io.Reader, opts StoryOptions) (*Item, error)

UploadStory posts a JPEG or WebP image to the story.

func (*Instagram) UserByID

func (insta *Instagram) UserByID(ctx context.Context, id int64) (*User, error)

type Int64

type Int64 int64

Int64 decodes JSON numbers and numeric strings; the API mixes both for ids.

func (Int64) String

func (n Int64) String() string

func (*Int64) UnmarshalJSON

func (n *Int64) UnmarshalJSON(b []byte) error

type InteractionTypeCount added in v0.7.0

type InteractionTypeCount struct {
	Type    string             `json:"interaction_type"`
	Total   int                `json:"total"`
	Entries []ContentTypeValue `json:"entries"`
}

InteractionTypeCount is one interaction (likes, comments, reposts, shares, saves, …) per content type.

type InteractionsBreakdown added in v0.7.0

type InteractionsBreakdown struct {
	Total  ContentTypeBreakdown   `json:"total_breakdown"`
	ByType []InteractionTypeCount `json:"sub_breakdowns"`
}

type InteractionsCount added in v0.7.0

type InteractionsCount struct {
	Total Metric `json:"total"`
	FollowerShare
}

type Item

type Item struct {
	TakenAt           Int64  `json:"taken_at"`
	Pk                Int64  `json:"pk"`
	ID                string `json:"id"`
	Index             int    // position in feed
	CommentsDisabled  bool   `json:"comments_disabled"`
	DeviceTimestamp   Int64  `json:"device_timestamp"`
	FacepileTopLikers []struct {
		FollowFrictionType float64 `json:"follow_friction_type"`
		FullName           string  `json:"full_name"`
		IsPrivate          bool    `json:"is_private"`
		IsVerified         bool    `json:"is_verified"`
		Pk                 float64 `json:"pk"`
		ProfilePicID       string  `json:"profile_pic_id"`
		ProfilePicURL      string  `json:"profile_pic_url"`
		Username           string  `json:"username"`
	} `json:"facepile_top_likers"`
	MediaType             MediaType `json:"media_type"`
	Code                  string    `json:"code"`
	ClientCacheKey        string    `json:"client_cache_key"`
	FilterType            int       `json:"filter_type"`
	User                  User      `json:"user"`
	CanReply              bool      `json:"can_reply"`
	CanReshare            bool      `json:"can_reshare"` // Used for stories
	CanViewerReshare      bool      `json:"can_viewer_reshare"`
	Caption               Caption   `json:"caption"`
	CaptionIsEdited       bool      `json:"caption_is_edited"`
	LikeViewCountDisabled bool      `json:"like_and_view_counts_disabled"`
	ShareCountDisabled    bool      `json:"share_count_disabled"`
	FundraiserTag         struct {
		HasStandaloneFundraiser bool `json:"has_standalone_fundraiser"`
	} `json:"fundraiser_tag"`
	IsSeen                       bool   `json:"is_seen"`
	InventorySource              string `json:"inventory_source"`
	ProductType                  string `json:"product_type"`
	Likes                        int    `json:"like_count"`
	HasLiked                     bool   `json:"has_liked"`
	NearlyCompleteCopyRightMatch bool   `json:"nearly_complete_copyright_match"`
	// Toplikers can be `string` or `[]string`.
	// Use TopLikers function instead of getting it directly.
	Toplikers  any     `json:"top_likers"`
	Likers     []*User `json:"likers"`
	PhotoOfYou bool    `json:"photo_of_you"`

	CommentLikesEnabled          bool `json:"comment_likes_enabled"`
	CommentThreadingEnabled      bool `json:"comment_threading_enabled"`
	HasMoreComments              bool `json:"has_more_comments"`
	MaxNumVisiblePreviewComments int  `json:"max_num_visible_preview_comments"`

	CommentCount int `json:"comment_count"`

	// Previewcomments can be `string` or `[]string` or `[]Comment`.
	// Use PreviewComments function instead of getting it directly.
	Previewcomments any `json:"preview_comments,omitempty"`

	Tags                 Tag      `json:"usertags,omitempty"`
	FbUserTags           Tag      `json:"fb_user_tags"`
	CanViewerSave        bool     `json:"can_viewer_save"`
	OrganicTrackingToken string   `json:"organic_tracking_token"`
	Images               Images   `json:"image_versions2,omitempty"`
	OriginalWidth        int      `json:"original_width,omitempty"`
	OriginalHeight       int      `json:"original_height,omitempty"`
	ImportedTakenAt      Int64    `json:"imported_taken_at,omitempty"`
	Location             Location `json:"location,omitempty"`
	Lat                  float64  `json:"lat,omitempty"`
	Lng                  float64  `json:"lng,omitempty"`

	CarouselParentID string `json:"carousel_parent_id"`
	CarouselMedia    []Item `json:"carousel_media,omitempty"`

	IsPostLive bool `json:"is_post_live"`

	Videos        []Video `json:"video_versions,omitempty"`
	VideoCodec    string  `json:"video_codec"`
	HasAudio      bool    `json:"has_audio,omitempty"`
	VideoDuration float64 `json:"video_duration,omitempty"`
	// AI voice translation state of a Reel; see VoiceTranslations.
	TranslatedLangsForAutodub []string          `json:"translated_langs_for_autodub,omitempty"`
	AutodubStatus             []json.RawMessage `json:"autodub_status,omitempty"`
	ViewCount                 float64           `json:"view_count,omitempty"`
	PlayCount                 float64           `json:"play_count,omitempty"`
	IsDashEligible            int               `json:"is_dash_eligible,omitempty"`
	IsUnifiedVideo            bool              `json:"is_unified_video"`
	VideoDashManifest         string            `json:"video_dash_manifest,omitempty"`
	NumberOfQualities         int               `json:"number_of_qualities,omitempty"`

	Title                    string `json:"title"`
	IGTVExistsInViewerSeries bool   `json:"igtv_exists_in_viewer_series"`
	IGTVSeriesInfo           struct {
		HasCoverPhoto bool `json:"has_cover_photo"`
		ID            int64
		NumEpisodes   int    `json:"num_episodes"`
		Title         string `json:"title"`
	} `json:"igtv_series_info"`
	IGTVAdsInfo struct {
		AdsToggledOn            bool `json:"ads_toggled_on"`
		EligibleForInsertingAds bool `json:"is_video_elegible_for_inserting_ads"`
	} `json:"igtv_ads_info"`

	IsCommercial        bool   `json:"is_commercial"`
	IsPaidPartnership   bool   `json:"is_paid_partnership"`
	CommercialityStatus string `json:"commerciality_status"`
	AdLink              string `json:"link"`
	AdLinkText          string `json:"link_text"`
	AdLinkHint          string `json:"link_hint_text"`
	AdTitle             string `json:"overlay_title"`
	AdSubtitle          string `json:"overlay_subtitle"`
	AdText              string `json:"overlay_text"`
	AdAction            string `json:"ad_action"`
	AdHeaderStyle       int    `json:"ad_header_style"`
	AdLinkType          int    `json:"ad_link_type"`
	AdMetadata          []struct {
		Type  int `json:"type"`
		Value any `json:"value"`
	} `json:"ad_metadata"`
	AndroidLinks []struct {
		AndroidClass      string `json:"androidClass"`
		CallToActionTitle string `json:"callToActionTitle"`
		DeeplinkUri       string `json:"deeplinkUri"`
		LinkType          int    `json:"linkType"`
		Package           string `json:"package"`
		WebUri            string `json:"webUri"`
	} `json:"android_links"`

	// Only for stories
	StoryEvents              []any              `json:"story_events"`
	StoryHashtags            []any              `json:"story_hashtags"`
	StoryPolls               []any              `json:"story_polls"`
	StoryFeedMedia           []any              `json:"story_feed_media"`
	StorySoundOn             []any              `json:"story_sound_on"`
	CreativeConfig           any                `json:"creative_config"`
	StoryLocations           []any              `json:"story_locations"`
	StorySliders             []any              `json:"story_sliders"`
	StoryQuestions           []any              `json:"story_questions"`
	StoryProductItems        []any              `json:"story_product_items"`
	StoryCTA                 []StoryCTA         `json:"story_cta"`
	IntegrityReviewDecision  string             `json:"integrity_review_decision"`
	IsReelMedia              bool               `json:"is_reel_media"`
	ProfileGridControl       bool               `json:"profile_grid_control_enabled"`
	ReelMentions             []StoryReelMention `json:"reel_mentions"`
	ExpiringAt               Int64              `json:"expiring_at"`
	CanSendCustomEmojis      bool               `json:"can_send_custom_emojis"`
	SupportsReelReactions    bool               `json:"supports_reel_reactions"`
	ShowOneTapFbShareTooltip bool               `json:"show_one_tap_fb_share_tooltip"`
	HasSharedToFb            Int64              `json:"has_shared_to_fb"`
	Mentions                 []Mentions
	Audience                 string `json:"audience,omitempty"`
	StoryMusicStickers       []struct {
		X              float64 `json:"x"`
		Y              float64 `json:"y"`
		Z              int     `json:"z"`
		Width          float64 `json:"width"`
		Height         float64 `json:"height"`
		Rotation       float64 `json:"rotation"`
		IsPinned       int     `json:"is_pinned"`
		IsHidden       int     `json:"is_hidden"`
		IsSticker      int     `json:"is_sticker"`
		MusicAssetInfo struct {
			ID                       string `json:"id"`
			Title                    string `json:"title"`
			Subtitle                 string `json:"subtitle"`
			DisplayArtist            string `json:"display_artist"`
			CoverArtworkURI          string `json:"cover_artwork_uri"`
			CoverArtworkThumbnailURI string `json:"cover_artwork_thumbnail_uri"`
			ProgressiveDownloadURL   string `json:"progressive_download_url"`
			HighlightStartTimesInMs  []int  `json:"highlight_start_times_in_ms"`
			IsExplicit               bool   `json:"is_explicit"`
			DashManifest             string `json:"dash_manifest"`
			HasLyrics                bool   `json:"has_lyrics"`
			AudioAssetID             string `json:"audio_asset_id"`
			IgArtist                 struct {
				Pk            Int64  `json:"pk"`
				Username      string `json:"username"`
				FullName      string `json:"full_name"`
				IsPrivate     bool   `json:"is_private"`
				ProfilePicURL string `json:"profile_pic_url"`
				ProfilePicID  string `json:"profile_pic_id"`
				IsVerified    bool   `json:"is_verified"`
			} `json:"ig_artist"`
			PlaceholderProfilePicURL string `json:"placeholder_profile_pic_url"`
			ShouldMuteAudio          bool   `json:"should_mute_audio"`
			ShouldMuteAudioReason    string `json:"should_mute_audio_reason"`
			OverlapDurationInMs      int    `json:"overlap_duration_in_ms"`
			AudioAssetStartTimeInMs  int    `json:"audio_asset_start_time_in_ms"`
			StoryLinkStickers        []struct {
				X           float64 `json:"x"`
				Y           float64 `json:"y"`
				Z           int     `json:"z"`
				Width       float64 `json:"width"`
				Height      float64 `json:"height"`
				Rotation    int     `json:"rotation"`
				IsPinned    int     `json:"is_pinned"`
				IsHidden    int     `json:"is_hidden"`
				IsSticker   int     `json:"is_sticker"`
				IsFbSticker int     `json:"is_fb_sticker"`
				StoryLink   struct {
					LinkType   string `json:"link_type"`
					URL        string `json:"url"`
					LinkTitle  string `json:"link_title"`
					DisplayURL string `json:"display_url"`
				} `json:"story_link"`
			} `json:"story_link_stickers"`
		} `json:"music_asset_info"`
	} `json:"story_music_stickers,omitempty"`
	// contains filtered or unexported fields
}

func (*Item) AddNote

func (item *Item) AddNote(ctx context.Context, text string) (*Note, error)

AddNote leaves a note on the media (the bubble shown over reels/posts).

func (*Item) Archive

func (item *Item) Archive(ctx context.Context) error

Archive hides one of the account's own posts from the profile (only_me).

func (*Item) Comment

func (item *Item) Comment(ctx context.Context, text string) (*Comment, error)

func (*Item) Comments

func (item *Item) Comments() *Comments

func (*Item) Delete

func (item *Item) Delete(ctx context.Context) error

Delete removes one of the account's own posts.

func (*Item) DeleteComments

func (item *Item) DeleteComments(ctx context.Context, ids ...string) error

DeleteComments removes comments by id (comment/bulk_delete).

func (*Item) DisableComments added in v0.7.0

func (item *Item) DisableComments(ctx context.Context) error

func (*Item) Download

func (item *Item) Download(ctx context.Context) ([]byte, error)

Download returns the photo or video; a carousel has one per child, so use DownloadTo or the children in CarouselMedia.

func (*Item) DownloadTo

func (item *Item) DownloadTo(ctx context.Context, dst string) ([]string, error)

DownloadTo saves the media and returns the paths written. dst is a file path, or a directory when it ends in a separator or names an existing directory. The extension comes from the URL and existing files are kept (a ".N" suffix is added). Carousel children download in parallel as <name>_<n>.

func (*Item) Edit added in v0.7.0

func (item *Item) Edit(ctx context.Context, e MediaEdit) error

Edit saves e on one of the account's own posts and refreshes the item from the server's copy.

func (*Item) EnableComments added in v0.7.0

func (item *Item) EnableComments(ctx context.Context) error

func (*Item) FetchLikers added in v0.7.0

func (item *Item) FetchLikers(ctx context.Context) ([]*User, error)

FetchLikers returns the accounts that liked the post (the first page, as the app shows it).

func (*Item) Insights added in v0.7.0

func (item *Item) Insights(ctx context.Context) (*Insights, error)

Insights loads the post's metrics.

func (*Item) Like

func (item *Item) Like(ctx context.Context) error

func (*Item) LikeStory

func (item *Item) LikeStory(ctx context.Context) error

func (*Item) Pin

func (item *Item) Pin(ctx context.Context) error

Pin pins one of the account's own posts to the top of the profile grid.

func (*Item) PreviewComments

func (item *Item) PreviewComments() []Comment

func (*Item) ReelInsights added in v0.7.0

func (item *Item) ReelInsights(ctx context.Context) (*ReelInsights, error)

ReelInsights loads a Reel's metrics. It runs the app's LongformInsightsQuery, which serves Reels; its ReelInsightsQuery needs variables the decompiled app does not name.

func (*Item) RemoveTag added in v0.7.0

func (item *Item) RemoveTag(ctx context.Context) error

RemoveTag removes the account's own people tag from the post.

func (*Item) Save

func (item *Item) Save(ctx context.Context) error

func (*Item) SetCountsHidden added in v0.7.0

func (item *Item) SetCountsHidden(ctx context.Context, likes, shares bool) error

SetCountsHidden hides or shows the like/view and share counts of an own post.

func (*Item) SetDownloads added in v0.7.0

func (item *Item) SetDownloads(ctx context.Context, allowed bool) error

SetDownloads allows or blocks downloading one of the account's own Reels.

func (*Item) SetRemixAllowed added in v0.7.0

func (item *Item) SetRemixAllowed(ctx context.Context, allowed bool) error

SetRemixAllowed allows or blocks remixes of one of the account's own Reels.

func (*Item) StoryIsCloseFriends

func (item *Item) StoryIsCloseFriends() bool

func (*Item) StoryViewers added in v0.7.0

func (item *Item) StoryViewers() *Pager[*User]

StoryViewers pages through the accounts that viewed one of the account's own stories.

func (*Item) TopLikers

func (item *Item) TopLikers() []string

func (*Item) Unarchive added in v0.7.0

func (item *Item) Unarchive(ctx context.Context) error

Unarchive shows an archived post on the profile again (undoes Archive).

func (*Item) VoiceTranslations added in v0.7.0

func (item *Item) VoiceTranslations(ctx context.Context) (*VoiceTranslations, error)

VoiceTranslations reads the Reel's AI voice translation state from its media info.

type Location

type Location struct {
	ID               Int64   `json:"pk"`
	Name             string  `json:"name"`
	Address          string  `json:"address"`
	City             string  `json:"city"`
	ShortName        string  `json:"short_name"`
	Lng              float64 `json:"lng"`
	Lat              float64 `json:"lat"`
	ExternalSource   string  `json:"external_source"`
	FacebookPlacesID Int64   `json:"facebook_places_id"`
}

type LocationTab added in v0.7.0

type LocationTab string

LocationTab is the order of a location's feed.

const (
	LocationTabRanked LocationTab = "ranked"
	LocationTabRecent LocationTab = "recent"
)

type LogoutResult

type LogoutResult struct {
	LoginNonce               string `json:"login_nonce"`
	CloudAccountIDLoginNonce string `json:"cloud_account_id_login_nonce"`
	DeviceBasedLoginEnabled  bool   `json:"device_based_login_enabled"`
	Status                   string `json:"status"`
}

LogoutResult carries the one-tap re-login nonces the server returns on logout.

type MediaEdit added in v0.7.0

type MediaEdit struct {
	Caption       string
	ClearLocation bool
	// RemoveChildren deletes album photos; ChildOrder reorders the remaining ones.
	RemoveChildren []*Item
	ChildOrder     []*Item
}

MediaEdit is one save of a post's "Edit" screen. Caption replaces the whole caption, so pass the current one to keep it.

type MediaProduct added in v0.7.0

type MediaProduct string

MediaProduct selects the kind of media in MediaInsightsGrid.

const (
	MediaProductFeed  MediaProduct = "FEED"
	MediaProductStory MediaProduct = "STORY"
	MediaProductReels MediaProduct = "CLIPS"
)

type MediaType

type MediaType int
const (
	MediaPhoto MediaType = 1
	MediaVideo MediaType = 2
	MediaAlbum MediaType = 8
)

func (MediaType) String

func (t MediaType) String() string

type Mentions

type Mentions struct {
	X        float64 `json:"x"`
	Y        float64 `json:"y"`
	Z        Int64   `json:"z"`
	Width    float64 `json:"width"`
	Height   float64 `json:"height"`
	Rotation float64 `json:"rotation"`
	IsPinned int     `json:"is_pinned"`
	User     User    `json:"user"`
}

type Metric added in v0.7.0

type Metric struct {
	ID             string             `json:"id"`
	Label          string             `json:"label"`
	Format         string             `json:"format"` // COUNT, PERCENTAGE, DURATION_SECONDS
	FormattedValue string             `json:"formatted_value"`
	Value          *float64           `json:"value"`
	Benchmark      *InsightsBenchmark `json:"benchmark"`
}

Metric is one labelled insights figure as the app shows it; Value stays nil until Instagram has data.

type Note

type Note struct {
	ID        string `json:"id"`
	MediaID   string `json:"media_id"`
	Text      string `json:"text"`
	UserID    string `json:"user_id"`
	Audience  int    `json:"audience"`
	NoteStyle int    `json:"note_style"`
	CreatedAt Int64  `json:"created_at"`
	ExpiresAt Int64  `json:"expires_at"`
}

type Pager

type Pager[T any] struct {
	Items []T
	// contains filtered or unexported fields
}

Pager walks a paged endpoint. Next loads the following page into Items and returns ErrNoMore past the last one; All ranges over the items of every remaining page:

for post, err := range user.Posts().All(ctx) { ... }

A Pager is not safe for concurrent use.

func (*Pager[T]) All

func (p *Pager[T]) All(ctx context.Context) iter.Seq2[T, error]

All loads pages from the current position on and yields their items. It stops at the end of the feed, or after yielding a non-nil error.

func (*Pager[T]) Collect

func (p *Pager[T]) Collect(ctx context.Context, limit int) ([]T, error)

Collect loads up to limit items (all when limit <= 0) from the current position. Stopping at limit leaves the rest of the last page unread in Items.

func (*Pager[T]) More

func (p *Pager[T]) More() bool

func (*Pager[T]) Next

func (p *Pager[T]) Next(ctx context.Context) error

type PicURLInfo

type PicURLInfo struct {
	Height int    `json:"height"`
	URL    string `json:"url"`
	Width  int    `json:"width"`
}

type PostOptions

type PostOptions struct {
	Caption string
	// ShareToThreads cross-posts to the Threads profile linked to the account.
	ShareToThreads bool
	// HideLikeCounts hides the like and view counts.
	HideLikeCounts  bool
	HideShareCounts bool
	// ShareToStory also shares the post to the story as a tappable post card
	// drawn from its first image. If only the story share fails, the post is
	// returned with the error.
	ShareToStory bool
}

PostOptions are the optional fields of a feed post; the zero value posts without a caption.

type PreferredLanguages added in v0.7.0

type PreferredLanguages struct {
	Selected   []string `json:"selected_lang_shortcodes_ordered"`
	Unselected []string `json:"unselected_lang_shortcodes"`
}

PreferredLanguages are ISO 639-1 short codes ("en", "fr").

type RecentItems

type RecentItems struct {
	Type      int `json:"type"`
	StoryType int `json:"story_type"`
	Args      struct {
		Text     string `json:"text"`
		RichText string `json:"rich_text"`
		IconURL  string `json:"icon_url"`
		Links    []struct {
			Start int    `json:"start"`
			End   int    `json:"end"`
			Type  string `json:"type"`
			ID    any    `json:"id"`
		} `json:"links"`
		InlineFollow struct {
			UserInfo        User `json:"user_info"`
			Following       bool `json:"following"`
			OutgoingRequest bool `json:"outgoing_request"`
		} `json:"inline_follow"`
		Actions         []string `json:"actions"`
		AfCandidateID   int      `json:"af_candidate_id"`
		ProfileID       Int64    `json:"profile_id"`
		ProfileImage    string   `json:"profile_image"`
		Timestamp       float64  `json:"timestamp"`
		Tuuid           string   `json:"tuuid"`
		Clicked         bool     `json:"clicked"`
		ProfileName     string   `json:"profile_name"`
		LatestReelMedia Int64    `json:"latest_reel_media"`
		Destination     string   `json:"destination"`
		Extra           any      `json:"extra"`
	} `json:"args"`
	Pk string `json:"pk"`
}

type Reel

type Reel struct {
	ID                     json.RawMessage `json:"id"`
	Items                  []*Item         `json:"items"`
	MediaCount             int             `json:"media_count"`
	MediaIDs               []Int64         `json:"media_ids"`
	Muted                  bool            `json:"muted"`
	LatestReelMedia        Int64           `json:"latest_reel_media"`
	LatestBestiesReelMedia float64         `json:"latest_besties_reel_media"`
	ExpiringAt             float64         `json:"expiring_at"`
	Seen                   float64         `json:"seen"`
	SeenRankedPosition     int             `json:"seen_ranked_position"`
	CanReply               bool            `json:"can_reply"`
	CanGifQuickReply       bool            `json:"can_gif_quick_reply"`
	ClientPrefetchScore    float64         `json:"client_prefetch_score"`
	Title                  string          `json:"title"`
	CanReshare             bool            `json:"can_reshare"`
	ReelType               string          `json:"reel_type"`
	ReelMentions           []string        `json:"reel_mentions"`
	PrefetchCount          int             `json:"prefetch_count"`
	HasBestiesMedia        any             `json:"has_besties_media"`
	HasPrideMedia          bool            `json:"has_pride_media"`
	HasVideo               bool            `json:"has_video"`
	IsCacheable            bool            `json:"is_cacheable"`
	IsSensitiveVerticalAd  bool            `json:"is_sensitive_vertical_ad"`
	RankedPosition         int             `json:"ranked_position"`
	RankerScores           struct {
		Fp   float64 `json:"fp"`
		Ptap float64 `json:"ptap"`
		Vm   float64 `json:"vm"`
	} `json:"ranker_scores"`
	StoryRankingToken    string `json:"story_ranking_token"`
	FaceFilterNuxVersion int    `json:"face_filter_nux_version"`
	HasNewNuxStory       bool   `json:"has_new_nux_story"`
	User                 User   `json:"user"`
	// CoverMedia is set on highlights.
	CoverMedia struct {
		MediaID  string    `json:"media_id"`
		CropRect []float64 `json:"crop_rect"`
	} `json:"cover_media"`
	// contains filtered or unexported fields
}

func (*Reel) AddItems added in v0.3.0

func (reel *Reel) AddItems(ctx context.Context, items ...*Item) error

AddItems adds story items to a highlight, as the story viewer's "Highlight" button does, and replaces the reel with the server's copy.

func (*Reel) Archive added in v0.4.0

func (reel *Reel) Archive(ctx context.Context) error

Archive hides the highlight from the profile; Unarchive shows it again.

func (*Reel) Delete added in v0.4.0

func (reel *Reel) Delete(ctx context.Context) error

Delete removes the highlight; its stories stay in the story archive.

func (*Reel) Edit added in v0.4.0

func (reel *Reel) Edit(ctx context.Context, e HighlightEdit) error

Edit applies e and replaces the reel with the server's copy.

func (*Reel) Loaded

func (reel *Reel) Loaded() bool

Loaded reports whether the reel carries all its items.

func (*Reel) MarkSeen

func (reel *Reel) MarkSeen(ctx context.Context, items ...*Item) error

func (*Reel) ReelID

func (reel *Reel) ReelID() string

ReelID is the tray identifier: a user id, or "highlight:<id>" for highlights.

func (*Reel) Sync

func (reel *Reel) Sync(ctx context.Context) error

func (*Reel) Unarchive added in v0.4.0

func (reel *Reel) Unarchive(ctx context.Context) error

type ReelInsights added in v0.7.0

type ReelInsights struct {
	MediaFBID          string   `json:"media_id"`
	Views              Metric   `json:"total_nullable_views"`
	TotalViews         Metric   `json:"aggregated_total_views"`
	Viewers            Metric   `json:"viewers_or_reach"`
	AvgWatchTime       Metric   `json:"avg_watch_time"`
	Follows            Metric   `json:"aggregated_follows"`
	PerformanceFactors []Metric `json:"performance_factors"` // skip rate and others
	Likes              int      `json:"likes"`
	Comments           int      `json:"comments"`
	Saves              int      `json:"saves"`
	Reposts            int      `json:"reposts"`
	Shares             *int     `json:"shares"`
	FollowersViews     int      `json:"followers_views"`
	NonFollowersViews  int      `json:"non_followers_views"`
	// ViewsOverTime holds all/followers/non_followers series and media_created_at.
	ViewsOverTime json.RawMessage `json:"views_over_time"`
	Demographics  json.RawMessage `json:"demographics"`
	LinkedReels   json.RawMessage `json:"linked_reels"`
	ThumbnailURL  string          `json:"thumbnail_url"`
}

ReelInsights are the metrics of a Reel or long-form video.

type ReelOptions added in v0.6.0

type ReelOptions struct {
	// Caption, ShareToThreads and the hidden counts work as for photos.
	// ShareToStory asks Instagram to reshare the Reel to the story itself.
	PostOptions
	// HideFromFeed keeps the Reel out of the feed (no clips_share_preview_to_feed).
	HideFromFeed     bool
	DisableComments  bool
	AllowDownloads   bool // third_party_downloads_enabled
	DisableTemplate  bool // is_template_disabled: others cannot use the Reel as a template
	Captions         bool // auto-generated captions (video_subtitles_enabled)
	TranslateCaption bool // translated captions (video_subtitles_translations_enabled)
	Gifting          bool // is_gifting_enabled
	Audience         Audience
	// CoverFrameMs picks the cover frame at that offset into the video.
	CoverFrameMs int
	// Trial posts a trial Reel, shown to non-followers first; Instagram offers
	// trials to professional accounts. A personal account gets HTTP 500, and the
	// Reel may still be published as a normal, public Reel.
	Trial TrialStrategy
	// VoiceTranslation asks for AI voice translation of the audio. The app also
	// has an upload-time form (autodub_creation_params) that needs its segmented
	// upload; this sends the configure_to_clips form, which Instagram accepts.
	VoiceTranslation *VoiceTranslation
	// ScheduledAt publishes the Reel later instead of now.
	ScheduledAt time.Time
	// Extra sets any other configure_to_clips field, last, so it also overrides the above.
	Extra map[string]any
}

ReelOptions are the optional fields of a Reel. The zero value posts with no caption and leaves every toggle at the account's default. Each field maps to a configure_to_clips parameter as the app sends it; docs/reel-fields.md lists them all.

type ReelSettings

type ReelSettings struct {
	AllowStoryReshare              bool   `json:"allow_story_reshare"`
	MessagePrefs                   string `json:"message_prefs"`
	PersistStoriesToPrivateProfile bool   `json:"persist_stories_to_private_profile"`
	ReelAutoArchive                string `json:"reel_auto_archive"`
	SaveRecentStoriesCaptures      bool   `json:"save_recent_stories_captures"`
	SaveToCameraRoll               bool   `json:"save_to_camera_roll"`
	BlockedReelsCount              int    `json:"blocked_reels_count"`
}

type Session

type Session = httplog.Session

Session: generate with `httplog session log_http.txt > session.json`.

type StoryCTA

type StoryCTA struct {
	Links []struct {
		LinkType                                int    `json:"linkType"`
		WebURI                                  string `json:"webUri"`
		AndroidClass                            string `json:"androidClass"`
		Package                                 string `json:"package"`
		DeeplinkURI                             string `json:"deeplinkUri"`
		CallToActionTitle                       string `json:"callToActionTitle"`
		RedirectURI                             any    `json:"redirectUri"`
		LeadGenFormID                           string `json:"leadGenFormId"`
		IgUserID                                string `json:"igUserId"`
		AppInstallObjectiveInvalidationBehavior any    `json:"appInstallObjectiveInvalidationBehavior"`
	} `json:"links"`
}

type StoryOptions added in v0.7.1

type StoryOptions struct {
	// LinkPost is a post or Reel opened by tapping the story. The link draws
	// nothing: the story shows the image as uploaded, so put any preview of
	// the post in the image. Instagram caps the tap area at the centered half
	// of the frame in each direction.
	LinkPost *Item
}

type StoryReelMention

type StoryReelMention struct {
	X           float64 `json:"x"`
	Y           float64 `json:"y"`
	Z           int     `json:"z"`
	Width       float64 `json:"width"`
	Height      float64 `json:"height"`
	Rotation    float64 `json:"rotation"`
	IsPinned    int     `json:"is_pinned"`
	IsHidden    int     `json:"is_hidden"`
	IsSticker   int     `json:"is_sticker"`
	IsFBSticker int     `json:"is_fb_sticker"`
	User        User
	DisplayType string `json:"display_type"`
}

type SubscriptionInsights added in v0.7.0

type SubscriptionInsights struct {
	TotalEarned string `json:"formatted_total_amount_earned_by_account"`
	// Per-media earnings; empty on every account seen so far, so the shape is unknown.
	MediaInsights []json.RawMessage `json:"media_insights"`
}

SubscriptionInsights is the paid subscriptions (user pay) dashboard.

type Tag

type Tag struct {
	In []struct {
		User                  User      `json:"user"`
		Position              []float64 `json:"position"`
		StartTimeInVideoInSec any       `json:"start_time_in_video_in_sec"`
		DurationInVideoInSec  any       `json:"duration_in_video_in_sec"`
	} `json:"in"`
}

type Thread added in v0.7.0

type Thread struct {
	ThreadID       string        `json:"thread_id"`
	ThreadV2ID     string        `json:"thread_v2_id"`
	Title          string        `json:"thread_title"`
	Users          []*User       `json:"users"`
	LeftUsers      []*User       `json:"left_users"`
	AdminUserIDs   []Int64       `json:"admin_user_ids"`
	Items          []*DirectItem `json:"items"`
	LastActivityAt Int64         `json:"last_activity_at"`
	ViewerID       Int64         `json:"viewer_id"`
	IsGroup        bool          `json:"is_group"`
	Muted          bool          `json:"muted"`
	IsPin          bool          `json:"is_pin"`
	Named          bool          `json:"named"`
	Canonical      bool          `json:"canonical"`
	Pending        bool          `json:"pending"`
	OldestCursor   string        `json:"oldest_cursor"`
	NewestCursor   string        `json:"newest_cursor"`
	HasOlder       bool          `json:"has_older"`
	HasNewer       bool          `json:"has_newer"`
	// LastSeenAt is keyed by user id.
	LastSeenAt map[string]ThreadSeen `json:"last_seen_at"`
	// contains filtered or unexported fields
}

Thread is a direct-message conversation.

func (*Thread) MarkSeen added in v0.7.0

func (t *Thread) MarkSeen(ctx context.Context, item *DirectItem) error

MarkSeen marks the thread read up to item.

func (*Thread) Messages added in v0.7.0

func (t *Thread) Messages() *Pager[*DirectItem]

Messages pages backwards through the thread's messages, newest first. A thread from Thread already holds the first page, so the walk starts after it.

func (*Thread) SendText added in v0.7.0

func (t *Thread) SendText(ctx context.Context, text string) (*DirectSent, error)

SendText sends a text message to the thread.

type ThreadSeen added in v0.7.0

type ThreadSeen struct {
	Timestamp string `json:"timestamp"`
	ItemID    string `json:"item_id"`
}

type TimeSeries added in v0.7.0

type TimeSeries struct {
	DataPoints []DataPoint `json:"data_points"`
}

TimeSeries is a chart, one point a day.

type Timeline

type Timeline struct {
	*Pager[*Item]
	// contains filtered or unexported fields
}

Timeline pages the home feed. Its first page is a cold start; Refresh reloads the head like pull-to-refresh.

func (*Timeline) Refresh

func (tl *Timeline) Refresh(ctx context.Context) error

type TranslateFromLanguage added in v0.7.0

type TranslateFromLanguage struct {
	Language string `json:"language"`
	Enabled  bool   `json:"enabled"`
}

type TranslationCreationSettings added in v0.7.0

type TranslationCreationSettings struct {
	VoiceTranslation  bool     `json:"voice_translation_opt_in"`
	LipSync           bool     `json:"lip_sync_opt_in"`
	ApprovalFlow      bool     `json:"approval_flow_opt_in"`
	AcceptedConsent   bool     `json:"has_accepted_voice_translations_consent_nux"`
	SeenConsent       bool     `json:"has_seen_voice_translations_consent_nux"`
	DisabledLanguages []string `json:"user_disabled_languages"`
}

TranslationCreationSettings are the account-wide AI voice translation choices for its own Reels.

type TranslationCreationUpdate added in v0.7.0

type TranslationCreationUpdate struct {
	VoiceTranslation *bool `json:"voice_translation_opt_in"`
	SeenConsent      *bool `json:"has_seen_voice_translations_consent_nux"`
	LipSync          *bool `json:"lip_sync_opt_in"`
	AcceptedConsent  *bool `json:"has_accepted_voice_translations_consent_nux"`
	ApprovalFlow     *bool `json:"approval_flow_opt_in"`
}

TranslationCreationUpdate changes the account's AI voice translation choices; a nil field is left as it is (the app sends it as null).

type TranslationSettings added in v0.7.0

type TranslationSettings struct {
	PreferredLanguages      PreferredLanguages          `json:"preferred_languages"`
	TranslateFrom           []TranslateFromLanguage     `json:"translate_from_preference"`
	TextTranslations        bool                        `json:"has_text_translations_consumption_enabled"`
	SubtitlesLanguage       string                      `json:"unified_subtitles_display_lang"`
	SubtitlesEnabled        bool                        `json:"unified_subtitles_enabled_pref"`
	Creation                TranslationCreationSettings `json:"translations_creation_settings"`
	ViewerPredictedLanguage string                      `json:"viewer_predicted_language"`
}

TranslationSettings are the account's translation preferences: what it reads translated, and how its own Reels get AI voice translation.

type Tray

type Tray struct {
	Reels                []*Reel `json:"tray"`
	StoryRankingToken    string  `json:"story_ranking_token"`
	FaceFilterNuxVersion int     `json:"face_filter_nux_version"`
	HasNewNuxStory       bool    `json:"has_new_nux_story"`
	NuxEligible          bool    `json:"stories_viewer_gestures_nux_eligible"`
	StickerVersion       float64 `json:"sticker_version"`
	ResponseTS           float64 `json:"response_timestamp"`
	Status               string  `json:"status"`
	EmojiReactionsConfig struct {
		UfiType                        float64 `json:"ufi_type"`
		DeliveryType                   float64 `json:"delivery_type"`
		OverlaySkinTonePickerEnabled   bool    `json:"overlay_skin_tone_picker_enabled"`
		SwipeUpToShowReactions         bool    `json:"swipe_up_to_show_reactions"`
		ComposerNuxType                float64 `json:"composer_nux_type"`
		HideStoryViewCount             bool    `json:"hide_story_view_count"`
		ReactionTrayInteractivePanning bool    `json:"reaction_tray_interactive_panning_enabled"`
		PersistentSelfStoryBadge       bool    `json:"persistent_self_story_badge_enabled"`
		SelfstoryBadging               bool    `json:"self_story_badging_enabled"`
		ExitTestNux                    bool    `json:"exit_test_nux_enabled"`
	} `json:"emoji_reactions_config"`
}

type TrayReason

type TrayReason string
const (
	TrayColdStart     TrayReason = "cold_start"
	TrayPullToRefresh TrayReason = "pull_to_refresh"
)

type TrialStrategy added in v0.6.0

type TrialStrategy string

TrialStrategy is when a trial Reel graduates to followers.

const (
	TrialManual      TrialStrategy = "manual"         // the creator decides
	TrialPerformance TrialStrategy = "ss_performance" // automatically, if it performs well
	TrialTimeLimit   TrialStrategy = "time_limit"     // automatically, after a delay
)

type User

type User struct {
	ID                     Int64  `json:"pk"`
	Username               string `json:"username"`
	FullName               string `json:"full_name,omitempty"`
	Email                  string `json:"email,omitempty"`
	PhoneNumber            string `json:"phone_number,omitempty"`
	WhatsappNumber         string `json:"whatsapp_number,omitempty"`
	Gender                 int    `json:"gender,omitempty"`
	PublicEmail            string `json:"public_email,omitempty"`
	PublicPhoneNumber      string `json:"public_phone_number,omitempty"`
	PublicPhoneCountryCode string `json:"public_phone_country_code,omitempty"`
	ContactPhoneNumber     string `json:"contact_phone_number,omitempty"`

	IsPrivate                  bool   `json:"is_private"`
	IsVerified                 bool   `json:"is_verified"`
	ExternalURL                string `json:"external_url,omitempty"`
	ExternalLynxURL            string `json:"external_lynx_url,omitempty"`
	FollowerCount              int    `json:"follower_count"`
	FollowingCount             int    `json:"following_count"`
	ProfilePicID               string `json:"profile_pic_id,omitempty"`
	ProfilePicURL              string `json:"profile_pic_url,omitempty"`
	HasAnonymousProfilePicture bool   `json:"has_anonymous_profile_picture"`
	Biography                  string `json:"biography,omitempty"`
	BiographyWithEntities      struct {
		RawText  string `json:"raw_text"`
		Entities []any  `json:"entities"`
	} `json:"biography_with_entities"`
	BiographyProductMentions []any `json:"biography_products_mentions"`

	IsNeedy                        bool    `json:"is_needy"`
	IsInterestAccount              bool    `json:"is_interest_account"`
	IsVideoCreator                 bool    `json:"is_video_creator"`
	IsBusiness                     bool    `json:"is_business"`
	BestiesCount                   int     `json:"besties_count"`
	ShowBestiesBadge               bool    `json:"show_besties_badge"`
	RecentlyBestiedByCount         int     `json:"recently_bestied_by_count"`
	AccountType                    int     `json:"account_type"`
	AccountBadges                  []any   `json:"account_badges,omitempty"`
	FbIdV2                         Int64   `json:"fbid_v2"`
	IsUnpublished                  bool    `json:"is_unpublished"`
	UserTagsCount                  int     `json:"usertags_count"`
	UserTagReviewEnabled           bool    `json:"usertag_review_enabled"`
	FollowingTagCount              int     `json:"following_tag_count"`
	MutualFollowersID              []Int64 `json:"profile_context_mutual_follow_ids,omitempty"`
	FollowFrictionType             int     `json:"follow_friction_type"`
	ProfileContext                 string  `json:"profile_context,omitempty"`
	HasBiographyTranslation        bool    `json:"has_biography_translation"`
	HasSavedItems                  bool    `json:"has_saved_items"`
	HasChaining                    bool    `json:"has_chaining"`
	IsFavorite                     bool    `json:"is_favorite"`
	IsFavoriteForStories           bool    `json:"is_favorite_for_stories"`
	IsFavoriteForHighlights        bool    `json:"is_favorite_for_highlights"`
	IsProfileActionNeeded          bool    `json:"is_profile_action_needed"`
	CanBeReportedAsFraud           bool    `json:"can_be_reported_as_fraud"`
	CanSeeSupportInbox             bool    `json:"can_see_support_inbox"`
	CanSeeSupportInboxV1           bool    `json:"can_see_support_inbox_v1"`
	CanSeePrimaryCountryInsettings bool    `json:"can_see_primary_country_in_settings"`
	CanFollowHashtag               bool    `json:"can_follow_hashtag"`

	CanBoostPosts                  bool   `json:"can_boost_post"`
	CanSeeOrganicInsights          bool   `json:"can_see_organic_insights"`
	CanConvertToBusiness           bool   `json:"can_convert_to_business"`
	CanCreateSponsorTags           bool   `json:"can_create_sponsor_tags"`
	CanCreateNewFundraiser         bool   `json:"can_create_new_standalone_fundraiser"`
	CanCreateNewPersonalFundraiser bool   `json:"can_create_new_standalone_personal_fundraiser"`
	CanBeTaggedAsSponsor           bool   `json:"can_be_tagged_as_sponsor"`
	PersonalAccountAdsPageName     string `json:"personal_account_ads_page_name,omitempty"`
	PersonalAccountAdsID           string `json:"personal_account_ads_page_id,omitempty"`
	Category                       string `json:"category,omitempty"`

	ShowShoppableFeed           bool `json:"show_shoppable_feed"`
	CanTagProductsFromMerchants bool `json:"can_tag_products_from_merchants"`

	IsMutedWordsGlobalEnabled bool   `json:"is_muted_words_global_enabled"`
	IsMutedWordsCustomEnabled bool   `json:"is_muted_words_custom_enabled"`
	AllowedCommenterType      string `json:"allowed_commenter_type,omitempty"`

	MediaCount          int   `json:"media_count"`
	IGTVCount           int   `json:"total_igtv_videos"`
	HasIGTVSeries       bool  `json:"has_igtv_series"`
	HasVideos           bool  `json:"has_videos"`
	TotalClipCount      int   `json:"total_clips_count"`
	TotalAREffects      int   `json:"total_ar_effects"`
	GeoMediaCount       int   `json:"geo_media_count"`
	HasProfileVideoFeed bool  `json:"has_profile_video_feed"`
	LiveBroadcastID     Int64 `json:"live_broadcast_id"`

	HasPlacedOrders bool `json:"has_placed_orders"`

	ShowInsightTerms           bool `json:"show_insights_terms"`
	ShowConversionEditEntry    bool `json:"show_conversion_edit_entry"`
	ShowPostsInsightEntryPoint bool `json:"show_post_insights_entry_point"`
	ShoppablePostsCount        int  `json:"shoppable_posts_count"`
	RequestContactEnabled      bool `json:"request_contact_enabled"`
	FeedPostReshareDisabled    bool `json:"feed_post_reshare_disabled"`
	CreatorShoppingInfo        struct {
		LinkedMerchantAccounts []any `json:"linked_merchant_accounts,omitempty"`
	} `json:"creator_shopping_info,omitempty"`
	StandaloneFundraiserInfo struct {
		HasActiveFundraiser                 bool   `json:"has_active_fundraiser"`
		FundraiserID                        Int64  `json:"fundraiser_id"`
		FundraiserTitle                     string `json:"fundraiser_title"`
		FundraiserType                      any    `json:"fundraiser_type"`
		FormattedGoalAmount                 string `json:"formatted_goal_amount"`
		BeneficiaryUsername                 string `json:"beneficiary_username"`
		FormattedFundraiserProgressInfoText string `json:"formatted_fundraiser_progress_info_text"`
		PercentRaised                       any    `json:"percent_raised"`
	} `json:"standalone_fundraiser_info"`
	AggregatePromoteEngagement   bool         `json:"aggregate_promote_engagement"`
	AllowMentionSetting          string       `json:"allow_mention_setting,omitempty"`
	AllowTagSetting              string       `json:"allow_tag_setting,omitempty"`
	LimitedInteractionsEnabled   bool         `json:"limited_interactions_enabled"`
	ReelAutoArchive              string       `json:"reel_auto_archive,omitempty"`
	HasHighlightReels            bool         `json:"has_highlight_reels"`
	HightlightReshareDisabled    bool         `json:"highlight_reshare_disabled"`
	IsMemorialized               bool         `json:"is_memorialized"`
	HasGuides                    bool         `json:"has_guides"`
	HasAffiliateShop             bool         `json:"has_active_affiliate_shop"`
	CityID                       Int64        `json:"city_id"`
	CityName                     string       `json:"city_name,omitempty"`
	AddressStreet                string       `json:"address_street,omitempty"`
	DirectMessaging              string       `json:"direct_messaging,omitempty"`
	Latitude                     float64      `json:"latitude"`
	Longitude                    float64      `json:"longitude"`
	BusinessContactMethod        string       `json:"business_contact_method"`
	IncludeDirectBlacklistStatus bool         `json:"include_direct_blacklist_status"`
	HdProfilePicURLInfo          PicURLInfo   `json:"hd_profile_pic_url_info,omitempty"`
	HdProfilePicVersions         []PicURLInfo `json:"hd_profile_pic_versions,omitempty"`
	Byline                       string       `json:"byline"`
	SocialContext                string       `json:"social_context,omitempty"`
	SearchSocialContext          string       `json:"search_social_context,omitempty"`
	MutualFollowersCount         float64      `json:"mutual_followers_count"`
	LatestReelMedia              Int64        `json:"latest_reel_media,omitempty"`
	IsCallToActionEnabled        bool         `json:"is_call_to_action_enabled"`
	IsPotentialBusiness          bool         `json:"is_potential_business"`
	FbPageCallToActionID         string       `json:"fb_page_call_to_action_id,omitempty"`
	FbPayExperienceEnabled       bool         `json:"fbpay_experience_enabled"`
	Zip                          string       `json:"zip,omitempty"`
	Friendship                   Friendship   `json:"friendship_status"`
	AutoExpandChaining           bool         `json:"auto_expand_chaining"`

	AllowedToCreateNonprofitFundraisers        bool   `json:"is_allowed_to_create_standalone_nonprofit_fundraisers"`
	AllowedToCreatePersonalFundraisers         bool   `json:"is_allowed_to_create_standalone_personal_fundraisers"`
	IsEligibleToShowFbCrossSharingNux          bool   `json:"is_eligible_to_show_fb_cross_sharing_nux"`
	PageIDForNewSumaBizAccount                 any    `json:"page_id_for_new_suma_biz_account"`
	EligibleShoppingSignupEntrypoints          []any  `json:"eligible_shopping_signup_entrypoints"`
	IsIgdProductPickerEnabled                  bool   `json:"is_igd_product_picker_enabled"`
	IsEligibleForAffiliateShopOnboarding       bool   `json:"is_eligible_for_affiliate_shop_onboarding"`
	IsEligibleForSMBSupportFlow                bool   `json:"is_eligible_for_smb_support_flow"`
	EligibleShoppingFormats                    []any  `json:"eligible_shopping_formats"`
	NeedsToAcceptShoppingSellerOnboardingTerms bool   `json:"needs_to_accept_shopping_seller_onboarding_terms"`
	SellerShoppableFeedType                    string `json:"seller_shoppable_feed_type"`
	VisibleProducts                            int    `json:"num_visible_storefront_products"`
	IsShoppingCatalogSettingsEnabled           bool   `json:"is_shopping_settings_enabled"`
	IsShoppingCommunityContentEnabled          bool   `json:"is_shopping_community_content_enabled"`
	IsShoppingAutoHighlightEnabled             bool   `json:"is_shopping_auto_highlight_eligible"`
	IsShoppingCatalogSourceSelectionEnabled    bool   `json:"is_shopping_catalog_source_selection_enabled"`
	ProfessionalConversionSuggestedAccountType int    `json:"professional_conversion_suggested_account_type"`
	InteropMessagingUserfbid                   Int64  `json:"interop_messaging_user_fbid"`
	ExistingUserAgeCollectionEnabled           bool   `json:"existing_user_age_collection_enabled"`
	AboutYourAccountBloksEntrypointEnabled     bool   `json:"about_your_account_bloks_entrypoint_enabled"`
	OpenExternalUrlWithInAppBrowser            bool   `json:"open_external_url_with_in_app_browser"`
	MerchantCheckoutStyle                      string `json:"merchant_checkout_style"`

	ProfilePic []byte
	// contains filtered or unexported fields
}

func (*User) ApproveFollowRequest added in v0.7.0

func (user *User) ApproveFollowRequest(ctx context.Context) error

ApproveFollowRequest accepts the user's request to follow the account.

func (*User) Block added in v0.7.0

func (user *User) Block(ctx context.Context) error

Block blocks the user and updates user.Friendship.

func (*User) DownloadProfilePic

func (user *User) DownloadProfilePic(ctx context.Context) ([]byte, error)

func (*User) DownloadProfilePicTo

func (user *User) DownloadProfilePicTo(ctx context.Context, dst string) (string, error)

DownloadProfilePicTo saves the picture to dst, see Item.DownloadTo; it returns the path written.

func (*User) Follow

func (user *User) Follow(ctx context.Context) error

Follow updates user.Friendship; for a private account it becomes an outgoing request.

func (*User) Followers

func (user *User) Followers() *Pager[*User]

func (*User) Following

func (user *User) Following() *Pager[*User]

func (*User) Highlights

func (user *User) Highlights(ctx context.Context) ([]*Reel, error)

Highlights returns every highlight cover, following the tray cursor past the first 10; LoadReels fills their items.

func (*User) IgnoreFollowRequest added in v0.7.0

func (user *User) IgnoreFollowRequest(ctx context.Context) error

IgnoreFollowRequest declines the user's request to follow the account.

func (*User) Info

func (user *User) Info(ctx context.Context) error

Info uses the legacy users/{id}/info/ endpoint, which the app still calls for the own account.

func (*User) LoadFriendship

func (user *User) LoadFriendship(ctx context.Context) (*Friendship, error)

func (*User) Mute added in v0.7.0

func (user *User) Mute(ctx context.Context, posts, stories bool) error

Mute hides a followed account's posts and/or stories from the feed and tray.

func (*User) Posts

func (user *User) Posts() *Pager[*Item]

func (*User) RemoveFollower added in v0.7.0

func (user *User) RemoveFollower(ctx context.Context) error

RemoveFollower makes the user stop following the account.

func (*User) SetInstagram

func (user *User) SetInstagram(insta *Instagram)

func (*User) Stories

func (user *User) Stories(ctx context.Context) (*Reel, error)

func (*User) SuggestedUsers

func (user *User) SuggestedUsers(ctx context.Context) ([]*User, error)

SuggestedUsers is the "similar accounts" carousel shown on a profile.

func (*User) Sync

func (user *User) Sync(ctx context.Context) error

func (*User) TaggedPosts added in v0.7.0

func (user *User) TaggedPosts() *Pager[*Item]

TaggedPosts pages the posts the user is tagged in.

func (*User) Unblock added in v0.7.0

func (user *User) Unblock(ctx context.Context) error

func (*User) Unfollow

func (user *User) Unfollow(ctx context.Context) error

func (*User) UnmarshalJSON added in v0.1.1

func (user *User) UnmarshalJSON(b []byte) error

func (*User) Unmute added in v0.7.0

func (user *User) Unmute(ctx context.Context, posts, stories bool) error

type Video

type Video struct {
	Type   int    `json:"type"`
	Width  int    `json:"width"`
	Height int    `json:"height"`
	URL    string `json:"url"`
	ID     string `json:"id"`
}

type ViewsCount added in v0.7.0

type ViewsCount struct {
	Total Metric        `json:"total"`
	Share FollowerShare `json:"follow_type_breakdown"`
}

type VoiceTranslation added in v0.6.0

type VoiceTranslation struct {
	InputLanguage string
	Languages     []string
	LipSync       bool
	// Approval holds each translation for the creator to review before it goes live.
	Approval bool
}

VoiceTranslation languages are ISO 639-3 codes ("eng", "spa", "fra"); the app offers eng and spa by default.

type VoiceTranslations added in v0.7.0

type VoiceTranslations struct {
	Languages []string          `json:"translated_langs_for_autodub"`
	Status    []json.RawMessage `json:"autodub_status"`
}

VoiceTranslations is a Reel's AI voice translation state. Both lists were empty on every Reel seen so far, so their element format is unverified.

Directories

Path Synopsis
cmd
httplog command
Command httplog inspects a device HTTP capture (log_http.txt).
Command httplog inspects a device HTTP capture (log_http.txt).
login command
Command login performs one Instagram password login and saves the session.
Command login performs one Instagram password login and saves the session.
smoke command
Command smoke runs the API methods against a logged-in session and reports which ones work.
Command smoke runs the API methods against a logged-in session and reports which ones work.
internal
httplog
Package httplog parses the plain-text HTTP capture format produced by the device proxy (log_http.txt) into structured entries.
Package httplog parses the plain-text HTTP capture format produced by the device proxy (log_http.txt) into structured entries.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL